OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [libbfd.c] - Blame information for rev 1770

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Assorted BFD support routines, only used internally.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001
4
   Free Software Foundation, Inc.
5
   Written by Cygnus Support.
6
 
7
This file is part of BFD, the Binary File Descriptor library.
8
 
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
 
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include "bfd.h"
24
#include "sysdep.h"
25
#include "libbfd.h"
26
 
27
#ifndef HAVE_GETPAGESIZE
28
#define getpagesize() 2048
29
#endif
30
 
31
static int real_read PARAMS ((PTR, size_t, size_t, FILE *));
32
 
33
/*
34
SECTION
35
        Internal functions
36
 
37
DESCRIPTION
38
        These routines are used within BFD.
39
        They are not intended for export, but are documented here for
40
        completeness.
41
*/
42
 
43
/* A routine which is used in target vectors for unsupported
44
   operations.  */
45
 
46
boolean
47
bfd_false (ignore)
48
     bfd *ignore ATTRIBUTE_UNUSED;
49
{
50
  bfd_set_error (bfd_error_invalid_operation);
51
  return false;
52
}
53
 
54
/* A routine which is used in target vectors for supported operations
55
   which do not actually do anything.  */
56
 
57
boolean
58
bfd_true (ignore)
59
     bfd *ignore ATTRIBUTE_UNUSED;
60
{
61
  return true;
62
}
63
 
64
/* A routine which is used in target vectors for unsupported
65
   operations which return a pointer value.  */
66
 
67
PTR
68
bfd_nullvoidptr (ignore)
69
     bfd *ignore ATTRIBUTE_UNUSED;
70
{
71
  bfd_set_error (bfd_error_invalid_operation);
72
  return NULL;
73
}
74
 
75
int
76
bfd_0 (ignore)
77
     bfd *ignore ATTRIBUTE_UNUSED;
78
{
79
  return 0;
80
}
81
 
82
unsigned int
83
bfd_0u (ignore)
84
     bfd *ignore ATTRIBUTE_UNUSED;
85
{
86
   return 0;
87
}
88
 
89
long
90
bfd_0l (ignore)
91
     bfd *ignore ATTRIBUTE_UNUSED;
92
{
93
  return 0;
94
}
95
 
96
/* A routine which is used in target vectors for unsupported
97
   operations which return -1 on error.  */
98
 
99
long
100
_bfd_n1 (ignore_abfd)
101
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
102
{
103
  bfd_set_error (bfd_error_invalid_operation);
104
  return -1;
105
}
106
 
107
void
108
bfd_void (ignore)
109
     bfd *ignore ATTRIBUTE_UNUSED;
110
{
111
}
112
 
113
boolean
114
_bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd)
115
     bfd *ignore_core_bfd ATTRIBUTE_UNUSED;
116
     bfd *ignore_exec_bfd ATTRIBUTE_UNUSED;
117
{
118
  bfd_set_error (bfd_error_invalid_operation);
119
  return false;
120
}
121
 
122
/* Routine to handle core_file_failing_command entry point for targets
123
   without core file support.  */
124
 
125
char *
126
_bfd_nocore_core_file_failing_command (ignore_abfd)
127
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
128
{
129
  bfd_set_error (bfd_error_invalid_operation);
130
  return (char *)NULL;
131
}
132
 
133
/* Routine to handle core_file_failing_signal entry point for targets
134
   without core file support.  */
135
 
136
int
137
_bfd_nocore_core_file_failing_signal (ignore_abfd)
138
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
139
{
140
  bfd_set_error (bfd_error_invalid_operation);
141
  return 0;
142
}
143
 
144
const bfd_target *
145
_bfd_dummy_target (ignore_abfd)
146
     bfd *ignore_abfd ATTRIBUTE_UNUSED;
147
{
148
  bfd_set_error (bfd_error_wrong_format);
149
  return 0;
150
}
151
 
152
/* Allocate memory using malloc.  */
153
 
154
PTR
155
bfd_malloc (size)
156
     size_t size;
157
{
158
  PTR ptr;
159
 
160
  ptr = (PTR) malloc (size);
161
  if (ptr == NULL && size != 0)
162
    bfd_set_error (bfd_error_no_memory);
163
  return ptr;
164
}
165
 
166
/* Reallocate memory using realloc.  */
167
 
168
PTR
169
bfd_realloc (ptr, size)
170
     PTR ptr;
171
     size_t size;
172
{
173
  PTR ret;
174
 
175
  if (ptr == NULL)
176
    ret = malloc (size);
177
  else
178
    ret = realloc (ptr, size);
179
 
180
  if (ret == NULL)
181
    bfd_set_error (bfd_error_no_memory);
182
 
183
  return ret;
184
}
185
 
186
/* Allocate memory using malloc and clear it.  */
187
 
188
PTR
189
bfd_zmalloc (size)
190
     size_t size;
191
{
192
  PTR ptr;
193
 
194
  ptr = (PTR) malloc (size);
195
 
196
  if (size != 0)
197
    {
198
      if (ptr == NULL)
199
        bfd_set_error (bfd_error_no_memory);
200
      else
201
        memset (ptr, 0, size);
202
    }
203
 
204
  return ptr;
205
}
206
 
207
/* Some IO code */
208
 
209
/* Note that archive entries don't have streams; they share their parent's.
210
   This allows someone to play with the iostream behind BFD's back.
211
 
212
   Also, note that the origin pointer points to the beginning of a file's
213
   contents (0 for non-archive elements).  For archive entries this is the
214
   first octet in the file, NOT the beginning of the archive header.  */
215
 
216
static int
217
real_read (where, a,b, file)
218
     PTR where;
219
     size_t a;
220
     size_t b;
221
     FILE *file;
