<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Oct 2, 2015 at 12:37 PM, 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 Oct  2 14:37:55 2015<br>
New Revision: 249175<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=249175&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=249175&view=rev</a><br>
Log:<br>
Add static initialization/finalization array support.<br>
<br>
This adds entries in the dynamic table for .init_array, .fini_array and<br>
.preinit_array.<br>
<br>
Modified:<br>
    lld/trunk/ELF/OutputSections.cpp<br>
    lld/trunk/ELF/OutputSections.h<br>
    lld/trunk/ELF/Writer.cpp<br>
    lld/trunk/test/elf2/init_array.s<br>
<br>
Modified: lld/trunk/ELF/OutputSections.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249175&r1=249174&r2=249175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249175&r1=249174&r2=249175&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/OutputSections.cpp (original)<br>
+++ lld/trunk/ELF/OutputSections.cpp Fri Oct  2 14:37:55 2015<br>
@@ -211,6 +211,13 @@ template <class ELFT> void DynamicSectio<br>
     DynStrSec.add(Config->SoName);<br>
   }<br>
<br>
+  if (PreInitArraySec)<br>
+    NumEntries += 2;<br>
+  if (InitArraySec)<br>
+    NumEntries += 2;<br>
+  if (FiniArraySec)<br>
+    NumEntries += 2;<br>
+<br>
   const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =<br>
       SymTab.getSharedFiles();<br>
   for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)<br>
@@ -257,6 +264,17 @@ template <class ELFT> void DynamicSectio<br>
   if (!Config->SoName.empty())<br>
     WriteVal(DT_SONAME, DynStrSec.getFileOff(Config->SoName));<br>
<br>
+  auto WriteArray = [&](int32_t T1, int32_t T2,<br>
+                        const OutputSection<ELFT> *Sec) {<br>
+    if (!Sec)<br>
+      return;<br>
+    WritePtr(T1, Sec->getVA());<br>
+    WriteVal(T2, Sec->getSize());<br>
+  };<br>
+  WriteArray(DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ, PreInitArraySec);<br>
+  WriteArray(DT_INIT_ARRAY, DT_INIT_ARRAYSZ, InitArraySec);<br>
+  WriteArray(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, FiniArraySec);<br>
+<br>
   const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =<br>
       SymTab.getSharedFiles();<br>
   for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)<br>
<br>
Modified: lld/trunk/ELF/OutputSections.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=249175&r1=249174&r2=249175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=249175&r1=249174&r2=249175&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/OutputSections.h (original)<br>
+++ lld/trunk/ELF/OutputSections.h Fri Oct  2 14:37:55 2015<br>
@@ -70,7 +70,7 @@ public:<br>
   void setSectionIndex(unsigned I) { SectionIndex = I; }<br>
<br>
   // Returns the size of the section in the output file.<br>
-  uintX_t getSize() { return Header.sh_size; }<br>
+  uintX_t getSize() const { return Header.sh_size; }<br>
   void setSize(uintX_t Val) { Header.sh_size = Val; }<br>
   uintX_t getFlags() { return Header.sh_flags; }<br>
   uintX_t getFileOff() { return Header.sh_offset; }<br>
@@ -324,6 +324,10 @@ public:<br>
   void finalize() override;<br>
   void writeTo(uint8_t *Buf) override;<br>
<br>
+  OutputSection<ELFT> *PreInitArraySec = nullptr;<br>
+  OutputSection<ELFT> *InitArraySec = nullptr;<br>
+  OutputSection<ELFT> *FiniArraySec = nullptr;<br>
+<br>
 private:<br>
   HashTableSection<ELFT> &HashSec;<br>
   SymbolTableSection<ELFT> &DynSymSec;<br>
