Bug 23591 - undefined reference to `__start___sancov_cntrs'
Summary: undefined reference to `__start___sancov_cntrs'
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.32
: P2 normal
Target Milestone: 2.32
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-30 04:38 UTC by Mike Hommey
Modified: 2018-09-03 08:35 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2018-08-30 00:00:00


Attachments
A patch (728 bytes, patch)
2018-08-30 16:30 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Hommey 2018-08-30 04:38:12 UTC
I haven't figured out a small test case, but here's a real world problem:

Get the Firefox/spidermonkey source from https://hg.mozilla.org/mozilla-central

Create a build directory and run the following from under it:
/path/to/mozilla-central/js/src/configure --enable-project=js --enable-fuzzing --enable-address-sanitizer --enable-linker=bfd CC=clang

(note this also requires llvm-config, rustc, and cargo)

Then run make -j<some-appropriate-number>

The build fails with:
BinSource.cpp:(.text.sancov.module_ctor[sancov.module_ctor]+0x4): undefined reference to `__start___sancov_cntrs'
BinSource.cpp:(.text.sancov.module_ctor[sancov.module_ctor]+0xb): undefined reference to `__stop___sancov_cntrs'
BinSource.cpp:(.text.sancov.module_ctor[sancov.module_ctor]+0x17): undefined reference to `__start___sancov_pcs'
BinSource.cpp:(.text.sancov.module_ctor[sancov.module_ctor]+0x1e): undefined reference to `__stop___sancov_pcs'

I bisected this to the following commit:

commit 7dba9362c172f1073487536eb137feb2da30b0ff
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Jun 16 19:41:41 2017 +0930
    Rewrite __start and __stop symbol handling
    
    This arranges for __start and __stop symbols to be defined before
    garbage collection, for all target formats.  That should allow the
    COFF and PE --gc-sections to keep a singleton orphan input section,
    a feature lost by 2017-06-13 commit cbd0eecf26.  The fancier ELF
    treatment of keeping all input sections associated with a __start or
    __stop symbol, from 2015-10-23 commit 1cce69b9dc, is retained.
    
    .startof. and .sizeof. symbols are deliberately not defined before
    garbage collection, so these won't affect garbage collection of
    sections.
    
    The patch also ensures __start, __stop, .startof. and .sizeof. symbols
    are defined before target size_dynamic_sections is called, albeit
    with a preliminary value, so that target code doesn't need to cope
    with a symbol changing from undefined at size_dynamic_sections to
    defined at relocate_section.
    
    Also, a number of problems with the testcases have been fixed.
