[lld] r248604 - Add support for creating the symbols __init_array_start and __init_array_end.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 25 12:04:52 PDT 2015
On Fri, Sep 25, 2015 at 11:56 AM, Rafael Espindola via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: rafael
> Date: Fri Sep 25 13:56:53 2015
> New Revision: 248604
>
> URL: http://llvm.org/viewvc/llvm-project?rev=248604&view=rev
> Log:
> Add support for creating the symbols __init_array_start and
> __init_array_end.
>
> Added:
> lld/trunk/test/elf2/init_array.s
> Modified:
> lld/trunk/ELF/OutputSections.cpp
> lld/trunk/ELF/OutputSections.h
> lld/trunk/ELF/SymbolTable.cpp
> lld/trunk/ELF/SymbolTable.h
> lld/trunk/ELF/Symbols.h
> lld/trunk/ELF/Writer.cpp
>
> Modified: lld/trunk/ELF/OutputSections.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=248604&r1=248603&r2=248604&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.cpp (original)
> +++ lld/trunk/ELF/OutputSections.cpp Fri Sep 25 13:56:53 2015
> @@ -295,6 +295,8 @@ typename ELFFile<ELFT>::uintX_t
> lld::elf2::getSymVA(const ELFSymbolBody<ELFT> &S,
> const OutputSection<ELFT> &BssSec) {
> switch (S.kind()) {
> + case SymbolBody::DefinedSyntheticKind:
> + return cast<DefinedSynthetic<ELFT>>(S).Section.getVA() +
> S.Sym.st_value;
> case SymbolBody::DefinedAbsoluteKind:
> return S.Sym.st_value;
> case SymbolBody::DefinedRegularKind: {
> @@ -434,6 +436,9 @@ template <class ELFT> void SymbolTableSe
> const InputSection<ELFT> *Section = nullptr;
>
> switch (EBody.kind()) {
> + case SymbolBody::DefinedSyntheticKind:
> + Out = &cast<DefinedSynthetic<ELFT>>(Body)->Section;
> + break;
> case SymbolBody::DefinedRegularKind:
> Section = &cast<DefinedRegular<ELFT>>(EBody).Section;
> break;
>
> Modified: lld/trunk/ELF/OutputSections.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=248604&r1=248603&r2=248604&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/OutputSections.h (original)
> +++ lld/trunk/ELF/OutputSections.h Fri Sep 25 13:56:53 2015
> @@ -165,7 +165,7 @@ public:
>
> void writeTo(uint8_t *Buf) override;
>
> - const SymbolTable &getSymTable() const { return Table; }
> + SymbolTable &getSymTable() const { return Table; }
>
> void addSymbol(StringRef Name, bool isLocal = false) {
> StrTabSec.add(Name);
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=248604&r1=248603&r2=248604&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Fri Sep 25 13:56:53 2015
> @@ -55,6 +55,17 @@ static TargetInfo *createTarget(uint16_t
> error("Unknown target machine");
> }
>
> +template <class ELFT>
> +void SymbolTable::addSyntheticSym(StringRef Name, OutputSection<ELFT>
> &Section,
> + typename ELFFile<ELFT>::uintX_t Value) {
> + typedef typename DefinedSynthetic<ELFT>::Elf_Sym Elf_Sym;
> + auto ESym = new (Alloc) Elf_Sym;
> + memset(ESym, 0, sizeof(Elf_Sym));
> + ESym->st_value = Value;
> + auto Sym = new (Alloc) DefinedSynthetic<ELFT>(Name, *ESym, Section);
> + resolve<ELFT>(Sym);
> +}
> +
> template <class ELFT> void SymbolTable::init(uint16_t EMachine) {
> Target.reset(createTarget(EMachine));
> if (Config->Shared)
> @@ -205,3 +216,20 @@ void SymbolTable::addMemberFile(Lazy *Bo
>
> addFile(std::move(File));
> }
> +
> +namespace lld {
> +namespace elf2 {
> +template void SymbolTable::addSyntheticSym(StringRef Name,
> + OutputSection<ELF32LE>
> &Section,
> + ELFFile<ELF32LE>::uintX_t
> Value);
> +template void SymbolTable::addSyntheticSym(StringRef Name,
> + OutputSection<ELF32BE>
> &Section,
> + ELFFile<ELF32BE>::uintX_t
> Value);
> +template void SymbolTable::addSyntheticSym(StringRef Name,
> + OutputSection<ELF64LE>
> &Section,
> + ELFFile<ELF64LE>::uintX_t
> Value);
> +template void SymbolTable::addSyntheticSym(StringRef Name,
> + OutputSection<ELF64BE>
> &Section,
> + ELFFile<ELF64BE>::uintX_t
> Value);
> +}
> +}
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=248604&r1=248603&r2=248604&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Fri Sep 25 13:56:53 2015
> @@ -61,6 +61,10 @@ public:
> return EntrySym->getReplacement();
> }
>
> + template <class ELFT>
> + void addSyntheticSym(StringRef Name, OutputSection<ELFT> &Section,
> + typename llvm::object::ELFFile<ELFT>::uintX_t
> Value);
> +
> private:
> Symbol *insert(SymbolBody *New);
> template <class ELFT> void addELFFile(ELFFileBase *File);
>
> Modified: lld/trunk/ELF/Symbols.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=248604&r1=248603&r2=248604&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Symbols.h (original)
> +++ lld/trunk/ELF/Symbols.h Fri Sep 25 13:56:53 2015
> @@ -41,10 +41,11 @@ public:
> DefinedRegularKind = 0,
> DefinedAbsoluteKind = 1,
> DefinedCommonKind = 2,
> - SharedKind = 3,
> - DefinedLast = 3,
> - UndefinedKind = 4,
> - LazyKind = 5,
> + DefinedSyntheticKind = 3,
> + SharedKind = 4,
> + DefinedLast = 4,
>
Can you write DefinedLast = SharedKind and remove all explicit integers so
that we don't have to update all the values when we add a new one?
> + UndefinedKind = 5,
> + LazyKind = 6,
> };
>
> Kind kind() const { return static_cast<Kind>(SymbolKind); }
> @@ -213,6 +214,22 @@ public:
> const InputSection<ELFT> &Section;
> };
>
> +template <class ELFT> class DefinedSynthetic : public Defined<ELFT> {
> + typedef Defined<ELFT> Base;
> +
> +public:
> + typedef typename Base::Elf_Sym Elf_Sym;
> + explicit DefinedSynthetic(StringRef N, const Elf_Sym &Sym,
> + OutputSection<ELFT> &Section)
> + : Defined<ELFT>(Base::DefinedSyntheticKind, N, Sym),
> Section(Section) {}
> +
> + static bool classof(const SymbolBody *S) {
> + return S->kind() == Base::DefinedSyntheticKind;
> + }
> +
> + const OutputSection<ELFT> &Section;
> +};
> +
> // Undefined symbol.
> template <class ELFT> class Undefined : public ELFSymbolBody<ELFT> {
> typedef ELFSymbolBody<ELFT> Base;
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=248604&r1=248603&r2=248604&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Fri Sep 25 13:56:53 2015
> @@ -295,7 +295,7 @@ template <class ELFT> void Writer<ELFT>:
> OutputSections.push_back(&BssSec);
> Map[{BssSec.getName(), BssSec.getType(), BssSec.getFlags()}] = &BssSec;
>
> - const SymbolTable &Symtab = SymTabSec.getSymTable();
> + SymbolTable &Symtab = SymTabSec.getSymTable();
> for (const std::unique_ptr<ObjectFileBase> &FileB :
> Symtab.getObjectFiles()) {
> auto &File = cast<ObjectFile<ELFT>>(*FileB);
> if (!Config->DiscardAll) {
> @@ -323,6 +323,12 @@ template <class ELFT> void Writer<ELFT>:
> }
> }
>
> + if (OutputSection<ELFT> *OS =
> + Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE |
> SHF_ALLOC})) {
> + Symtab.addSyntheticSym<ELFT>("__init_array_start", *OS, 0);
> + Symtab.addSyntheticSym<ELFT>("__init_array_end", *OS, OS->getSize());
> + }
> +
> // FIXME: Try to avoid the extra walk over all global symbols.
> std::vector<DefinedCommon<ELFT> *> CommonSymbols;
> for (auto &P : Symtab.getSymbols()) {
>
> Added: lld/trunk/test/elf2/init_array.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/init_array.s?rev=248604&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf2/init_array.s (added)
> +++ lld/trunk/test/elf2/init_array.s Fri Sep 25 13:56:53 2015
> @@ -0,0 +1,49 @@
> +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +// RUN: lld -flavor gnu2 %t -o %t2
> +// RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s
> +// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
> +// REQUIRES: x86
> +
> +.globl _start
> +_start:
> + call __init_array_start
> + call __init_array_end
> +
> +
> +.section .init_array,"aw", at init_array
> + .quad 0
> +
> +
> +// CHECK: Name: .init_array
> +// CHECK-NEXT: Type: SHT_INIT_ARRAY
> +// CHECK-NEXT: Flags [
> +// CHECK-NEXT: SHF_ALLOC
> +// CHECK-NEXT: SHF_WRITE
> +// CHECK-NEXT: ]
> +// CHECK-NEXT: Address: 0x12000
> +// CHECK-NEXT: Offset:
> +// CHECK-NEXT: Size: 8
> +
> +// CHECK: Name: __init_array_end
> +// CHECK-NEXT: Value: 0x12008
> +// CHECK-NEXT: Size: 0
> +// CHECK-NEXT: Binding: Local
> +// CHECK-NEXT: Type: None
> +// CHECK-NEXT: Other: 0
> +// CHECK-NEXT: Section: .init_array
> +// CHECK-NEXT: }
> +// CHECK-NEXT: Symbol {
> +// CHECK-NEXT: Name: __init_array_start
> +// CHECK-NEXT: Value: 0x12000
> +// CHECK-NEXT: Size: 0
> +// CHECK-NEXT: Binding: Local
> +// CHECK-NEXT: Type: None
> +// CHECK-NEXT: Other: 0
> +// CHECK-NEXT: Section: .init_array
> +// CHECK-NEXT: }
> +
> +// 0x12000 - (0x11000 + 5) = 4091
> +// 0x12008 - (0x11005 + 5) = 4094
> +// DISASM: _start:
> +// DISASM-NEXT: 11000: e8 fb 0f 00 00 callq 4091
> +// DISASM-NEXT: 11005: e8 fe 0f 00 00 callq 4094
>
>
> _______________________________________________
> 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/20150925/9ed8896e/attachment.html>
More information about the llvm-commits
mailing list