222
{
223
  /* FIXME - this looks like an optimization, but it's really to cover
224
     up for a feature of some OSs (not solaris - sigh) that
225
     ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
226
     internally and tries to link against them.  BFD seems to be smart
227
     enough to realize there are no symbol records in the "file" that
228
     doesn't exist but attempts to read them anyway.  On Solaris,
229
     attempting to read zero bytes from a NULL file results in a core
230
     dump, but on other platforms it just returns zero bytes read.
231
     This makes it to something reasonable. - DJ */
232
  if (a == 0 || b == 0)
233
    return 0;
234
 
235
 
236
#if defined (__VAX) && defined (VMS)
237
  /* Apparently fread on Vax VMS does not keep the record length
238
     information.  */
239
  return read (fileno (file), where, a * b);
240
#else
241
  return fread (where, a, b, file);
242
#endif
243
}
244
 
245
/* Return value is amount read (FIXME: how are errors and end of file dealt
246
   with?  We never call bfd_set_error, which is probably a mistake).  */
247
 
248
bfd_size_type
249
bfd_read (ptr, size, nitems, abfd)
250
     PTR ptr;
251
     bfd_size_type size;
252
     bfd_size_type nitems;
253
     bfd *abfd;
254
{
255
  int nread;
256
 
257
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
258
    {
259
      struct bfd_in_memory *bim;
260
      bfd_size_type get;
261
 
262
      bim = (struct bfd_in_memory *) abfd->iostream;
263
      get = size * nitems;
264
      if (abfd->where + get > bim->size)
265
        {
266
          if (bim->size < (bfd_size_type) abfd->where)
267
            get = 0;
268
          else
269
            get = bim->size - abfd->where;
270
          bfd_set_error (bfd_error_file_truncated);
271
        }
272
      memcpy (ptr, bim->buffer + abfd->where, get);
273
      abfd->where += get;
274
      return get;
275
    }
276
 
277
  nread = real_read (ptr, 1, (size_t) (size*nitems), bfd_cache_lookup(abfd));
278
  if (nread > 0)
279
    abfd->where += nread;
280
 
281
  /* Set bfd_error if we did not read as much data as we expected.
282
 
283
     If the read failed due to an error set the bfd_error_system_call,
284
     else set bfd_error_file_truncated.
285
 
286
     A BFD backend may wish to override bfd_error_file_truncated to
287
     provide something more useful (eg. no_symbols or wrong_format).  */
288
  if (nread != (int) (size * nitems))
289
    {
290
      if (ferror (bfd_cache_lookup (abfd)))
291
        bfd_set_error (bfd_error_system_call);
292
      else
293
        bfd_set_error (bfd_error_file_truncated);
294
    }
295
 
296
  return nread;
297
}
298
 
299
/* The window support stuff should probably be broken out into
300
   another file....  */
301
/* The idea behind the next and refcount fields is that one mapped
302
   region can suffice for multiple read-only windows or multiple
303
   non-overlapping read-write windows.  It's not implemented yet
304
   though.  */
305
struct _bfd_window_internal {
306
  struct _bfd_window_internal *next;
307
  PTR data;
308
  bfd_size_type size;
309
  int refcount : 31;            /* should be enough...  */
310
  unsigned mapped : 1;          /* 1 = mmap, 0 = malloc */
311
};
312
 
313
void
314
bfd_init_window (windowp)
315
     bfd_window *windowp;
316
{
317
  windowp->data = 0;
318
  windowp->i = 0;
319
  windowp->size = 0;
320
}
321
 
322
/* Currently, if USE_MMAP is undefined, none if the window stuff is
323
   used.  Okay, so it's mis-named.  At least the command-line option
324
   "--without-mmap" is more obvious than "--without-windows" or some
325
   such.  */
326
#ifdef USE_MMAP
327
 
328
#undef HAVE_MPROTECT /* code's not tested yet */
329
 
330
#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE
331
#include <sys/mman.h>
332
#endif
333
 
334
#ifndef MAP_FILE
335
#define MAP_FILE 0
336
#endif
337
 
338
static int debug_windows;
339
 
340
void
341
bfd_free_window (windowp)
342
     bfd_window *windowp;
343
{
344
  bfd_window_internal *i = windowp->i;
345
  windowp->i = 0;
346
  windowp->data = 0;
347
  if (i == 0)
348
    return;
349
  i->refcount--;
350
  if (debug_windows)
351
    fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n",
352
             windowp, windowp->data, windowp->size, windowp->i);
353
  if (i->refcount != 0)
354
    return;
355
 
356
  if (i->mapped)
357
    {
358
#ifdef HAVE_MMAP
359
      munmap (i->data, i->size);
360
      goto no_free;
361
#else
362
      abort ();
363
#endif
364
    }
365
#ifdef HAVE_MPROTECT
366
  mprotect (i->data, i->size, PROT_READ | PROT_WRITE);
367
#endif
368
  free (i->data);
369
#ifdef HAVE_MMAP
370
 no_free:
371
#endif
372
  i->data = 0;
373
  /* There should be no more references to i at this point.  */
374
  free (i);
375
}
376
 
377
static int ok_to_map = 1;
378
 
379
boolean
380
bfd_get_file_window (abfd, offset, size, windowp, writable)
381
     bfd *abfd;
382
     file_ptr offset;
383
     bfd_size_type size;
384
     bfd_window *windowp;
385
     boolean writable;
386
{
387
  static size_t pagesize;
388
  bfd_window_internal *i = windowp->i;
389
  size_t size_to_alloc = size;
390
 
391
  if (debug_windows)
392
    fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)",
393
             abfd, (long) offset, (long) size,
394
             windowp, windowp->data, (unsigned long) windowp->size,
395
             windowp->i, writable);
