X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Fbfd.c;h=6b4d4473edbceac01e8b06a2b7857142681c9529;hb=a643e6260e2b817cffecd200214b1fceee802ab8;hp=ad30a1b6cbc9ddf05d26d2a5e1835e2d3429beda;hpb=6724ff46c812880323b37d7bcf039866b02c882b;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/bfd.c b/bfd/bfd.c index ad30a1b6cb..6b4d4473ed 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1,5 +1,5 @@ /* Generic BFD library interface and support routines. - Copyright (C) 1990-1991 Free Software Foundation, Inc. + Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -18,154 +18,173 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id$ */ - -/*proto* -@section typedef bfd - -Pointers to bfd structs are the cornerstone of any application using -libbfd. References though the BFD and to data in the BFD give the -entire BFD functionality. - -Finally! The BFD struct itself. This contains the major data about -the file, and contains pointers to the rest of the data. - -*+++ - -$struct _bfd -${ - The filename the application opened the BFD with. - -$ CONST char *filename; - -A pointer to the target jump table. - -$ struct bfd_target *xvec; - - -To avoid dragging too many header files into every file that -includes @file{bfd.h}, IOSTREAM has been declared as a "char *", and MTIME -as a "long". Their correct types, to which they are cast when used, -are "FILE *" and "time_t". - -The iostream is the result of an fopen on the filename. - -$ char *iostream; - -Is the file being cached @xref{File Caching}. - -$ boolean cacheable; - -Marks whether there was a default target specified when the BFD was -opened. This is used to select what matching algorithm to use to chose -the back end. - -$ boolean target_defaulted; - -The caching routines use these to maintain an LRU list of BFDs. - -$ struct _bfd *lru_prev, *lru_next; - -When a file is closed by the caching routines, it retains the state -here: - -$ file_ptr where; - -and here: - -$ boolean opened_once; - -$ boolean mtime_set; -File modified time - -$ long mtime; - -For output files, channel we locked (is this used?). - -$int ifd; - -The format which belongs to the BFD. - -$ bfd_format format; - -The direction the BFD was opened with - -$ enum bfd_direction {no_direction = 0, -$ read_direction = 1, -$ write_direction = 2, -$ both_direction = 3} direction; - -Format_specific flags - -$ flagword flags; - -Currently my_archive is tested before adding origin to anything. I -believe that this can become always an add of origin, with origin set -to 0 for non archive files. - -$ file_ptr origin; - -Remember when output has begun, to stop strange things happening. - -$ boolean output_has_begun; - -Pointer to linked list of sections - -$ struct sec *sections; - -The number of sections - -$ unsigned int section_count; - -Stuff only usefull for object files: -The start address. - -$ bfd_vma start_address; -Used for input and output - -$ unsigned int symcount; -Symtab for output BFD - -$ struct symbol_cache_entry **outsymbols; - -Architecture of object machine, eg m68k - -$ enum bfd_architecture obj_arch; - -Particular machine within arch, e.g. 68010 - -$ unsigned long obj_machine; - -Stuff only usefull for archives: - -$ PTR arelt_data; -$ struct _bfd *my_archive; -$ struct _bfd *next; -$ struct _bfd *archive_head; -$ boolean has_armap; - -Used by the back end to hold private data. - -$ PTR tdata; - -Used by the application to hold private data - -$ PTR usrdata; - -Where all the allocated stuff under this BFD goes - -$ struct obstack memory; -$}; - -*--- - +/* +SECTION + <> + + A BFD is has type <>; objects of this type are the + cornerstone of any application using <>. References + though the BFD and to data in the BFD give the entire BFD + functionality. + + Here is the struct used to define the type <>. This + contains the major data about the file, and contains pointers + to the rest of the data. + +CODE_FRAGMENT +. +.struct _bfd +.{ +. {* The filename the application opened the BFD with. *} +. CONST char *filename; +. +. {* A pointer to the target jump table. *} +. struct bfd_target *xvec; +. +. {* To avoid dragging too many header files into every file that +. includes `<>', IOSTREAM has been declared as a "char +. *", and MTIME as a "long". Their correct types, to which they +. are cast when used, are "FILE *" and "time_t". The iostream +. is the result of an fopen on the filename. *} +. char *iostream; +. +. {* Is the file being cached *} +. +. boolean cacheable; +. +. {* Marks whether there was a default target specified when the +. BFD was opened. This is used to select what matching algorithm +. to use to chose the back end. *} +. +. boolean target_defaulted; +. +. {* The caching routines use these to maintain a +. least-recently-used list of BFDs *} +. +. struct _bfd *lru_prev, *lru_next; +. +. {* When a file is closed by the caching routines, BFD retains +. state information on the file here: +. *} +. +. file_ptr where; +. +. {* and here:*} +. +. boolean opened_once; +. +. {* Set if we have a locally maintained mtime value, rather than +. getting it from the file each time: *} +. +. boolean mtime_set; +. +. {* File modified time, if mtime_set is true: *} +. +. long mtime; +. +. {* Reserved for an unimplemented file locking extension.*} +. +. int ifd; +. +. {* The format which belongs to the BFD.*} +. +. bfd_format format; +. +. {* The direction the BFD was opened with*} +. +. enum bfd_direction {no_direction = 0, +. read_direction = 1, +. write_direction = 2, +. both_direction = 3} direction; +. +. {* Format_specific flags*} +. +. flagword flags; +. +. {* Currently my_archive is tested before adding origin to +. anything. I believe that this can become always an add of +. origin, with origin set to 0 for non archive files. *} +. +. file_ptr origin; +. +. {* Remember when output has begun, to stop strange things +. happening. *} +. boolean output_has_begun; +. +. {* Pointer to linked list of sections*} +. struct sec *sections; +. +. {* The number of sections *} +. unsigned int section_count; +. +. {* Stuff only useful for object files: +. The start address. *} +. bfd_vma start_address; +. +. {* Used for input and output*} +. unsigned int symcount; +. +. {* Symbol table for output BFD*} +. struct symbol_cache_entry **outsymbols; +. +. {* Pointer to structure which contains architecture information*} +. struct bfd_arch_info *arch_info; +. +. {* Stuff only useful for archives:*} +. PTR arelt_data; +. struct _bfd *my_archive; +. struct _bfd *next; +. struct _bfd *archive_head; +. boolean has_armap; +. +. {* Used by the back end to hold private data. *} +. +. union +. { +. struct aout_data_struct *aout_data; +. struct artdata *aout_ar_data; +. struct _oasys_data *oasys_obj_data; +. struct _oasys_ar_data *oasys_ar_data; +. struct coff_tdata *coff_obj_data; +. struct ecoff_tdata *ecoff_obj_data; +. struct ieee_data_struct *ieee_data; +. struct ieee_ar_data_struct *ieee_ar_data; +. struct srec_data_struct *srec_data; +. struct tekhex_data_struct *tekhex_data; +. struct elf_obj_tdata *elf_obj_data; +. struct nlm_obj_tdata *nlm_obj_data; +. struct bout_data_struct *bout_data; +. struct sun_core_struct *sun_core_data; +. struct trad_core_struct *trad_core_data; +. struct hppa_data_struct *hppa_data; +. struct hpux_core_struct *hpux_core_data; +. struct sgi_core_struct *sgi_core_data; +. PTR any; +. } tdata; +. +. {* Used by the application to hold private data*} +. PTR usrdata; +. +. {* Where all the allocated stuff under this BFD goes *} +. struct obstack memory; +. +. {* Is this really needed in addition to usrdata? *} +. asymbol **ld_symbols; +.}; +. */ -#include + #include "bfd.h" +#include "sysdep.h" #include "libbfd.h" +#include "coff/sym.h" +#include "libecoff.h" +#undef strerror +extern char *strerror(); -short _bfd_host_big_endian = 0x0100; + +CONST short _bfd_host_big_endian = 0x0100; /* Accessing the above as (*(char*)&_bfd_host_big_endian), will return 1 if the host is big-endian, 0 otherwise. (assuming that a short is two bytes long!!! FIXME) @@ -181,7 +200,8 @@ short _bfd_host_big_endian = 0x0100; bfd_ec bfd_error = no_error; -char *bfd_errmsgs[] = { "No error", +CONST char *CONST bfd_errmsgs[] = { + "No error", "System call error", "Invalid target", "File in wrong format", @@ -196,6 +216,9 @@ char *bfd_errmsgs[] = { "No error", "File format is ambiguous", "Section has no contents", "Nonrepresentable section on output", + "Symbol needs debug section which does not exist", + "Bad value", + "File truncated", "#" }; @@ -212,26 +235,49 @@ DEFUN(bfd_nonrepresentable_section,(abfd, name), exit(1); } +/*ARGSUSED*/ +static +void +DEFUN(bfd_undefined_symbol,(relent, seclet), + CONST arelent *relent AND + CONST struct bfd_seclet *seclet) +{ + asymbol *symbol = *(relent->sym_ptr_ptr); + printf("bfd error relocating, symbol %s is undefined\n", + symbol->name); + exit(1); +} +/*ARGSUSED*/ +static +void +DEFUN(bfd_reloc_value_truncated,(relent, seclet), + CONST arelent *relent AND + struct bfd_seclet *seclet) +{ + printf("bfd error relocating, value truncated\n"); + exit(1); +} +/*ARGSUSED*/ +static +void +DEFUN(bfd_reloc_is_dangerous,(relent, seclet), + CONST arelent *relent AND + CONST struct bfd_seclet *seclet) +{ + printf("bfd error relocating, dangerous\n"); + exit(1); +} + bfd_error_vector_type bfd_error_vector = { - bfd_nonrepresentable_section + bfd_nonrepresentable_section , + bfd_undefined_symbol, + bfd_reloc_value_truncated, + bfd_reloc_is_dangerous, }; -#if 1 || !defined(ANSI_LIBRARIES) && !defined(__STDC__) -char * -strerror (code) - int code; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" : - sys_errlist [code]); -} -#endif /* not ANSI_LIBRARIES */ - - -char * +CONST char * bfd_errmsg (error_tag) bfd_ec error_tag; { @@ -248,15 +294,15 @@ bfd_errmsg (error_tag) return bfd_errmsgs [(int)error_tag]; } - -void bfd_default_error_trap(error_tag) -bfd_ec error_tag; +void +DEFUN (bfd_default_error_trap, (error_tag), + bfd_ec error_tag) { printf("bfd assert fail (%s)\n", bfd_errmsg(error_tag)); } -void (*bfd_error_trap)() = bfd_default_error_trap; -void (*bfd_error_nonrepresentabltrap)() = bfd_default_error_trap; +void (*bfd_error_trap) PARAMS ((bfd_ec)) = bfd_default_error_trap; +void (*bfd_error_nonrepresentabltrap) PARAMS ((bfd_ec)) = bfd_default_error_trap; void DEFUN(bfd_perror,(message), @@ -275,12 +321,26 @@ DEFUN(bfd_perror,(message), /** Symbols */ -/* returns the number of octets of storage required */ + +/* +FUNCTION + bfd_get_reloc_upper_bound + +SYNOPSIS + unsigned int bfd_get_reloc_upper_bound(bfd *abfd, asection *sect); + +DESCRIPTION + This function return the number of bytes required to store the + relocation information associated with section <> + attached to bfd <> + +*/ + unsigned int -get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; +DEFUN(bfd_get_reloc_upper_bound,(abfd, asect), + bfd *abfd AND + sec_ptr asect) { if (abfd->format != bfd_object) { bfd_error = invalid_operation; @@ -290,21 +350,66 @@ get_reloc_upper_bound (abfd, asect) return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect)); } +/* +FUNCTION + bfd_canonicalize_reloc + +SYNOPSIS + unsigned int bfd_canonicalize_reloc + (bfd *abfd, + asection *sec, + arelent **loc, + asymbol **syms); + +DESCRIPTION + This function calls the back end associated with the open + <> and translates the external form of the relocation + information attached to <> into the internal canonical + form. The table is placed into memory at <>, which has + been preallocated, usually by a call to + <>. + + The <> table is also needed for horrible internal magic + reasons. + + +*/ unsigned int -bfd_canonicalize_reloc (abfd, asect, location, symbols) - bfd *abfd; - sec_ptr asect; - arelent **location; - asymbol **symbols; +DEFUN(bfd_canonicalize_reloc,(abfd, asect, location, symbols), + bfd *abfd AND + sec_ptr asect AND + arelent **location AND + asymbol **symbols) { - if (abfd->format != bfd_object) { - bfd_error = invalid_operation; - return 0; + if (abfd->format != bfd_object) { + bfd_error = invalid_operation; + return 0; + } + return BFD_SEND (abfd, _bfd_canonicalize_reloc, + (abfd, asect, location, symbols)); } - return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols)); -} +/* +FUNCTION + bfd_set_file_flags + +SYNOPSIS + boolean bfd_set_file_flags(bfd *abfd, flagword flags); + +DESCRIPTION + This function attempts to set the flag word in the referenced + BFD structure to the value supplied. + + Possible errors are: + o wrong_format - The target bfd was not of object format. + o invalid_operation - The target bfd was open for reading. + o invalid_operation - + The flag word contained a bit which was not applicable to the + type of file. eg, an attempt was made to set the D_PAGED bit + on a bfd format which does not support demand paging + +*/ boolean bfd_set_file_flags (abfd, flags) @@ -321,16 +426,29 @@ bfd_set_file_flags (abfd, flags) return false; } + bfd_get_file_flags (abfd) = flags; if ((flags & bfd_applicable_file_flags (abfd)) != flags) { bfd_error = invalid_operation; return false; } - bfd_get_file_flags (abfd) = flags; return true; } +/* +FUNCTION + bfd_set_reloc + +SYNOPSIS + void bfd_set_reloc + (bfd *abfd, asection *sec, arelent **rel, unsigned int count) + +DESCRIPTION + This function sets the relocation pointer and count within a + section to the supplied values. +*/ +/*ARGSUSED*/ void bfd_set_reloc (ignore_abfd, asect, location, count) bfd *ignore_abfd; @@ -351,12 +469,18 @@ int line; } -/*proto* bfd_set_start_address +/* +FUNCTION + bfd_set_start_address + +DESCRIPTION + Marks the entry point of an output BFD. -Marks the entry point of an output BFD. Returns @code{true} on -success, @code{false} otherwise. +RETURNS + Returns <> on success, <> otherwise. -*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma)); +SYNOPSIS + boolean bfd_set_start_address(bfd *, bfd_vma); */ boolean @@ -369,13 +493,16 @@ bfd_vma vma; } -/*proto* bfd_get_mtime +/* +FUNCTION + The bfd_get_mtime function -Return cached file modification time (e.g. as read from archive header -for archive members, or from file system if we have been called -before); else determine modify time, cache it, and return it. +SYNOPSIS + long bfd_get_mtime(bfd *); -*; PROTO(long, bfd_get_mtime, (bfd *)); +DESCRIPTION + Return file modification time (as read from file system, or + from archive header for archive members). */ @@ -393,47 +520,138 @@ bfd_get_mtime (abfd) if (0 != fstat (fileno (fp), &buf)) return 0; - abfd->mtime_set = true; - abfd->mtime = buf.st_mtime; - return abfd->mtime; + abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */ + return buf.st_mtime; } -/*proto* stuff - -*+ +/* +FUNCTION + The bfd_get_size function + +SYNOPSIS + long bfd_get_size(bfd *); + +DESCRIPTION + Return file size (as read from file system) for the file + associated with a bfd. + + Note that the initial motivation for, and use of, this routine is not + so we can get the exact size of the object the bfd applies to, since + that might not be generally possible (archive members for example?). + Although it would be ideal if someone could eventually modify + it so that such results were guaranteed. + + Instead, we want to ask questions like "is this NNN byte sized + object I'm about to try read from file offset YYY reasonable?" + As as example of where we might want to do this, some object formats + use string tables for which the first sizeof(long) bytes of the table + contain the size of the table itself, including the size bytes. + If an application tries to read what it thinks is one of these + string tables, without some way to validate the size, and for + some reason the size is wrong (byte swapping error, wrong location + for the string table, etc), the only clue is likely to be a read + error when it tries to read the table, or a "virtual memory + exhausted" error when it tries to allocated 15 bazillon bytes + of space for the 15 bazillon byte table it is about to read. + This function at least allows us to answer the quesion, "is the + size reasonable?". +*/ -#define bfd_sizeof_headers(abfd, reloc) \ - BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) +long +bfd_get_size (abfd) + bfd *abfd; +{ + FILE *fp; + struct stat buf; -#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \ - BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, section, symbols, offset, filename_ptr, func, line_ptr)) + fp = bfd_cache_lookup (abfd); + if (0 != fstat (fileno (fp), &buf)) + return 0; -#define bfd_debug_info_start(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) + return buf.st_size; +} -#define bfd_debug_info_end(abfd) \ - BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) +/* +FUNCTION + The bfd_get_gp_size function -#define bfd_debug_info_accumulate(abfd, section) \ - BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) +SYNOPSIS + int bfd_get_gp_size(bfd *); -#define bfd_stat_arch_elt(abfd, stat) \ - BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) +DESCRIPTION + Get the maximum size of objects to be optimized using the GP + register under MIPS ECOFF. This is typically set by the -G + argument to the compiler, assembler or linker. +*/ -#define bfd_coff_swap_aux_in(a,e,t,c,i) \ - BFD_SEND (a, _bfd_coff_swap_aux_in, (a,e,t,c,i)) +int +bfd_get_gp_size (abfd) + bfd *abfd; +{ + if (abfd->xvec->flavour == bfd_target_ecoff_flavour) + return ecoff_data (abfd)->gp_size; + return 0; +} -#define bfd_coff_swap_sym_in(a,e,i) \ - BFD_SEND (a, _bfd_coff_swap_sym_in, (a,e,i)) +/* +FUNCTION + The bfd_set_gp_size function -#define bfd_coff_swap_lineno_in(a,e,i) \ - BFD_SEND ( a, _bfd_coff_swap_lineno_in, (a,e,i)) -*- +SYNOPSIS + void bfd_set_gp_size(bfd *, int); +DESCRIPTION + Set the maximum size of objects to be optimized using the GP + register under MIPS ECOFF. This is typically set by the -G + argument to the compiler, assembler or linker. */ +void +bfd_set_gp_size (abfd, i) + bfd *abfd; + int i; +{ + if (abfd->xvec->flavour == bfd_target_ecoff_flavour) + ecoff_data (abfd)->gp_size = i; +} +/* +FUNCTION + stuff + +DESCRIPTION + stuff which should be documented + +.#define bfd_sizeof_headers(abfd, reloc) \ +. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) +. +.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ +. BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line)) +. +. {* Do these three do anything useful at all, for any back end? *} +.#define bfd_debug_info_start(abfd) \ +. BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) +. +.#define bfd_debug_info_end(abfd) \ +. BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) +. +.#define bfd_debug_info_accumulate(abfd, section) \ +. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) +. +. +.#define bfd_stat_arch_elt(abfd, stat) \ +. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) +. +.#define bfd_set_arch_mach(abfd, arch, mach)\ +. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) +. +.#define bfd_get_relocated_section_contents(abfd, seclet, data, relocateable) \ +. BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet, data, relocateable)) +. +.#define bfd_relax_section(abfd, section, symbols) \ +. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols)) +. +.#define bfd_seclet_link(abfd, data, relocateable) \ +. BFD_SEND (abfd, _bfd_seclet_link, (abfd, data, relocateable)) - - - +*/