diff options
-rw-r--r-- | bfd/aout-adobe.c | 2 | ||||
-rw-r--r-- | bfd/aout-target.h | 9 | ||||
-rw-r--r-- | bfd/aoutx.h | 308 | ||||
-rw-r--r-- | bfd/bout.c | 11 | ||||
-rw-r--r-- | bfd/hp300hpux.c | 7 | ||||
-rw-r--r-- | bfd/i386lynx.c | 15 | ||||
-rw-r--r-- | bfd/i386os9k.c | 2 | ||||
-rw-r--r-- | bfd/libaout.h | 10 |
8 files changed, 200 insertions, 164 deletions
diff --git a/bfd/aout-adobe.c b/bfd/aout-adobe.c index 3de6af6..89961d7 100644 --- a/bfd/aout-adobe.c +++ b/bfd/aout-adobe.c @@ -484,7 +484,7 @@ aout_adobe_sizeof_headers (ignore_abfd, ignore) #define aout_32_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols #define aout_32_bfd_final_link _bfd_generic_final_link -#define aout_32_bfd_free_cached_info bfd_true +#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info bfd_target a_out_adobe_vec = { diff --git a/bfd/aout-target.h b/bfd/aout-target.h index dc59e27..6c2ace9 100644 --- a/bfd/aout-target.h +++ b/bfd/aout-target.h @@ -316,9 +316,6 @@ MY_bfd_final_link (abfd, info) #ifndef MY_write_armap #define MY_write_armap NAME(aout,write_armap) #endif -#ifndef MY_close_and_cleanup -#define MY_close_and_cleanup NAME(aout,close_and_cleanup) -#endif #ifndef MY_set_section_contents #define MY_set_section_contents NAME(aout,set_section_contents) #endif @@ -401,7 +398,11 @@ MY_bfd_final_link (abfd, info) #endif #ifndef MY_bfd_free_cached_info -#define MY_bfd_free_cached_info bfd_true +#define MY_bfd_free_cached_info NAME(aout,bfd_free_cached_info) +#endif + +#ifndef MY_close_and_cleanup +#define MY_close_and_cleanup MY_bfd_free_cached_info #endif /* Aout symbols normally have leading underscores */ diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 14b4bd3..6a7fba8 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -133,6 +133,7 @@ DESCRIPTION #include "aout/stab_gnu.h" #include "aout/ar.h" +static boolean aout_get_external_symbols PARAMS ((bfd *)); static boolean translate_symbol_table PARAMS ((bfd *, aout_symbol_type *, struct external_nlist *, bfd_size_type, char *, @@ -1086,6 +1087,82 @@ NAME(aout,set_section_contents) (abfd, section, location, offset, count) #define sym_is_indirect(sym) \ (((sym)->type & N_ABS)== N_ABS) +/* Read the external symbols from an a.out file. */ + +static boolean +aout_get_external_symbols (abfd) + bfd *abfd; +{ + if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL) + { + bfd_size_type count; + struct external_nlist *syms; + + count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE; + + /* We allocate using malloc to make the values easy to free + later on. If we put them on the obstack it might not be + possible to free them. */ + syms = ((struct external_nlist *) + malloc ((size_t) count * EXTERNAL_NLIST_SIZE)); + if (syms == (struct external_nlist *) NULL && count != 0) + { + bfd_set_error (bfd_error_no_memory); + return false; + } + + if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 + || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd) + != exec_hdr (abfd)->a_syms)) + { + free (syms); + return false; + } + + obj_aout_external_syms (abfd) = syms; + obj_aout_external_sym_count (abfd) = count; + } + + if (obj_aout_external_strings (abfd) == NULL) + { + unsigned char string_chars[BYTES_IN_WORD]; + bfd_size_type stringsize; + char *strings; + + /* Get the size of the strings. */ + if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0 + || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd) + != BYTES_IN_WORD)) + return false; + stringsize = GET_WORD (abfd, string_chars); + + strings = (char *) malloc ((size_t) stringsize + 1); + if (strings == NULL) + { + bfd_set_error (bfd_error_no_memory); + return false; + } + + /* Skip space for the string count in the buffer for convenience + when using indexes. */ + if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, + abfd) + != stringsize - BYTES_IN_WORD) + { + free (strings); + return false; + } + + /* Sanity preservation. */ + strings[stringsize] = '\0'; + + obj_aout_external_strings (abfd) = strings; + obj_aout_external_string_size (abfd) = stringsize; + } + + return true; +} + /* Only in their own functions for ease of debugging; when sym flags have stabilised these should be inlined into their (single) caller */ @@ -1465,31 +1542,29 @@ boolean NAME(aout,slurp_symbol_table) (abfd) bfd *abfd; { - bfd_size_type symbol_size; - bfd_size_type string_size; - unsigned char string_chars[BYTES_IN_WORD]; - struct external_nlist *syms; - char *strings; + struct external_nlist *old_external_syms; aout_symbol_type *cached; + size_t cached_size; bfd_size_type dynsym_count = 0; struct external_nlist *dynsyms = NULL; char *dynstrs = NULL; bfd_size_type dynstr_size; /* If there's no work to be done, don't do any */ - if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true; - symbol_size = exec_hdr(abfd)->a_syms; - if (symbol_size == 0) + if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL) + return true; + + old_external_syms = obj_aout_external_syms (abfd); + + if (! aout_get_external_symbols (abfd)) + return false; + + if (obj_aout_external_sym_count (abfd) == 0) { bfd_set_error (bfd_error_no_symbols); return false; } - bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET); - if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD) - return false; - string_size = GET_WORD (abfd, string_chars); - /* If this is a dynamic object, see if we can get the dynamic symbol table. */ if ((bfd_get_file_flags (abfd) & DYNAMIC) != 0 @@ -1501,59 +1576,52 @@ NAME(aout,slurp_symbol_table) (abfd) return false; } - strings = (char *) bfd_alloc (abfd, string_size + 1); - cached = ((aout_symbol_type *) - bfd_zalloc (abfd, - ((bfd_get_symcount (abfd) + dynsym_count) - * sizeof (aout_symbol_type)))); + cached_size = ((obj_aout_external_sym_count (abfd) + dynsym_count) + * sizeof (aout_symbol_type)); + cached = (aout_symbol_type *) malloc (cached_size); + memset (cached, 0, cached_size); - /* Don't allocate on the obstack, so we can free it easily. */ - syms = (struct external_nlist *) malloc(symbol_size); - if (!strings || !cached || !syms) + if (cached == NULL) { bfd_set_error (bfd_error_no_memory); return false; } - bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET); - if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) + + /* Convert from external symbol information to internal. */ + if (! translate_symbol_table (abfd, cached, + obj_aout_external_syms (abfd), + obj_aout_external_sym_count (abfd), + obj_aout_external_strings (abfd), + obj_aout_external_string_size (abfd), + false) + || ! translate_symbol_table (abfd, + (cached + + obj_aout_external_sym_count (abfd)), + dynsyms, dynsym_count, dynstrs, + dynstr_size, true)) { - bailout: - if (syms) - free (syms); - if (cached) - bfd_release (abfd, cached); - if (strings) - bfd_release (abfd, strings); + free (cached); return false; } - bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET); - if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) - { - goto bailout; - } - strings[string_size] = 0; /* Just in case. */ + bfd_get_symcount (abfd) = (obj_aout_external_sym_count (abfd) + + dynsym_count); - /* OK, now walk the new symtable, cacheing symbol properties */ - if (! translate_symbol_table (abfd, cached, syms, bfd_get_symcount (abfd), - strings, string_size, false)) - goto bailout; - if (dynsym_count > 0) - { - if (! translate_symbol_table (abfd, cached + bfd_get_symcount (abfd), - dynsyms, dynsym_count, dynstrs, - dynstr_size, true)) - goto bailout; + obj_aout_symbols (abfd) = cached; - bfd_get_symcount (abfd) += dynsym_count; + /* It is very likely that anybody who calls this function will not + want the external symbol information, so if it was allocated + because of our call to aout_get_external_symbols, we free it up + right away to save space. */ + if (old_external_syms == (struct external_nlist *) NULL + && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL) + { + free (obj_aout_external_syms (abfd)); + obj_aout_external_syms (abfd) = NULL; } - obj_aout_symbols (abfd) = cached; - free((PTR)syms); - return true; } - /* Possible improvements: + look for strings matching trailing substrings of other strings @@ -2315,7 +2383,7 @@ NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols) MOVE_ADDRESS(0); } -/* Reloc hackery */ +/* Read and swap the relocs for a section. */ boolean NAME(aout,slurp_reloc_table) (abfd, asect, symbols) @@ -2333,9 +2401,11 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols) unsigned int counter = 0; arelent *cache_ptr; - if (asect->relocation) return true; + if (asect->relocation) + return true; - if (asect->flags & SEC_CONSTRUCTOR) return true; + if (asect->flags & SEC_CONSTRUCTOR) + return true; if (asect == obj_datasec (abfd)) reloc_size = exec_hdr(abfd)->a_drsize; @@ -2356,34 +2426,34 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols) return false; } - bfd_seek (abfd, asect->rel_filepos, SEEK_SET); + if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) + return false; + each_size = obj_reloc_entry_size (abfd); count = reloc_size / each_size; - reloc_cache = ((arelent *) - bfd_zalloc (abfd, - (size_t) ((count + dynrel_count) - * sizeof (arelent)))); - if (!reloc_cache) + reloc_cache = (arelent *) malloc ((size_t) ((count + dynrel_count) + * sizeof (arelent))); + if (reloc_cache == NULL && count != 0) { - nomem: bfd_set_error (bfd_error_no_memory); return false; } + memset (reloc_cache, 0, (count + dynrel_count) * sizeof (arelent)); - relocs = (PTR) bfd_alloc (abfd, reloc_size); - if (!relocs) + relocs = malloc (reloc_size); + if (relocs == NULL && reloc_size != 0) { - bfd_release (abfd, reloc_cache); - goto nomem; + free (reloc_cache); + bfd_set_error (bfd_error_no_memory); + return false; } if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) { - bfd_release (abfd, relocs); - bfd_release (abfd, reloc_cache); - bfd_set_error (bfd_error_system_call); + free (relocs); + free (reloc_cache); return false; } @@ -2398,13 +2468,15 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols) } else { - register struct reloc_std_external *rptr - = (struct reloc_std_external *) relocs; + register struct reloc_std_external *rptr = + (struct reloc_std_external *) relocs; for (; counter < count; counter++, rptr++, cache_ptr++) NAME(aout,swap_std_reloc_in) (abfd, rptr, cache_ptr, symbols); } + free (relocs); + if (dynrel_count > 0) { asymbol **dynsyms; @@ -2446,14 +2518,12 @@ NAME(aout,slurp_reloc_table) (abfd, asect, symbols) } } - bfd_release (abfd,relocs); asect->relocation = reloc_cache; asect->reloc_count = cache_ptr - reloc_cache; + return true; } - - /* Write out a relocation section into an object file. */ boolean @@ -2794,6 +2864,26 @@ NAME(aout,sizeof_headers) (abfd, execable) { return adata(abfd).exec_bytes_size; } + +/* Free all information we have cached for this BFD. We can always + read it again later if we need it. */ + +boolean +NAME(aout,bfd_free_cached_info) (abfd) + bfd *abfd; +{ + asection *o; + +#define FREE(x) if (x != NULL) { free (x); x = NULL; } + FREE (obj_aout_symbols (abfd)); + FREE (obj_aout_external_syms (abfd)); + FREE (obj_aout_external_strings (abfd)); + for (o = abfd->sections; o != (asection *) NULL; o = o->next) + FREE (o->relocation); +#undef FREE + + return true; +} /* a.out link code. */ @@ -2821,7 +2911,6 @@ static boolean aout_link_add_object_symbols PARAMS ((bfd *, struct bfd_link_info *)); static boolean aout_link_check_archive_element PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean aout_link_get_symbols PARAMS ((bfd *)); static boolean aout_link_free_symbols PARAMS ((bfd *)); static boolean aout_link_check_ar_symbols PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); @@ -2931,7 +3020,7 @@ aout_link_add_object_symbols (abfd, info) bfd *abfd; struct bfd_link_info *info; { - if (! aout_link_get_symbols (abfd)) + if (! aout_get_external_symbols (abfd)) return false; if (! aout_link_add_symbols (abfd, info)) return false; @@ -2954,7 +3043,7 @@ aout_link_check_archive_element (abfd, info, pneeded) struct bfd_link_info *info; boolean *pneeded; { - if (! aout_link_get_symbols (abfd)) + if (! aout_get_external_symbols (abfd)) return false; if (! aout_link_check_ar_symbols (abfd, info, pneeded)) @@ -2979,69 +3068,6 @@ aout_link_check_archive_element (abfd, info, pneeded) return true; } -/* Read the internal symbols from an a.out file. */ - -static boolean -aout_link_get_symbols (abfd) - bfd *abfd; -{ - bfd_size_type count; - struct external_nlist *syms; - unsigned char string_chars[BYTES_IN_WORD]; - bfd_size_type stringsize; - char *strings; - - if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL) - { - /* We already have them. */ - return true; - } - - count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE; - - /* We allocate using malloc to make the values easy to free - later on. If we put them on the obstack it might not be possible - to free them. */ - syms = ((struct external_nlist *) - malloc ((size_t) count * EXTERNAL_NLIST_SIZE)); - if (syms == (struct external_nlist *) NULL && count != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || (bfd_read ((PTR) syms, 1, exec_hdr (abfd)->a_syms, abfd) - != exec_hdr (abfd)->a_syms)) - return false; - - /* Get the size of the strings. */ - if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0 - || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd) - != BYTES_IN_WORD)) - return false; - stringsize = GET_WORD (abfd, string_chars); - strings = (char *) malloc ((size_t) stringsize); - if (strings == NULL && stringsize != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - /* Skip space for the string count in the buffer for convenience - when using indexes. */ - if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, abfd) - != stringsize - BYTES_IN_WORD) - return false; - - /* Save the data. */ - obj_aout_external_syms (abfd) = syms; - obj_aout_external_sym_count (abfd) = count; - obj_aout_external_strings (abfd) = strings; - - return true; -} - /* Free up the internal symbols read from an a.out file. */ static boolean @@ -3593,7 +3619,7 @@ aout_link_input_bfd (finfo, input_bfd) /* Get the symbols. We probably have them already, unless finfo->info->keep_memory is false. */ - if (! aout_link_get_symbols (input_bfd)) + if (! aout_get_external_symbols (input_bfd)) return false; sym_count = obj_aout_external_sym_count (input_bfd); @@ -4100,7 +4126,7 @@ aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr, if (! aout_link_input_section_ext (finfo, input_bfd, input_section, (struct reloc_ext_external *) relocs, rel_size, contents, symbol_map)) - return false; + goto error_return; } /* Write out the section contents. */ @@ -457,8 +457,10 @@ b_out_slurp_reloc_table (abfd, asect, symbols) struct relocation_info *relocs; arelent *reloc_cache; - if (asect->relocation) return true; - if (!aout_32_slurp_symbol_table (abfd)) return false; + if (asect->relocation) + return true; + if (!aout_32_slurp_symbol_table (abfd)) + return false; if (asect == obj_datasec (abfd)) { reloc_size = exec_hdr(abfd)->a_drsize; @@ -474,7 +476,8 @@ b_out_slurp_reloc_table (abfd, asect, symbols) return false; doit: - bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET); + if (bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET) != 0) + return false; count = reloc_size / sizeof (struct relocation_info); relocs = (struct relocation_info *) malloc (reloc_size); @@ -1379,7 +1382,7 @@ b_out_get_relocated_section_contents (in_abfd, link_info, link_order, data, #define aout_32_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols #define aout_32_bfd_final_link _bfd_generic_final_link -#define aout_32_bfd_free_cached_info bfd_true +#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info bfd_target b_out_vec_big_host = { diff --git a/bfd/hp300hpux.c b/bfd/hp300hpux.c index fded557..d73ab1a 100644 --- a/bfd/hp300hpux.c +++ b/bfd/hp300hpux.c @@ -119,7 +119,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define DEFAULT_ARCH bfd_arch_m68k #define MY_get_section_contents aout_32_get_section_contents -#define MY_close_and_cleanup aout_32_close_and_cleanup #define MY_slurp_armap bfd_slurp_bsd_armap_f2 /***********************************************/ @@ -137,6 +136,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MY_bfd_link_add_symbols _bfd_generic_link_add_symbols #define MY_bfd_final_link _bfd_generic_final_link +/* Until and unless we convert the slurp_reloc and slurp_symtab + routines in this file, we can not use the default aout + free_cached_info routine which assumes that the relocs and symtabs + were allocated using malloc. */ +#define MY_bfd_free_cached_info bfd_true + #define hp300hpux_write_syms aout_32_write_syms #define MY_callback MY(callback) diff --git a/bfd/i386lynx.c b/bfd/i386lynx.c index fde6ad3..e643dad 100644 --- a/bfd/i386lynx.c +++ b/bfd/i386lynx.c @@ -367,7 +367,7 @@ NAME (lynx, swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols) /* Reloc hackery */ boolean -NAME (lynx, slurp_reloc_table) (abfd, asect, symbols) +NAME(lynx,slurp_reloc_table) (abfd, asect, symbols) bfd *abfd; sec_ptr asect; asymbol **symbols; @@ -400,32 +400,33 @@ NAME (lynx, slurp_reloc_table) (abfd, asect, symbols) return false; doit: - bfd_seek (abfd, asect->rel_filepos, SEEK_SET); + if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) + return false; each_size = obj_reloc_entry_size (abfd); count = reloc_size / each_size; - reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t) (count * sizeof - (arelent))); - if (!reloc_cache) + reloc_cache = (arelent *) malloc (count * sizeof (arelent)); + if (!reloc_cache && count != 0) { nomem: bfd_set_error (bfd_error_no_memory); return false; } + memset (reloc_cache, 0, count * sizeof (arelent)); relocs = (PTR) bfd_alloc (abfd, reloc_size); if (!relocs) { - bfd_release (abfd, reloc_cache); + free (reloc_cache); goto nomem; } if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) { bfd_release (abfd, relocs); - bfd_release (abfd, reloc_cache); + free (reloc_cache); return false; } diff --git a/bfd/i386os9k.c b/bfd/i386os9k.c index c6955fe..eb6ee84 100644 --- a/bfd/i386os9k.c +++ b/bfd/i386os9k.c @@ -338,7 +338,7 @@ os9k_sizeof_headers (ignore_abfd, ignore) #define aout_32_bfd_reloc_type_lookup \ ((CONST struct reloc_howto_struct *(*) PARAMS \ ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr) -#define aout_32_bfd_free_cached_info bfd_true +#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info bfd_target i386os9k_vec = { diff --git a/bfd/libaout.h b/bfd/libaout.h index c9793f8..0b22dee 100644 --- a/bfd/libaout.h +++ b/bfd/libaout.h @@ -252,6 +252,7 @@ struct aoutdata { struct external_nlist *external_syms; bfd_size_type external_sym_count; char *external_strings; + bfd_size_type external_string_size; struct aout_link_hash_entry **sym_hashes; /* A pointer for shared library information. */ @@ -277,6 +278,7 @@ struct aout_data_struct { #define obj_aout_external_syms(bfd) (adata(bfd).external_syms) #define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count) #define obj_aout_external_strings(bfd) (adata(bfd).external_strings) +#define obj_aout_external_string_size(bfd) (adata(bfd).external_string_size) #define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes) #define obj_aout_dynamic_info(bfd) (adata(bfd).dynamic_info) @@ -356,9 +358,6 @@ NAME(aout,get_symbol_info) PARAMS ((bfd *ignore_abfd, asymbol *symbol, symbol_info *ret)); boolean -NAME(aout,close_and_cleanup) PARAMS ((bfd *abfd)); - -boolean NAME(aout,find_nearest_line) PARAMS ((bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset, CONST char **filename_ptr, CONST char **functionname_ptr, unsigned int *line_ptr)); @@ -389,6 +388,9 @@ NAME(aout,final_link) PARAMS ((bfd *, struct bfd_link_info *, void (*) (bfd *, file_ptr *, file_ptr *, file_ptr *))); +boolean +NAME(aout,bfd_free_cached_info) PARAMS ((bfd *)); + /* Prototypes for functions in stab-syms.c. */ CONST char * @@ -397,10 +399,8 @@ aout_stab_name PARAMS ((int code)); /* A.out uses the generic versions of these routines... */ #define aout_32_get_section_contents bfd_generic_get_section_contents -#define aout_32_close_and_cleanup bfd_generic_close_and_cleanup #define aout_64_get_section_contents bfd_generic_get_section_contents -#define aout_64_close_and_cleanup bfd_generic_close_and_cleanup #ifndef NO_WRITE_HEADER_KLUDGE #define NO_WRITE_HEADER_KLUDGE 0 #endif |