[lld] r250432 - ELF2: Implement __start_SECNAME and __stop_SECNAME.

Sean Silva via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 16 16:05:08 PDT 2015


Thanks!

btw, in the future it would be nice to mention the PR (PR25188) in the
commit message.

-- Sean Silva

On Thu, Oct 15, 2015 at 10:11 AM, Rui Ueyama via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: ruiu
> Date: Thu Oct 15 12:11:03 2015
> New Revision: 250432
>
> URL: http://llvm.org/viewvc/llvm-project?rev=250432&view=rev
> Log:
> ELF2: Implement __start_SECNAME and __stop_SECNAME.
>
> If a section name is valid as a C identifier (which is rare because of
> the leading '.'), linkers are expected to define __start_<secname> and
> __stop_<secname> symbols. They are at beginning and end of the section,
> respectively. This is not requested by the ELF standard, but GNU ld and
> gold provide this feature.
>
> Added:
>     lld/trunk/test/elf2/startstop.s
> Modified:
>     lld/trunk/ELF/SymbolTable.cpp
>     lld/trunk/ELF/SymbolTable.h
>     lld/trunk/ELF/Writer.cpp
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=250432&r1=250431&r2=250432&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Thu Oct 15 12:11:03 2015
> @@ -88,6 +88,12 @@ template <class ELFT> void SymbolTable<E
>    resolve(Sym);
>  }
>
> +template <class ELFT> bool SymbolTable<ELFT>::isUndefined(StringRef Name)
> {
> +  if (SymbolBody *Sym = find(Name))
> +    return Sym->isUndefined();
> +  return false;
> +}
> +
>  template <class ELFT>
>  void SymbolTable<ELFT>::addELFFile(ELFFileBase<ELFT> *File) {
>    if (auto *O = dyn_cast<ObjectFile<ELFT>>(File))
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=250432&r1=250431&r2=250432&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Thu Oct 15 12:11:03 2015
> @@ -54,6 +54,7 @@ public:
>                         OutputSectionBase<ELFT::Is64Bits> &Section,
>                         typename llvm::object::ELFFile<ELFT>::uintX_t
> Value);
>    void addIgnoredSym(StringRef Name);
> +  bool isUndefined(StringRef Name);
>    void scanShlibUndefined();
>
>  private:
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=250432&r1=250431&r2=250432&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Thu Oct 15 12:11:03 2015
> @@ -16,6 +16,7 @@
>  #include "llvm/ADT/SmallPtrSet.h"
>  #include "llvm/ADT/StringSwitch.h"
>  #include "llvm/Support/FileOutputBuffer.h"
> +#include "llvm/Support/StringSaver.h"
>
>  using namespace llvm;
>  using namespace llvm::ELF;
> @@ -70,9 +71,11 @@ private:
>    std::unique_ptr<llvm::FileOutputBuffer> Buffer;
>
>    SpecificBumpPtrAllocator<OutputSection<ELFT>> SecAlloc;
> +  BumpPtrAllocator Alloc;
>    std::vector<OutputSectionBase<ELFT::Is64Bits> *> OutputSections;
>    unsigned getNumSections() const { return OutputSections.size() + 1; }
>
> +  void addStartStopSymbols(OutputSection<ELFT> *Sec);
>    void setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags, uintX_t
> FileOff,
>                 uintX_t VA, uintX_t Align);
>    void copyPhdr(Elf_Phdr *PH, OutputSectionBase<ELFT::Is64Bits> *From);
> @@ -400,6 +403,8 @@ template <class ELFT> void Writer<ELFT>:
>    if (!isOutputDynamic())
>      Symtab.addIgnoredSym("__tls_get_addr");
>
> +  std::vector<OutputSection<ELFT> *> RegularSections;
> +
>    for (const std::unique_ptr<ObjectFile<ELFT>> &F :
> Symtab.getObjectFiles()) {
>      for (InputSection<ELFT> *C : F->getSections()) {
>        if (!C || C == &InputSection<ELFT>::Discarded)
> @@ -413,12 +418,16 @@ template <class ELFT> void Writer<ELFT>:
>          Sec = new (SecAlloc.Allocate())
>              OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
>          OutputSections.push_back(Sec);
> +        RegularSections.push_back(Sec);
>        }
>        Sec->addSection(C);
>        scanRelocs(*C);
>      }
>    }
>
> +  for (OutputSection<ELFT> *Sec : RegularSections)
> +    addStartStopSymbols(Sec);
> +
>    Out<ELFT>::Dynamic->PreInitArraySec =
>        Map.lookup({".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE |
> SHF_ALLOC});
>    Out<ELFT>::Dynamic->InitArraySec =
> @@ -501,6 +510,38 @@ template <class ELFT> void Writer<ELFT>:
>    Out<ELFT>::Opd = Map.lookup({".opd", SHT_PROGBITS, SHF_WRITE |
> SHF_ALLOC});
>  }
>
> +static bool isAlpha(char C) {
> +  return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';
> +}
> +
> +static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <=
> '9'); }
> +
> +// Returns true if S is valid as a C language identifier.
> +static bool isValidCIdentifier(StringRef S) {
> +  if (S.empty() || !isAlpha(S[0]))
> +    return false;
> +  return std::all_of(S.begin() + 1, S.end(), isAlnum);
> +}
> +
> +// If a section name is valid as a C identifier (which is rare because of
> +// the leading '.'), linkers are expected to define __start_<secname> and
> +// __stop_<secname> symbols. They are at beginning and end of the section,
> +// respectively. This is not requested by the ELF standard, but GNU ld and
> +// gold provide the feature, and used by many programs.
> +template <class ELFT>
> +void Writer<ELFT>::addStartStopSymbols(OutputSection<ELFT> *Sec) {
> +  StringRef S = Sec->getName();
> +  if (!isValidCIdentifier(S))
> +    return;
> +  StringSaver Saver(Alloc);
> +  StringRef Start = Saver.save("__start_" + S);
> +  StringRef Stop = Saver.save("__stop_" + S);
> +  if (Symtab.isUndefined(Start))
> +    Symtab.addSyntheticSym(Start, *Sec, 0);
> +  if (Symtab.isUndefined(Stop))
> +    Symtab.addSyntheticSym(Stop, *Sec, Sec->getSize());
> +}
> +
>  template <class ELFT>
>  static bool needsPhdr(OutputSectionBase<ELFT::Is64Bits> *Sec) {
>    return Sec->getFlags() & SHF_ALLOC;
>
> Added: lld/trunk/test/elf2/startstop.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/startstop.s?rev=250432&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf2/startstop.s (added)
> +++ lld/trunk/test/elf2/startstop.s Thu Oct 15 12:11:03 2015
> @@ -0,0 +1,54 @@
> +// REQUIRES: x86
> +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +// RUN: ld.lld2 %t -o %tout
> +// RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
> +// RUN: llvm-readobj -symbols %tout | FileCheck -check-prefix=SYMBOL %s
> +
> +// DISASM: _start:
> +// DISASM:    11000:       e8 0a 00 00 00  callq   10
> +// DISASM:    11005:       e8 08 00 00 00  callq   8
> +// DISASM:    1100a:       e8 03 00 00 00  callq   3
> +// DISASM: Disassembly of section foo:
> +// DISASM: __start_foo:
> +// DISASM:    1100f:       90      nop
> +// DISASM:    11010:       90      nop
> +// DISASM:    11011:       90      nop
> +// DISASM: Disassembly of section bar:
> +// DISASM: __start_bar:
> +// DISASM:    11012:       90      nop
> +// DISASM:    11013:       90      nop
> +// DISASM:    11014:       90      nop
> +
> +// SYMBOL: Symbol {
> +// SYMBOL:   Name: __start_bar
> +// SYMBOL:   Value: 0x11012
> +// SYMBOL:   Section: bar
> +// SYMBOL: }
> +// SYMBOL-NOT:   Section: __stop_bar
> +// SYMBOL: Symbol {
> +// SYMBOL:   Name: __start_foo
> +// SYMBOL:   Value: 0x1100F
> +// SYMBOL:   Section: foo
> +// SYMBOL: }
> +// SYMBOL: Symbol {
> +// SYMBOL:   Name: __stop_foo
> +// SYMBOL:   Value: 0x11012
> +// SYMBOL:   Section: foo (0x2)
> +// SYMBOL: }
> +
> +.global _start
> +.text
> +_start:
> +       call __start_foo
> +       call __stop_foo
> +       call __start_bar
> +
> +.section foo,"ax"
> +       nop
> +       nop
> +       nop
> +
> +.section bar,"ax"
> +       nop
> +       nop
> +       nop
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151016/701b78df/attachment-0001.html>


More information about the llvm-commits mailing list