396
 
397
  /* Make sure we know the page size, so we can be friendly to mmap.  */
398
  if (pagesize == 0)
399
    pagesize = getpagesize ();
400
  if (pagesize == 0)
401
    abort ();
402
 
403
  if (i == 0)
404
    {
405
      windowp->i = i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
406
      if (i == 0)
407
        return false;
408
      i->data = 0;
409
    }
410
#ifdef HAVE_MMAP
411
  if (ok_to_map
412
      && (i->data == 0 || i->mapped == 1)
413
      && (abfd->flags & BFD_IN_MEMORY) == 0)
414
    {
415
      file_ptr file_offset, offset2;
416
      size_t real_size;
417
      int fd;
418
      FILE *f;
419
 
420
      /* Find the real file and the real offset into it.  */
421
      while (abfd->my_archive != NULL)
422
        {
423
          offset += abfd->origin;
424
          abfd = abfd->my_archive;
425
        }
426
      f = bfd_cache_lookup (abfd);
427
      fd = fileno (f);
428
 
429
      /* Compute offsets and size for mmap and for the user's data.  */
430
      offset2 = offset % pagesize;
431
      if (offset2 < 0)
432
        abort ();
433
      file_offset = offset - offset2;
434
      real_size = offset + size - file_offset;
435
      real_size = real_size + pagesize - 1;
436
      real_size -= real_size % pagesize;
437
 
438
      /* If we're re-using a memory region, make sure it's big enough.  */
439
      if (i->data && i->size < size)
440
        {
441
          munmap (i->data, i->size);
442
          i->data = 0;
443
        }
444
      i->data = mmap (i->data, real_size,
445
                      writable ? PROT_WRITE | PROT_READ : PROT_READ,
446
                      (writable
447
                       ? MAP_FILE | MAP_PRIVATE
448
                       : MAP_FILE | MAP_SHARED),
449
                      fd, file_offset);
450
      if (i->data == (PTR) -1)
451
        {
452
          /* An error happened.  Report it, or try using malloc, or
453
             something.  */
454
          bfd_set_error (bfd_error_system_call);
455
          i->data = 0;
456
          windowp->data = 0;
457
          if (debug_windows)
458
            fprintf (stderr, "\t\tmmap failed!\n");
459
          return false;
460
        }
461
      if (debug_windows)
462
        fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n",
463
                 (long) real_size, i->data, (long) offset2);
464
      i->size = real_size;
465
      windowp->data = (PTR) ((bfd_byte *) i->data + offset2);
466
      windowp->size = size;
467
      i->mapped = 1;
468
      return true;
469
    }
470
  else if (debug_windows)
471
    {
472
      if (ok_to_map)
473
        fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"),
474
                 (unsigned long) i->data, (int) i->mapped);
475
      else
476
        fprintf (stderr, _("not mapping: env var not set\n"));
477
    }
478
#else
479
  ok_to_map = 0;
480
#endif
481
 
482
#ifdef HAVE_MPROTECT
483
  if (!writable)
484
    {
485
      size_to_alloc += pagesize - 1;
486
      size_to_alloc -= size_to_alloc % pagesize;
487
    }
488
#endif
489
  if (debug_windows)
490
    fprintf (stderr, "\n\t%s(%6ld)",
491
             i->data ? "realloc" : " malloc", (long) size_to_alloc);
492
  i->data = (PTR) bfd_realloc (i->data, size_to_alloc);
493
  if (debug_windows)
494
    fprintf (stderr, "\t-> %p\n", i->data);
495
  i->refcount = 1;
496
  if (i->data == NULL)
497
    {
498
      if (size_to_alloc == 0)
499
        return true;
500
      bfd_set_error (bfd_error_no_memory);
501
      return false;
502
    }
503
  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
504
    return false;
505
  i->size = bfd_read (i->data, size, 1, abfd);
506
  if (i->size != size)
507
    return false;
508
  i->mapped = 0;
509
#ifdef HAVE_MPROTECT
510
  if (!writable)
511
    {
512
      if (debug_windows)
513
        fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data,
514
                 (long) i->size);
515
      mprotect (i->data, i->size, PROT_READ);
516
    }
517
#endif
518
  windowp->data = i->data;
519
  windowp->size = i->size;
520
  return true;
521
}
522
 
523
#endif /* USE_MMAP */
524
 
525
bfd_size_type
526
bfd_write (ptr, size, nitems, abfd)
527
     CONST PTR ptr;
528
     bfd_size_type size;
529
     bfd_size_type nitems;
530
     bfd *abfd;
531
{
532
  long nwrote;
533
 
534
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
535
    {
536
      struct bfd_in_memory *bim = (struct bfd_in_memory *) (abfd->iostream);
537
      size *= nitems;
538
      if (abfd->where + size > bim->size)
539
        {
540
          long newsize, oldsize = (bim->size + 127) & ~127;
541
          bim->size = abfd->where + size;
542
          /* Round up to cut down on memory fragmentation */
543
          newsize = (bim->size + 127) & ~127;
544
          if (newsize > oldsize)
545
            {
546
              bim->buffer = bfd_realloc (bim->buffer, newsize);
547
              if (bim->buffer == 0)
548
                {
549
                  bim->size = 0;
550
                  return 0;
551
                }
552
            }
553
        }
554
      memcpy (bim->buffer + abfd->where, ptr, size);
555
      abfd->where += size;
556
      return size;
557
    }
558
 
559
  nwrote = fwrite (ptr, 1, (size_t) (size * nitems),
560
                   bfd_cache_lookup (abfd));
561
  if (nwrote > 0)
562
    abfd->where += nwrote;
563
  if ((bfd_size_type) nwrote != size * nitems)
564
    {
565
#ifdef ENOSPC
566
      if (nwrote >= 0)
567
        errno = ENOSPC;
568
#endif
569
      bfd_set_error (bfd_error_system_call);
570
    }
571
  return nwrote;
572
}
573
 
