diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-06-28 06:53:17 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-06-28 06:53:17 -0700 |
commit | be87e6fe55a7bee7d7d1455607f08ed9e651de7a (patch) | |
tree | bf400a5f7f747e1e67ffffc2fdff25a1fb3fa2d5 | |
parent | fca72df16a5731e3de8929dbae3bfce6c6c39c33 (diff) | |
download | binutils-gdb-be87e6fe55a7bee7d7d1455607f08ed9e651de7a.tar.gz |
Remove binutils-pr18451.patch
It has been applied to master branch.
-rw-r--r-- | patches/README | 1 | ||||
-rw-r--r-- | patches/binutils-pr18451.patch | 910 |
2 files changed, 0 insertions, 911 deletions
diff --git a/patches/README b/patches/README index 3e51d489e83..beddf181d63 100644 --- a/patches/README +++ b/patches/README @@ -22,7 +22,6 @@ patches=" binutils-secondary.patch binutils-pr18321.patch binutils-pr18322.patch - binutils-pr18451.patch " for p in $patches diff --git a/patches/binutils-pr18451.patch b/patches/binutils-pr18451.patch deleted file mode 100644 index e97d7d791e7..00000000000 --- a/patches/binutils-pr18451.patch +++ /dev/null @@ -1,910 +0,0 @@ -From 163dcfe99109ad0ab28829e7a637ee4e1a143572 Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" <hjl.tools@gmail.com> -Date: Tue, 26 May 2015 04:10:03 -0700 -Subject: [PATCH] Use strtab with GC and suffix merging for .strtab - -This patch uses ELF strtab with GC and suffix merging support to create -ELF .strtab section. There is some small memory overhead to use ELF -strtab: - -==14928== HEAP SUMMARY: -==14928== in use at exit: 3,276,318 bytes in 679 blocks -==14928== total heap usage: 1,544 allocs, 865 frees, 15,259,146 bytes allocated - -vs. - -==14936== HEAP SUMMARY: -==14936== in use at exit: 3,276,318 bytes in 679 blocks -==14936== total heap usage: 1,532 allocs, 853 frees, 15,026,402 bytes allocated - -when running: - -./ld-new -m elf_x86_64 -o tmpdir/ld-partial.o -r ldgram.o ldlex-wrapper.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o plugin.o ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o ldfile.o ldcref.o eelf_x86_64.o eelf32_x86_64.o eelf_i386.o eelf_iamcu.o ei386linux.o eelf_l1om.o eelf_k1om.o ldbuildid.o - -The results are - - [32] .strtab STRTAB 0+ 3beff8 00407a 00 0 0 1 - - vs - - [32] .strtab STRTAB 0+ 3beff8 0041d8 00 0 0 1 - -It reduces the .strtab size by 350 bytes, about 2%. - -bfd/ - - PR gas/18451 - * elf-bfd.h (elf_sym_strtab): New. - (elf_link_hash_table): Add strtabcount, strtabsize and - strtab. - (_bfd_elf_stringtab_init): Removed. - * elf.c (_bfd_elf_stringtab_init): Removed. - (_bfd_elf_compute_section_file_positions): Replace - bfd_strtab_hash/_bfd_elf_stringtab_init/_bfd_stringtab_free/ - _bfd_stringtab_size with - elf_strtab_hash/_bfd_elf_strtab_init/_bfd_elf_strtab_free/ - _bfd_elf_strtab_size. Use _bfd_elf_strtab_add, - _bfd_elf_strtab_finalize and _bfd_elf_strtab_offset to get - st_name. - (swap_out_syms): Likewise. - * elflink.c (elf_final_link_info): Replace bfd_strtab_hash - with elf_strtab_hash. Remove symbuf, symbuf_count, - symbuf_size and shndxbuf_size. - (elf_link_flush_output_syms): Removed. - (elf_link_output_sym): Renamed to ... - (elf_link_output_symstrtab): This. Replace _bfd_stringtab_add - with _bfd_elf_strtab_add. Don't flush symbols to the file nor - swap out symbols. - (elf_link_swap_symbols_out): New. - (elf_link_output_extsym): Replace elf_link_output_sym with - elf_link_output_symstrtab. - (elf_link_input_bfd): Likewise. - (elf_final_link_free): Replace _bfd_stringtab_free with - _bfd_elf_strtab_free. Remove symbuf. - (bfd_elf_final_link): Replace _bfd_elf_stringtab_init with - _bfd_elf_strtab_init. Don't set symbuf, symbuf_count, - symbuf_size nor shndxbuf_size. Initialize strtabsize and - strtab. Initialize symshndxbuf to -1 when number of sections - >= 64K. Replace elf_link_output_sym/elf_link_output_sym with - elf_link_output_symstrtab/elf_link_output_symstrtab. Don't - call elf_link_flush_output_syms. Call _bfd_elf_strtab_finalize - and elf_link_swap_symbols_out. Replace _bfd_stringtab_size - and _bfd_stringtab_emit with _bfd_elf_strtab_size and - _bfd_elf_strtab_emit. - -gas/testsuite/ - - PR gas/18451 - * gas/elf/elf.exp: Run strtab. - * gas/elf/strtab.d: New file. - * gas/elf/strtab.s: Likewise. - -ld/testsuite/ - - PR gas/18451 - * ld-elf/strtab.d: New file. - * ld-elf/strtab.s: Likewise. ---- - bfd/elf-bfd.h | 20 ++- - bfd/elf.c | 122 +++++++++++-------- - bfd/elflink.c | 270 +++++++++++++++++++++++------------------ - gas/testsuite/gas/elf/elf.exp | 2 + - gas/testsuite/gas/elf/strtab.d | 7 ++ - gas/testsuite/gas/elf/strtab.s | 8 ++ - ld/testsuite/ld-elf/strtab.d | 7 ++ - ld/testsuite/ld-elf/strtab.s | 8 ++ - 8 files changed, 270 insertions(+), 174 deletions(-) - create mode 100644 gas/testsuite/gas/elf/strtab.d - create mode 100644 gas/testsuite/gas/elf/strtab.s - create mode 100644 ld/testsuite/ld-elf/strtab.d - create mode 100644 ld/testsuite/ld-elf/strtab.s - -diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h -index e435e52..15fd525 100644 ---- a/bfd/elf-bfd.h -+++ b/bfd/elf-bfd.h -@@ -444,6 +444,13 @@ enum elf_target_id - GENERIC_ELF_DATA - }; - -+struct elf_sym_strtab -+{ -+ Elf_Internal_Sym sym; -+ unsigned long dest_index; -+ unsigned long destshndx_index; -+}; -+ - /* ELF linker hash table. */ - - struct elf_link_hash_table -@@ -487,6 +494,17 @@ 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; -+ -+ /* The array of strings, which becomes the .strtab section. */ -+ struct elf_sym_strtab *strtab; -+ - /* The number of buckets in the hash table in the .hash section. - This is based on the number of dynamic symbols. */ - bfd_size_type bucketcount; -@@ -1955,8 +1973,6 @@ extern Elf_Internal_Sym *bfd_sym_from_r_symndx - (struct sym_cache *, bfd *, unsigned long); - extern asection *bfd_section_from_elf_index - (bfd *, unsigned int); --extern struct bfd_strtab_hash *_bfd_elf_stringtab_init -- (void); - - extern struct elf_strtab_hash * _bfd_elf_strtab_init - (void); -diff --git a/bfd/elf.c b/bfd/elf.c -index 619a640..e148a5f 100644 ---- a/bfd/elf.c -+++ b/bfd/elf.c -@@ -51,7 +51,7 @@ SECTION - static int elf_sort_sections (const void *, const void *); - static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *); - static bfd_boolean prep_headers (bfd *); --static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ; -+static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int) ; - static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ; - static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size, - file_ptr offset); -@@ -1610,29 +1610,6 @@ bfd_elf_print_symbol (bfd *abfd, - break; - } - } -- --/* Allocate an ELF string table--force the first byte to be zero. */ -- --struct bfd_strtab_hash * --_bfd_elf_stringtab_init (void) --{ -- struct bfd_strtab_hash *ret; -- -- ret = _bfd_stringtab_init (); -- if (ret != NULL) -- { -- bfd_size_type loc; -- -- loc = _bfd_stringtab_add (ret, "", TRUE, FALSE); -- BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1); -- if (loc == (bfd_size_type) -1) -- { -- _bfd_stringtab_free (ret); -- ret = NULL; -- } -- } -- return ret; --} - - /* ELF .o/exec file reading */ - -@@ -3742,7 +3719,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd, - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct fake_section_arg fsargs; - bfd_boolean failed; -- struct bfd_strtab_hash *strtab = NULL; -+ struct elf_strtab_hash *strtab = NULL; - Elf_Internal_Shdr *shstrtab_hdr; - bfd_boolean need_symtab; - -@@ -3827,9 +3804,9 @@ _bfd_elf_compute_section_file_positions (bfd *abfd, - /* Now that we know where the .strtab section goes, write it - out. */ - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0 -- || ! _bfd_stringtab_emit (abfd, strtab)) -+ || ! _bfd_elf_strtab_emit (abfd, strtab)) - return FALSE; -- _bfd_stringtab_free (strtab); -+ _bfd_elf_strtab_free (strtab); - } - - abfd->output_has_begun = TRUE; -@@ -7065,18 +7042,21 @@ _bfd_elf_copy_private_symbol_data (bfd *ibfd, - - static bfd_boolean - swap_out_syms (bfd *abfd, -- struct bfd_strtab_hash **sttp, -+ struct elf_strtab_hash **sttp, - int relocatable_p) - { - const struct elf_backend_data *bed; - int symcount; - asymbol **syms; -- struct bfd_strtab_hash *stt; -+ struct elf_strtab_hash *stt; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symtab_shndx_hdr; - Elf_Internal_Shdr *symstrtab_hdr; -+ struct elf_sym_strtab *symstrtab; - bfd_byte *outbound_syms; - bfd_byte *outbound_shndx; -+ unsigned long outbound_syms_index; -+ unsigned long outbound_shndx_index; - int idx; - unsigned int num_locals; - bfd_size_type amt; -@@ -7086,7 +7066,7 @@ swap_out_syms (bfd *abfd, - return FALSE; - - /* Dump out the symtabs. */ -- stt = _bfd_elf_stringtab_init (); -+ stt = _bfd_elf_strtab_init (); - if (stt == NULL) - return FALSE; - -@@ -7102,16 +7082,29 @@ swap_out_syms (bfd *abfd, - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - symstrtab_hdr->sh_type = SHT_STRTAB; - -+ /* Allocate buffer to swap out the .strtab section. */ -+ symstrtab = (struct elf_sym_strtab *) bfd_malloc ((symcount + 1) -+ * sizeof (*symstrtab)); -+ if (symstrtab == NULL) -+ { -+ _bfd_elf_strtab_free (stt); -+ return FALSE; -+ } -+ - outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount, - bed->s->sizeof_sym); - if (outbound_syms == NULL) - { -- _bfd_stringtab_free (stt); -+error_return: -+ _bfd_elf_strtab_free (stt); -+ free (symstrtab); - return FALSE; - } - symtab_hdr->contents = outbound_syms; -+ outbound_syms_index = 0; - - outbound_shndx = NULL; -+ outbound_shndx_index = 0; - symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; - if (symtab_shndx_hdr->sh_name != 0) - { -@@ -7119,10 +7112,7 @@ swap_out_syms (bfd *abfd, - outbound_shndx = (bfd_byte *) - bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx)); - if (outbound_shndx == NULL) -- { -- _bfd_stringtab_free (stt); -- return FALSE; -- } -+ goto error_return; - - symtab_shndx_hdr->contents = outbound_shndx; - symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; -@@ -7142,10 +7132,12 @@ swap_out_syms (bfd *abfd, - sym.st_other = 0; - sym.st_shndx = SHN_UNDEF; - sym.st_target_internal = 0; -- bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx); -- outbound_syms += bed->s->sizeof_sym; -+ 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 += sizeof (Elf_External_Sym_Shndx); -+ outbound_shndx_index++; - } - - name_local_sections -@@ -7153,7 +7145,7 @@ swap_out_syms (bfd *abfd, - && bed->elf_backend_name_local_section_symbols (abfd)); - - syms = bfd_get_outsymbols (abfd); -- for (idx = 0; idx < symcount; idx++) -+ for (idx = 0; idx < symcount;) - { - Elf_Internal_Sym sym; - bfd_vma value = syms[idx]->value; -@@ -7165,18 +7157,17 @@ swap_out_syms (bfd *abfd, - && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM) - { - /* Local section symbols have no name. */ -- sym.st_name = 0; -+ sym.st_name = (unsigned long) -1; - } - else - { -- sym.st_name = (unsigned long) _bfd_stringtab_add (stt, -- syms[idx]->name, -- TRUE, FALSE); -+ /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize -+ to get the final offset for st_name. */ -+ sym.st_name -+ = (unsigned long) _bfd_elf_strtab_add (stt, syms[idx]->name, -+ FALSE); - if (sym.st_name == (unsigned long) -1) -- { -- _bfd_stringtab_free (stt); -- return FALSE; -- } -+ goto error_return; - } - - type_ptr = elf_symbol_from (abfd, syms[idx]); -@@ -7266,8 +7257,7 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), - syms[idx]->name ? syms[idx]->name : "<Local sym>", - sec->name); - bfd_set_error (bfd_error_invalid_operation); -- _bfd_stringtab_free (stt); -- return FALSE; -+ goto error_return; - } - - shndx = _bfd_elf_section_from_bfd_section (abfd, sec2); -@@ -7353,14 +7343,40 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"), - sym.st_target_internal = 0; - } - -- bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx); -- outbound_syms += bed->s->sizeof_sym; -+ 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 += sizeof (Elf_External_Sym_Shndx); -+ outbound_shndx_index++; - } - -+ /* Finalize the .strtab section. */ -+ _bfd_elf_strtab_finalize (stt); -+ -+ /* Swap out the .strtab section. */ -+ for (idx = 0; idx <= symcount; idx++) -+ { -+ struct elf_sym_strtab *elfsym = &symstrtab[idx]; -+ if (elfsym->sym.st_name == (unsigned long) -1) -+ elfsym->sym.st_name = 0; -+ else -+ elfsym->sym.st_name = _bfd_elf_strtab_offset (stt, -+ elfsym->sym.st_name); -+ bed->s->swap_symbol_out (abfd, &elfsym->sym, -+ (outbound_syms -+ + (elfsym->dest_index -+ * bed->s->sizeof_sym)), -+ (outbound_shndx -+ + (elfsym->destshndx_index -+ * sizeof (Elf_External_Sym_Shndx)))); -+ } -+ free (symstrtab); -+ - *sttp = stt; -- symstrtab_hdr->sh_size = _bfd_stringtab_size (stt); -+ symstrtab_hdr->sh_size = _bfd_elf_strtab_size (stt); - symstrtab_hdr->sh_type = SHT_STRTAB; - - symstrtab_hdr->sh_flags = 0; -diff --git a/bfd/elflink.c b/bfd/elflink.c -index 6efe1e4..ca2f153 100644 ---- a/bfd/elflink.c -+++ b/bfd/elflink.c -@@ -7403,7 +7403,7 @@ struct elf_final_link_info - /* Output BFD. */ - bfd *output_bfd; - /* Symbol string table. */ -- struct bfd_strtab_hash *symstrtab; -+ struct elf_strtab_hash *symstrtab; - /* .dynsym section. */ - asection *dynsym_sec; - /* .hash section. */ -@@ -7430,16 +7430,8 @@ struct elf_final_link_info - /* Array large enough to hold a section pointer for each local - symbol of any input BFD. */ - asection **sections; -- /* Buffer to hold swapped out symbols. */ -- bfd_byte *symbuf; -- /* And one for symbol section indices. */ -+ /* Buffer for SHT_SYMTAB_SHNDX section. */ - Elf_External_Sym_Shndx *symshndxbuf; -- /* Number of swapped out symbols in buffer. */ -- size_t symbuf_count; -- /* Number of symbols which fit in symbuf. */ -- size_t symbuf_size; -- /* And same for symshndxbuf. */ -- size_t shndxbuf_size; - /* Number of STT_FILE syms seen. */ - size_t filesym_count; - }; -@@ -8529,47 +8521,21 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) - return ret; - } - --/* Flush the output symbols to the file. */ -- --static bfd_boolean --elf_link_flush_output_syms (struct elf_final_link_info *flinfo, -- const struct elf_backend_data *bed) --{ -- if (flinfo->symbuf_count > 0) -- { -- Elf_Internal_Shdr *hdr; -- file_ptr pos; -- bfd_size_type amt; -- -- hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr; -- pos = hdr->sh_offset + hdr->sh_size; -- amt = flinfo->symbuf_count * bed->s->sizeof_sym; -- if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) != 0 -- || bfd_bwrite (flinfo->symbuf, amt, flinfo->output_bfd) != amt) -- return FALSE; -- -- hdr->sh_size += amt; -- flinfo->symbuf_count = 0; -- } -- -- return TRUE; --} -- --/* Add a symbol to the output symbol table. */ -+/* Add a symbol to the output symbol string table. */ - - static int --elf_link_output_sym (struct elf_final_link_info *flinfo, -- const char *name, -- Elf_Internal_Sym *elfsym, -- asection *input_sec, -- struct elf_link_hash_entry *h) --{ -- bfd_byte *dest; -- Elf_External_Sym_Shndx *destshndx; -+elf_link_output_symstrtab (struct elf_final_link_info *flinfo, -+ const char *name, -+ Elf_Internal_Sym *elfsym, -+ asection *input_sec, -+ struct elf_link_hash_entry *h) -+{ - int (*output_symbol_hook) - (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); -+ struct elf_link_hash_table *hash_table; - const struct elf_backend_data *bed; -+ bfd_size_type strtabsize; - - BFD_ASSERT (elf_onesymtab (flinfo->output_bfd)); - -@@ -8582,49 +8548,119 @@ elf_link_output_sym (struct elf_final_link_info *flinfo, - return ret; - } - -- if (name == NULL || *name == '\0') -- elfsym->st_name = 0; -- else if (input_sec->flags & SEC_EXCLUDE) -- elfsym->st_name = 0; -+ if (name == NULL -+ || *name == '\0' -+ || (input_sec->flags & SEC_EXCLUDE)) -+ elfsym->st_name = (unsigned long) -1; - else - { -- elfsym->st_name = (unsigned long) _bfd_stringtab_add (flinfo->symstrtab, -- name, TRUE, FALSE); -+ /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize -+ to get the final offset for st_name. */ -+ elfsym->st_name -+ = (unsigned long) _bfd_elf_strtab_add (flinfo->symstrtab, -+ name, FALSE); - if (elfsym->st_name == (unsigned long) -1) - return 0; - } - -- if (flinfo->symbuf_count >= flinfo->symbuf_size) -+ hash_table = elf_hash_table (flinfo->info); -+ strtabsize = hash_table->strtabsize; -+ if (strtabsize <= hash_table->strtabcount) - { -- if (! elf_link_flush_output_syms (flinfo, bed)) -+ strtabsize += strtabsize; -+ hash_table->strtabsize = strtabsize; -+ strtabsize *= sizeof (*hash_table->strtab); -+ hash_table->strtab -+ = (struct elf_sym_strtab *) bfd_realloc (hash_table->strtab, -+ strtabsize); -+ 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; -+ -+ bfd_get_symcount (flinfo->output_bfd) += 1; -+ hash_table->strtabcount += 1; -+ -+ return 1; -+} -+ -+/* Swap symbols out to the symbol table and flush the output symbols to -+ the file. */ - -- dest = flinfo->symbuf + flinfo->symbuf_count * bed->s->sizeof_sym; -- destshndx = flinfo->symshndxbuf; -- if (destshndx != NULL) -+static bfd_boolean -+elf_link_swap_symbols_out (struct elf_final_link_info *flinfo) -+{ -+ struct elf_link_hash_table *hash_table = elf_hash_table (flinfo->info); -+ bfd_size_type amt, i; -+ const struct elf_backend_data *bed; -+ bfd_byte *symbuf; -+ Elf_Internal_Shdr *hdr; -+ file_ptr pos; -+ bfd_boolean ret; -+ -+ if (!hash_table->strtabcount) -+ 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; -+ symbuf = (bfd_byte *) bfd_malloc (amt); -+ if (symbuf == NULL) -+ return FALSE; -+ -+ if (flinfo->symshndxbuf) - { -- if (bfd_get_symcount (flinfo->output_bfd) >= flinfo->shndxbuf_size) -+ amt = (sizeof (Elf_External_Sym_Shndx) -+ * (bfd_get_symcount (flinfo->output_bfd))); -+ flinfo->symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt); -+ if (flinfo->symshndxbuf == NULL) - { -- bfd_size_type amt; -- -- amt = flinfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); -- destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx, -- amt * 2); -- if (destshndx == NULL) -- return 0; -- flinfo->symshndxbuf = destshndx; -- memset ((char *) destshndx + amt, 0, amt); -- flinfo->shndxbuf_size *= 2; -+ free (symbuf); -+ return FALSE; - } -- destshndx += bfd_get_symcount (flinfo->output_bfd); - } - -- bed->s->swap_symbol_out (flinfo->output_bfd, elfsym, dest, destshndx); -- flinfo->symbuf_count += 1; -- bfd_get_symcount (flinfo->output_bfd) += 1; -+ for (i = 0; i < hash_table->strtabcount; i++) -+ { -+ struct elf_sym_strtab *elfsym = &hash_table->strtab[i]; -+ if (elfsym->sym.st_name == (unsigned long) -1) -+ elfsym->sym.st_name = 0; -+ else -+ elfsym->sym.st_name -+ = (unsigned long) _bfd_elf_strtab_offset (flinfo->symstrtab, -+ elfsym->sym.st_name); -+ bed->s->swap_symbol_out (flinfo->output_bfd, &elfsym->sym, -+ ((bfd_byte *) symbuf -+ + (elfsym->dest_index -+ * bed->s->sizeof_sym)), -+ (flinfo->symshndxbuf -+ + elfsym->destshndx_index)); -+ } -+ -+ hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr; -+ pos = hdr->sh_offset + hdr->sh_size; -+ amt = hash_table->strtabcount * bed->s->sizeof_sym; -+ if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) == 0 -+ && bfd_bwrite (symbuf, amt, flinfo->output_bfd) == amt) -+ { -+ hdr->sh_size += amt; -+ ret = TRUE; -+ } -+ else -+ ret = FALSE; - -- return 1; -+ free (symbuf); -+ -+ free (hash_table->strtab); -+ hash_table->strtab = NULL; -+ -+ return ret; - } - - /* Return TRUE if the dynamic symbol SYM in ABFD is supported. */ -@@ -9250,15 +9286,16 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) - memset (&fsym, 0, sizeof (fsym)); - fsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - fsym.st_shndx = SHN_ABS; -- if (!elf_link_output_sym (eoinfo->flinfo, NULL, &fsym, -- bfd_und_section_ptr, NULL)) -+ if (!elf_link_output_symstrtab (eoinfo->flinfo, NULL, &fsym, -+ bfd_und_section_ptr, NULL)) - return FALSE; - - eoinfo->file_sym_done = TRUE; - } - - indx = bfd_get_symcount (flinfo->output_bfd); -- ret = elf_link_output_sym (flinfo, h->root.root.string, &sym, input_sec, h); -+ ret = elf_link_output_symstrtab (flinfo, h->root.root.string, &sym, -+ input_sec, h); - if (ret == 0) - { - eoinfo->failed = TRUE; -@@ -9551,10 +9588,11 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) - memset (&osym, 0, sizeof (osym)); - osym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - osym.st_shndx = SHN_ABS; -- if (!elf_link_output_sym (flinfo, -- (input_bfd->lto_output ? NULL -- : input_bfd->filename), -- &osym, bfd_abs_section_ptr, NULL)) -+ if (!elf_link_output_symstrtab (flinfo, -+ (input_bfd->lto_output ? NULL -+ : input_bfd->filename), -+ &osym, bfd_abs_section_ptr, -+ NULL)) - return FALSE; - } - -@@ -9586,7 +9624,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) - } - - indx = bfd_get_symcount (output_bfd); -- ret = elf_link_output_sym (flinfo, name, &osym, isec, NULL); -+ ret = elf_link_output_symstrtab (flinfo, name, &osym, isec, NULL); - if (ret == 0) - return FALSE; - else if (ret == 1) -@@ -9669,7 +9707,8 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) - sym.st_value += o->output_offset; - - indx = bfd_get_symcount (output_bfd); -- ret = elf_link_output_sym (flinfo, name, &sym, o, NULL); -+ ret = elf_link_output_symstrtab (flinfo, name, &sym, o, -+ NULL); - if (ret == 0) - return FALSE; - else if (ret == 1) -@@ -10144,8 +10183,9 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd) - } - - indx = bfd_get_symcount (output_bfd); -- ret = elf_link_output_sym (flinfo, name, &sym, sec, -- NULL); -+ ret = elf_link_output_symstrtab (flinfo, name, -+ &sym, sec, -+ NULL); - if (ret == 0) - return FALSE; - else if (ret == 1) -@@ -10584,7 +10624,7 @@ elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo) - asection *o; - - if (flinfo->symstrtab != NULL) -- _bfd_stringtab_free (flinfo->symstrtab); -+ _bfd_elf_strtab_free (flinfo->symstrtab); - if (flinfo->contents != NULL) - free (flinfo->contents); - if (flinfo->external_relocs != NULL) -@@ -10601,8 +10641,6 @@ elf_final_link_free (bfd *obfd, struct elf_final_link_info *flinfo) - free (flinfo->indices); - if (flinfo->sections != NULL) - free (flinfo->sections); -- if (flinfo->symbuf != NULL) -- free (flinfo->symbuf); - if (flinfo->symshndxbuf != NULL) - free (flinfo->symshndxbuf); - for (o = obfd->sections; o != NULL; o = o->next) -@@ -10660,7 +10698,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - - flinfo.info = info; - flinfo.output_bfd = abfd; -- flinfo.symstrtab = _bfd_elf_stringtab_init (); -+ flinfo.symstrtab = _bfd_elf_strtab_init (); - if (flinfo.symstrtab == NULL) - return FALSE; - -@@ -10687,10 +10725,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - flinfo.internal_syms = NULL; - flinfo.indices = NULL; - flinfo.sections = NULL; -- flinfo.symbuf = NULL; - flinfo.symshndxbuf = NULL; -- flinfo.symbuf_count = 0; -- flinfo.shndxbuf_size = 0; - flinfo.filesym_count = 0; - - /* The object attributes have been merged. Remove the input -@@ -10922,27 +10957,18 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - /* sh_offset is set just below. */ - symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; - -- /* Allocate a buffer to hold swapped out symbols. This is to avoid -- continuously seeking to the right position in the file. */ -- if (! info->keep_memory || max_sym_count < 20) -- flinfo.symbuf_size = 20; -- else -- flinfo.symbuf_size = max_sym_count; -- amt = flinfo.symbuf_size; -- amt *= bed->s->sizeof_sym; -- flinfo.symbuf = (bfd_byte *) bfd_malloc (amt); -- if (flinfo.symbuf == NULL) -+ if (max_sym_count < 20) -+ max_sym_count = 20; -+ elf_hash_table (info)->strtabsize = max_sym_count; -+ amt = max_sym_count * sizeof (struct elf_sym_strtab); -+ elf_hash_table (info)->strtab -+ = (struct elf_sym_strtab *) bfd_malloc (amt); -+ if (elf_hash_table (info)->strtab == NULL) - goto error_return; -- if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) -- { -- /* Wild guess at number of output symbols. realloc'd as needed. */ -- amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; -- flinfo.shndxbuf_size = amt; -- amt *= sizeof (Elf_External_Sym_Shndx); -- flinfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt); -- if (flinfo.symshndxbuf == NULL) -- goto error_return; -- } -+ /* The real buffer will be allocated in elf_link_swap_symbols_out. */ -+ flinfo.symshndxbuf -+ = (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF) -+ ? (Elf_External_Sym_Shndx *) -1 : NULL); - - if (info->strip != strip_all || emit_relocs) - { -@@ -10962,8 +10988,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - elfsym.st_other = 0; - elfsym.st_shndx = SHN_UNDEF; - elfsym.st_target_internal = 0; -- if (elf_link_output_sym (&flinfo, NULL, &elfsym, bfd_und_section_ptr, -- NULL) != 1) -+ if (elf_link_output_symstrtab (&flinfo, NULL, &elfsym, -+ bfd_und_section_ptr, NULL) != 1) - goto error_return; - - /* Output a symbol for each section. We output these even if we are -@@ -10986,7 +11012,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - elfsym.st_shndx = i; - if (!info->relocatable) - elfsym.st_value = o->vma; -- if (elf_link_output_sym (&flinfo, NULL, &elfsym, o, NULL) != 1) -+ if (elf_link_output_symstrtab (&flinfo, NULL, &elfsym, o, -+ NULL) != 1) - goto error_return; - } - } -@@ -11200,7 +11227,8 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - struct elf_link_hash_entry *); - - if (! ((*bed->elf_backend_output_arch_local_syms) -- (abfd, info, &flinfo, (out_sym_func) elf_link_output_sym))) -+ (abfd, info, &flinfo, -+ (out_sym_func) elf_link_output_symstrtab))) - return FALSE; - } - -@@ -11311,12 +11339,16 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - struct elf_link_hash_entry *); - - if (! ((*bed->elf_backend_output_arch_syms) -- (abfd, info, &flinfo, (out_sym_func) elf_link_output_sym))) -+ (abfd, info, &flinfo, -+ (out_sym_func) elf_link_output_symstrtab))) - return FALSE; - } - -- /* Flush all symbols to the file. */ -- if (! elf_link_flush_output_syms (&flinfo, bed)) -+ /* Finalize the .strtab section. */ -+ _bfd_elf_strtab_finalize (flinfo.symstrtab); -+ -+ /* Swap out the .strtab section. */ -+ if (!elf_link_swap_symbols_out (&flinfo)) - return FALSE; - - /* Now we know the size of the symtab section. */ -@@ -11349,7 +11381,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - symstrtab_hdr->sh_type = SHT_STRTAB; - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; -- symstrtab_hdr->sh_size = _bfd_stringtab_size (flinfo.symstrtab); -+ symstrtab_hdr->sh_size = _bfd_elf_strtab_size (flinfo.symstrtab); - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; -@@ -11361,7 +11393,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) - elf_next_file_pos (abfd) = off; - - if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 -- || ! _bfd_stringtab_emit (abfd, flinfo.symstrtab)) -+ || ! _bfd_elf_strtab_emit (abfd, flinfo.symstrtab)) - return FALSE; - } - -diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp -index 47b5a21..ff19bad 100644 ---- a/gas/testsuite/gas/elf/elf.exp -+++ b/gas/testsuite/gas/elf/elf.exp -@@ -209,6 +209,8 @@ if { [is_elf_format] } then { - run_dump_test "common1" - run_dump_test "common2" - -+ run_dump_test "strtab" -+ - load_lib gas-dg.exp - dg-init - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s $srcdir/$subdir/warn-*.s]] "" "" -diff --git a/gas/testsuite/gas/elf/strtab.d b/gas/testsuite/gas/elf/strtab.d -new file mode 100644 -index 0000000..c6495d7 ---- /dev/null -+++ b/gas/testsuite/gas/elf/strtab.d -@@ -0,0 +1,7 @@ -+#readelf: -W -x .strtab -+#name: .strtab section -+ -+#failif -+#... -+ +0x[0-9 ]+.*\.xxxx\..* -+#... -diff --git a/gas/testsuite/gas/elf/strtab.s b/gas/testsuite/gas/elf/strtab.s -new file mode 100644 -index 0000000..931d9ef ---- /dev/null -+++ b/gas/testsuite/gas/elf/strtab.s -@@ -0,0 +1,8 @@ -+ .text -+.globl x; x: -+.globl xx; xx: -+.globl xxx; xxx: -+.globl xxxx; xxxx: -+.globl xxxxx; xxxxx: -+.globl xxxxxx; xxxxxx: -+ .byte 0 -diff --git a/ld/testsuite/ld-elf/strtab.d b/ld/testsuite/ld-elf/strtab.d -new file mode 100644 -index 0000000..0797708 ---- /dev/null -+++ b/ld/testsuite/ld-elf/strtab.d -@@ -0,0 +1,7 @@ -+#ld: -shared -+#readelf: -W -x .strtab -+ -+#failif -+#... -+ +0x[0-9 ]+.*\.xxxx\..* -+#... -diff --git a/ld/testsuite/ld-elf/strtab.s b/ld/testsuite/ld-elf/strtab.s -new file mode 100644 -index 0000000..931d9ef ---- /dev/null -+++ b/ld/testsuite/ld-elf/strtab.s -@@ -0,0 +1,8 @@ -+ .text -+.globl x; x: -+.globl xx; xx: -+.globl xxx; xxx: -+.globl xxxx; xxxx: -+.globl xxxxx; xxxxx: -+.globl xxxxxx; xxxxxx: -+ .byte 0 --- -1.9.3 - |