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