574
/*
575
INTERNAL_FUNCTION
576
        bfd_write_bigendian_4byte_int
577
 
578
SYNOPSIS
579
        void bfd_write_bigendian_4byte_int(bfd *abfd,  int i);
580
 
581
DESCRIPTION
582
        Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
583
        endian order regardless of what else is going on.  This is useful in
584
        archives.
585
 
586
*/
587
void
588
bfd_write_bigendian_4byte_int (abfd, i)
589
     bfd *abfd;
590
     int i;
591
{
592
  bfd_byte buffer[4];
593
  bfd_putb32(i, buffer);
594
  if (bfd_write((PTR)buffer, 4, 1, abfd) != 4)
595
    abort ();
596
}
597
 
598
long
599
bfd_tell (abfd)
600
     bfd *abfd;
601
{
602
  file_ptr ptr;
603
 
604
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
605
    return abfd->where;
606
 
607
  ptr = ftell (bfd_cache_lookup(abfd));
608
 
609
  if (abfd->my_archive)
610
    ptr -= abfd->origin;
611
  abfd->where = ptr;
612
  return ptr;
613
}
614
 
615
int
616
bfd_flush (abfd)
617
     bfd *abfd;
618
{
619
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
620
    return 0;
621
  return fflush (bfd_cache_lookup(abfd));
622
}
623
 
624
/* Returns 0 for success, negative value for failure (in which case
625
   bfd_get_error can retrieve the error code).  */
626
int
627
bfd_stat (abfd, statbuf)
628
     bfd *abfd;
629
     struct stat *statbuf;
630
{
631
  FILE *f;
632
  int result;
633
 
634
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
635
    abort ();
636
 
637
  f = bfd_cache_lookup (abfd);
638
  if (f == NULL)
639
    {
640
      bfd_set_error (bfd_error_system_call);
641
      return -1;
642
    }
643
  result = fstat (fileno (f), statbuf);
644
  if (result < 0)
645
    bfd_set_error (bfd_error_system_call);
646
  return result;
647
}
648
 
649
/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
650
   can retrieve the error code).  */
651
 
652
int
653
bfd_seek (abfd, position, direction)
654
     bfd *abfd;
655
     file_ptr position;
656
     int direction;
657
{
658
  int result;
659
  FILE *f;
660
  file_ptr file_position;
661
  /* For the time being, a BFD may not seek to it's end.  The problem
662
     is that we don't easily have a way to recognize the end of an
663
     element in an archive.  */
664
 
665
  BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
666
 
667
  if (direction == SEEK_CUR && position == 0)
668
    return 0;
669
 
670
  if ((abfd->flags & BFD_IN_MEMORY) != 0)
671
    {
672
      struct bfd_in_memory *bim;
673
 
674
      bim = (struct bfd_in_memory *) abfd->iostream;
675
 
676
      if (direction == SEEK_SET)
677
        abfd->where = position;
678
      else
679
        abfd->where += position;
680
 
681
      if ((bfd_size_type) abfd->where > bim->size)
682
        {
683
          if ((abfd->direction == write_direction) ||
684
              (abfd->direction == both_direction))
685
            {
686
              long newsize, oldsize = (bim->size + 127) & ~127;
687
              bim->size = abfd->where;
688
              /* Round up to cut down on memory fragmentation */
689
              newsize = (bim->size + 127) & ~127;
690
              if (newsize > oldsize)
691
                {
692
                  bim->buffer = bfd_realloc (bim->buffer, newsize);
693
                  if (bim->buffer == 0)
694
                    {
695
                      bim->size = 0;
696
                      bfd_set_error (bfd_error_no_memory);
697
                      return -1;
698
                    }
699
                }
700
            }
701
          else
702
            {
703
              abfd->where = bim->size;
704
              bfd_set_error (bfd_error_file_truncated);
705
              return -1;
706
            }
707
        }
708
      return 0;
709
    }
710
 
711
  if (abfd->format != bfd_archive && abfd->my_archive == 0)
712
    {
713
#if 0
714
      /* Explanation for this code: I'm only about 95+% sure that the above
715
         conditions are sufficient and that all i/o calls are properly
716
         adjusting the `where' field.  So this is sort of an `assert'
717
         that the `where' field is correct.  If we can go a while without
718
         tripping the abort, we can probably safely disable this code,
719
         so that the real optimizations happen.  */
720
      file_ptr where_am_i_now;
721
      where_am_i_now = ftell (bfd_cache_lookup (abfd));
722
      if (abfd->my_archive)
723
        where_am_i_now -= abfd->origin;
724
      if (where_am_i_now != abfd->where)
725
        abort ();
726
#endif
727
      if (direction == SEEK_SET && position == abfd->where)
728
        return 0;
729
    }
730
  else
731
    {
732
      /* We need something smarter to optimize access to archives.
733
         Currently, anything inside an archive is read via the file
734
         handle for the archive.  Which means that a bfd_seek on one
735
         component affects the `current position' in the archive, as
736
         well as in any other component.
737
 
738
         It might be sufficient to put a spike through the cache
739
         abstraction, and look to the archive for the file position,
740
         but I think we should try for something cleaner.
741
 
742
         In the meantime, no optimization for archives.  */
743
    }
744
 
745
  f = bfd_cache_lookup (abfd);
746
  file_position = position;
747
  if (direction == SEEK_SET && abfd->my_archive != NULL)
748
    file_position += abfd->origin;
749
 
750
  result = fseek (f, file_position, direction);
751
  if (result != 0)
752
    {
753
      int hold_errno = errno;
754
 
755
      /* Force redetermination of `where' field.  */
756
      bfd_tell (abfd);
757
 
758
      /* An EINVAL error probably means that the file offset was
759
         absurd.  */
760
      if (hold_errno == EINVAL)
761
        bfd_set_error (bfd_error_file_truncated);
762
      else
763
        {
764
          bfd_set_error (bfd_error_system_call);
765
          errno = hold_errno;
766
        }
767
    }
768
  else
769
    {
770
      /* Adjust `where' field.  */
771
      if (direction == SEEK_SET)
772
        abfd->where = position;
773
      else
774
        abfd->where += position;
775
    }
776
  return result;
777
}
778
 
