aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-03-04 20:32:35 -0800
committerH.J. Lu <hjl.tools@gmail.com>2023-06-29 10:29:47 -0700
commit46675b6b8160e97485583522852ad86507bd9072 (patch)
tree7db5843df9cdc601838344c9b077f9f80e3d961e /bfd/elflink.c
parent02c1ba6c94d4bb3f53dfeeb4401c8434c7834a32 (diff)
downloadgdb-46675b6b8160e97485583522852ad86507bd9072.zip
gdb-46675b6b8160e97485583522852ad86507bd9072.tar.gz
gdb-46675b6b8160e97485583522852ad86507bd9072.tar.bz2
bfd: Improve nm and objdump without section header
When there is no section header in an executable or shared library, we reconstruct dynamic symbol table from the PT_DYNAMIC segment, which contains DT_HASH/DT_GNU_HASH/DT_MIPS_XHASH, DT_STRTAB, DT_SYMTAB, DT_STRSZ, and DT_SYMENT entries, to improve nm and objdump. For DT_HASH, the number of dynamic symbol table entries equals the number of chains. For DT_GNU_HASH/DT_MIPS_XHASH, only defined symbols with non-STB_LOCAL indings are in hash table. Since DT_GNU_HASH/DT_MIPS_XHASH place all symbols with STB_LOCAL binding before symbols with other bindings and all undefined symbols defined ones in dynamic symbol table, the highest symbol index in DT_GNU_HASH/DT_MIPS_XHASH is the highest dynamic symbol table index. We can also get symbol version from DT_VERSYM, DT_VERDEF and DT_VERNEED entries. dt_symtab, dt_versym, dt_verdef, dt_verneed, dt_symtab_count, dt_verdef_count, dt_verneed_count and dt_strtab are added to elf_obj_tdata to store dynamic symbol table information. PR ld/25617 * elf-bfd.h (elf_obj_tdata): Add dt_symtab, dt_verdef, dt_verneed, dt_symtab_count, dt_verdef_count, dt_verneed_count and dt_strtab. (elf_use_dt_symtab_p): New. (_bfd_elf_get_dynamic_symbols): Likewise. (_bfd_elf_get_section_from_dynamic_symbol): Likewise. * elf.c (bfd_elf_get_elf_syms): Use dynamic symbol table if neeeded. (_bfd_elf_get_dynamic_symtab_upper_bound): Likewise. (_bfd_elf_slurp_version_tables): Likewise. (offset_from_vma): New function. (get_hash_table_data): Likewise. (_bfd_elf_get_dynamic_symbols): Likewise. (_bfd_elf_get_section_from_dynamic_symbol): Likewise. (_bfd_elf_get_symbol_version_name): Likewise. * elfcode.h (elf_object_p): Call _bfd_elf_get_dynamic_symbols to reconstruct dynamic symbol table from PT_DYNAMIC segment if there is no section header. (elf_slurp_symbol_table): Use dynamic symbol table if neeeded. Don't free isymbuf when dynamic symbol table is used. * elflink.c (elf_link_is_defined_archive_symbol): Return wrong format error when dynamic symbol table is used. (elf_link_add_object_symbols): Likewise.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 4f87900..7217c2f 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3571,6 +3571,12 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
if (! bfd_check_format (abfd, bfd_object))
return false;
+ if (elf_use_dt_symtab_p (abfd))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
/* Select the appropriate symbol table. If we don't know if the
object file is an IR object, give linker LTO plugin a chance to
get the correct symbol table. */
@@ -4233,6 +4239,12 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
htab = elf_hash_table (info);
bed = get_elf_backend_data (abfd);
+ if (elf_use_dt_symtab_p (abfd))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return false;
+ }
+
if ((abfd->flags & DYNAMIC) == 0)
dynamic = false;
else