From b03b65e2aa3243bc0224ba3f933a3e94f1eed8a1 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 2 Sep 2021 09:56:11 +0930 Subject: [PATCH] SHT_SYMTAB_SHNDX handling .symtab_shndx section contents is an array, one entry for each symbol in .symtab, present when the number of symbols exceeds a little less than 64k. Since the mapping is 1-1 with symbols there is no need to keep both dest_index and destshndx_index in elf_sym_strtab. Instead, just make sure that the shndx pointers to the swap functions are kept NULL when .symtab_shndx does not exist. Also, strtabcount in the linker's elf hash table is incremented in lock-step with the output symcount, so that can disappear too. --- bfd/elf-bfd.h | 5 ----- bfd/elf.c | 14 +++----------- bfd/elflink.c | 24 ++++++++++-------------- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index b3f56b8c2ce..c247d52c615 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -538,7 +538,6 @@ struct elf_sym_strtab { Elf_Internal_Sym sym; unsigned long dest_index; - unsigned long destshndx_index; }; struct bfd_link_needed_list @@ -622,10 +621,6 @@ struct elf_link_hash_table section. */ struct elf_strtab_hash *dynstr; - /* The number of symbol strings found in the link which must be put - into the .strtab section. */ - bfd_size_type strtabcount; - /* The array size of the symbol string table, which becomes the .strtab section. */ bfd_size_type strtabsize; diff --git a/bfd/elf.c b/bfd/elf.c index 380d64d699d..dea3bb00879 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -8095,7 +8095,6 @@ swap_out_syms (bfd *abfd, bfd_byte *outbound_syms; bfd_byte *outbound_shndx; unsigned long outbound_syms_index; - unsigned long outbound_shndx_index; unsigned int idx; unsigned int num_locals; size_t amt; @@ -8144,7 +8143,6 @@ swap_out_syms (bfd *abfd, outbound_syms_index = 0; outbound_shndx = NULL; - outbound_shndx_index = 0; if (elf_symtab_shndx_list (abfd)) { @@ -8180,10 +8178,7 @@ swap_out_syms (bfd *abfd, sym.st_target_internal = 0; symstrtab[0].sym = sym; symstrtab[0].dest_index = outbound_syms_index; - symstrtab[0].destshndx_index = outbound_shndx_index; outbound_syms_index++; - if (outbound_shndx != NULL) - outbound_shndx_index++; } name_local_sections @@ -8415,11 +8410,8 @@ Unable to handle section index %x in ELF symbol. Using ABS instead."), idx++; symstrtab[idx].sym = sym; symstrtab[idx].dest_index = outbound_syms_index; - symstrtab[idx].destshndx_index = outbound_shndx_index; outbound_syms_index++; - if (outbound_shndx != NULL) - outbound_shndx_index++; } /* Finalize the .strtab section. */ @@ -8444,9 +8436,9 @@ Unable to handle section index %x in ELF symbol. Using ABS instead."), (outbound_syms + (elfsym->dest_index * bed->s->sizeof_sym)), - (outbound_shndx - + (elfsym->destshndx_index - * sizeof (Elf_External_Sym_Shndx)))); + NPTR_ADD (outbound_shndx, + (elfsym->dest_index + * sizeof (Elf_External_Sym_Shndx)))); } free (symstrtab); diff --git a/bfd/elflink.c b/bfd/elflink.c index 354cebbe766..77450c8fa8d 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -9916,7 +9916,7 @@ elf_link_output_symstrtab (void *finf, hash_table = elf_hash_table (flinfo->info); strtabsize = hash_table->strtabsize; - if (strtabsize <= hash_table->strtabcount) + if (strtabsize <= flinfo->output_bfd->symcount) { strtabsize += strtabsize; hash_table->strtabsize = strtabsize; @@ -9927,14 +9927,10 @@ elf_link_output_symstrtab (void *finf, if (hash_table->strtab == NULL) return 0; } - hash_table->strtab[hash_table->strtabcount].sym = *elfsym; - hash_table->strtab[hash_table->strtabcount].dest_index - = hash_table->strtabcount; - hash_table->strtab[hash_table->strtabcount].destshndx_index - = flinfo->symshndxbuf ? bfd_get_symcount (flinfo->output_bfd) : 0; - + hash_table->strtab[flinfo->output_bfd->symcount].sym = *elfsym; + hash_table->strtab[flinfo->output_bfd->symcount].dest_index + = flinfo->output_bfd->symcount; flinfo->output_bfd->symcount += 1; - hash_table->strtabcount += 1; return 1; } @@ -9954,14 +9950,14 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo) file_ptr pos; bool ret; - if (!hash_table->strtabcount) + if (flinfo->output_bfd->symcount == 0) return true; BFD_ASSERT (elf_onesymtab (flinfo->output_bfd)); bed = get_elf_backend_data (flinfo->output_bfd); - amt = bed->s->sizeof_sym * hash_table->strtabcount; + amt = bed->s->sizeof_sym * flinfo->output_bfd->symcount; symbuf = (bfd_byte *) bfd_malloc (amt); if (symbuf == NULL) return false; @@ -9979,7 +9975,7 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo) } /* Now swap out the symbols. */ - for (i = 0; i < hash_table->strtabcount; i++) + for (i = 0; i < flinfo->output_bfd->symcount; i++) { struct elf_sym_strtab *elfsym = &hash_table->strtab[i]; if (elfsym->sym.st_name == (unsigned long) -1) @@ -9999,13 +9995,13 @@ elf_link_swap_symbols_out (struct elf_final_link_info *flinfo) ((bfd_byte *) symbuf + (elfsym->dest_index * bed->s->sizeof_sym)), - (flinfo->symshndxbuf - + elfsym->destshndx_index)); + NPTR_ADD (flinfo->symshndxbuf, + elfsym->dest_index)); } hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr; pos = hdr->sh_offset + hdr->sh_size; - amt = hash_table->strtabcount * bed->s->sizeof_sym; + amt = bed->s->sizeof_sym * flinfo->output_bfd->symcount; if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) == 0 && bfd_bwrite (symbuf, amt, flinfo->output_bfd) == amt) { -- 2.30.2