779
/** The do-it-yourself (byte) sex-change kit */
780
 
781
/* The middle letter e.g. get<b>short indicates Big or Little endian
782
   target machine.  It doesn't matter what the byte order of the host
783
   machine is; these routines work for either.  */
784
 
785
/* FIXME: Should these take a count argument?
786
   Answer (gnu@cygnus.com):  No, but perhaps they should be inline
787
                             functions in swap.h #ifdef __GNUC__.
788
                             Gprof them later and find out.  */
789
 
790
/*
791
FUNCTION
792
        bfd_put_size
793
FUNCTION
794
        bfd_get_size
795
 
796
DESCRIPTION
797
        These macros as used for reading and writing raw data in
798
        sections; each access (except for bytes) is vectored through
799
        the target format of the BFD and mangled accordingly. The
800
        mangling performs any necessary endian translations and
801
        removes alignment restrictions.  Note that types accepted and
802
        returned by these macros are identical so they can be swapped
803
        around in macros---for example, @file{libaout.h} defines <<GET_WORD>>
804
        to either <<bfd_get_32>> or <<bfd_get_64>>.
805
 
806
        In the put routines, @var{val} must be a <<bfd_vma>>.  If we are on a
807
        system without prototypes, the caller is responsible for making
808
        sure that is true, with a cast if necessary.  We don't cast
809
        them in the macro definitions because that would prevent <<lint>>
810
        or <<gcc -Wall>> from detecting sins such as passing a pointer.
811
        To detect calling these with less than a <<bfd_vma>>, use
812
        <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s.
813
 
814
.
815
.{* Byte swapping macros for user section data.  *}
816
.
817
.#define bfd_put_8(abfd, val, ptr) \
818
.                ((void) (*((unsigned char *) (ptr)) = (unsigned char) (val)))
819
.#define bfd_put_signed_8 \
820
.               bfd_put_8
821
.#define bfd_get_8(abfd, ptr) \
822
.                (*(unsigned char *) (ptr))
823
.#define bfd_get_signed_8(abfd, ptr) \
824
.               ((*(unsigned char *) (ptr) ^ 0x80) - 0x80)
825
.
826
.#define bfd_put_16(abfd, val, ptr) \
827
.                BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
828
.#define bfd_put_signed_16 \
829
.                bfd_put_16
830
.#define bfd_get_16(abfd, ptr) \
831
.                BFD_SEND(abfd, bfd_getx16, (ptr))
832
.#define bfd_get_signed_16(abfd, ptr) \
833
.                BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
834
.
835
.#define bfd_put_32(abfd, val, ptr) \
836
.                BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
837
.#define bfd_put_signed_32 \
838
.                bfd_put_32
839
.#define bfd_get_32(abfd, ptr) \
840
.                BFD_SEND(abfd, bfd_getx32, (ptr))
841
.#define bfd_get_signed_32(abfd, ptr) \
842
.                BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
843
.
844
.#define bfd_put_64(abfd, val, ptr) \
845
.                BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
846
.#define bfd_put_signed_64 \
847
.                bfd_put_64
848
.#define bfd_get_64(abfd, ptr) \
849
.                BFD_SEND(abfd, bfd_getx64, (ptr))
850
.#define bfd_get_signed_64(abfd, ptr) \
851
.                BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
852
.
853
.#define bfd_get(bits, abfd, ptr)                               \
854
.                ((bits) == 8 ? bfd_get_8 (abfd, ptr)           \
855
.                : (bits) == 16 ? bfd_get_16 (abfd, ptr)        \
856
.                : (bits) == 32 ? bfd_get_32 (abfd, ptr)        \
857
.                : (bits) == 64 ? bfd_get_64 (abfd, ptr)        \
858
.                : (abort (), (bfd_vma) - 1))
859
.
860
.#define bfd_put(bits, abfd, val, ptr)                          \
861
.                ((bits) == 8 ? bfd_put_8 (abfd, val, ptr)      \
862
.                : (bits) == 16 ? bfd_put_16 (abfd, val, ptr)   \
863
.                : (bits) == 32 ? bfd_put_32 (abfd, val, ptr)   \
864
.                : (bits) == 64 ? bfd_put_64 (abfd, val, ptr)   \
865
.                : (abort (), (void) 0))
866
.
867
*/
868
 
