Bug 17451 - Can't use partial linker scripts
Summary: Can't use partial linker scripts
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-02 11:35 UTC by Mike Hommey
Modified: 2014-10-02 11:35 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 Mike Hommey 2014-10-02 11:35:02 UTC
There are many reasons one may want to use a partial linker script, such as rearranging sections. Going with a complete linker script in those cases is most of the time too much of a hassle.

See following reduced test case:

$ cat > test.c <<EOF
__attribute__((section(".foo")))
void foo() {}
void bar() {}
EOF

$ cat > test.ld <<EOF
SECTIONS {
/DISCARD/ : {
*(.foo)
}
}
EOF

$ gcc -B gold -o test.so -shared test.c test.ld
gold/ld: error: test.ld: SECTIONS seen after other input files; try -T/--script
gold/ld: internal error in write_sections, at ../../gold/reloc.cc:830
collect2: error: ld returned 1 exit status

So, yeah, sure, test.ld is after other input files, like test.c, but even putting it before test.c doesn't work because, guess what, gcc adds crti.o and crtbeginS.o before test.ld.

$ gcc -B gold  -Wl,--version
collect2 version 4.9.1
gold/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccJe4jfn.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -Lgold -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. --version -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o
GNU gold (GNU Binutils for Debian 2.24.51.20140918) 1.11
Copyright (C) 2014 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

bfd.ld is perfectly happy with the same command line:

$ gcc -o test.so -shared test.c test.ld

$ readelf -SW test.so | grep foo

$ gcc -Wl,--version
collect2 version 4.9.1
/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/cceYFA30.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. --version -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o
GNU ld (GNU Binutils for Debian) 2.24.51.20140918
Copyright (C) 2014 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

Note that when you go past the ordering issue due to the gcc crt files, there are still issues:
$ gold/ld -shared -o test.so test.ld test.o
$ readelf -lSW test.so
There are 14 section headers, starting at offset 0x1288:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 001000 000006 00  AX  0   0  1
  [ 2] .eh_frame         PROGBITS        0000000000000008 001008 000038 00   A  0   0  8
  [ 3] .dynsym           DYNSYM          0000000000000040 001040 000030 18   A  4   1  8
  [ 4] .dynstr           STRTAB          0000000000000070 001070 000005 00   A  0   0  1
  [ 5] .hash             HASH            0000000000000078 001078 000014 04   A  3   0  8
  [ 6] .data             PROGBITS        000000000000008c 00108c 000000 00  WA  0   0  1
  [ 7] .dynamic          DYNAMIC         0000000000000090 001090 0000b0 10  WA  4   0  8
  [ 8] .bss              NOBITS          0000000000000140 001140 000000 00  WA  0   0  1
  [ 9] .comment          PROGBITS        0000000000000000 001140 00001e 01  MS  0   0  1
  [10] .note.gnu.gold-version NOTE            0000000000000000 001160 00001c 00      0   0  4
  [11] .symtab           SYMTAB          0000000000000000 001180 000078 18     12   3  8
  [12] .strtab           STRTAB          0000000000000000 0011f8 000019 00      0   0  1
  [13] .shstrtab         STRTAB          0000000000000000 001211 000075 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Look where the .text section ends up, compared to when building without test.ld:
There are 15 section headers, starting at offset 0x500:

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .dynsym           DYNSYM          0000000000000158 000158 000090 18   A  2   1  8
  [ 2] .dynstr           STRTAB          00000000000001e8 0001e8 000021 00   A  0   0  1
  [ 3] .hash             HASH            0000000000000210 000210 00002c 04   A  1   0  8
  [ 4] .text             PROGBITS        000000000000023c 00023c 000006 00  AX  0   0  1
  [ 5] .foo              PROGBITS        0000000000000242 000242 000006 00  AX  0   0  1
  [ 6] .eh_frame         PROGBITS        0000000000000248 000248 000058 00   A  0   0  8
  [ 7] .dynamic          DYNAMIC         00000000000012a0 0002a0 0000b0 10  WA  2   0  8
  [ 8] .data             PROGBITS        0000000000001350 000350 000000 00  WA  0   0  1
  [ 9] .bss              NOBITS          0000000000001350 000350 000000 00  WA  0   0  1
  [10] .comment          PROGBITS        0000000000000000 000350 00001e 01  MS  0   0  1
  [11] .note.gnu.gold-version NOTE            0000000000000000 000370 00001c 00      0   0  4
  [12] .symtab           SYMTAB          0000000000000000 000390 0000c0 18     13   3  8
  [13] .strtab           STRTAB          0000000000000000 000450 000031 00      0   0  1
  [14] .shstrtab         STRTAB          0000000000000000 000481 00007a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

IIRC (I actually hit this problem a while ago, sorry I didn't report earlier), different linker scripts have different side effects.
Comment 1 Mike Hommey 2014-10-02 11:35:31 UTC
I believe https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=624208 is the same bug.