[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