869
/*
870
FUNCTION
871
        bfd_h_put_size
872
        bfd_h_get_size
873
 
874
DESCRIPTION
875
        These macros have the same function as their <<bfd_get_x>>
876
        bretheren, except that they are used for removing information
877
        for the header records of object files. Believe it or not,
878
        some object files keep their header records in big endian
879
        order and their data in little endian order.
880
.
881
.{* Byte swapping macros for file header data.  *}
882
.
883
.#define bfd_h_put_8(abfd, val, ptr) \
884
.               bfd_put_8 (abfd, val, ptr)
885
.#define bfd_h_put_signed_8(abfd, val, ptr) \
886
.               bfd_put_8 (abfd, val, ptr)
887
.#define bfd_h_get_8(abfd, ptr) \
888
.               bfd_get_8 (abfd, ptr)
889
.#define bfd_h_get_signed_8(abfd, ptr) \
890
.               bfd_get_signed_8 (abfd, ptr)
891
.
892
.#define bfd_h_put_16(abfd, val, ptr) \
893
.                BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
894
.#define bfd_h_put_signed_16 \
895
.                bfd_h_put_16
896
.#define bfd_h_get_16(abfd, ptr) \
897
.                BFD_SEND(abfd, bfd_h_getx16,(ptr))
898
.#define bfd_h_get_signed_16(abfd, ptr) \
899
.                BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
900
.
901
.#define bfd_h_put_32(abfd, val, ptr) \
902
.                BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
903
.#define bfd_h_put_signed_32 \
904
.                bfd_h_put_32
905
.#define bfd_h_get_32(abfd, ptr) \
906
.                BFD_SEND(abfd, bfd_h_getx32,(ptr))
907
.#define bfd_h_get_signed_32(abfd, ptr) \
908
.                BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
909
.
910
.#define bfd_h_put_64(abfd, val, ptr) \
911
.                BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
912
.#define bfd_h_put_signed_64 \
913
.                bfd_h_put_64
914
.#define bfd_h_get_64(abfd, ptr) \
915
.                BFD_SEND(abfd, bfd_h_getx64,(ptr))
916
.#define bfd_h_get_signed_64(abfd, ptr) \
917
.                BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
918
.
919
*/
920
 
921
/* Sign extension to bfd_signed_vma.  */
922
#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
923
#define COERCE32(x) \
924
  ((bfd_signed_vma) (long) (((unsigned long) (x) ^ 0x80000000) - 0x80000000))