<br>
Modified: lld/trunk/ELF/Writer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249175&r1=249174&r2=249175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249175&r1=249174&r2=249175&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Writer.cpp (original)<br>
+++ lld/trunk/ELF/Writer.cpp Fri Oct  2 14:37:55 2015<br>
@@ -328,8 +328,14 @@ 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>
+  DynamicSec.PreInitArraySec =<br>
+      Map.lookup({".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC});<br>
+  DynamicSec.InitArraySec =<br>
+      Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC});<br>
+  DynamicSec.FiniArraySec =<br>
+      Map.lookup({".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC});<br>
</blockquote><div><br></div><div>It feels that these section plumbings got a bit too complicated. Other than these, we passed GOT section to PLT, DynSymSec to Hash, etc. We probably should make all output sections accessible from all output sections. I'll try to make such change.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+<br>
+  if (OutputSection<ELFT> *OS = DynamicSec.InitArraySec) {<br>
     Symtab.addSyntheticSym<ELFT>("__init_array_start", *OS, 0);<br>
     Symtab.addSyntheticSym<ELFT>("__init_array_end", *OS, OS->getSize());<br>
   } else {<br>
<br>
Modified: 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=249175&r1=249174&r2=249175&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/init_array.s?rev=249175&r1=249174&r2=249175&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/elf2/init_array.s (original)<br>
+++ lld/trunk/test/elf2/init_array.s Fri Oct  2 14:37:55 2015<br>
@@ -1,6 +1,8 @@<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-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2<br>
+// RUN: lld -flavor gnu2 %t2 -o t2.so -shared<br>
+// RUN: lld -flavor gnu2 %t t2.so -o %t2<br>
+// RUN: llvm-readobj -symbols -sections -dynamic-table %t2 | FileCheck %s<br>
 // RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s<br>
 // REQUIRES: x86<br>
<br>
@@ -13,6 +15,13 @@ _start:<br>
 .section .init_array,"aw",@init_array<br>
   .quad 0<br>
<br>
+.section .preinit_array,"aw",@preinit_array<br>
+        .quad 0<br>
+        .byte 0<br>
+<br>
+.section .fini_array,"aw",@fini_array<br>
+        .quad 0<br>
+        .short 0<br>
<br>
 // CHECK:      Name: .init_array<br>
 // CHECK-NEXT: Type: SHT_INIT_ARRAY<br>
@@ -20,12 +29,34 @@ _start:<br>
 // CHECK-NEXT:   SHF_ALLOC<br>
 // CHECK-NEXT:   SHF_WRITE<br>
 // CHECK-NEXT: ]<br>
-// CHECK-NEXT: Address: 0x12000<br>
+// CHECK-NEXT: Address: [[INIT_ADDR:.*]]<br>
 // CHECK-NEXT: Offset:<br>
-// CHECK-NEXT: Size: 8<br>
+// CHECK-NEXT: Size: [[INIT_SIZE:.*]]<br>
+<br>
+<br>
+// CHECK:     Name: .preinit_array<br>
+// CHECK-NEXT: Type: SHT_PREINIT_ARRAY<br>
+// CHECK-NEXT: Flags [<br>
+// CHECK-NEXT:   SHF_ALLOC<br>
+// CHECK-NEXT:   SHF_WRITE<br>
+// CHECK-NEXT:    ]<br>
+// CHECK-NEXT: Address: [[PREINIT_ADDR:.*]]<br>
+// CHECK-NEXT: Offset:<br>
+// CHECK-NEXT: Size: [[PREINIT_SIZE:.*]]<br>
+<br>
+<br>
+// CHECK:      Name: .fini_array<br>
+// CHECK-NEXT: Type: SHT_FINI_ARRAY<br>
+// CHECK-NEXT: Flags [<br>
+// CHECK-NEXT:   SHF_ALLOC<br>
+// CHECK-NEXT:   SHF_WRITE<br>
+// CHECK-NEXT: ]<br>
+// CHECK-NEXT: Address: [[FINI_ADDR:.*]]<br>
+// CHECK-NEXT: Offset:<br>
+// CHECK-NEXT: Size: [[FINI_SIZE:.*]]<br>
<br>
 // CHECK:        Name: __init_array_end<br>
-// CHECK-NEXT:   Value: 0x12008<br>
+// CHECK-NEXT:   Value: 0x13008<br>
 // CHECK-NEXT:   Size: 0<br>
 // CHECK-NEXT:   Binding: Local<br>
 // CHECK-NEXT:   Type: None<br>
@@ -34,7 +65,7 @@ _start:<br>
 // CHECK-NEXT: }<br>
 // CHECK-NEXT: Symbol {<br>
 // CHECK-NEXT:   Name: __init_array_start<br>
-// CHECK-NEXT:   Value: 0x12000<br>
+// CHECK-NEXT:   Value: [[INIT_ADDR]]<br>
 // CHECK-NEXT:   Size: 0<br>
 // CHECK-NEXT:   Binding: Local<br>
 // CHECK-NEXT:   Type: None<br>
@@ -42,8 +73,18 @@ _start:<br>
 // CHECK-NEXT:   Section: .init_array<br>
 // CHECK-NEXT: }<br>
<br>
-// 0x12000 - (0x11000 + 5) = 4091<br>
-// 0x12008 - (0x11005 + 5) = 4094<br>
+<br>
+// CHECK: DynamicSection<br>
+// CHECK: PREINIT_ARRAY        [[PREINIT_ADDR]]<br>
+// CHECK: PREINIT_ARRAYSZ      [[PREINIT_SIZE]] (bytes)<br>
+// CHECK: INIT_ARRAY           [[INIT_ADDR]]<br>
+// CHECK: INIT_ARRAYSZ         [[INIT_SIZE]] (bytes)<br>
+// CHECK: FINI_ARRAY           [[FINI_ADDR]]<br>
+// CHECK: FINI_ARRAYSZ         [[FINI_SIZE]] (bytes)<br>
+<br>
+<br>
+// 0x13000 - (0x12000 + 5) = 4091<br>
+// 0x13008 - (0x12005 + 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>
+// DISASM-NEXT:   12000:  e8 fb 0f 00 00  callq  4091<br>
+// DISASM-NEXT:   12005:  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>