From: Ian Lance Taylor Date: Thu, 13 Jul 1995 14:46:06 +0000 (+0000) Subject: * targets.c (bfd_target): Add fields _read_minisymbols and X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=c3246d9b00ee6626c79eced991d3b669aa4846ab;p=deliverable%2Fbinutils-gdb.git * targets.c (bfd_target): Add fields _read_minisymbols and _minisymbol_to_symbol. (BFD_JUMP_TABLE_SYMBOLS): Add _read_minisymbols and _minisymbol_to_symbol. (bfd_read_minisymbols): Define. (bfd_minisymbol_to_symbol): Define. * syms.c (_bfd_generic_read_minisymbols): Define. (_bfd_generic_minisymbol_to_symbol): Define. * libbfd-in.h (_bfd_nosymbols_read_minisymbols): Define. (_bfd_nosymbols_minisymbol_to_symbol): Define. (_bfd_generic_read_minisymbols): Declare. (_bfd_generic_minisymbol_to_symbol): Declare. * bfd-in2.h: Rebuild. * libbfd.h: Rebuild. * aoutx.h (MINISYM_THRESHOLD): Define. (NAME(aout,read_minisymbols)): New function. (NAME(aout,minisymbol_to_symbol)): New function. * libaout.h (NAME(aout,read_minisymbols)): Declare. (NAME(aout,minisymbol_to_symbol)): Declare. * aout-target.h (MY_read_minisymbols): Define. (MY_minisymbol_to_symbol): Define. * All targets: Define read_minisymbols and minisymbol_to_symbol. PR 5332. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 19a53a5b05..7d20576f55 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,28 @@ +Thu Jul 13 10:33:25 1995 Ian Lance Taylor + + * targets.c (bfd_target): Add fields _read_minisymbols and + _minisymbol_to_symbol. + (BFD_JUMP_TABLE_SYMBOLS): Add _read_minisymbols and + _minisymbol_to_symbol. + (bfd_read_minisymbols): Define. + (bfd_minisymbol_to_symbol): Define. + * syms.c (_bfd_generic_read_minisymbols): Define. + (_bfd_generic_minisymbol_to_symbol): Define. + * libbfd-in.h (_bfd_nosymbols_read_minisymbols): Define. + (_bfd_nosymbols_minisymbol_to_symbol): Define. + (_bfd_generic_read_minisymbols): Declare. + (_bfd_generic_minisymbol_to_symbol): Declare. + * bfd-in2.h: Rebuild. + * libbfd.h: Rebuild. + * aoutx.h (MINISYM_THRESHOLD): Define. + (NAME(aout,read_minisymbols)): New function. + (NAME(aout,minisymbol_to_symbol)): New function. + * libaout.h (NAME(aout,read_minisymbols)): Declare. + (NAME(aout,minisymbol_to_symbol)): Declare. + * aout-target.h (MY_read_minisymbols): Define. + (MY_minisymbol_to_symbol): Define. + * All targets: Define read_minisymbols and minisymbol_to_symbol. + Wed Jul 12 17:55:55 1995 Ken Raeburn * elflink.h (elf_link_add_object_symbols): Cast return value from diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 8c6ebb13de..8d2385ec58 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2539,6 +2539,78 @@ NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how) } } +/* If we don't have to allocate more than 1MB to hold the generic + symbols, we use the generic minisymbol methord: it's faster, since + it only translates the symbols once, not multiple times. */ +#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol)) + +/* Read minisymbols. For minisymbols, we use the unmodified a.out + symbols. The minisymbol_to_symbol function translates these into + BFD asymbol structures. */ + +long +NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep) + bfd *abfd; + boolean dynamic; + PTR *minisymsp; + unsigned int *sizep; +{ + if (dynamic) + { + /* We could handle the dynamic symbols here as well, but it's + easier to hand them off. */ + return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); + } + + if (! aout_get_external_symbols (abfd)) + return -1; + + if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD) + return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); + + *minisymsp = (PTR) obj_aout_external_syms (abfd); + + /* By passing the external symbols back from this routine, we are + giving up control over the memory block. Clear + obj_aout_external_syms, so that we do not try to free it + ourselves. */ + obj_aout_external_syms (abfd) = NULL; + + *sizep = EXTERNAL_NLIST_SIZE; + return obj_aout_external_sym_count (abfd); +} + +/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an + unmodified a.out symbol. The SYM argument is a structure returned + by bfd_make_empty_symbol, which we fill in here. */ + +asymbol * +NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym) + bfd *abfd; + boolean dynamic; + const PTR minisym; + asymbol *sym; +{ + if (dynamic + || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD) + return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym); + + memset (sym, 0, sizeof (aout_symbol_type)); + + /* We call translate_symbol_table to translate a single symbol. */ + if (! (NAME(aout,translate_symbol_table) + (abfd, + (aout_symbol_type *) sym, + (struct external_nlist *) minisym, + (bfd_size_type) 1, + obj_aout_external_strings (abfd), + obj_aout_external_string_size (abfd), + false))) + return NULL; + + return sym; +} + /* provided a BFD, a section and an offset into the section, calculate and return the name of the source file and the line nearest to the @@ -2761,12 +2833,12 @@ NAME(aout,link_hash_table_create) (abfd) struct aout_link_hash_table *ret; ret = ((struct aout_link_hash_table *) - malloc (sizeof (struct aout_link_hash_table))); - if (ret == (struct aout_link_hash_table *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_link_hash_table *) NULL; - } + bfd_alloc (abfd, sizeof (struct aout_link_hash_table))); + if (ret == NULL) + { + bfd_set_error (bfd_error_no_memory); + return (struct bfd_link_hash_table *) NULL; + } if (! NAME(aout,link_hash_table_init) (ret, abfd, NAME(aout,link_hash_newfunc))) { @@ -2784,26 +2856,11 @@ NAME(aout,link_add_symbols) (abfd, info) bfd *abfd; struct bfd_link_info *info; { - bfd *first; - switch (bfd_get_format (abfd)) { case bfd_object: return aout_link_add_object_symbols (abfd, info); case bfd_archive: - first = bfd_openr_next_archived_file (abfd, (bfd *) NULL); - if (first == NULL) - return false; - if (! bfd_check_format (first, bfd_object)) - return false; - if (bfd_get_flavour (first) != bfd_target_aout_flavour) - { - /* On Linux, we may have an ELF archive which got recognized - as an a.out archive. Therefore, we treat all archives as - though they were actually of the flavour of their first - element. */ - return (*first->xvec->_bfd_link_add_symbols) (abfd, info); - } return _bfd_generic_link_add_archive_symbols (abfd, info, aout_link_check_archive_element); default: diff --git a/bfd/ieee.c b/bfd/ieee.c index 9a29fc46b0..fc4be70c4b 100644 --- a/bfd/ieee.c +++ b/bfd/ieee.c @@ -16,7 +16,7 @@ GNU General Public License for more details. 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define KEEPMINUSPCININST 0 @@ -227,14 +227,14 @@ ieee_write_expression (abfd, value, symbol, pcrel, index) } if (bfd_is_com_section (symbol->section) - || symbol->section == &bfd_und_section) + || bfd_is_und_section (symbol->section)) { /* Def of a common symbol */ ieee_write_byte (abfd, ieee_variable_X_enum); ieee_write_int (abfd, symbol->value); term_count++; } - else if (symbol->section != &bfd_abs_section) + else if (! bfd_is_abs_section (symbol->section)) { /* Ref to defined symbol - */ @@ -435,7 +435,7 @@ parse_expression (ieee, value, symbol, pcrel, extra, section) next_byte (&(ieee->h)); *pcrel = true; section_n = must_parse_int (&(ieee->h)); - PUSH (NOSYMBOL, &bfd_abs_section, + PUSH (NOSYMBOL, bfd_abs_section_ptr, TOS.value = ieee->section_table[section_n]->vma + ieee_per_section (ieee->section_table[section_n])->pc); break; @@ -467,7 +467,7 @@ parse_expression (ieee, value, symbol, pcrel, extra, section) sy.index = (int) (must_parse_int (&(ieee->h))); sy.letter = 'X'; - PUSH (sy, &bfd_und_section, 0); + PUSH (sy, bfd_und_section_ptr, 0); } break; case ieee_function_minus_enum: @@ -493,7 +493,9 @@ parse_expression (ieee, value, symbol, pcrel, extra, section) POP (sy1, section1, value1); POP (sy2, section2, value2); - PUSH (sy1.letter ? sy1 : sy2, section1 != &bfd_abs_section ? section1 : section2, value1 + value2); + PUSH (sy1.letter ? sy1 : sy2, + bfd_is_abs_section (section1) ? section2 : section1, + value1 + value2); } break; default: @@ -503,7 +505,7 @@ parse_expression (ieee, value, symbol, pcrel, extra, section) || this_byte (&(ieee->h)) > (int) ieee_variable_Z_enum); if (parse_int (&(ieee->h), &va)) { - PUSH (NOSYMBOL, &bfd_abs_section, va); + PUSH (NOSYMBOL, bfd_abs_section_ptr, va); } else { @@ -623,7 +625,7 @@ ieee_slurp_external_symbols (abfd) symbol->symbol.the_bfd = abfd; symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata = (PTR) NULL; + symbol->symbol.udata.p = (PTR) NULL; symbol->symbol.flags = BSF_NO_FLAGS; break; case ieee_external_symbol_enum: @@ -639,7 +641,7 @@ ieee_slurp_external_symbols (abfd) symbol->symbol.the_bfd = abfd; symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata = (PTR) NULL; + symbol->symbol.udata.p = (PTR) NULL; symbol->symbol.flags = BSF_NO_FLAGS; break; case ieee_attribute_record_enum >> 8: @@ -706,7 +708,7 @@ ieee_slurp_external_symbols (abfd) value = 0; } /* This turns into a common */ - symbol->symbol.section = &bfd_com_section; + symbol->symbol.section = bfd_com_section_ptr; symbol->symbol.value = size; } break; @@ -722,8 +724,8 @@ ieee_slurp_external_symbols (abfd) symbol->symbol.the_bfd = abfd; symbol->symbol.name = read_id (&(ieee->h)); - symbol->symbol.udata = (PTR) NULL; - symbol->symbol.section = &bfd_und_section; + symbol->symbol.udata.p = (PTR) NULL; + symbol->symbol.section = bfd_und_section_ptr; symbol->symbol.value = (bfd_vma) 0; symbol->symbol.flags = 0; @@ -812,7 +814,7 @@ ieee_get_symtab (abfd, location) static bfd dummy_bfd; static asymbol empty_symbol = /* the_bfd, name, value, attr, section */ - {&dummy_bfd, " ieee empty", (symvalue) 0, BSF_DEBUGGING, &bfd_abs_section}; + {&dummy_bfd, " ieee empty", (symvalue) 0, BSF_DEBUGGING, bfd_abs_section_ptr}; if (abfd->symcount) { @@ -1796,7 +1798,7 @@ ieee_write_section_part (abfd) ieee->w.r.section_part = bfd_tell (abfd); for (s = abfd->sections; s != (asection *) NULL; s = s->next) { - if (s != &bfd_abs_section) + if (! bfd_is_abs_section (s)) { ieee_write_byte (abfd, ieee_section_type_enum); ieee_write_byte (abfd, (bfd_byte) (s->index + IEEE_SECTION_NUMBER_BASE)); @@ -2823,7 +2825,7 @@ ieee_write_debug_part (abfd) ieee_write_byte (abfd, 0); ieee_write_byte (abfd, 0xf9); ieee_write_expression (abfd, s->size, - bfd_abs_section.symbol, 0, 0, 0); + bfd_abs_section_ptr->symbol, 0, 0, 0); i++; } @@ -2957,7 +2959,7 @@ ieee_write_external_part (abfd) { asymbol *p = *q; hadone = true; - if (p->section == &bfd_und_section) + if (bfd_is_und_section (p->section)) { /* This must be a symbol reference .. */ ieee_write_byte (abfd, ieee_external_reference_enum); @@ -2998,7 +3000,7 @@ ieee_write_external_part (abfd) /* Write out the value */ ieee_write_2bytes (abfd, ieee_value_record_enum); ieee_write_int (abfd, public_index); - if (p->section != &bfd_abs_section) + if (! bfd_is_abs_section (p->section)) { if (abfd->flags & EXEC_P) { @@ -3020,7 +3022,7 @@ ieee_write_external_part (abfd) { ieee_write_expression (abfd, p->value, - bfd_abs_section.symbol, + bfd_abs_section_ptr->symbol, false, 0); } p->value = public_index; @@ -3349,15 +3351,21 @@ ieee_bfd_debug_info_accumulate (abfd, section) #define ieee_slurp_armap bfd_true #define ieee_slurp_extended_name_table bfd_true +#define ieee_construct_extended_name_table \ + ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ + bfd_true) #define ieee_truncate_arname bfd_dont_truncate_arname #define ieee_write_armap \ ((boolean (*) \ PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ bfd_true) +#define ieee_update_armap_timestamp bfd_true #define ieee_bfd_is_local_label bfd_generic_is_local_label #define ieee_get_lineno _bfd_nosymbols_get_lineno #define ieee_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define ieee_read_minisymbols _bfd_generic_read_minisymbols +#define ieee_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define ieee_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup @@ -3369,6 +3377,7 @@ ieee_bfd_debug_info_accumulate (abfd, section) #define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define ieee_bfd_link_add_symbols _bfd_generic_link_add_symbols #define ieee_bfd_final_link _bfd_generic_final_link +#define ieee_bfd_link_split_section _bfd_generic_link_split_section /*SUPPRESS 460 */ const bfd_target ieee_vec = diff --git a/bfd/libelf.h b/bfd/libelf.h index d0aa970d36..c0d2f7ebdd 100644 --- a/bfd/libelf.h +++ b/bfd/libelf.h @@ -601,6 +601,8 @@ extern boolean _bfd_elf_find_nearest_line PARAMS ((bfd *, asection *, bfd_vma, CONST char **, CONST char **, unsigned int *)); +#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols +#define _bfd_elf_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol extern int _bfd_elf_sizeof_headers PARAMS ((bfd *, boolean)); extern boolean _bfd_elf_new_section_hook PARAMS ((bfd *, asection *)); diff --git a/bfd/oasys.c b/bfd/oasys.c index 26876e3732..8cd85058fd 100644 --- a/bfd/oasys.c +++ b/bfd/oasys.c @@ -1,5 +1,5 @@ /* BFD back-end for oasys objects. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support, . This file is part of BFD, the Binary File Descriptor library. @@ -16,7 +16,7 @@ GNU General Public License for more details. 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define UNDERSCORE_HACK 1 #include "bfd.h" @@ -1174,7 +1174,7 @@ oasys_write_data (abfd) if (relocs_to_go != 0) { arelent *r = *p; - const reloc_howto_type *const how = r->howto; + reloc_howto_type *const how = r->howto; /* There is a relocation, is it for this byte ? */ if (r->address == current_byte_index) { @@ -1475,6 +1475,9 @@ oasys_sizeof_headers (abfd, exec) #define oasys_slurp_armap bfd_true #define oasys_slurp_extended_name_table bfd_true +#define oasys_construct_extended_name_table \ + ((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ + bfd_true) #define oasys_truncate_arname bfd_dont_truncate_arname #define oasys_write_armap \ ((boolean (*) \ @@ -1485,6 +1488,8 @@ oasys_sizeof_headers (abfd, exec) #define oasys_bfd_is_local_label bfd_generic_is_local_label #define oasys_get_lineno _bfd_nosymbols_get_lineno #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define oasys_read_minisymbols _bfd_generic_read_minisymbols +#define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup @@ -1496,6 +1501,7 @@ oasys_sizeof_headers (abfd, exec) #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols #define oasys_bfd_final_link _bfd_generic_final_link +#define oasys_bfd_link_split_section _bfd_generic_link_split_section /*SUPPRESS 460 */ const bfd_target oasys_vec = diff --git a/bfd/som.c b/bfd/som.c index e43e3946af..4bcd388281 100644 --- a/bfd/som.c +++ b/bfd/som.c @@ -19,7 +19,7 @@ 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. */ + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" @@ -5943,6 +5943,8 @@ som_bfd_link_split_section (abfd, sec) #define som_get_lineno _bfd_nosymbols_get_lineno #define som_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define som_read_minisymbols _bfd_generic_read_minisymbols +#define som_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define som_bfd_get_relocated_section_contents \ bfd_generic_get_relocated_section_contents diff --git a/bfd/srec.c b/bfd/srec.c index 720868a4c7..34c8ce7369 100644 --- a/bfd/srec.c +++ b/bfd/srec.c @@ -16,7 +16,7 @@ GNU General Public License for more details. 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* SUBSECTION @@ -778,8 +778,7 @@ srec_get_section_contents (abfd, section, location, offset, count) return true; } -/* we have to save up all the Srecords for a splurge before output, - also remember */ +/* we have to save up all the Srecords for a splurge before output */ static boolean srec_set_section_contents (abfd, section, location, offset, bytes_to_do) @@ -800,7 +799,8 @@ srec_set_section_contents (abfd, section, location, offset, bytes_to_do) return false; } - if ((section->flags & SEC_ALLOC) + if (bytes_to_do + && (section->flags & SEC_ALLOC) && (section->flags & SEC_LOAD)) { bfd_byte *data = (bfd_byte *) bfd_alloc (abfd, bytes_to_do); @@ -811,11 +811,11 @@ srec_set_section_contents (abfd, section, location, offset, bytes_to_do) } memcpy ((PTR) data, location, bytes_to_do); - if ((section->lma + offset + bytes_to_do) <= 0xffff) + if ((section->lma + offset + bytes_to_do - 1) <= 0xffff) { } - else if ((section->lma + offset + bytes_to_do) <= 0xffffff + else if ((section->lma + offset + bytes_to_do - 1) <= 0xffffff && tdata->type < 2) { tdata->type = 2; @@ -1212,6 +1212,8 @@ srec_print_symbol (ignore_abfd, afile, symbol, how) #define srec_get_lineno _bfd_nosymbols_get_lineno #define srec_find_nearest_line _bfd_nosymbols_find_nearest_line #define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define srec_read_minisymbols _bfd_generic_read_minisymbols +#define srec_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define srec_get_reloc_upper_bound \ ((long (*) PARAMS ((bfd *, asection *))) bfd_0l) @@ -1227,6 +1229,7 @@ srec_print_symbol (ignore_abfd, afile, symbol, how) #define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create #define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols #define srec_bfd_final_link _bfd_generic_final_link +#define srec_bfd_link_split_section _bfd_generic_link_split_section const bfd_target srec_vec = { diff --git a/bfd/syms.c b/bfd/syms.c index 2234c80f6b..402d766635 100644 --- a/bfd/syms.c +++ b/bfd/syms.c @@ -16,7 +16,7 @@ GNU General Public License for more details. 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. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* SECTION @@ -91,7 +91,7 @@ SUBSECTION INODE -Writing Symbols, typedef asymbol, Reading Symbols, Symbols +Writing Symbols, Mini symbols, Reading Symbols, Symbols SUBSECTION Writing symbols @@ -137,6 +137,28 @@ SUBSECTION which is not one of <<.text>>, <<.data>> or <<.bss>> cannot be described. +INODE +Mini symbols, typedef asymbol, Writing Symbols, Symbols +SUBSECTION + Mini symbols + + Mini symbols provide read-only access to the symbol table. + They use less memory space, but require more time to access. + They can be useful for tools like nm or objdump, which may + have to handle symbol tables of extremely large executables. + + The <> function will read the symbols + into memory in an internal form. It will return a <> + pointer to a block of memory, a symbol count, and the size of + each symbol. The pointer is allocated using <>, and + should be freed by the caller when it is no longer needed. + + The function <> will take a pointer + to a minisymbol, and a pointer to a structure returned by + <>, and return a <> structure. + The return value may or may not be the same as the value from + <> which was passed in. + */ @@ -144,7 +166,7 @@ SUBSECTION /* DOCDD INODE -typedef asymbol, symbol handling functions, Writing Symbols, Symbols +typedef asymbol, symbol handling functions, Mini symbols, Symbols */ /* @@ -589,3 +611,64 @@ DESCRIPTION . (ibfd, isymbol, obfd, osymbol)) */ + +/* The generic version of the function which returns mini symbols. + This is used when the backend does not provide a more efficient + version. It just uses BFD asymbol structures as mini symbols. */ + +long +_bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep) + bfd *abfd; + boolean dynamic; + PTR *minisymsp; + unsigned int *sizep; +{ + long storage; + asymbol **syms = NULL; + long symcount; + + if (dynamic) + storage = bfd_get_dynamic_symtab_upper_bound (abfd); + else + storage = bfd_get_symtab_upper_bound (abfd); + if (storage < 0) + goto error_return; + + syms = (asymbol **) malloc (storage); + if (syms == NULL) + { + bfd_set_error (bfd_error_no_memory); + goto error_return; + } + + if (dynamic) + symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); + else + symcount = bfd_canonicalize_symtab (abfd, syms); + if (symcount < 0) + goto error_return; + + *minisymsp = (PTR) syms; + *sizep = sizeof (asymbol *); + return symcount; + + error_return: + if (syms != NULL) + free (syms); + return -1; +} + +/* The generic version of the function which converts a minisymbol to + an asymbol. We don't worry about the sym argument we are passed; + we just return the asymbol the minisymbol points to. */ + +/*ARGSUSED*/ +asymbol * +_bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym) + bfd *abfd; + boolean dynamic; + const PTR minisym; + asymbol *sym; +{ + return *(asymbol **) minisym; +} diff --git a/bfd/versados.c b/bfd/versados.c index ad89ccd477..b55508528a 100644 --- a/bfd/versados.c +++ b/bfd/versados.c @@ -19,7 +19,7 @@ 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. */ + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* SUBSECTION @@ -52,41 +52,46 @@ static const bfd_target *versados_object_p PARAMS ((bfd *)); #define VHEADER '1' -#define VEXTDEF '2' +#define VESTDEF '2' #define VOTR '3' #define VEND '4' -#define ES_BASE 17 /* first symbol has esdid 17 */ +#define ES_BASE 17 /* first symbol has esdid 17 */ /* Per file target dependent information */ /* one for each section */ struct esdid -{ - asection *section; /* ptr to bfd version */ - unsigned char *contents; /* used to build image */ - int pc; - int relocs; /* reloc count, valid end of pass 1 */ - int donerel; /* have relocs been translated */ -}; + { + asection *section; /* ptr to bfd version */ + unsigned char *contents; /* used to build image */ + int pc; + int relocs; /* reloc count, valid end of pass 1 */ + int donerel; /* have relocs been translated */ + }; typedef struct versados_data_struct -{ - int es_done; /* count of symbol index, starts at ES_BASE */ - asymbol *symbols; /* pointer to local symbols */ - char *strings; /* strings of all the above */ - int stringlen; /* len of string table (valid end of pass1) */ - int nsyms; /* number of symbols (valid end of pass1) */ - int nsecsyms; /* number of sections */ + { + int es_done; /* count of symbol index, starts at ES_BASE */ + asymbol *symbols; /* pointer to local symbols */ + char *strings; /* strings of all the above */ + int stringlen; /* len of string table (valid end of pass1) */ + int nsecsyms; /* number of sections */ - int pass_2_done; + int ndefs; /* number of exported symbols (they dont get esdids) */ + int nrefs; /* number of imported symbols (valid end of pass1) */ - struct esdid e[16]; /* per section info */ - int alert; /* to see if we're trampling */ - asymbol *rest[256 - 16]; /* per symbol info */ + int ref_idx; /* current processed value of the above */ + int def_idx; -} + int pass_2_done; + + struct esdid e[16]; /* per section info */ + int alert; /* to see if we're trampling */ + asymbol *rest[256 - 16]; /* per symbol info */ + + } tdata_type; #define VDATA(abfd) (abfd->tdata.versados_data) @@ -97,7 +102,7 @@ struct ext_otr { unsigned char size; char type; - char map[4]; + unsigned char map[4]; unsigned char esdid; unsigned char data[200]; }; @@ -125,14 +130,17 @@ struct ext_esd char type; unsigned char esd_entries[1]; }; -#define ESD_ABS 0 -#define EST_SHRT_REL_SEC 1 -#define EST_STD_REL_SEC 2 +#define ESD_ABS 0 +#define ESD_COMMON 1 +#define ESD_STD_REL_SEC 2 +#define ESD_SHRT_REL_SEC 3 #define ESD_XDEF_IN_SEC 4 #define ESD_XREF_SYM 7 +#define ESD_XREF_SEC 6 +#define ESD_XDEF_IN_ABS 5 union ext_any { - char size; + unsigned char size; struct ext_vheader header; struct ext_esd esd; struct ext_otr otr; @@ -160,7 +168,7 @@ versados_mkobject (abfd) } abfd->tdata.versados_data = tdata; tdata->symbols = NULL; - VDATA(abfd)->alert = 0x12345678; + VDATA (abfd)->alert = 0x12345678; } bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); @@ -270,10 +278,10 @@ process_esd (abfd, esd, pass) { default: abort (); - + case ESD_XREF_SEC: case ESD_XREF_SYM: { - int snum = VDATA (abfd)->nsyms++; + int snum = VDATA (abfd)->ref_idx++; get_10 (&ptr, name); if (pass == 1) { @@ -291,20 +299,24 @@ process_esd (abfd, esd, pass) } } break; + + case ESD_ABS: size = get_4 (&ptr); start = get_4 (&ptr); break; - case EST_STD_REL_SEC: - case EST_SHRT_REL_SEC: + case ESD_STD_REL_SEC: + case ESD_SHRT_REL_SEC: { sec->_raw_size = get_4 (&ptr); - sec->flags |= SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; + sec->flags |= SEC_ALLOC; } break; + case ESD_XDEF_IN_ABS: + sec = (asection *) & bfd_abs_section; case ESD_XDEF_IN_SEC: { - int snum = VDATA (abfd)->nsyms++; + int snum = VDATA (abfd)->def_idx++; long val; get_10 (&ptr, name); val = get_4 (&ptr); @@ -317,7 +329,7 @@ process_esd (abfd, esd, pass) { asymbol *s; char *n = new_symbol_string (abfd, name); - s = versados_new_symbol (abfd, snum, n, val, sec, scn); + s = versados_new_symbol (abfd, snum + VDATA (abfd)->nrefs, n, val, sec, scn); s->flags |= BSF_GLOBAL; } } @@ -334,21 +346,40 @@ process_esd (abfd, esd, pass) reloc_howto_type versados_howto_table[] = { HOWTO (R_RELWORD, 0, 1, 16, false, - 0, complain_overflow_bitfield, 0, + 0, complain_overflow_dont, 0, "+v16", true, 0x0000ffff, 0x0000ffff, false), HOWTO (R_RELLONG, 0, 2, 32, false, - 0, complain_overflow_bitfield, 0, + 0, complain_overflow_dont, 0, "+v32", true, 0xffffffff, 0xffffffff, false), HOWTO (R_RELWORD_NEG, 0, -1, 16, false, - 0, complain_overflow_bitfield, 0, + 0, complain_overflow_dont, 0, "-v16", true, 0x0000ffff, 0x0000ffff, false), HOWTO (R_RELLONG_NEG, 0, -2, 32, false, - 0, complain_overflow_bitfield, 0, + 0, complain_overflow_dont, 0, "-v32", true, 0xffffffff, 0xffffffff, false), }; +static int +get_offset (len, ptr) + int len; + unsigned char *ptr; +{ + int val = 0; + if (len) + { + int i; + val = *ptr++; + if (val & 0x80) + val |= ~0xff; + for (i = 1; i < len; i++) + val = (val << 8) | *ptr++; + } + + return val; +} + static void process_otr (abfd, otr, pass) bfd *abfd; @@ -364,92 +395,88 @@ process_otr (abfd, otr, pass) | (otr->map[2] << 8) | (otr->map[3] << 0); - unsigned char *contents = EDATA (abfd, otr->esdid - 1).contents; + struct esdid *esdid = &EDATA (abfd, otr->esdid - 1); + unsigned char *contents = esdid->contents; + int need_contents = 0; + int dst_idx = esdid->pc; - int dst_idx = EDATA (abfd, otr->esdid - 1).pc; - for (shift = (1 << 31); srcp < endp; shift >>= 1) + for (shift = (1 << 31); shift && srcp < endp; shift >>= 1) { if (bits & shift) { int flag = *srcp++; - int esdids = (flag >> 5) & 3; + int esdids = (flag >> 5) & 0x7; int sizeinwords = ((flag >> 3) & 1) ? 2 : 1; - int offsetlen = flag & 7; - + int offsetlen = flag & 0x7; int j; - for (j = 0; j < esdids; j++) - { - int esdid = *srcp++; - /* don't process zero esdids */ - if (esdid) - { - int rn = EDATA (abfd, otr->esdid - 1).relocs++; - if (pass == 1) - { - /* this is the first pass over the data, - just remember that we need a reloc */ - } - else - { - arelent *n = - EDATA (abfd, otr->esdid - 1).section->relocation + rn; - n->address = dst_idx; - n->sym_ptr_ptr = (asymbol **) esdid; - n->addend = 0; - n->howto - = versados_howto_table - + ((j & 1) * 2) - + (sizeinwords - 1); - } - - } + if (esdids == 0) + { + /* A zero esdid means the new pc is the offset given */ + dst_idx += get_offset (offsetlen, srcp); + srcp += offsetlen; } - - if (offsetlen) + else { - /* MSB is sign extended */ - val = srcp[0] | ((srcp[0] & 0x80) ? ~0xff : 0); - for (j = 1; j < offsetlen; j++) + int val = get_offset (offsetlen, srcp + esdids); + if (pass == 1) + need_contents = 1; + else + for (j = 0; j < sizeinwords * 2; j++) + { + contents[dst_idx + (sizeinwords * 2) - j - 1] = val; + val >>= 8; + } + + for (j = 0; j < esdids; j++) { - val = val << 8; - val |= srcp[j]; + int esdid = *srcp++; + + if (esdid) + { + int rn = EDATA (abfd, otr->esdid - 1).relocs++; + if (pass == 1) + { + /* this is the first pass over the data, + just remember that we need a reloc */ + } + else + { + arelent *n = + EDATA (abfd, otr->esdid - 1).section->relocation + rn; + n->address = dst_idx; + + n->sym_ptr_ptr = (asymbol **) esdid; + n->addend = 0; + n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); + } + } } srcp += offsetlen; + dst_idx += sizeinwords * 2; } - else - val = 0; - - /* Insert addend into stream */ - if (pass == 2) - switch (sizeinwords) - { - case 2: - contents[dst_idx++] = val >> 24; - contents[dst_idx++] = val >> 16; - /* fall through */ - case 1: - contents[dst_idx++] = val >> 8; - contents[dst_idx++] = val >> 0; - break; - } - } else { - if (pass == 2) - { - /* absolute code, comes in 16 bit lumps */ - contents[dst_idx] = srcp[0]; - contents[dst_idx + 1] = srcp[1]; - } + need_contents = 1; + if (dst_idx < esdid->section->_raw_size) + if (pass == 2) + { + /* absolute code, comes in 16 bit lumps */ + contents[dst_idx] = srcp[0]; + contents[dst_idx + 1] = srcp[1]; + } dst_idx += 2; srcp += 2; } } EDATA (abfd, otr->esdid - 1).pc = dst_idx; + if (!contents && need_contents) + esdid->contents = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size); + + } static boolean @@ -459,6 +486,12 @@ versados_scan (abfd) int loop = 1; int i; int j; + int nsecs = 0; + + VDATA (abfd)->nrefs = 0; + VDATA (abfd)->ndefs = 0; + VDATA (abfd)->ref_idx = 0; + VDATA (abfd)->def_idx = 0; while (loop) { @@ -472,7 +505,7 @@ versados_scan (abfd) case VEND: loop = 0; break; - case VEXTDEF: + case VESTDEF: process_esd (abfd, &any.esd, 1); break; case VOTR: @@ -483,6 +516,13 @@ versados_scan (abfd) /* Now allocate space for the relocs and sections */ + VDATA (abfd)->nrefs = VDATA (abfd)->ref_idx; + VDATA (abfd)->ndefs = VDATA (abfd)->def_idx; + VDATA (abfd)->ref_idx = 0; + VDATA (abfd)->def_idx = 0; + + abfd->symcount = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs; + for (i = 0; i < 16; i++) { struct esdid *esdid = &EDATA (abfd, i); @@ -491,28 +531,35 @@ versados_scan (abfd) esdid->section->relocation = (arelent *) bfd_alloc (abfd, sizeof (arelent) * esdid->relocs); - esdid->contents - = (unsigned char *) bfd_alloc (abfd, esdid->section->_raw_size); - esdid->pc = 0; + + if (esdid->contents) + esdid->section->flags |= SEC_HAS_CONTENTS | SEC_LOAD; + esdid->section->reloc_count = esdid->relocs; if (esdid->relocs) esdid->section->flags |= SEC_RELOC; + esdid->relocs = 0; /* Add an entry into the symbol table for it */ - abfd->symcount++; + nsecs++; VDATA (abfd)->stringlen += strlen (esdid->section->name) + 1; } } + + abfd->symcount += nsecs; + VDATA (abfd)->symbols = (asymbol *) bfd_alloc (abfd, - sizeof (asymbol) * abfd->symcount); + sizeof (asymbol) * (abfd->symcount)); + VDATA (abfd)->strings = bfd_alloc (abfd, VDATA (abfd)->stringlen); - abfd->symcount = VDATA (abfd)->nsyms; - /* Actually fill in the section symbols */ - for (j = 0, i = 0; i < 16; i++) + /* Actually fill in the section symbols, + we stick them at the end of the table */ + + for (j = VDATA (abfd)->nrefs + VDATA (abfd)->ndefs, i = 0; i < 16; i++) { struct esdid *esdid = &EDATA (abfd, i); asection *sec = esdid->section; @@ -527,11 +574,15 @@ versados_scan (abfd) j++; } } - abfd->symcount += j; if (abfd->symcount) abfd->flags |= HAS_SYMS; - VDATA (abfd)->nsecsyms = j; - VDATA (abfd)->nsyms = j; + + /* Set this to nsecs - since we've already planted the section + symbols */ + VDATA (abfd)->nsecsyms = nsecs; + + VDATA (abfd)->ref_idx = 0; + return 1; } @@ -583,6 +634,7 @@ versados_pass_2 (abfd) VDATA (abfd)->es_done = ES_BASE; + /* read records till we get to where we want to be */ while (1) @@ -593,7 +645,7 @@ versados_pass_2 (abfd) case VEND: VDATA (abfd)->pass_2_done = 1; return 1; - case VEXTDEF: + case VESTDEF: process_esd (abfd, &any.esd, 2); break; case VOTR: @@ -747,15 +799,24 @@ versados_canonicalize_reloc (abfd, section, relptr, symbols) for (count = 0; count < section->reloc_count; count++) { int esdid = (int) src[count].sym_ptr_ptr; - if (esdid < ES_BASE) /* Section relative thing */ + + if (esdid == 0) { - src[count].sym_ptr_ptr - = EDATA (abfd, esdid - 1).section->symbol_ptr_ptr; + src[count].sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr; + } + else if (esdid < ES_BASE) /* Section relative thing */ + { + struct esdid *e = &EDATA (abfd, esdid - 1); + if (!section) + { + /** relocation relative to section which was + never declared ! */ + } + src[count].sym_ptr_ptr = e->section->symbol_ptr_ptr; } else { - src[count].sym_ptr_ptr - = symbols + esdid - 17 + VDATA (abfd)->nsecsyms; + src[count].sym_ptr_ptr = symbols + esdid - ES_BASE; } } @@ -777,6 +838,8 @@ versados_canonicalize_reloc (abfd, section, relptr, symbols) #define versados_get_lineno _bfd_nosymbols_get_lineno #define versados_find_nearest_line _bfd_nosymbols_find_nearest_line #define versados_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define versados_read_minisymbols _bfd_generic_read_minisymbols +#define versados_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol #define versados_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup