diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -108,12 +108,21 @@ } } - // This check is for -z keep-text-section-prefix. This option separates text - // sections with prefix ".text.hot", ".text.unlikely", ".text.startup" or - // ".text.exit". - // When enabled, this allows identifying the hot code region (.text.hot) in - // the final binary which can be selectively mapped to huge pages or mlocked, - // for instance. + // A BssSection created for a common symbol is identified as "COMMON" in + // linker scripts. It should go to .bss section. + if (s->name == "COMMON") + return ".bss"; + + if (script->hasSectionsCommand) + return s->name; + + // When no SECTIONS is specified, emulate GNU ld's internal linker scripts + // by grouping sections with certain prefixes. + + // GNU ld places text sections with prefix ".text.hot.", ".text.unlikely.", + // ".text.startup." or ".text.exit." before others. We provide an option -z + // keep-text-section-prefix to group such sections into separate output + // sections. This is more flexible. See also sortISDBySectionOrder(). if (config->zKeepTextSectionPrefix) for (StringRef v : {".text.hot.", ".text.unlikely.", ".text.startup.", ".text.exit."}) @@ -127,11 +136,6 @@ if (isSectionPrefix(v, s->name)) return v.drop_back(); - // CommonSection is identified as "COMMON" in linker scripts. - // By default, it should go to .bss section. - if (s->name == "COMMON") - return ".bss"; - return s->name; } diff --git a/lld/test/ELF/linkerscript/data-commands-gc.s b/lld/test/ELF/linkerscript/data-commands-gc.s --- a/lld/test/ELF/linkerscript/data-commands-gc.s +++ b/lld/test/ELF/linkerscript/data-commands-gc.s @@ -4,7 +4,7 @@ # RUN: ld.lld --gc-sections -o %t %t.o --script %t.script # RUN: llvm-objdump -t %t | FileCheck %s -# CHECK: 0000000000000008 g .rodata 0000000000000000 bar +# CHECK: 0000000000000008 g .rodata.bar 0000000000000000 bar .section .rodata.bar .quad 0x1122334455667788 diff --git a/lld/test/ELF/linkerscript/icf-output-sections.s b/lld/test/ELF/linkerscript/icf-output-sections.s --- a/lld/test/ELF/linkerscript/icf-output-sections.s +++ b/lld/test/ELF/linkerscript/icf-output-sections.s @@ -28,13 +28,19 @@ # SEC2: .text.foo PROGBITS 0000000000000000 001000 000001 # SEC2-NEXT: .text.bar PROGBITS 0000000000000001 001001 000001 -## .text.bar* are orphans that get assigned to .text. +## .text.bar* are orphan sections. # RUN: echo 'SECTIONS { .text.foo : {*(.text.foo*)} }' > %t3.script -# RUN: ld.lld %t.o --script %t3.script --icf=all --print-icf-sections -o %t | FileCheck --check-prefix=ICF2 %s -# RUN: llvm-readelf -S %t | FileCheck --check-prefix=SEC3 %s +# RUN: ld.lld %t.o -T %t3.script --icf=all --print-icf-sections -o %t3 | FileCheck --check-prefix=ICF3 %s +# RUN: llvm-readelf -S %t3 | FileCheck --check-prefix=SEC3 %s +# ICF3: selected section {{.*}}.o:(.text.foo0) +# ICF3-NEXT: removing identical section {{.*}}.o:(.text.foo1) + +# SEC3: Name Type Address Off Size # SEC3: .text.foo PROGBITS 0000000000000000 001000 000001 -# SEC3-NEXT: .text PROGBITS 0000000000000004 001004 000001 +# SEC3-NEXT: .text PROGBITS 0000000000000004 001004 000000 +# SEC3-NEXT: .text.bar0 PROGBITS 0000000000000004 001004 000001 +# SEC3-NEXT: .text.bar1 PROGBITS 0000000000000005 001005 000001 .section .text.foo0,"ax" ret diff --git a/lld/test/ELF/linkerscript/linkorder.s b/lld/test/ELF/linkerscript/linkorder.s --- a/lld/test/ELF/linkerscript/linkorder.s +++ b/lld/test/ELF/linkerscript/linkorder.s @@ -1,11 +1,11 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .text : { *(.text.bar) *(.text.foo) } }" > %t.script +# RUN: echo "SECTIONS { .rodata : {*(.rodata*)} .text : {*(.text.bar) *(.text.foo)} }" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o # RUN: llvm-objdump -s %t | FileCheck %s -# RUN: echo "SECTIONS { .text : { *(.text.foo) *(.text.bar) } }" > %t.script +# RUN: echo "SECTIONS { .rodata : {*(.rodata*)} .text : {*(.text.foo) *(.text.bar)} }" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o # RUN: llvm-objdump -s %t | FileCheck --check-prefix=INV %s diff --git a/lld/test/ELF/linkerscript/linkorder2.s b/lld/test/ELF/linkerscript/linkorder2.s --- a/lld/test/ELF/linkerscript/linkorder2.s +++ b/lld/test/ELF/linkerscript/linkorder2.s @@ -1,6 +1,6 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o -# RUN: echo "SECTIONS { .text : { *(.text.*) } }" > %t.script +# RUN: echo 'SECTIONS { .rodata : {*(.rodata.*)} .text : {*(.text.*)} }' > %t.script # RUN: echo "_bar" > %t.ord # RUN: echo "_foo" >> %t.ord diff --git a/lld/test/ELF/linkerscript/memory3.s b/lld/test/ELF/linkerscript/memory3.s --- a/lld/test/ELF/linkerscript/memory3.s +++ b/lld/test/ELF/linkerscript/memory3.s @@ -18,6 +18,6 @@ # CHECK: 0 00000000 0000000000000000 # CHECK: 1 .text 00000001 0000000000001000 -.section .text.foo,"ax",%progbits +.section .text,"ax",%progbits foo: nop diff --git a/lld/test/ELF/linkerscript/orphan-report.s b/lld/test/ELF/linkerscript/orphan-report.s --- a/lld/test/ELF/linkerscript/orphan-report.s +++ b/lld/test/ELF/linkerscript/orphan-report.s @@ -24,7 +24,7 @@ # RUN: %t.o 2>&1 | FileCheck %s --check-prefixes=COMMON,DYNSYM,SYMTAB # COMMON: {{.*}}.o:(.text) is being placed in '.text' -# COMMON-NEXT: {{.*}}.o:(.text.2) is being placed in '.text' +# COMMON-NEXT: {{.*}}.o:(.text.2) is being placed in '.text.2' # COMMON-NEXT: :(.comment) is being placed in '.comment' # DYNSYM-NEXT: :(.dynsym) is being placed in '.dynsym' # DYNSYM-NEXT: :(.gnu.hash) is being placed in '.gnu.hash' diff --git a/lld/test/ELF/linkerscript/symbol-assign-many-passes2.test b/lld/test/ELF/linkerscript/symbol-assign-many-passes2.test --- a/lld/test/ELF/linkerscript/symbol-assign-many-passes2.test +++ b/lld/test/ELF/linkerscript/symbol-assign-many-passes2.test @@ -22,7 +22,7 @@ b = c + 1; c = d + 1; d = e + 1; - *(.text); + *(.text*); } e = .; } diff --git a/lld/test/ELF/mips-npic-call-pic-script.s b/lld/test/ELF/mips-npic-call-pic-script.s --- a/lld/test/ELF/mips-npic-call-pic-script.s +++ b/lld/test/ELF/mips-npic-call-pic-script.s @@ -87,13 +87,13 @@ # ORPH1: Disassembly of section .text: # ORPH1-EMPTY: # ORPH1-NEXT: <__start>: -# ORPH1-NEXT: 20000: jal 131156 <__LA25Thunk_foo1a> +# ORPH1-NEXT: 20000: jal 131168 <__LA25Thunk_foo1a> # ORPH1-NEXT: 20004: nop -# ORPH1-NEXT: 20008: jal 131208 <__LA25Thunk_foo2> +# ORPH1-NEXT: 20008: jal 131216 <__LA25Thunk_foo2> # ORPH1-NEXT: 2000c: nop -# ORPH1-NEXT: 20010: jal 131172 <__LA25Thunk_foo1b> +# ORPH1-NEXT: 20010: jal 131184 <__LA25Thunk_foo1b> # ORPH1-NEXT: 20014: nop -# ORPH1-NEXT: 20018: jal 131208 <__LA25Thunk_foo2> +# ORPH1-NEXT: 20018: jal 131216 <__LA25Thunk_foo2> # ORPH1-NEXT: 2001c: nop # ORPH1-NEXT: 20020: jal 131120 <__LA25Thunk_fpic> # ORPH1-NEXT: 20024: nop @@ -113,16 +113,16 @@ # ORPH1-NEXT: 20050: nop # ORPH1: <__LA25Thunk_foo1a>: -# ORPH1-NEXT: 20054: lui $25, 2 -# ORPH1-NEXT: 20058: j 131200 -# ORPH1-NEXT: 2005c: addiu $25, $25, 128 -# ORPH1-NEXT: 20060: nop +# ORPH1-NEXT: 20060: lui $25, 2 +# ORPH1-NEXT: j 131200 +# ORPH1-NEXT: addiu $25, $25, 128 +# ORPH1-NEXT: nop # ORPH1: <__LA25Thunk_foo1b>: -# ORPH1-NEXT: 20064: lui $25, 2 -# ORPH1-NEXT: 20068: j 131204 -# ORPH1-NEXT: 2006c: addiu $25, $25, 132 -# ORPH1-NEXT: 20070: nop +# ORPH1-NEXT: 20070: lui $25, 2 +# ORPH1-NEXT: j 131204 +# ORPH1-NEXT: addiu $25, $25, 132 +# ORPH1-NEXT: nop # ORPH1: : # ORPH1-NEXT: 20080: nop @@ -131,17 +131,17 @@ # ORPH1-NEXT: 20084: nop # ORPH1: <__LA25Thunk_foo2>: -# ORPH1-NEXT: 20088: lui $25, 2 -# ORPH1-NEXT: 2008c: j 131232 -# ORPH1-NEXT: 20090: addiu $25, $25, 160 -# ORPH1-NEXT: 20094: nop +# ORPH1-NEXT: 20090: lui $25, 2 +# ORPH1-NEXT: j 131232 +# ORPH1-NEXT: addiu $25, $25, 160 +# ORPH1-NEXT: nop # ORPH1: : # ORPH1-NEXT: 200a0: nop # Test script with orphans added to new OutputSection, the .text.1 and # .text.2 sections will form a new OutputSection .text -# RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } }" > %t3.script +# RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } .text : {*(.text*)} }" > %t3.script # RUN: ld.lld --script %t3.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t3.exe # RUN: llvm-objdump -d --no-show-raw-insn %t3.exe | FileCheck --check-prefix=ORPH2 %s diff --git a/lld/test/ELF/shuffle-sections-init-fini.s b/lld/test/ELF/shuffle-sections-init-fini.s --- a/lld/test/ELF/shuffle-sections-init-fini.s +++ b/lld/test/ELF/shuffle-sections-init-fini.s @@ -30,7 +30,9 @@ ## With a SECTIONS command, SHT_INIT_ARRAY prirotities are ignored. ## All .init_array* are shuffled together. -# RUN: echo 'SECTIONS {}' > %t.script +# RUN: echo 'SECTIONS { \ +# RUN: .init_array : { *(.init_array*) } \ +# RUN: .fini_array : { *(.fini_array*) }}' > %t.script # RUN: ld.lld -T %t.script %t.o -o %t2 # RUN: llvm-readelf -x .init -x .fini -x .init_array -x .fini_array %t2 | \ # RUN: FileCheck --check-prefixes=CHECK2,ORDERED2 %s diff --git a/lld/test/ELF/text-section-prefix.s b/lld/test/ELF/text-section-prefix.s --- a/lld/test/ELF/text-section-prefix.s +++ b/lld/test/ELF/text-section-prefix.s @@ -1,4 +1,7 @@ # REQUIRES: x86 +## -z keep-text-section-prefix separates text sections with prefix .text.hot, +## .text.unlikely, .text.startup, or .text.exit, in the absence of a SECTIONS command. + # RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o # RUN: ld.lld %t.o -o %t1 # RUN: llvm-readelf -S %t1 | FileCheck --check-prefix=NOKEEP %s @@ -17,9 +20,18 @@ # NOKEEP: [ 1] .text # NOKEEP-NOT: .text +## With a SECTIONS command, orphan sections are created verbatim. +## No grouping is performed for them. # RUN: echo 'SECTIONS {}' > %t.lds # RUN: ld.lld -T %t.lds -z keep-text-section-prefix %t.o -o %t.script -# RUN: llvm-readelf -S %t.script | FileCheck --check-prefix=KEEP %s +# RUN: llvm-readelf -S %t.script | FileCheck --check-prefix=SCRIPT %s + +# SCRIPT: .text +# SCRIPT-NEXT: .text.f +# SCRIPT-NEXT: .text.hot.f_hot +# SCRIPT-NEXT: .text.startup.f_startup +# SCRIPT-NEXT: .text.exit.f_exit +# SCRIPT-NEXT: .text.unlikely.f_unlikely .globl _start _start: