From cb71adf12b02561228bafbb2497baafaa930e6b9 Mon Sep 17 00:00:00 2001 From: Peter Schauer Date: Thu, 21 Apr 1994 17:01:12 +0000 Subject: [PATCH] * libelf.h (elf_obj_tdata): Add members for dynamic symbol table handling. * elfcode.h (bfd_section_from_shdr): Handle dynamic symbol table. * elfcode.h (elf_slurp_symbol_table): Take additional parameter to select static or dynamic symbol table and return number of symbols slurped or -1 on error. * elfcode.h (elf_get_symtab): Set bfd symcount from elf_slurp_symbol_table result. * elfcode.h (elf_get_dynamic_symtab_upper_bound, elf_canonicalize_dynamic_symtab): New functions to handle dynamic symbol table. * elf32-target.h, elf64-target.h (BFD_JUMP_TABLE_DYNAMIC): Change to handle dynamic symbol table, provide default definitions for dynamic relocs. * aoutx.h (howto_table_std, NAME(aout,swap_std_reloc_out), NAME(aout,swap_std_reloc_in), aout_link_input_section_std, aout_link_reloc_link_order): Handle r_jmptable and r_relative relocations. --- bfd/ChangeLog | 21 +++++++++++ bfd/elf32-target.h | 13 ++++++- bfd/elf64-target.h | 13 ++++++- bfd/elfcode.h | 94 ++++++++++++++++++++++++++++++++++------------ bfd/libelf.h | 9 ++++- 5 files changed, 122 insertions(+), 28 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c69b2c04439..0fffbe01b12 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,24 @@ +Thu Apr 21 09:29:37 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + * libelf.h (elf_obj_tdata): Add members for dynamic symbol table + handling. + * elfcode.h (bfd_section_from_shdr): Handle dynamic symbol table. + * elfcode.h (elf_slurp_symbol_table): Take additional parameter + to select static or dynamic symbol table and return number of + symbols slurped or -1 on error. + * elfcode.h (elf_get_symtab): Set bfd symcount from + elf_slurp_symbol_table result. + * elfcode.h (elf_get_dynamic_symtab_upper_bound, + elf_canonicalize_dynamic_symtab): New functions to handle dynamic + symbol table. + * elf32-target.h, elf64-target.h (BFD_JUMP_TABLE_DYNAMIC): + Change to handle dynamic symbol table, provide default definitions + for dynamic relocs. + * aoutx.h (howto_table_std, NAME(aout,swap_std_reloc_out), + NAME(aout,swap_std_reloc_in), aout_link_input_section_std, + aout_link_reloc_link_order): Handle r_jmptable and r_relative + relocations. + Thu Apr 21 11:58:19 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) * libnlm.h (struct nlm_obj_tdata): Add nlm_cygnus_section_hdr diff --git a/bfd/elf32-target.h b/bfd/elf32-target.h index dc0ccf6a701..d661ced4a55 100644 --- a/bfd/elf32-target.h +++ b/bfd/elf32-target.h @@ -59,6 +59,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define bfd_elf32_bfd_is_local_label bfd_generic_is_local_label #endif +#ifndef bfd_elf32_get_dynamic_reloc_upper_bound +#define bfd_elf32_get_dynamic_reloc_upper_bound \ + _bfd_nodynamic_get_dynamic_reloc_upper_bound +#endif +#ifndef bfd_elf32_canonicalize_dynamic_reloc +#define bfd_elf32_canonicalize_dynamic_reloc \ + _bfd_nodynamic_canonicalize_dynamic_reloc +#endif + #ifndef elf_info_to_howto_rel #define elf_info_to_howto_rel 0 #endif @@ -208,7 +217,7 @@ bfd_target TARGET_BIG_SYM = BFD_JUMP_TABLE_RELOCS (bfd_elf32), BFD_JUMP_TABLE_WRITE (bfd_elf32), BFD_JUMP_TABLE_LINK (bfd_elf32), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + BFD_JUMP_TABLE_DYNAMIC (bfd_elf32), /* backend_data: */ (PTR) &elf32_bed, @@ -296,7 +305,7 @@ bfd_target TARGET_LITTLE_SYM = BFD_JUMP_TABLE_RELOCS (bfd_elf32), BFD_JUMP_TABLE_WRITE (bfd_elf32), BFD_JUMP_TABLE_LINK (bfd_elf32), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + BFD_JUMP_TABLE_DYNAMIC (bfd_elf32), /* backend_data: */ (PTR) &elf32_bed, diff --git a/bfd/elf64-target.h b/bfd/elf64-target.h index 31940738639..ab1cde939cb 100644 --- a/bfd/elf64-target.h +++ b/bfd/elf64-target.h @@ -62,6 +62,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define bfd_elf64_bfd_is_local_label bfd_generic_is_local_label #endif +#ifndef bfd_elf64_get_dynamic_reloc_upper_bound +#define bfd_elf64_get_dynamic_reloc_upper_bound \ + _bfd_nodynamic_get_dynamic_reloc_upper_bound +#endif +#ifndef bfd_elf64_canonicalize_dynamic_reloc +#define bfd_elf64_canonicalize_dynamic_reloc \ + _bfd_nodynamic_canonicalize_dynamic_reloc +#endif + #ifndef elf_info_to_howto_rel #define elf_info_to_howto_rel 0 #endif @@ -211,7 +220,7 @@ bfd_target TARGET_BIG_SYM = BFD_JUMP_TABLE_RELOCS (bfd_elf64), BFD_JUMP_TABLE_WRITE (bfd_elf64), BFD_JUMP_TABLE_LINK (bfd_elf64), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + BFD_JUMP_TABLE_DYNAMIC (bfd_elf64), /* backend_data: */ (PTR) &elf64_bed, @@ -299,7 +308,7 @@ bfd_target TARGET_LITTLE_SYM = BFD_JUMP_TABLE_RELOCS (bfd_elf64), BFD_JUMP_TABLE_WRITE (bfd_elf64), BFD_JUMP_TABLE_LINK (bfd_elf64), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + BFD_JUMP_TABLE_DYNAMIC (bfd_elf64), /* backend_data: */ (PTR) &elf64_bed, diff --git a/bfd/elfcode.h b/bfd/elfcode.h index b30d5c3382f..a93ac60f37f 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -75,13 +75,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command) #define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal) -#define elf_core_file_matches_executable_p NAME(bfd_elf,core_file_matches_executable_p) +#define elf_core_file_matches_executable_p \ + NAME(bfd_elf,core_file_matches_executable_p) #define elf_object_p NAME(bfd_elf,object_p) #define elf_core_file_p NAME(bfd_elf,core_file_p) #define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound) +#define elf_get_dynamic_symtab_upper_bound \ + NAME(bfd_elf,get_dynamic_symtab_upper_bound) #define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) #define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) #define elf_get_symtab NAME(bfd_elf,get_symtab) +#define elf_canonicalize_dynamic_symtab \ + NAME(bfd_elf,canonicalize_dynamic_symtab) #define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) #define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) #define elf_print_symbol NAME(bfd_elf,print_symbol) @@ -123,7 +128,7 @@ static struct sec *section_from_elf_index PARAMS ((bfd *, unsigned int)); static int elf_section_from_bfd_section PARAMS ((bfd *, struct sec *)); -static boolean elf_slurp_symbol_table PARAMS ((bfd *, asymbol **)); +static long elf_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); static int elf_symbol_from_bfd_symbol PARAMS ((bfd *, struct symbol_cache_entry **)); @@ -547,6 +552,18 @@ bfd_section_from_shdr (abfd, shindex) abfd->flags |= HAS_SYMS; return true; + case SHT_DYNSYM: /* A dynamic symbol table */ + if (elf_dynsymtab (abfd) == shindex) + return true; + + BFD_ASSERT (hdr->sh_entsize == sizeof (Elf_External_Sym)); + BFD_ASSERT (elf_dynsymtab (abfd) == 0); + elf_dynsymtab (abfd) = shindex; + elf_tdata (abfd)->dynsymtab_hdr = *hdr; + elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynsymtab_hdr; + abfd->flags |= HAS_SYMS; + return true; + case SHT_STRTAB: /* A string table */ if (hdr->rawdata) return true; @@ -572,6 +589,12 @@ bfd_section_from_shdr (abfd, shindex) elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr; return true; } + if (elf_dynsymtab (abfd) == i) + { + elf_tdata (abfd)->dynstrtab_hdr = *hdr; + elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynstrtab_hdr; + return true; + } #if 0 /* Not handling other string tables specially right now. */ hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */ /* We have a strtab for some random other section. */ @@ -664,7 +687,6 @@ bfd_section_from_shdr (abfd, shindex) break; case SHT_HASH: - case SHT_DYNSYM: /* could treat this like symtab... */ #if 0 fprintf (stderr, "Dynamic Linking sections not yet supported.\n"); BFD_FAIL (); @@ -2584,25 +2606,19 @@ elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr) return idx; } -static boolean -elf_slurp_symbol_table (abfd, symptrs) +static long +elf_slurp_symbol_table (abfd, symptrs, dynamic) bfd *abfd; asymbol **symptrs; /* Buffer for generated bfd symbols */ + boolean dynamic; { - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; + Elf_Internal_Shdr *hdr; long symcount; /* Number of external ELF symbols */ elf_symbol_type *sym; /* Pointer to current bfd symbol */ elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ Elf_Internal_Sym i_sym; Elf_External_Sym *x_symp = NULL; - /* this is only valid because there is only one symtab... */ - /* FIXME: This is incorrect, there may also be a dynamic symbol - table which is a subset of the full symbol table. We either need - to be prepared to read both (and merge them) or ensure that we - only read the full symbol table. Currently we only get called to - read the full symbol table. -fnf */ - /* Read each raw ELF symbol, converting from external ELF form to internal ELF form, and then using the information to create a canonical bfd symbol table entry. @@ -2613,8 +2629,12 @@ elf_slurp_symbol_table (abfd, symptrs) space left over at the end. When we have all the symbols, we build the caller's pointer vector. */ + if (dynamic) + hdr = &elf_tdata (abfd)->dynsymtab_hdr; + else + hdr = &elf_tdata (abfd)->symtab_hdr; if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return false; + return -1; symcount = hdr->sh_size / sizeof (Elf_External_Sym); @@ -2625,14 +2645,14 @@ elf_slurp_symbol_table (abfd, symptrs) long i; if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return false; + return -1; symbase = ((elf_symbol_type *) bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type))); if (symbase == (elf_symbol_type *) NULL) { bfd_set_error (bfd_error_no_memory); - return false; + return -1; } sym = symbase; @@ -2716,6 +2736,9 @@ elf_slurp_symbol_table (abfd, symptrs) break; } + if (dynamic) + sym->symbol.flags |= BSF_DYNAMIC; + /* Do some backend-specific processing on this symbol. */ { struct elf_backend_data *ebd = get_elf_backend_data (abfd); @@ -2736,13 +2759,15 @@ elf_slurp_symbol_table (abfd, symptrs) /* We rely on the zalloc to clear out the final symbol entry. */ - bfd_get_symcount (abfd) = symcount = sym - symbase; + symcount = sym - symbase; /* Fill in the user's symbol pointer vector if needed. */ if (symptrs) { + long l = symcount; + sym = symbase; - while (symcount-- > 0) + while (l-- > 0) { *symptrs++ = &sym->symbol; sym++; @@ -2752,11 +2777,11 @@ elf_slurp_symbol_table (abfd, symptrs) if (x_symp != NULL) free (x_symp); - return true; + return symcount; error_return: if (x_symp != NULL) free (x_symp); - return false; + return -1; } /* Return the number of bytes required to hold the symtab vector. @@ -2779,6 +2804,20 @@ elf_get_symtab_upper_bound (abfd) return symtab_size; } +long +elf_get_dynamic_symtab_upper_bound (abfd) + bfd *abfd; +{ + long symcount; + long symtab_size; + Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; + + symcount = hdr->sh_size / sizeof (Elf_External_Sym); + symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *)); + + return symtab_size; +} + /* This function return the number of bytes required to store the relocation information associated with section <> @@ -3106,10 +3145,19 @@ elf_get_symtab (abfd, alocation) bfd *abfd; asymbol **alocation; { - if (!elf_slurp_symbol_table (abfd, alocation)) - return -1; + long symcount = elf_slurp_symbol_table (abfd, alocation, false); + + if (symcount >= 0) + bfd_get_symcount (abfd) = symcount; + return symcount; +} - return bfd_get_symcount (abfd); +long +elf_canonicalize_dynamic_symtab (abfd, alocation) + bfd *abfd; + asymbol **alocation; +{ + return elf_slurp_symbol_table (abfd, alocation, true); } asymbol * diff --git a/bfd/libelf.h b/bfd/libelf.h index ce22cc12089..f0c270b9fb6 100644 --- a/bfd/libelf.h +++ b/bfd/libelf.h @@ -206,7 +206,9 @@ struct elf_obj_tdata Elf_Internal_Shdr symtab_hdr; Elf_Internal_Shdr shstrtab_hdr; Elf_Internal_Shdr strtab_hdr; - int symtab_section, shstrtab_section, strtab_section; + Elf_Internal_Shdr dynsymtab_hdr; + Elf_Internal_Shdr dynstrtab_hdr; + int symtab_section, shstrtab_section, strtab_section, dynsymtab_section; file_ptr next_file_pos; void *prstatus; /* The raw /proc prstatus structure */ void *prpsinfo; /* The raw /proc prpsinfo structure */ @@ -219,6 +221,7 @@ struct elf_obj_tdata #define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) #define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr) #define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) +#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section) #define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals) #define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals) #define elf_sym_extra(bfd) (elf_tdata(bfd) -> sym_extra) @@ -265,6 +268,8 @@ extern boolean bfd_elf32_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, extern long bfd_elf32_get_symtab_upper_bound PARAMS ((bfd *)); extern long bfd_elf32_get_symtab PARAMS ((bfd *, asymbol **)); +extern long bfd_elf32_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); +extern long bfd_elf32_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); extern long bfd_elf32_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); extern long bfd_elf32_canonicalize_reloc PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); @@ -301,6 +306,8 @@ extern boolean bfd_elf64_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, extern long bfd_elf64_get_symtab_upper_bound PARAMS ((bfd *)); extern long bfd_elf64_get_symtab PARAMS ((bfd *, asymbol **)); +extern long bfd_elf64_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); +extern long bfd_elf64_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); extern long bfd_elf64_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); extern long bfd_elf64_canonicalize_reloc PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); -- 2.30.2