925
#define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32)
926
#define COERCE64(x) \
927
  (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
928
 
929
bfd_vma
930
bfd_getb16 (addr)
931
     register const bfd_byte *addr;
932
{
933
  return (addr[0] << 8) | addr[1];
934
}
935
 
936
bfd_vma
937
bfd_getl16 (addr)
938
     register const bfd_byte *addr;
939
{
940
  return (addr[1] << 8) | addr[0];
941
}
942
 
943
bfd_signed_vma
944
bfd_getb_signed_16 (addr)
945
     register const bfd_byte *addr;
946
{
947
  return COERCE16((addr[0] << 8) | addr[1]);
948
}
949
 
950
bfd_signed_vma
951
bfd_getl_signed_16 (addr)
952
     register const bfd_byte *addr;
953
{
954
  return COERCE16((addr[1] << 8) | addr[0]);
955
}
956
 
957
void
958
bfd_putb16 (data, addr)
959
     bfd_vma data;
960
     register bfd_byte *addr;
961
{
962
  addr[0] = (bfd_byte) (data >> 8);
963
  addr[1] = (bfd_byte) data;
964
}
965
 
966
void
967
bfd_putl16 (data, addr)
968
     bfd_vma data;
969
     register bfd_byte *addr;
970
{
971
  addr[0] = (bfd_byte) data;
972
  addr[1] = (bfd_byte) (data >> 8);
973
}
974
 
975
bfd_vma
976
bfd_getb32 (addr)
977
     register const bfd_byte *addr;
978
{
979
  unsigned long v;
980
 
981
  v = (unsigned long) addr[0] << 24;
982
  v |= (unsigned long) addr[1] << 16;
983
  v |= (unsigned long) addr[2] << 8;
984
  v |= (unsigned long) addr[3];
985
  return (bfd_vma) v;
986
}
987
 
988
bfd_vma
989
bfd_getl32 (addr)
990
     register const bfd_byte *addr;
991
{
992
  unsigned long v;
993
 
994
  v = (unsigned long) addr[0];
995
  v |= (unsigned long) addr[1] << 8;
996
  v |= (unsigned long) addr[2] << 16;
997
  v |= (unsigned long) addr[3] << 24;
998
  return (bfd_vma) v;
999
}
1000
 
1001
bfd_signed_vma
1002
bfd_getb_signed_32 (addr)
1003
     register const bfd_byte *addr;
1004
{
1005
  unsigned long v;
1006
 
1007
  v = (unsigned long) addr[0] << 24;
1008
  v |= (unsigned long) addr[1] << 16;
1009
  v |= (unsigned long) addr[2] << 8;
1010
  v |= (unsigned long) addr[3];
1011
  return COERCE32 (v);
1012
}
1013
 
1014
bfd_signed_vma
1015
bfd_getl_signed_32 (addr)
1016
     register const bfd_byte *addr;
1017
{
1018
  unsigned long v;
1019
 
1020
  v = (unsigned long) addr[0];
1021
  v |= (unsigned long) addr[1] << 8;
1022
  v |= (unsigned long) addr[2] << 16;
1023
  v |= (unsigned long) addr[3] << 24;
1024
  return COERCE32 (v);
1025
}
1026
 
1027
bfd_vma
1028
bfd_getb64 (addr)
1029
     register const bfd_byte *addr ATTRIBUTE_UNUSED;
1030
{
1031
#ifdef BFD64
1032
  bfd_vma low, high;
1033
 
1034
  high= ((((((((addr[0]) << 8) |
1035
              addr[1]) << 8) |
1036
            addr[2]) << 8) |
1037
          addr[3]) );
1038
 
1039
  low = (((((((((bfd_vma)addr[4]) << 8) |
1040
              addr[5]) << 8) |
1041
            addr[6]) << 8) |
1042
          addr[7]));
1043
 
1044
  return high << 32 | low;
1045
#else
1046
  BFD_FAIL();
1047
  return 0;
1048
#endif
1049
}
1050
 
1051
bfd_vma
1052
bfd_getl64 (addr)
1053
     register const bfd_byte *addr ATTRIBUTE_UNUSED;
1054
{
1055
#ifdef BFD64
1056
  bfd_vma low, high;
1057
  high= (((((((addr[7] << 8) |
1058
              addr[6]) << 8) |
1059
            addr[5]) << 8) |
1060
          addr[4]));
1061
 
1062
  low = ((((((((bfd_vma)addr[3] << 8) |
1063
              addr[2]) << 8) |
1064
            addr[1]) << 8) |
1065
          addr[0]) );
1066
 
1067
  return high << 32 | low;
1068
#else
1069
  BFD_FAIL();
1070
  return 0;
1071
#endif
1072
 
1073
}
1074
 
1075
bfd_signed_vma
1076
bfd_getb_signed_64 (addr)
1077
     register const bfd_byte *addr ATTRIBUTE_UNUSED;
1078
{
1079
#ifdef BFD64
1080
  bfd_vma low, high;
1081
 
1082
  high= ((((((((addr[0]) << 8) |
1083
              addr[1]) << 8) |
1084
            addr[2]) << 8) |
1085
          addr[3]) );
1086
 
1087
  low = (((((((((bfd_vma)addr[4]) << 8) |
1088
              addr[5]) << 8) |
1089
            addr[6]) << 8) |
1090
          addr[7]));
1091
 
1092
  return COERCE64(high << 32 | low);
1093
#else
1094
  BFD_FAIL();
1095
  return 0;
1096
#endif
1097
}
1098
 
1099
bfd_signed_vma
1100
bfd_getl_signed_64 (addr)
1101
     register const bfd_byte *addr ATTRIBUTE_UNUSED;
1102
{
1103
#ifdef BFD64
1104
  bfd_vma low, high;
1105
  high= (((((((addr[7] << 8) |
1106
              addr[6]) << 8) |
1107
            addr[5]) << 8) |
1108
          addr[4]));
1109
 
1110
  low = ((((((((bfd_vma)addr[3] << 8) |
1111
              addr[2]) << 8) |
1112
            addr[1]) << 8) |
1113
          addr[0]) );
1114
 
1115
  return COERCE64(high << 32 | low);
1116
#else
1117
  BFD_FAIL();
1118
  return 0;
1119
#endif
1120
}
1121
 
1122
void
1123
bfd_putb32 (data, addr)
1124
     bfd_vma data;
1125
     register bfd_byte *addr;
1126
{
1127
        addr[0] = (bfd_byte) (data >> 24);
1128
        addr[1] = (bfd_byte) (data >> 16);
1129
        addr[2] = (bfd_byte) (data >>  8);
1130
        addr[3] = (bfd_byte) data;
1131
}
1132
 
1133
void
1134
bfd_putl32 (data, addr)
1135
     bfd_vma data;
1136
     register bfd_byte *addr;
1137
{
1138
        addr[0] = (bfd_byte) data;
1139
        addr[1] = (bfd_byte) (data >>  8);
1140
        addr[2] = (bfd_byte) (data >> 16);
1141
        addr[3] = (bfd_byte) (data >> 24);
1142
}
1143
 
1144
void
1145
bfd_putb64 (data, addr)
1146
     bfd_vma data ATTRIBUTE_UNUSED;
1147
     register bfd_byte *addr ATTRIBUTE_UNUSED;
1148
{
1149
#ifdef BFD64
1150
  addr[0] = (bfd_byte) (data >> (7*8));
1151
  addr[1] = (bfd_byte) (data >> (6*8));
1152
  addr[2] = (bfd_byte) (data >> (5*8));
1153
  addr[3] = (bfd_byte) (data >> (4*8));
1154
  addr[4] = (bfd_byte) (data >> (3*8));
1155
  addr[5] = (bfd_byte) (data >> (2*8));
1156
  addr[6] = (bfd_byte) (data >> (1*8));
1157
  addr[7] = (bfd_byte) (data >> (0*8));
1158
#else
1159
  BFD_FAIL();
1160
#endif
1161
}
1162
 
1163
void
1164
bfd_putl64 (data, addr)
1165
     bfd_vma data ATTRIBUTE_UNUSED;
1166
     register bfd_byte *addr ATTRIBUTE_UNUSED;
1167
{
1168
#ifdef BFD64
1169
  addr[7] = (bfd_byte) (data >> (7*8));
1170
  addr[6] = (bfd_byte) (data >> (6*8));
1171
  addr[5] = (bfd_byte) (data >> (5*8));
1172
  addr[4] = (bfd_byte) (data >> (4*8));
1173
  addr[3] = (bfd_byte) (data >> (3*8));
1174
  addr[2] = (bfd_byte) (data >> (2*8));
1175
  addr[1] = (bfd_byte) (data >> (1*8));
1176
  addr[0] = (bfd_byte) (data >> (0*8));
1177
#else
1178
  BFD_FAIL();
1179
#endif
1180
}
1181
 
1182
void
1183
bfd_put_bits (data, addr, bits, big_p)
1184
     bfd_vma data;
1185
     bfd_byte *addr;
1186
     int bits;
1187
     boolean big_p;
1188
{
1189
  int i;
1190
  int bytes;
1191
 
1192
  if (bits % 8 != 0)
1193
    abort ();
1194
 
1195
  bytes = bits / 8;
1196
  for (i = 0; i < bytes; i++)
1197
    {
1198
      int index = big_p ? bytes - i - 1 : i;
1199
 
1200
      addr[index] = (bfd_byte) data;
1201
      data >>= 8;
1202
    }
1203
}
1204
 
1205
bfd_vma
1206
bfd_get_bits (addr, bits, big_p)
1207
     bfd_byte *addr;
1208
     int bits;
1209
     boolean big_p;
1210
{
1211
  bfd_vma data;
1212
  int i;
1213
  int bytes;
1214
 
1215
  if (bits % 8 != 0)
1216
    abort ();
1217
 
1218
  data = 0;
1219
  bytes = bits / 8;
1220
  for (i = 0; i < bytes; i++)
1221
    {
1222
      int index = big_p ? i : bytes - i - 1;
1223
 
1224
      data = (data << 8) | addr[index];
1225
    }
1226
 
1227
  return data;
1228
}
1229
 
1230
/* Default implementation */
1231
 
1232
boolean
1233
_bfd_generic_get_section_contents (abfd, section, location, offset, count)
1234
     bfd *abfd;
1235
     sec_ptr section;
1236
     PTR location;
1237
     file_ptr offset;
1238
     bfd_size_type count;
1239
{
1240
  if (count == 0)
1241
    return true;
1242
 
1243
  if ((bfd_size_type) (offset + count) > section->_raw_size)
1244
    {
1245
      bfd_set_error (bfd_error_invalid_operation);
1246
      return false;
1247
    }
1248
 
1249
  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1250
      || bfd_read (location, (bfd_size_type) 1, count, abfd) != count)
1251
    return false;
1252
 
1253
  return true;
1254
}
1255
 
