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

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 16 16:06:24 PDT 2015


Will do next time.

On Fri, Oct 16, 2015 at 4:05 PM, Sean Silva <chisophugis at gmail.com> wrote:

> 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/53a221b1/attachment.html>


More information about the llvm-commits mailing list