Comment 1 Mike Hommey 2018-08-30 06:36:44 UTC
It seems to be due to most __sancov_cntrs sections having the SHT_GROUP flag.
This makes _bfd_elf_section_already_linked set the section's output_section to bfd_abs_section_ptr, which then fulfils the condition in undef_start_stop (bfs_abs_section_ptr->owner != link_info.output_bfd), which then marks the __start/__stop symbols as undefined.
Comment 2 H.J. Lu 2018-08-30 09:47:30 UTC
(In reply to Mike Hommey from comment #1)
> It seems to be due to most __sancov_cntrs sections having the SHT_GROUP flag.
> This makes _bfd_elf_section_already_linked set the section's output_section
> to bfd_abs_section_ptr, which then fulfils the condition in undef_start_stop
> (bfs_abs_section_ptr->owner != link_info.output_bfd), which then marks the
> __start/__stop symbols as undefined.

From gABI:

SHT_GROUP
This section defines a section group. A section group is a set of sections that are related and that must be treated specially by the linker (see below for further details). Sections of type SHT_GROUP may appear only in relocatable objects (objects with the ELF header e_type member set to ET_REL). The section header table entry for a group section must appear in the section header table before the entries for any of the sections that are members of the group.

How were __sancov_cntrs sections generated?
Comment 3 Mike Hommey 2018-08-30 09:53:06 UTC
They are generate by clang from the combination of -fsanitize=address and -fsanitize=fuzzer-no-link. But using that with some dummy source file doesn't trigger the problem, so some subtle thing is happening.

Also, correction: they have the SHF_GROUP flag. Only .group sections have the SHT_GROUP _type_.
Comment 4 Mike Hommey 2018-08-30 09:54:06 UTC
It's worth noting that gold doesn't trip on the same object files (that is, chanfing the linker command line to include -fuse-ld=gold makes it work)
Comment 5 H.J. Lu 2018-08-30 15:50:52 UTC
[hjl@gnu-cfl-1 pr23591]$ cat foo.S
	.section        __sancov_cntrs,"aG",%progbits,foo1,comdat
	.long 0
	.section .text,"axG",%progbits,foo1,comdat
	.globl foo1
	.type foo1, @function
foo1:
	.long 0
	.section        __sancov_cntrs,"aG",%progbits,foo2,comdat
	.long 1
	.section .text,"axG",%progbits,foo2,comdat
	.globl foo2
	.type foo2, @function
foo2:
	.long 1
[hjl@gnu-cfl-1 pr23591]$ cat foo-auto.S 
	.section .text,"axG",%progbits,foo1,comdat
	.globl foo1
	.type foo1, @function
foo1:
	.byte 0
[hjl@gnu-cfl-1 pr23591]$ cat x.c 
extern int __start___sancov_cntrs;

int
bar (void)
{
   int* ap = &__start___sancov_cntrs;
   return ap[0];
}
[hjl@gnu-cfl-1 pr23591]$ cat y.S 
	.hidden __start___sancov_cntrs
[hjl@gnu-cfl-1 pr23591]$ make
gcc -B../ -fPIC -O2 -g   -c -o x.o x.c
gcc -B../ -fPIC -O2 -g -c -o y.o y.S
gcc -B../ -fPIC -O2 -g -c -o foo-auto.o foo-auto.S
gcc -B../ -fPIC -O2 -g -c -o foo.o foo.S
./ld -shared  -o x.so x.o y.o foo-auto.o foo.o
./ld: x.o: in function `bar':
/export/home/hjl/bugs/binutils/pr23591/x.c:7: undefined reference to `__start___sancov_cntrs'
make: *** [Makefile:12: x.so] Error 1
[hjl@gnu-cfl-1 pr23591]$ make LD=ld.gold
ld.gold -shared  -o x.so x.o y.o foo-auto.o foo.o
[hjl@gnu-cfl-1 pr23591]$
Comment 6 H.J. Lu 2018-08-30 16:30:36 UTC
Created attachment 11219 [details]
A patch

Please try this.
Comment 7 Mike Hommey 2018-08-30 23:18:47 UTC
It worked.
Comment 8 H.J. Lu 2018-08-31 12:22:30 UTC
Comment on attachment 11219 [details]
A patch

The final patch is posted at

https://sourceware.org/ml/binutils/2018-08/msg00482.html
Comment 9 Sourceware Commits 2018-08-31 16:28:05 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=4d1c6335455aeeda9de8a5eb58998f919ea35a1e

commit 4d1c6335455aeeda9de8a5eb58998f919ea35a1e
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Aug 31 09:25:31 2018 -0700

    ld: Lookup section in output with the same name
    
    When there are more than one input sections with the same section name,
    SECNAME, linker picks the first one to define __start_SECNAME and
    __stop_SECNAME symbols.  When the first input section is removed by
    comdat group, we need to check if there is still an output section
    with section name SECNAME.
    
    	PR ld/23591
    	* ldlang.c (undef_start_stop): Lookup section in output with
    	the same name.
    	* testsuite/ld-elf/pr23591.d: New file.
    	* testsuite/ld-elf/pr23591a.s: Likewise.
    	* testsuite/ld-elf/pr23591b.s: Likewise.
    	* testsuite/ld-elf/pr23591c.s: Likewise.
Comment 10 H.J. Lu 2018-08-31 16:36:00 UTC
Fixed for 2.32.
Comment 11 Sourceware Commits 2018-09-03 08:35:55 UTC
The master branch has been updated by Alan Modra <amodra@sourceware.org>:

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

commit 0d9a433be406220413671495a9b0fab577a48b5e
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Sep 3 10:49:57 2018 +0930

    Re: ld: Lookup section in output with the same name
    
    Fixes pr23591 test failures on hppa64-hpux and score-elf, and xfails
    frv-linux and lm32-linux.
    
    	PR ld/23591
    	* testsuite/ld-elf/pr23591a.s,
    	* testsuite/ld-elf/pr23591b.s,
    	* testsuite/ld-elf/pr23591c.s: Don't start directives in first column.
    	* testsuite/ld-elf/pr23591.d: xfail frv-linux and lm32-linux.
    	Allow __start___sancov_cntrs as a local symbol.