[PATCH] D34203: [LLD][LinkerScript] Add support for segment NONE.

Andrew Ng via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 16 09:36:37 PDT 2017


Yes, I have LLVM commit access, assuming LLD doesn't require anything extra.

Cheers,
Andrew

On 16 June 2017 at 17:04, Rafael Avila de Espindola <
rafael.espindola at gmail.com> wrote:

> Do you have commit access btw?
>
> Cheers,
> Rafael
>
> Rafael Avila de Espindola <rafael.espindola at gmail.com> writes:
>
> > LGTM.
> >
> > Thanks!
> >
> > Andrew Ng via Phabricator <reviews at reviews.llvm.org> writes:
> >
> >> andrewng created this revision.
> >> Herald added a subscriber: emaste.
> >>
> >> 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.
> >>
> >>
> >> https://reviews.llvm.org/D34203
> >>
> >> Files:
> >>   ELF/LinkerScript.cpp
> >>   test/ELF/linkerscript/segment-none.s
> >>
> >>
> >> Index: test/ELF/linkerscript/segment-none.s
> >> ===================================================================
> >> --- /dev/null
> >> +++ 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
> >> Index: ELF/LinkerScript.cpp
> >> ===================================================================
> >> --- ELF/LinkerScript.cpp
> >> +++ ELF/LinkerScript.cpp
> >> @@ -1200,27 +1200,37 @@
> >>
> >>  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) {
> >>      if (Cmd.Name == 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);
> >>
> >>
> >> Index: test/ELF/linkerscript/segment-none.s
> >> ===================================================================
> >> --- /dev/null
> >> +++ 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
> >> Index: ELF/LinkerScript.cpp
> >> ===================================================================
> >> --- ELF/LinkerScript.cpp
> >> +++ ELF/LinkerScript.cpp
> >> @@ -1200,27 +1200,37 @@
> >>
> >>  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) {
> >>      if (Cmd.Name == 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);
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170616/987494d2/attachment.html>


More information about the llvm-commits mailing list