Bug 12851 - --gc-sections doesn't work on note sections
Summary: --gc-sections doesn't work on note sections
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: Unassigned
URL: http://sourceware.org/ml/binutils/201...
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-07 03:15 UTC by H.J. Lu
Modified: 2011-06-14 02:47 UTC (History)
1 user (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 H.J. Lu 2011-06-07 03:15:11 UTC
When compiling GCC 4.7 on Fedora 15 with
systemtap-sdt-devel-1.4-9.fc15.x86_64, x64-64
unwind-dw2.s has

.pushsection .note.stapsdt,"?","note"
.balign 4
.4byte 992f-991f,994f-993f,3
991: .asciz "stapsdt"
992: .balign 4
993: .8byte 990b
.8byte _.stapsdt.base
.8byte 0
.asciz "libgcc"
.asciz "unwind"
.asciz "8@%rdi 8@%rsi"
994: .balign 4
.popsection

# 0 "" 2
# 1555 "/export/gnu/import/git/gcc-x32/libgcc/../gcc/unwind-dw2.c" 1
        .ifndef _.stapsdt.base
.pushsection .stapsdt.base,"aG","progbits",.stapsdt.base,comdat
.weak _.stapsdt.base
.hidden _.stapsdt.base
_.stapsdt.base: .space 1
.size _.stapsdt.base,1

It is unsafe since .stapsdt.base section may be deleted
by another .stapsdt.base section group and it leads
to undefined reference error in .note.stapsdt section.
2 sections must be put in the same section group.
Comment 1 Mark Wielaard 2011-06-07 11:32:52 UTC
The intention is that the .note.stapsdt gets into the same section group as the section it is defined in. That is what the "?" .pushsection flag is about.

Are you are saying the .stapsdt.base section should be in the same section group?

But I believe we only want one .stapsdt.base section, that is why it is in a comdat group, so that duplicates can be deleted. And nothing in the .stapsdt.base section refers to anything else. It is just there to detect the prelinking address adjustment.

I am probably missing the exact scenario when this causes an issue.
Could you post a fuller example that shows the actual error you see?
Comment 2 H.J. Lu 2011-06-07 13:10:48 UTC
Please build and run "make check" GCC mainline on Fedora 15/x86.
I see

`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(libc-lowlevellock.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(dl-lookup.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(setjmp.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(__longjmp.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(__longjmp.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(dl-runtime.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/../lib/libc.a(dl-runtime.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)^M


[hjl@gnu-33 tmp]$ readelf -Sg bsd-_setjmp.o
There are 14 section headers, starting at offset 0x15c:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .group            GROUP           00000000 000034 000008 04     12   2  4
  [ 2] .text             PROGBITS        00000000 000040 000037 00  AX  0   0 16
  [ 3] .data             PROGBITS        00000000 000078 000000 00  WA  0   0  4
  [ 4] .bss              NOBITS          00000000 000078 000000 00  WA  0   0  4
  [ 5] .note.stapsdt     NOTE            00000000 000078 000040 00      0   0  4
  [ 6] .rel.note.stapsdt REL             00000000 000454 000010 08     12   5  4
  [ 7] .stapsdt.base     PROGBITS        00000000 0000b8 000001 00  AG  0   0  1
  [ 8] .note.GNU-stack   PROGBITS        00000000 0000b9 000000 00      0   0  1
  [ 9] .eh_frame         PROGBITS        00000000 0000bc 00002c 00   A  0   0  4
  [10] .rel.eh_frame     REL             00000000 000464 000008 08     12   9  4
  [11] .shstrtab         STRTAB          00000000 0000e8 000071 00      0   0  1
  [12] .symtab           SYMTAB          00000000 00038c 0000b0 10     13   9  4
  [13] .strtab           STRTAB          00000000 00043c 000018 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

COMDAT group section [    1] `.group' [.stapsdt.base] contains 1 sections:
   [Index]    Name
   [    7]   .stapsdt.base
[hjl@gnu-33 tmp]$ 

.stapsdt.base and .note.stapsdt aren't in the same section group.
Comment 3 Mark Wielaard 2011-06-07 13:59:04 UTC
(In reply to comment #2)
> Please build and run "make check" GCC mainline on Fedora 15/x86.
> I see
> 
> `_.stapsdt.base' referenced in section `.note.stapsdt' of
> /usr/lib/../lib/libc.a(libc-lowlevellock.o): defined in discarded section
> `.stapsdt.base[.stapsdt.base]' of /usr/lib/../lib/libc.a(bsd-_setjmp.o)

I'll try and replicate. But don't currently have such a setup.

> [hjl@gnu-33 tmp]$ readelf -Sg bsd-_setjmp.o
> There are 14 section headers, starting at offset 0x15c:
> 
> Section Headers:
>   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf
> Al
> [...]
>   [ 5] .note.stapsdt     NOTE            00000000 000078 000040 00      0   0 
> 4
>   [ 6] .rel.note.stapsdt REL             00000000 000454 000010 08     12   5 
> 4
>   [ 7] .stapsdt.base     PROGBITS        00000000 0000b8 000001 00  AG  0   0 
> 1
> [...]
> Key to Flags:
>   W (write), A (alloc), X (execute), M (merge), S (strings)
>   I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
>   O (extra OS processing required) o (OS specific), p (processor specific)
> 
> COMDAT group section [    1] `.group' [.stapsdt.base] contains 1 sections:
>    [Index]    Name
>    [    7]   .stapsdt.base
> [hjl@gnu-33 tmp]$ 
> 
> .stapsdt.base and .note.stapsdt aren't in the same section group.

Why does it matter whether they are in the same section group or not?
.stapsdt.base is in a comdat group, and so one copy will always be retained.

It looks like the linker is picking the wrong section, one that does get discarded. While ignoring the section that is being kept and should be used to link against.

I am curious why we haven't seen this before.
Against which binutils/linker is this?
Comment 4 H.J. Lu 2011-06-07 14:42:08 UTC
(In reply to comment #3)
> 
> Why does it matter whether they are in the same section group or not?
> .stapsdt.base is in a comdat group, and so one copy will always be retained.
> 
> It looks like the linker is picking the wrong section, one that does get
> discarded. While ignoring the section that is being kept and should be used to
> link against.

No. Linker is correct.  YOU CAN'T HAVE LOCAL REFERENCES OUTSIDE OF
A COMDAT GROUP. In your case, you have

.pushsection .note.stapsdt,"?","note"
.balign 4
.4byte 992f-991f,994f-993f,3
991: .asciz "stapsdt"
992: .balign 4
993: .8byte 990b
.8byte _.stapsdt.base
.8byte 0
.asciz "libgcc"
.asciz "unwind"
.asciz "8@%rdi 8@%rsi"
994: .balign 4
.popsection

# 0 "" 2
# 1555 "/export/gnu/import/git/gcc-x32/libgcc/../gcc/unwind-dw2.c" 1
        .ifndef _.stapsdt.base
.pushsection .stapsdt.base,"aG","progbits",.stapsdt.base,comdat
.weak _.stapsdt.base
.hidden _.stapsdt.base
_.stapsdt.base: .space 1
.size _.stapsdt.base,1

Non comdat member section, .note.stapsdt, has a local
reference of _.stapsdt.base, which is defined in a comdat
section. Did you mean to put .note.stapsdt section in the same
comdat group as .stapsdt.base section?
> I am curious why we haven't seen this before.
> Against which binutils/linker is this?

You need glibc with systemtap support, like Fedora 15, to
see the problem:

[hjl@gnu-6 tmp]$ cat gcsec-1.c
/* AIX gld supports garbage collection. But AIX gcc does not support 
   -ffunction-sections or -fdata-sections.  */
/* { dg-do run { xfail rs6000-*-aix* powerpc*-*-aix* } } */
/* { dg-require-gc-sections "" } */

/* { dg-options "-ffunction-sections -fdata-sections -Wl,--gc-sections" } */
/* { dg-options "-ffunction-sections -fdata-sections -Wl,--gc-sections -static" { target static } } */

#include <stdlib.h>

static int unusedint=5;

static int usedint=1;

int unused(void) {
    return 1;
}

int foo(void) {
    return usedint;
}

int main(void) {

    if (foo())
        exit(0);
    else
        abort();
}
[hjl@gnu-6 tmp]$ gcc gcsec-1.c -ffunction-sections -fdata-sections -Wl,--gc-sections -static -B/usr/bin/
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(setjmp.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(dl-lookup.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(__longjmp.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(__longjmp.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(dl-runtime.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(dl-runtime.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(dl-sym.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/libgcc_eh.a(unwind-dw2.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
`.text' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(fork.o): defined in discarded section `.text' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(fork.o)
`_.stapsdt.base' referenced in section `.note.stapsdt' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(fork.o): defined in discarded section `.stapsdt.base[.stapsdt.base]' of /usr/lib/gcc/x86_64-redhat-linux/4.6.0/../../../../lib64/libc.a(libc-lowlevellock.o)
collect2: ld returned 1 exit status
[hjl@gnu-6 tmp]$
Comment 5 Mark Wielaard 2011-06-08 15:15:34 UTC
(In reply to comment #4)
> No. Linker is correct.  YOU CAN'T HAVE LOCAL REFERENCES OUTSIDE OF
> A COMDAT GROUP.

I assume you are referring to gabi:

"To facilitate removing a group without leaving dangling references and with only minimal processing of the symbol table, the following rules must be followed:

    A symbol table entry with STB_GLOBAL or STB_WEAK binding that is defined relative to one of a group's sections, and that is contained in a symbol table section that is not part of the group, must be converted to an undefined symbol (its section index must be changed to SHN_UNDEF) if the group members are discarded. References to this symbol table entry from outside the group are allowed."


> Non comdat member section, .note.stapsdt, has a local
> reference of _.stapsdt.base, which is defined in a comdat
> section. Did you mean to put .note.stapsdt section in the same
> comdat group as .stapsdt.base section?

No. It is deliberately in its own COMDAT group to make sure there is only one .stapsdt.base section in the final object.

> > I am curious why we haven't seen this before.
> > Against which binutils/linker is this?
> 
> You need glibc with systemtap support, like Fedora 15, to
> see the problem:
> [...]
> [hjl@gnu-6 tmp]$ gcc gcsec-1.c -ffunction-sections -fdata-sections
> -Wl,--gc-sections -static -B/usr/bin/

Thanks for that testcase. So it is --gc-sections that is removing the .stapsdt.base section because the linker thinks it is unused. hmmm. tricky.

When is --gc-sections used?
Comment 6 H.J. Lu 2011-06-08 15:43:19 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > No. Linker is correct.  YOU CAN'T HAVE LOCAL REFERENCES OUTSIDE OF
> > A COMDAT GROUP.
> 
> I assume you are referring to gabi:
> 
> "To facilitate removing a group without leaving dangling references and with
> only minimal processing of the symbol table, the following rules must be
> followed:
> 
>     A symbol table entry with STB_GLOBAL or STB_WEAK binding that is defined
                                ^^^^^^^^^^^^^^^^^^^^^^^

You missed the key part.

> relative to one of a group's sections, and that is contained in a symbol table
> section that is not part of the group, must be converted to an undefined symbol
> (its section index must be changed to SHN_UNDEF) if the group members are
> discarded. References to this symbol table entry from outside the group are
> allowed."
> 
> 
> > Non comdat member section, .note.stapsdt, has a local
> > reference of _.stapsdt.base, which is defined in a comdat
> > section. Did you mean to put .note.stapsdt section in the same
> > comdat group as .stapsdt.base section?
> 
> No. It is deliberately in its own COMDAT group to make sure there is only one
> .stapsdt.base section in the final object.
> 

Then don't make symbol defined in .stapsdt.base section referenced from
other files local.
Comment 7 H.J. Lu 2011-06-08 15:44:21 UTC
I will take a look. It may be a linker bug.
Comment 8 H.J. Lu 2011-06-08 17:39:45 UTC
[hjl@gnu-6 pr12851]$ make clean
rm -f a.out x
[hjl@gnu-6 pr12851]$ cat foo.s
	.section .note.stapsdt,"?","note"
	.dc.a _.stapsdt.base
	.section .stapsdt.base,"aG","progbits",.stapsdt.base,comdat
_.stapsdt.base: .space 1
	.size _.stapsdt.base,1
[hjl@gnu-6 pr12851]$ cat bar.s
	.section .note.stapsdt,"?","note"
	.dc.a _.stapsdt.base
	.section .stapsdt.base,"aG","progbits",.stapsdt.base,comdat
	.weak _.stapsdt.base
_.stapsdt.base: .space 1
	.size _.stapsdt.base,1
[hjl@gnu-6 pr12851]$ cat start.s
	.text
	.global start	/* Used by SH targets.  */
start:
	.global _start
_start:
	.global __start
__start:
	.global main	/* Used by HPPA targets.  */
main:
	.dc.a 0
[hjl@gnu-6 pr12851]$ make x
./ld --gc-sections -o x foo1.o foo2.o start.o
`_.stapsdt.base' referenced in section `.note.stapsdt' of foo1.o: defined in discarded section `.stapsdt.base[.stapsdt.base]' of foo1.o
`_.stapsdt.base' referenced in section `.note.stapsdt' of foo2.o: defined in discarded section `.stapsdt.base[.stapsdt.base]' of foo2.o
make: *** [x] Error 1
[hjl@gnu-6 pr12851]$ make y
./ld --gc-sections -o y bar1.o bar2.o start.o
`_.stapsdt.base' referenced in section `.note.stapsdt' of bar1.o: defined in discarded section `.stapsdt.base[.stapsdt.base]' of bar1.o
`_.stapsdt.base' referenced in section `.note.stapsdt' of bar2.o: defined in discarded section `.stapsdt.base[.stapsdt.base]' of bar1.o
make: *** [y] Error 1
[hjl@gnu-6 pr12851]$
Comment 9 H.J. Lu 2011-06-08 20:11:27 UTC
A patch is posted at

http://sourceware.org/ml/binutils/2011-06/msg00107.html
Comment 10 Sourceware Commits 2011-06-09 04:52:20 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2011-06-09 04:52:15

Modified files:
	bfd            : ChangeLog elflink.c 
	ld/testsuite   : ChangeLog 
Added files:
	ld/testsuite/ld-elf: pr12851.d pr12851.s 

Log message:
	Check relocations in note sections for --gc-sections.
	
	bfd/
	
	2011-06-08  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/12851
	* elflink.c (elf_gc_sweep): Don't check SHT_NOTE sections here.
	(bfd_elf_gc_sections): Also check SHT_NOTE sections.
	
	ld/testsuite/
	
	2011-06-08  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/12851
	* ld-elf/pr12851.d: New.
	* ld-elf/pr12851.s: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5375&r2=1.5376
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.407&r2=1.408
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1420&r2=1.1421
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/pr12851.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/pr12851.s.diff?cvsroot=src&r1=NONE&r2=1.1
Comment 11 H.J. Lu 2011-06-09 12:42:00 UTC
Fixed.
Comment 12 Sourceware Commits 2011-06-14 02:45:16 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2011-06-14 02:45:12

Modified files:
	bfd            : ChangeLog elflink.c elf-bfd.h elfxx-target.h 
	                 elf32-arm.c elf32-tic6x.c 

Log message:
	PR ld/12851
	* elflink.c (_bfd_elf_gc_mark_extra_sections): New function.
	(elf_gc_sweep): Don't treat debug and sections like .comment
	specially here.
	(bfd_elf_gc_sections): Treat note sections as gc roots only when
	not part of a group.  Always call gc_mark_extra_sections.
	* elf-bfd.h (_bfd_elf_gc_mark_extra_sections): Declare.
	* elfxx-target.h (elf_backend_gc_mark_extra_sections): Default to
	_bfd_elf_gc_mark_extra_sections.
	* elf32-arm.c (elf32_arm_gc_mark_extra_sections): Call
	_bfd_elf_gc_mark_extra_sections.
	* elf32-tic6x.c (elf32_tic6x_gc_mark_extra_sections): Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5384&r2=1.5385
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.410&r2=1.411
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf-bfd.h.diff?cvsroot=src&r1=1.321&r2=1.322
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elfxx-target.h.diff?cvsroot=src&r1=1.125&r2=1.126
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-arm.c.diff?cvsroot=src&r1=1.270&r2=1.271
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-tic6x.c.diff?cvsroot=src&r1=1.25&r2=1.26
Comment 13 Sourceware Commits 2011-06-14 02:47:00 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	amodra@sourceware.org	2011-06-14 02:46:58

Modified files:
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-elf: pr12851.d 

Log message:
	PR ld/12851
	* ld-elf/pr12851.d: Correct target selection and comment.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1425&r2=1.1426
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-elf/pr12851.d.diff?cvsroot=src&r1=1.1&r2=1.2