1256
boolean
1257
_bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count)
1258
     bfd *abfd ATTRIBUTE_UNUSED;
1259
     sec_ptr section ATTRIBUTE_UNUSED;
1260
     bfd_window *w ATTRIBUTE_UNUSED;
1261
     file_ptr offset ATTRIBUTE_UNUSED;
1262
     bfd_size_type count ATTRIBUTE_UNUSED;
1263
{
1264
#ifdef USE_MMAP
1265
  if (count == 0)
1266
    return true;
1267
  if (abfd->xvec->_bfd_get_section_contents != _bfd_generic_get_section_contents)
1268
    {
1269
      /* We don't know what changes the bfd's get_section_contents
1270
         method may have to make.  So punt trying to map the file
1271
         window, and let get_section_contents do its thing.  */
1272
      /* @@ FIXME : If the internal window has a refcount of 1 and was
1273
         allocated with malloc instead of mmap, just reuse it.  */
1274
      bfd_free_window (w);
1275
      w->i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
1276
      if (w->i == NULL)
1277
        return false;
1278
      w->i->data = (PTR) bfd_malloc ((size_t) count);
1279
      if (w->i->data == NULL)
1280
        {
1281
          free (w->i);
1282
          w->i = NULL;
1283
          return false;
1284
        }
1285
      w->i->mapped = 0;
1286
      w->i->refcount = 1;
1287
      w->size = w->i->size = count;
1288
      w->data = w->i->data;
1289
      return bfd_get_section_contents (abfd, section, w->data, offset, count);
1290
    }
1291
  if ((bfd_size_type) (offset+count) > section->_raw_size
1292
      || (bfd_get_file_window (abfd, section->filepos + offset, count, w, true)
1293
          == false))
1294
    return false;
1295
  return true;
1296
#else
1297
  abort ();
1298
#endif
1299
}
1300
 
1301
/* This generic function can only be used in implementations where creating
1302
   NEW sections is disallowed.  It is useful in patching existing sections
1303
   in read-write files, though.  See other set_section_contents functions
1304
   to see why it doesn't work for new sections.  */
1305
boolean
1306
_bfd_generic_set_section_contents (abfd, section, location, offset, count)
1307
     bfd *abfd;
1308
     sec_ptr section;
1309
     PTR location;
1310
     file_ptr offset;
1311
     bfd_size_type count;
1312
{
1313
  if (count == 0)
1314
    return true;
1315
 
1316
  if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) == -1
1317
      || bfd_write (location, (bfd_size_type) 1, count, abfd) != count)
1318
    return false;
1319
 
1320
  return true;
1321
}
1322
 
1323
/*
1324
INTERNAL_FUNCTION
1325
        bfd_log2
1326
 
1327
SYNOPSIS
1328
        unsigned int bfd_log2(bfd_vma x);
1329
 
1330
DESCRIPTION
1331
        Return the log base 2 of the value supplied, rounded up.  E.g., an
1332
        @var{x} of 1025 returns 11.
1333
*/
1334
 
1335
unsigned int
1336
bfd_log2 (x)
1337
     bfd_vma x;
1338
{
1339
  unsigned int result = 0;
1340
 
1341
  while ((x = (x >> 1)) != 0)
1342
    ++result;
1343
  return result;
1344
}
1345
 
1346
boolean
1347
bfd_generic_is_local_label_name (abfd, name)
1348
     bfd *abfd;
1349
     const char *name;
1350
{
1351
  char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
1352
 
1353
  return (name[0] == locals_prefix);
1354
}
1355
 
1356
/*  Can be used from / for bfd_merge_private_bfd_data to check that
1357
    endianness matches between input and output file.  Returns
1358
    true for a match, otherwise returns false and emits an error.  */
1359
boolean
1360
_bfd_generic_verify_endian_match (ibfd, obfd)
1361
     bfd *ibfd;
1362
     bfd *obfd;
1363
{
1364
  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1365
      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1366
      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
1367
    {
1368
      const char *msg;
1369
 
1370
      if (bfd_big_endian (ibfd))
1371
        msg = _("%s: compiled for a big endian system and target is little endian");
1372
      else
1373
        msg = _("%s: compiled for a little endian system and target is big endian");
1374
 
1375
      (*_bfd_error_handler) (msg, bfd_get_filename (ibfd));
1376
 
1377
      bfd_set_error (bfd_error_wrong_format);
1378
      return false;
1379
    }
1380
 
1381
  return true;
1382
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.