source: trunk/src/binutils/bfd/libbfd.c@ 10

Last change on this file since 10 was 10, checked in by bird, 22 years ago

Initial revision

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