Bug 13621 - dangling global hidden symbol in symtab
Summary: dangling global hidden symbol in symtab
Status: REOPENED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Richard Henderson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-01-24 23:13 UTC by Mark Wielaard
Modified: 2013-07-14 21:15 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2012-01-24 23:13:17 UTC
gcc 4.7 (not yet released) introduces a new __TMC_END__ global hidden symbol to mark the end of a .tm_clone_table section. When linking a program that doesn't use any tm_clone_table entries the __TMC_END__ symbol is left in .symtab pointing outside any section. For example just compiling an empty program int main(int argc, char **argv) { return 0; } produces on x86_64 with gcc (GCC) 4.7.0 20120119
(Red Hat 4.7.0-0.8) and binutils-2.22-4.fc17.x86_64  a __TMC_END__ symbol in .symtab that looks as follows:
   66: 0000000000600850      0 OBJECT  GLOBAL HIDDEN        24 __TMC_END__
Section 24 is:
[24] .data                PROGBITS     0000000000600848 00000848 00000004  0 WA     0   0  4
So the address of __TMC_END__ is outside that section.

With gcc < 4.7 the following mimics what happens:

$ cat attrsec.c
typedef void (*func_ptr) (void);
static func_ptr __TMC_LIST__[]
  __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void*))))
  = { };
extern func_ptr __TMC_END__[] __attribute__((__visibility__ ("hidden")));

void
deregister_tm_clones (void)
{
  if (__TMC_END__ - __TMC_LIST__ == 0)
    return;
}

func_ptr __TMC_END__[]
  __attribute__((used, section(".tm_clone_table"), aligned(sizeof(void *))))
  __attribute__((__visibility__ ("hidden"))) = { };

$ gcc -c attrsec.c 

$ readelf -a attrsec.o

[...]
  [ 5] .tm_clone_table   PROGBITS         0000000000000000  00000068
       0000000000000000  0000000000000000  WA       0     0     8
[...]
Symbol table '.symtab' contains 12 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS attrsec.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 OBJECT  LOCAL  DEFAULT    5 __TMC_LIST__
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
     9: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
    10: 0000000000000000    34 FUNC    GLOBAL DEFAULT    1 deregister_tm_clones
    11: 0000000000000000     0 OBJECT  GLOBAL HIDDEN     5 __TMC_END__

$ cat attrsecmain.c 
int main (int argc, char **argv)
{
  deregister_tm_clones ();
  return 0;
}

$ gcc -o attrsec attrsec.o attrsecmain.c 

$ readelf -a attrsec
[...]
  [24] .data             PROGBITS         0000000000600898  00000898
       0000000000000004  0000000000000000  WA       0     0     4
[...]
    64: 00000000006008a0     0 OBJECT  GLOBAL HIDDEN    24 __TMC_END__
