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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [libbfd.c] - Blame information for rev 1771

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

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

powered by: WebSVN 2.1.0

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