[lld] r248604 - Add support for creating the symbols __init_array_start and __init_array_end.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 25 11:56:54 PDT 2015


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,
+    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




More information about the llvm-commits mailing list