Comment 1 H.J. Lu 2012-01-25 22:11:15 UTC
Since __TMC_END__ is 0, it is placed in .bss section.
Comment 2 Mark Wielaard 2012-01-26 10:19:53 UTC
(In reply to comment #1)
> Since __TMC_END__ is 0, it is placed in .bss section.

O that is interesting. In both my examples the .bss section is right after the section that the .symtab st_shndx field claims the symbol is in. And the address does fall in that section. So are we just seeing some off-by-one issue?

Although I would not have expected that because the variables are marked with __attribute__((used, section(".tm_clone_table")), wouldn't that force them in the .tm_clone_table sections? (Which seems to have been purged after the link.)
Comment 3 Richard Henderson 2012-01-27 20:39:23 UTC
__TMC_END__ isn't placed in the .bss section.  You'd have seen that
in the object file.  Of course that doesn't happen because there is
a section attribute.

There is something odd happening though.  The .tm_clone_table section
is zero sized (which makes sense for all programs that don't use TM).
The section is layed out in the map file:

.tm_clone_table
                0x00000000006008a0        0x0
 .tm_clone_table
                0x00000000006008a0        0x0 z.o

but the section is not present in the output (presumably due to the
size being zero?).  But the two symbols that were in the section get
arbitrarily moved to .data:

  [24] .data             PROGBITS         0000000000600898  00000898
       0000000000000004  0000000000000000  WA       0     0     4
...
    69: 00000000006008a0     0 OBJECT  GLOBAL HIDDEN    24 __TMC_LIST__
    70: 00000000006008a0     0 OBJECT  GLOBAL HIDDEN    24 __TMC_END__

(I adjusted the test case so that the start symbol was also global,
so that I could see it in all the output files.)

My current guess is that there's some "unused section" pruning code
that's triggering to remove the section.  My guess is that it should
avoid doing that if there are symbols present in the section.
Comment 4 Richard Henderson 2012-01-27 21:07:21 UTC
FYI, gold gets this correct:

  [25] .tm_clone_table   PROGBITS         00000000004018c8  000008c8
       0000000000000000  0000000000000000  WA       0     0     8
...
    18: 00000000004018c8     0 OBJECT  LOCAL  HIDDEN    25 __TMC_LIST__
    19: 00000000004018c8     0 OBJECT  LOCAL  HIDDEN    25 __TMC_END__
Comment 5 Ian Lance Taylor 2012-01-28 00:10:10 UTC
GNU ld does indeed drop output sections whose size is zero (with various exceptions and caveats).  See strip_excluded_output_sections in ld/ldlang.c.  This is done because otherwise all the output sections listed in the linker script would wind up in the output file.  gold works differently.
Comment 6 Richard Henderson 2012-01-30 00:58:32 UTC
Proposed patch:

http://sourceware.org/ml/binutils/2012-01/msg00269.html
Comment 7 cvs-commit@gcc.gnu.org 2012-02-13 18:08:56 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	rth@sourceware.org	2012-02-13 18:08:51

Modified files:
	bfd            : ChangeLog linker.c 
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-elf: warn2.d 

Log message:
	PR ld/13621
	
	bfd/
	* linker.c (fix_syms): Force symbols outside any section into
	bfd_abs_section_ptr.
	ld/testsuite/
	* ld-elf/warn2.d: Expect ABS section for Foo.
	* ld-elf/zerosize1.d, zerosize1.s: New test.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5607&r2=1.5608
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/linker.c.diff?cvsroot=src&r1=1.91&r2=1.92
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1490&r2=1.1491
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/warn2.d.diff?cvsroot=src&r1=1.6&r2=1.7
Comment 8 Richard Henderson 2012-02-13 18:12:27 UTC
Fixed.
Comment 9 Mark Wielaard 2012-02-14 15:09:43 UTC
Thanks for pushing the fix so quickly.
I verified it fixes the eu-elflint issues.

Note that you forgot to add/commit the new test files:

        * ld-elf/zerosize1.d, zerosize1.s: New test.
Comment 10 cvs-commit@gcc.gnu.org 2012-02-14 20:43:30 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	rth@sourceware.org	2012-02-14 20:43:26

Modified files:
	ld/testsuite   : ChangeLog 
Added files:
	ld/testsuite/ld-elf: zerosize1.d zerosize1.s 

Log message:
	PR ld/13621
	* ld-elf/zerosize1.d, ld-elf/zerosize1.s: New test.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1492&r2=1.1493
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/zerosize1.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/zerosize1.s.diff?cvsroot=src&r1=NONE&r2=1.1
Comment 11 cvs-commit@gcc.gnu.org 2012-05-05 04:51:22 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2012-05-05 04:51:16

Modified files:
	bfd            : ChangeLog linker.c 
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-elf: warn2.d 
Removed files:
	ld/testsuite/ld-elf: zerosize1.d zerosize1.s 

Log message:
	PR ld/14052
	PR ld/13621
	bfd/
	* linker.c (_bfd_nearby_section): Revert 2012-02-13 change.
	ld/testsuite/
	* ld-elf/warn2.d: Revert 2012-02-13 change.
	* ld-elf/zerosize1.d, ld-elf/zerosize1.s: Delete.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5669&r2=1.5670
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/linker.c.diff?cvsroot=src&r1=1.94&r2=1.95
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1518&r2=1.1519
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/warn2.d.diff?cvsroot=src&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/zerosize1.d.diff?cvsroot=src&r1=1.2&r2=NONE
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/zerosize1.s.diff?cvsroot=src&r1=1.1&r2=NONE
Comment 12 Alan Modra 2012-05-05 04:54:14 UTC
Reopening since I've just reverted the fix that was applied for this bug.  Making symbols absolute just isn't a good idea.  See http://sourceware.org/bugzilla/show_bug.cgi?id=14052