X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Flibbfd.c;h=695df8d51ab200e73cd62ed68636538cd65cae0c;hb=aa4f99bbfde8d1650d61163622544d106c7eeab0;hp=cd8f896cb71549b8440b054506ae42e289dbf25f;hpb=64d5f5d061563094cce2f2edbe6447f9ac6adddd;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/libbfd.c b/bfd/libbfd.c index cd8f896cb7..695df8d51a 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -1,5 +1,7 @@ /* Assorted BFD support routines, only used internally. - Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc. + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001 + Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -22,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sysdep.h" #include "libbfd.h" +#ifndef HAVE_GETPAGESIZE +#define getpagesize() 2048 +#endif + static int real_read PARAMS ((PTR, size_t, size_t, FILE *)); /* @@ -37,10 +43,9 @@ DESCRIPTION /* A routine which is used in target vectors for unsupported operations. */ -/*ARGSUSED*/ boolean bfd_false (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_invalid_operation); return false; @@ -49,10 +54,9 @@ bfd_false (ignore) /* A routine which is used in target vectors for supported operations which do not actually do anything. */ -/*ARGSUSED*/ boolean bfd_true (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { return true; } @@ -60,35 +64,31 @@ bfd_true (ignore) /* A routine which is used in target vectors for unsupported operations which return a pointer value. */ -/*ARGSUSED*/ PTR bfd_nullvoidptr (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_invalid_operation); return NULL; } -/*ARGSUSED*/ -int +int bfd_0 (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { return 0; } -/*ARGSUSED*/ -unsigned int +unsigned int bfd_0u (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { return 0; } -/*ARGUSED*/ long bfd_0l (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { return 0; } @@ -96,27 +96,24 @@ bfd_0l (ignore) /* A routine which is used in target vectors for unsupported operations which return -1 on error. */ -/*ARGSUSED*/ long _bfd_n1 (ignore_abfd) - bfd *ignore_abfd; + bfd *ignore_abfd ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_invalid_operation); return -1; } -/*ARGSUSED*/ -void +void bfd_void (ignore) - bfd *ignore; + bfd *ignore ATTRIBUTE_UNUSED; { } -/*ARGSUSED*/ boolean _bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd) - bfd *ignore_core_bfd; - bfd *ignore_exec_bfd; + bfd *ignore_core_bfd ATTRIBUTE_UNUSED; + bfd *ignore_exec_bfd ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_invalid_operation); return false; @@ -125,10 +122,9 @@ _bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd) /* Routine to handle core_file_failing_command entry point for targets without core file support. */ -/*ARGSUSED*/ char * _bfd_nocore_core_file_failing_command (ignore_abfd) - bfd *ignore_abfd; + bfd *ignore_abfd ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_invalid_operation); return (char *)NULL; @@ -137,19 +133,17 @@ _bfd_nocore_core_file_failing_command (ignore_abfd) /* Routine to handle core_file_failing_signal entry point for targets without core file support. */ -/*ARGSUSED*/ int _bfd_nocore_core_file_failing_signal (ignore_abfd) - bfd *ignore_abfd; + bfd *ignore_abfd ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_invalid_operation); return 0; } -/*ARGSUSED*/ const bfd_target * _bfd_dummy_target (ignore_abfd) - bfd *ignore_abfd; + bfd *ignore_abfd ATTRIBUTE_UNUSED; { bfd_set_error (bfd_error_wrong_format); return 0; @@ -212,13 +206,12 @@ bfd_zmalloc (size) /* Some IO code */ - /* Note that archive entries don't have streams; they share their parent's. This allows someone to play with the iostream behind BFD's back. Also, note that the origin pointer points to the beginning of a file's contents (0 for non-archive elements). For archive entries this is the - first octet in the file, NOT the beginning of the archive header. */ + first octet in the file, NOT the beginning of the archive header. */ static int real_read (where, a,b, file) @@ -227,7 +220,26 @@ real_read (where, a,b, file) size_t b; FILE *file; { + /* FIXME - this looks like an optimization, but it's really to cover + up for a feature of some OSs (not solaris - sigh) that + ld/pe-dll.c takes advantage of (apparently) when it creates BFDs + internally and tries to link against them. BFD seems to be smart + enough to realize there are no symbol records in the "file" that + doesn't exist but attempts to read them anyway. On Solaris, + attempting to read zero bytes from a NULL file results in a core + dump, but on other platforms it just returns zero bytes read. + This makes it to something reasonable. - DJ */ + if (a == 0 || b == 0) + return 0; + + +#if defined (__VAX) && defined (VMS) + /* Apparently fread on Vax VMS does not keep the record length + information. */ + return read (fileno (file), where, a * b); +#else return fread (where, a, b, file); +#endif } /* Return value is amount read (FIXME: how are errors and end of file dealt @@ -251,7 +263,10 @@ bfd_read (ptr, size, nitems, abfd) get = size * nitems; if (abfd->where + get > bim->size) { - get = bim->size - abfd->where; + if (bim->size < (bfd_size_type) abfd->where) + get = 0; + else + get = bim->size - abfd->where; bfd_set_error (bfd_error_file_truncated); } memcpy (ptr, bim->buffer + abfd->where, get); @@ -259,11 +274,9 @@ bfd_read (ptr, size, nitems, abfd) return get; } - nread = real_read (ptr, 1, (size_t)(size*nitems), bfd_cache_lookup(abfd)); -#ifdef FILE_OFFSET_IS_CHAR_INDEX + nread = real_read (ptr, 1, (size_t) (size*nitems), bfd_cache_lookup(abfd)); if (nread > 0) abfd->where += nread; -#endif /* Set bfd_error if we did not read as much data as we expected. @@ -272,7 +285,7 @@ bfd_read (ptr, size, nitems, abfd) A BFD backend may wish to override bfd_error_file_truncated to provide something more useful (eg. no_symbols or wrong_format). */ - if (nread < (int)(size * nitems)) + if (nread != (int) (size * nitems)) { if (ferror (bfd_cache_lookup (abfd))) bfd_set_error (bfd_error_system_call); @@ -293,7 +306,7 @@ struct _bfd_window_internal { struct _bfd_window_internal *next; PTR data; bfd_size_type size; - int refcount : 31; /* should be enough... */ + int refcount : 31; /* should be enough... */ unsigned mapped : 1; /* 1 = mmap, 0 = malloc */ }; @@ -305,11 +318,16 @@ bfd_init_window (windowp) windowp->i = 0; windowp->size = 0; } + +/* Currently, if USE_MMAP is undefined, none if the window stuff is + used. Okay, so it's mis-named. At least the command-line option + "--without-mmap" is more obvious than "--without-windows" or some + such. */ +#ifdef USE_MMAP #undef HAVE_MPROTECT /* code's not tested yet */ #if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE -#include #include #endif @@ -319,12 +337,6 @@ bfd_init_window (windowp) static int debug_windows; -/* Currently, if USE_MMAP is undefined, none if the window stuff is - used. Okay, so it's mis-named. At least the command-line option - "--without-mmap" is more obvious than "--without-windows" or some - such. */ -#ifdef USE_MMAP - void bfd_free_window (windowp) bfd_window *windowp; @@ -361,7 +373,6 @@ bfd_free_window (windowp) /* There should be no more references to i at this point. */ free (i); } -#endif static int ok_to_map = 1; @@ -377,15 +388,11 @@ bfd_get_file_window (abfd, offset, size, windowp, writable) bfd_window_internal *i = windowp->i; size_t size_to_alloc = size; -#ifndef USE_MMAP - abort (); -#endif - if (debug_windows) fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)", abfd, (long) offset, (long) size, - windowp, windowp->data, windowp->size, windowp->i, - writable); + windowp, windowp->data, (unsigned long) windowp->size, + windowp->i, writable); /* Make sure we know the page size, so we can be friendly to mmap. */ if (pagesize == 0) @@ -463,10 +470,10 @@ bfd_get_file_window (abfd, offset, size, windowp, writable) else if (debug_windows) { if (ok_to_map) - fprintf (stderr, "not mapping: data=%lx mapped=%d\n", + fprintf (stderr, _("not mapping: data=%lx mapped=%d\n"), (unsigned long) i->data, (int) i->mapped); else - fprintf (stderr, "not mapping: env var not set\n"); + fprintf (stderr, _("not mapping: env var not set\n")); } #else ok_to_map = 0; @@ -513,6 +520,8 @@ bfd_get_file_window (abfd, offset, size, windowp, writable) return true; } +#endif /* USE_MMAP */ + bfd_size_type bfd_write (ptr, size, nitems, abfd) CONST PTR ptr; @@ -523,14 +532,34 @@ bfd_write (ptr, size, nitems, abfd) long nwrote; if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); + { + struct bfd_in_memory *bim = (struct bfd_in_memory *) (abfd->iostream); + size *= nitems; + if (abfd->where + size > bim->size) + { + long newsize, oldsize = (bim->size + 127) & ~127; + bim->size = abfd->where + size; + /* Round up to cut down on memory fragmentation */ + newsize = (bim->size + 127) & ~127; + if (newsize > oldsize) + { + bim->buffer = bfd_realloc (bim->buffer, newsize); + if (bim->buffer == 0) + { + bim->size = 0; + return 0; + } + } + } + memcpy (bim->buffer + abfd->where, ptr, size); + abfd->where += size; + return size; + } nwrote = fwrite (ptr, 1, (size_t) (size * nitems), bfd_cache_lookup (abfd)); -#ifdef FILE_OFFSET_IS_CHAR_INDEX if (nwrote > 0) abfd->where += nwrote; -#endif if ((bfd_size_type) nwrote != size * nitems) { #ifdef ENOSPC @@ -631,7 +660,7 @@ bfd_seek (abfd, position, direction) file_ptr file_position; /* For the time being, a BFD may not seek to it's end. The problem is that we don't easily have a way to recognize the end of an - element in an archive. */ + element in an archive. */ BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR); @@ -640,14 +669,45 @@ bfd_seek (abfd, position, direction) if ((abfd->flags & BFD_IN_MEMORY) != 0) { + struct bfd_in_memory *bim; + + bim = (struct bfd_in_memory *) abfd->iostream; + if (direction == SEEK_SET) abfd->where = position; else abfd->where += position; + + if ((bfd_size_type) abfd->where > bim->size) + { + if ((abfd->direction == write_direction) || + (abfd->direction == both_direction)) + { + long newsize, oldsize = (bim->size + 127) & ~127; + bim->size = abfd->where; + /* Round up to cut down on memory fragmentation */ + newsize = (bim->size + 127) & ~127; + if (newsize > oldsize) + { + bim->buffer = bfd_realloc (bim->buffer, newsize); + if (bim->buffer == 0) + { + bim->size = 0; + bfd_set_error (bfd_error_no_memory); + return -1; + } + } + } + else + { + abfd->where = bim->size; + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return 0; } -#ifdef FILE_OFFSET_IS_CHAR_INDEX if (abfd->format != bfd_archive && abfd->my_archive == 0) { #if 0 @@ -681,7 +741,6 @@ bfd_seek (abfd, position, direction) In the meantime, no optimization for archives. */ } -#endif f = bfd_cache_lookup (abfd); file_position = position; @@ -689,22 +748,30 @@ bfd_seek (abfd, position, direction) file_position += abfd->origin; result = fseek (f, file_position, direction); - if (result != 0) { + int hold_errno = errno; + /* Force redetermination of `where' field. */ bfd_tell (abfd); - bfd_set_error (bfd_error_system_call); + + /* An EINVAL error probably means that the file offset was + absurd. */ + if (hold_errno == EINVAL) + bfd_set_error (bfd_error_file_truncated); + else + { + bfd_set_error (bfd_error_system_call); + errno = hold_errno; + } } else { -#ifdef FILE_OFFSET_IS_CHAR_INDEX /* Adjust `where' field. */ if (direction == SEEK_SET) abfd->where = position; else abfd->where += position; -#endif } return result; } @@ -717,7 +784,7 @@ bfd_seek (abfd, position, direction) /* FIXME: Should these take a count argument? Answer (gnu@cygnus.com): No, but perhaps they should be inline - functions in swap.h #ifdef __GNUC__. + functions in swap.h #ifdef __GNUC__. Gprof them later and find out. */ /* @@ -748,13 +815,13 @@ DESCRIPTION .{* Byte swapping macros for user section data. *} . .#define bfd_put_8(abfd, val, ptr) \ -. (*((unsigned char *)(ptr)) = (unsigned char)(val)) +. ((void) (*((unsigned char *) (ptr)) = (unsigned char) (val))) .#define bfd_put_signed_8 \ . bfd_put_8 .#define bfd_get_8(abfd, ptr) \ -. (*(unsigned char *)(ptr)) +. (*(unsigned char *) (ptr)) .#define bfd_get_signed_8(abfd, ptr) \ -. ((*(unsigned char *)(ptr) ^ 0x80) - 0x80) +. ((*(unsigned char *) (ptr) ^ 0x80) - 0x80) . .#define bfd_put_16(abfd, val, ptr) \ . BFD_SEND(abfd, bfd_putx16, ((val),(ptr))) @@ -783,7 +850,21 @@ DESCRIPTION .#define bfd_get_signed_64(abfd, ptr) \ . BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) . -*/ +.#define bfd_get(bits, abfd, ptr) \ +. ((bits) == 8 ? bfd_get_8 (abfd, ptr) \ +. : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ +. : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ +. : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ +. : (abort (), (bfd_vma) - 1)) +. +.#define bfd_put(bits, abfd, val, ptr) \ +. ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ +. : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ +. : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ +. : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ +. : (abort (), (void) 0)) +. +*/ /* FUNCTION @@ -835,11 +916,12 @@ DESCRIPTION .#define bfd_h_get_signed_64(abfd, ptr) \ . BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr)) . -*/ +*/ /* Sign extension to bfd_signed_vma. */ #define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000) -#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000) +#define COERCE32(x) \ + ((bfd_signed_vma) (long) (((unsigned long) (x) ^ 0x80000000) - 0x80000000)) #define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32) #define COERCE64(x) \ (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION) @@ -877,54 +959,74 @@ bfd_putb16 (data, addr) bfd_vma data; register bfd_byte *addr; { - addr[0] = (bfd_byte)(data >> 8); - addr[1] = (bfd_byte )data; + addr[0] = (bfd_byte) (data >> 8); + addr[1] = (bfd_byte) data; } void bfd_putl16 (data, addr) - bfd_vma data; + bfd_vma data; register bfd_byte *addr; { - addr[0] = (bfd_byte )data; - addr[1] = (bfd_byte)(data >> 8); + addr[0] = (bfd_byte) data; + addr[1] = (bfd_byte) (data >> 8); } bfd_vma bfd_getb32 (addr) register const bfd_byte *addr; { - return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8) - | addr[2]) << 8 | addr[3]; + unsigned long v; + + v = (unsigned long) addr[0] << 24; + v |= (unsigned long) addr[1] << 16; + v |= (unsigned long) addr[2] << 8; + v |= (unsigned long) addr[3]; + return (bfd_vma) v; } bfd_vma bfd_getl32 (addr) register const bfd_byte *addr; { - return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]; + unsigned long v; + + v = (unsigned long) addr[0]; + v |= (unsigned long) addr[1] << 8; + v |= (unsigned long) addr[2] << 16; + v |= (unsigned long) addr[3] << 24; + return (bfd_vma) v; } bfd_signed_vma bfd_getb_signed_32 (addr) register const bfd_byte *addr; { - return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8) - | addr[2]) << 8 | addr[3]); + unsigned long v; + + v = (unsigned long) addr[0] << 24; + v |= (unsigned long) addr[1] << 16; + v |= (unsigned long) addr[2] << 8; + v |= (unsigned long) addr[3]; + return COERCE32 (v); } bfd_signed_vma bfd_getl_signed_32 (addr) register const bfd_byte *addr; { - return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]); + unsigned long v; + + v = (unsigned long) addr[0]; + v |= (unsigned long) addr[1] << 8; + v |= (unsigned long) addr[2] << 16; + v |= (unsigned long) addr[3] << 24; + return COERCE32 (v); } bfd_vma bfd_getb64 (addr) - register const bfd_byte *addr; + register const bfd_byte *addr ATTRIBUTE_UNUSED; { #ifdef BFD64 bfd_vma low, high; @@ -948,7 +1050,7 @@ bfd_getb64 (addr) bfd_vma bfd_getl64 (addr) - register const bfd_byte *addr; + register const bfd_byte *addr ATTRIBUTE_UNUSED; { #ifdef BFD64 bfd_vma low, high; @@ -972,7 +1074,7 @@ bfd_getl64 (addr) bfd_signed_vma bfd_getb_signed_64 (addr) - register const bfd_byte *addr; + register const bfd_byte *addr ATTRIBUTE_UNUSED; { #ifdef BFD64 bfd_vma low, high; @@ -996,7 +1098,7 @@ bfd_getb_signed_64 (addr) bfd_signed_vma bfd_getl_signed_64 (addr) - register const bfd_byte *addr; + register const bfd_byte *addr ATTRIBUTE_UNUSED; { #ifdef BFD64 bfd_vma low, high; @@ -1022,10 +1124,10 @@ bfd_putb32 (data, addr) bfd_vma data; register bfd_byte *addr; { - addr[0] = (bfd_byte)(data >> 24); - addr[1] = (bfd_byte)(data >> 16); - addr[2] = (bfd_byte)(data >> 8); - addr[3] = (bfd_byte)data; + addr[0] = (bfd_byte) (data >> 24); + addr[1] = (bfd_byte) (data >> 16); + addr[2] = (bfd_byte) (data >> 8); + addr[3] = (bfd_byte) data; } void @@ -1033,26 +1135,26 @@ bfd_putl32 (data, addr) bfd_vma data; register bfd_byte *addr; { - addr[0] = (bfd_byte)data; - addr[1] = (bfd_byte)(data >> 8); - addr[2] = (bfd_byte)(data >> 16); - addr[3] = (bfd_byte)(data >> 24); + addr[0] = (bfd_byte) data; + addr[1] = (bfd_byte) (data >> 8); + addr[2] = (bfd_byte) (data >> 16); + addr[3] = (bfd_byte) (data >> 24); } void bfd_putb64 (data, addr) - bfd_vma data; - register bfd_byte *addr; + bfd_vma data ATTRIBUTE_UNUSED; + register bfd_byte *addr ATTRIBUTE_UNUSED; { #ifdef BFD64 - addr[0] = (bfd_byte)(data >> (7*8)); - addr[1] = (bfd_byte)(data >> (6*8)); - addr[2] = (bfd_byte)(data >> (5*8)); - addr[3] = (bfd_byte)(data >> (4*8)); - addr[4] = (bfd_byte)(data >> (3*8)); - addr[5] = (bfd_byte)(data >> (2*8)); - addr[6] = (bfd_byte)(data >> (1*8)); - addr[7] = (bfd_byte)(data >> (0*8)); + addr[0] = (bfd_byte) (data >> (7*8)); + addr[1] = (bfd_byte) (data >> (6*8)); + addr[2] = (bfd_byte) (data >> (5*8)); + addr[3] = (bfd_byte) (data >> (4*8)); + addr[4] = (bfd_byte) (data >> (3*8)); + addr[5] = (bfd_byte) (data >> (2*8)); + addr[6] = (bfd_byte) (data >> (1*8)); + addr[7] = (bfd_byte) (data >> (0*8)); #else BFD_FAIL(); #endif @@ -1060,22 +1162,70 @@ bfd_putb64 (data, addr) void bfd_putl64 (data, addr) - bfd_vma data; - register bfd_byte *addr; + bfd_vma data ATTRIBUTE_UNUSED; + register bfd_byte *addr ATTRIBUTE_UNUSED; { #ifdef BFD64 - addr[7] = (bfd_byte)(data >> (7*8)); - addr[6] = (bfd_byte)(data >> (6*8)); - addr[5] = (bfd_byte)(data >> (5*8)); - addr[4] = (bfd_byte)(data >> (4*8)); - addr[3] = (bfd_byte)(data >> (3*8)); - addr[2] = (bfd_byte)(data >> (2*8)); - addr[1] = (bfd_byte)(data >> (1*8)); - addr[0] = (bfd_byte)(data >> (0*8)); + addr[7] = (bfd_byte) (data >> (7*8)); + addr[6] = (bfd_byte) (data >> (6*8)); + addr[5] = (bfd_byte) (data >> (5*8)); + addr[4] = (bfd_byte) (data >> (4*8)); + addr[3] = (bfd_byte) (data >> (3*8)); + addr[2] = (bfd_byte) (data >> (2*8)); + addr[1] = (bfd_byte) (data >> (1*8)); + addr[0] = (bfd_byte) (data >> (0*8)); #else BFD_FAIL(); #endif } + +void +bfd_put_bits (data, addr, bits, big_p) + bfd_vma data; + bfd_byte *addr; + int bits; + boolean big_p; +{ + int i; + int bytes; + + if (bits % 8 != 0) + abort (); + + bytes = bits / 8; + for (i = 0; i < bytes; i++) + { + int index = big_p ? bytes - i - 1 : i; + + addr[index] = (bfd_byte) data; + data >>= 8; + } +} + +bfd_vma +bfd_get_bits (addr, bits, big_p) + bfd_byte *addr; + int bits; + boolean big_p; +{ + bfd_vma data; + int i; + int bytes; + + if (bits % 8 != 0) + abort (); + + data = 0; + bytes = bits / 8; + for (i = 0; i < bytes; i++) + { + int index = big_p ? i : bytes - i - 1; + + data = (data << 8) | addr[index]; + } + + return data; +} /* Default implementation */ @@ -1087,22 +1237,29 @@ _bfd_generic_get_section_contents (abfd, section, location, offset, count) file_ptr offset; bfd_size_type count; { - if (count == 0) - return true; - if ((bfd_size_type)(offset+count) > section->_raw_size - || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1 - || bfd_read(location, (bfd_size_type)1, count, abfd) != count) - return (false); /* on error */ - return (true); + if (count == 0) + return true; + + if ((bfd_size_type) (offset + count) > section->_raw_size) + { + bfd_set_error (bfd_error_invalid_operation); + return false; + } + + if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 + || bfd_read (location, (bfd_size_type) 1, count, abfd) != count) + return false; + + return true; } boolean _bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count) - bfd *abfd; - sec_ptr section; - bfd_window *w; - file_ptr offset; - bfd_size_type count; + bfd *abfd ATTRIBUTE_UNUSED; + sec_ptr section ATTRIBUTE_UNUSED; + bfd_window *w ATTRIBUTE_UNUSED; + file_ptr offset ATTRIBUTE_UNUSED; + bfd_size_type count ATTRIBUTE_UNUSED; { #ifdef USE_MMAP if (count == 0) @@ -1175,23 +1332,51 @@ DESCRIPTION @var{x} of 1025 returns 11. */ -unsigned -bfd_log2(x) +unsigned int +bfd_log2 (x) bfd_vma x; { - unsigned result = 0; - while ( (bfd_vma)(1<< result) < x) - result++; + unsigned int result = 0; + + while ((x = (x >> 1)) != 0) + ++result; return result; } boolean -bfd_generic_is_local_label (abfd, sym) +bfd_generic_is_local_label_name (abfd, name) bfd *abfd; - asymbol *sym; + const char *name; { char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.'; - return (sym->name[0] == locals_prefix); + return (name[0] == locals_prefix); } +/* Can be used from / for bfd_merge_private_bfd_data to check that + endianness matches between input and output file. Returns + true for a match, otherwise returns false and emits an error. */ +boolean +_bfd_generic_verify_endian_match (ibfd, obfd) + bfd *ibfd; + bfd *obfd; +{ + if (ibfd->xvec->byteorder != obfd->xvec->byteorder + && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN + && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN) + { + const char *msg; + + if (bfd_big_endian (ibfd)) + msg = _("%s: compiled for a big endian system and target is little endian"); + else + msg = _("%s: compiled for a little endian system and target is big endian"); + + (*_bfd_error_handler) (msg, bfd_get_filename (ibfd)); + + bfd_set_error (bfd_error_wrong_format); + return false; + } + + return true; +}