Bug 18451

Summary: Inefficient .strtab implementation
Product: binutils Reporter: H.J. Lu <hjl.tools>
Component: gasAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: jsweval
Priority: P2    
Version: 2.26   
Target Milestone: 2.26   
Host: Target:
Build: Last reconfirmed:

Description H.J. Lu 2015-05-23 14:22:42 UTC
[hjl@gnu-tools-1 strtab-1]$ cat x.S
#define GLOBAL(x) .globl x; x
	.text
GLOBAL(x):
GLOBAL(xx):
GLOBAL(xxx):
GLOBAL(xxxx):
GLOBAL(xxxxx):
GLOBAL(xxxxxx):
	mov %eax,%edx
[hjl@gnu-tools-1 strtab-1]$ gcc -c x.S
[hjl@gnu-tools-1 strtab-1]$ readelf -x 6 x.o

Hex dump of section '.strtab':
  0x00000000 00780078 78007878 78007878 78780078 .x.xx.xxx.xxxx.x
  0x00000010 78787878 00787878 78787800          xxxx.xxxxxx.

[hjl@gnu-tools-1 strtab-1]$ 

They can share a single "xxxxxx" entry.
Comment 1 Sourceware Commits 2015-06-25 15:17:33 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ef10c3ace00674e8c3599c3bf95f06c87d68898b

commit ef10c3ace00674e8c3599c3bf95f06c87d68898b
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Jun 25 08:16:00 2015 -0700

    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%
    
    Saving on libc.so from glibc is much more since libc.so has many alias
    symbols with the same suffix.  For x32 glibc,
    
     [82] .strtab STRTAB 0+ 81b348 0159e7 00 0 0 1
    
    vs
    
     [82] .strtab STRTAB 0+ 81b8bc 019e72 00 0 0 1
    
    It reduces the .strtab size by 17547 bytes, about 16%.
    
    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.
Comment 2 H.J. Lu 2015-06-25 15:18:46 UTC
Fixed.