<div dir="ltr"><div class="gmail_default" style="font-size:small">Yes, I have LLVM commit access, assuming LLD doesn't require anything extra.<br><br></div><div class="gmail_default" style="font-size:small">Cheers,<br></div><div class="gmail_default" style="font-size:small">Andrew<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 16 June 2017 at 17:04, Rafael Avila de Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Do you have commit access btw?<br>
<br>
Cheers,<br>
Rafael<br>
<div class="HOEnZb"><div class="h5"><br>
Rafael Avila de Espindola <<a href="mailto:rafael.espindola@gmail.com">rafael.espindola@gmail.com</a>> writes:<br>
<br>
> LGTM.<br>
><br>
> Thanks!<br>
><br>
> Andrew Ng via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> writes:<br>
><br>
>> andrewng created this revision.<br>
>> Herald added a subscriber: emaste.<br>
>><br>
>> This patch adds support for segment NONE in linker scripts which enables the<br>
>> specification that a section should not be assigned to any segment.<br>
>><br>
>> Note that GNU ld does not disallow the definition of a segment named NONE, which<br>
>> if defined, effectively overrides the behaviour described above. This feature<br>
>> has been copied.<br>
>><br>
>><br>
>> <a href="https://reviews.llvm.org/D34203" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D34203</a><br>
>><br>
>> Files:<br>
>> ELF/LinkerScript.cpp<br>
>> test/ELF/linkerscript/segment-<wbr>none.s<br>
>><br>
>><br>
>> Index: test/ELF/linkerscript/segment-<wbr>none.s<br>
>> ==============================<wbr>==============================<wbr>=======<br>
>> --- /dev/null<br>
>> +++ test/ELF/linkerscript/segment-<wbr>none.s<br>
>> @@ -0,0 +1,39 @@<br>
>> +# REQUIRES: x86<br>
>> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o<br>
>> +<br>
>> +## Test that section .foo is not placed in any segment when assigned to segment<br>
>> +## NONE in the linker script and segment NONE is not defined.<br>
>> +# RUN: echo "PHDRS {text PT_LOAD;} \<br>
>> +# RUN: SECTIONS { \<br>
>> +# RUN: .text : {*(.text .text*)} :text \<br>
>> +# RUN: .foo : {*(.foo)} :NONE \<br>
>> +# RUN: }" > %t.script<br>
>> +# RUN: ld.lld -o %t --script %t.script %t.o<br>
>> +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s<br>
>> +<br>
>> +## Test that section .foo is placed in segment NONE when assigned to segment<br>
>> +## NONE in the linker script and segment NONE is defined.<br>
>> +# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \<br>
>> +# RUN: SECTIONS { \<br>
>> +# RUN: .text : {*(.text .text*)} :text \<br>
>> +# RUN: .foo : {*(.foo)} :NONE \<br>
>> +# RUN: }" > %t.script<br>
>> +# RUN: ld.lld -o %t --script %t.script %t.o<br>
>> +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s<br>
>> +<br>
>> +# CHECK: Section to Segment mapping:<br>
>> +# CHECK-NEXT: Segment Sections...<br>
>> +# CHECK-NOT: .foo<br>
>> +<br>
>> +# DEFINED: Section to Segment mapping:<br>
>> +# DEFINED-NEXT: Segment Sections...<br>
>> +# DEFINED-NEXT: 00 .text<br>
>> +# DEFINED-NEXT: 01 .foo<br>
>> +<br>
>> +.global _start<br>
>> +_start:<br>
>> + nop<br>
>> +<br>
>> +.section .foo,"a"<br>
>> +foo:<br>
>> + .long 0<br>
>> Index: ELF/LinkerScript.cpp<br>
>> ==============================<wbr>==============================<wbr>=======<br>
>> --- ELF/LinkerScript.cpp<br>
>> +++ ELF/LinkerScript.cpp<br>
>> @@ -1200,27 +1200,37 @@<br>
>><br>
>> bool LinkerScript::isDefined(<wbr>StringRef S) { return findSymbol(S) != nullptr; }<br>
>><br>
>> +static const size_t NoPhdr = -1;<br>
>> +<br>
>> // Returns indices of ELF headers containing specific section. Each index is a<br>
>> // zero based number of ELF header listed within PHDRS {} script block.<br>
>> std::vector<size_t> LinkerScript::getPhdrIndices(<wbr>OutputSection *Sec) {<br>
>> if (OutputSectionCommand *Cmd = getCmd(Sec)) {<br>
>> std::vector<size_t> Ret;<br>
>> - for (StringRef PhdrName : Cmd->Phdrs)<br>
>> - Ret.push_back(getPhdrIndex(<wbr>Cmd->Location, PhdrName));<br>
>> + for (StringRef PhdrName : Cmd->Phdrs) {<br>
>> + size_t Index = getPhdrIndex(Cmd->Location, PhdrName);<br>
>> + if (Index != NoPhdr)<br>
>> + Ret.push_back(Index);<br>
>> + }<br>
>> return Ret;<br>
>> }<br>
>> return {};<br>
>> }<br>
>><br>
>> +// Returns the index of the segment named PhdrName if found otherwise<br>
>> +// NoPhdr. When not found, if PhdrName is not the special case value 'NONE'<br>
>> +// (which can be used to explicitly specify that a section isn't assigned to a<br>
>> +// segment) then error.<br>
>> size_t LinkerScript::getPhdrIndex(<wbr>const Twine &Loc, StringRef PhdrName) {<br>
>> size_t I = 0;<br>
>> for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {<br>
>> if (Cmd.Name == PhdrName)<br>
>> return I;<br>
>> ++I;<br>
>> }<br>
>> - error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");<br>
>> - return 0;<br>
>> + if (PhdrName != "NONE")<br>
>> + error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");<br>
>> + return NoPhdr;<br>
>> }<br>
>><br>
>> template void OutputSectionCommand::writeTo<<wbr>ELF32LE>(uint8_t *Buf);<br>
>><br>
>><br>
>> Index: test/ELF/linkerscript/segment-<wbr>none.s<br>
>> ==============================<wbr>==============================<wbr>=======<br>
>> --- /dev/null<br>
>> +++ test/ELF/linkerscript/segment-<wbr>none.s<br>
>> @@ -0,0 +1,39 @@<br>
>> +# REQUIRES: x86<br>
>> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o<br>
>> +<br>
>> +## Test that section .foo is not placed in any segment when assigned to segment<br>
>> +## NONE in the linker script and segment NONE is not defined.<br>
>> +# RUN: echo "PHDRS {text PT_LOAD;} \<br>
>> +# RUN: SECTIONS { \<br>
>> +# RUN: .text : {*(.text .text*)} :text \<br>
>> +# RUN: .foo : {*(.foo)} :NONE \<br>
>> +# RUN: }" > %t.script<br>
>> +# RUN: ld.lld -o %t --script %t.script %t.o<br>
>> +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s<br>
>> +<br>
>> +## Test that section .foo is placed in segment NONE when assigned to segment<br>
>> +## NONE in the linker script and segment NONE is defined.<br>
>> +# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \<br>
>> +# RUN: SECTIONS { \<br>
>> +# RUN: .text : {*(.text .text*)} :text \<br>
>> +# RUN: .foo : {*(.foo)} :NONE \<br>
>> +# RUN: }" > %t.script<br>
>> +# RUN: ld.lld -o %t --script %t.script %t.o<br>
>> +# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s<br>
>> +<br>
>> +# CHECK: Section to Segment mapping:<br>
>> +# CHECK-NEXT: Segment Sections...<br>
>> +# CHECK-NOT: .foo<br>
>> +<br>
>> +# DEFINED: Section to Segment mapping:<br>
>> +# DEFINED-NEXT: Segment Sections...<br>
>> +# DEFINED-NEXT: 00 .text<br>
>> +# DEFINED-NEXT: 01 .foo<br>
>> +<br>
>> +.global _start<br>
>> +_start:<br>
>> + nop<br>
>> +<br>
>> +.section .foo,"a"<br>
>> +foo:<br>
>> + .long 0<br>
>> Index: ELF/LinkerScript.cpp<br>
>> ==============================<wbr>==============================<wbr>=======<br>
>> --- ELF/LinkerScript.cpp<br>
>> +++ ELF/LinkerScript.cpp<br>
>> @@ -1200,27 +1200,37 @@<br>
>><br>
>> bool LinkerScript::isDefined(<wbr>StringRef S) { return findSymbol(S) != nullptr; }<br>
>><br>
>> +static const size_t NoPhdr = -1;<br>
>> +<br>
>> // Returns indices of ELF headers containing specific section. Each index is a<br>
>> // zero based number of ELF header listed within PHDRS {} script block.<br>
>> std::vector<size_t> LinkerScript::getPhdrIndices(<wbr>OutputSection *Sec) {<br>
>> if (OutputSectionCommand *Cmd = getCmd(Sec)) {<br>
>> std::vector<size_t> Ret;<br>
>> - for (StringRef PhdrName : Cmd->Phdrs)<br>
>> - Ret.push_back(getPhdrIndex(<wbr>Cmd->Location, PhdrName));<br>
>> + for (StringRef PhdrName : Cmd->Phdrs) {<br>
>> + size_t Index = getPhdrIndex(Cmd->Location, PhdrName);<br>
>> + if (Index != NoPhdr)<br>
>> + Ret.push_back(Index);<br>
>> + }<br>
>> return Ret;<br>
>> }<br>
>> return {};<br>
>> }<br>
>><br>
>> +// Returns the index of the segment named PhdrName if found otherwise<br>
>> +// NoPhdr. When not found, if PhdrName is not the special case value 'NONE'<br>
>> +// (which can be used to explicitly specify that a section isn't assigned to a<br>
>> +// segment) then error.<br>
>> size_t LinkerScript::getPhdrIndex(<wbr>const Twine &Loc, StringRef PhdrName) {<br>
>> size_t I = 0;<br>
>> for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {<br>
>> if (Cmd.Name == PhdrName)<br>
>> return I;<br>
>> ++I;<br>
>> }<br>
>> - error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");<br>
>> - return 0;<br>
>> + if (PhdrName != "NONE")<br>
>> + error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");<br>
>> + return NoPhdr;<br>
>> }<br>
>><br>
>> template void OutputSectionCommand::writeTo<<wbr>ELF32LE>(uint8_t *Buf);<br>
</div></div></blockquote></div><br></div>