+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
#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
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,
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,
#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
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,
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,
#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)
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 **));
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;
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. */
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 ();
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.
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);
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;
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);
/* 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++;
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.
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 <<sect>>
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 *
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 */
#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)
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 **));
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 **));