diff options
author | Andrew Ng <anng.sw@gmail.com> | 2017-06-19 15:28:58 +0000 |
---|---|---|
committer | Andrew Ng <anng.sw@gmail.com> | 2017-06-19 15:28:58 +0000 |
commit | 6e9f98c19821549f56cd37823723e546d3e70d4a (patch) | |
tree | 0ad56e7fa0f7139e2f1cdd2268947bd52e2cd0d8 | |
parent | 7949f4529acead11a7658223bfa555591d976174 (diff) | |
download | bcm5719-llvm-6e9f98c19821549f56cd37823723e546d3e70d4a.tar.gz bcm5719-llvm-6e9f98c19821549f56cd37823723e546d3e70d4a.zip |
[LLD][LinkerScript] Add support for segment NONE.
This patch adds support for segment NONE in linker scripts which enables the
specification that a section should not be assigned to any segment.
Note that GNU ld does not disallow the definition of a segment named NONE, which
if defined, effectively overrides the behaviour described above. This feature
has been copied.
Differential Revision: https://reviews.llvm.org/D34203
llvm-svn: 305700
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 18 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/segment-none.s | 39 |
2 files changed, 53 insertions, 4 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 8c20bf60432..327a962384a 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -1111,18 +1111,27 @@ ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) { bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; } +static const size_t NoPhdr = -1; + // Returns indices of ELF headers containing specific section. Each index is a // zero based number of ELF header listed within PHDRS {} script block. std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *Sec) { if (OutputSectionCommand *Cmd = getCmd(Sec)) { std::vector<size_t> Ret; - for (StringRef PhdrName : Cmd->Phdrs) - Ret.push_back(getPhdrIndex(Cmd->Location, PhdrName)); + for (StringRef PhdrName : Cmd->Phdrs) { + size_t Index = getPhdrIndex(Cmd->Location, PhdrName); + if (Index != NoPhdr) + Ret.push_back(Index); + } return Ret; } return {}; } +// Returns the index of the segment named PhdrName if found otherwise +// NoPhdr. When not found, if PhdrName is not the special case value 'NONE' +// (which can be used to explicitly specify that a section isn't assigned to a +// segment) then error. size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) { size_t I = 0; for (PhdrsCommand &Cmd : Opt.PhdrsCommands) { @@ -1130,8 +1139,9 @@ size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) { return I; ++I; } - error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS"); - return 0; + if (PhdrName != "NONE") + error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS"); + return NoPhdr; } template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf); diff --git a/lld/test/ELF/linkerscript/segment-none.s b/lld/test/ELF/linkerscript/segment-none.s new file mode 100644 index 00000000000..d54e835a0c2 --- /dev/null +++ b/lld/test/ELF/linkerscript/segment-none.s @@ -0,0 +1,39 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o + +## Test that section .foo is not placed in any segment when assigned to segment +## NONE in the linker script and segment NONE is not defined. +# RUN: echo "PHDRS {text PT_LOAD;} \ +# RUN: SECTIONS { \ +# RUN: .text : {*(.text .text*)} :text \ +# RUN: .foo : {*(.foo)} :NONE \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s + +## Test that section .foo is placed in segment NONE when assigned to segment +## NONE in the linker script and segment NONE is defined. +# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \ +# RUN: SECTIONS { \ +# RUN: .text : {*(.text .text*)} :text \ +# RUN: .foo : {*(.foo)} :NONE \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s + +# CHECK: Section to Segment mapping: +# CHECK-NEXT: Segment Sections... +# CHECK-NOT: .foo + +# DEFINED: Section to Segment mapping: +# DEFINED-NEXT: Segment Sections... +# DEFINED-NEXT: 00 .text +# DEFINED-NEXT: 01 .foo + +.global _start +_start: + nop + +.section .foo,"a" +foo: + .long 0 |