<div dir="ltr"><div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">Wow, I'm amazed that the tiny subset of ELF functionality I was able to implement in yaml2obj this Summer turned out to be useful!</span><br>
</div><div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px">-- Sean Silva</span></div><div><span style="color:rgb(0,0,0);font-family:arial,sans-serif;font-size:13px"><br>
</span></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Oct 25, 2013 at 7:59 PM, Michael J. Spencer <span dir="ltr"><<a href="mailto:bigcheesegs@gmail.com" target="_blank">bigcheesegs@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mspencer<br>
Date: Fri Oct 25 18:59:06 2013<br>
New Revision: 193451<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=193451&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=193451&view=rev</a><br>
Log:<br>
[ELF] Implement .{init,fini}_array ordering.<br>
<br>
Added:<br>
    lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp<br>
    lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h<br>
    lld/trunk/test/elf/init_array-order.test<br>
Modified:<br>
    lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt<br>
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h<br>
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp<br>
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h<br>
    lld/trunk/test/elf/dynamic.test<br>
    lld/trunk/test/elf/entry.objtxt<br>
    lld/trunk/test/elf/phdr.test<br>
<br>
Added: lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp?rev=193451&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp?rev=193451&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp (added)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp Fri Oct 25 18:59:06 2013<br>
@@ -0,0 +1,44 @@<br>
+//===- lib/ReaderWriter/ELF/ArrayOrderPass.cpp ----------------------------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "ArrayOrderPass.h"<br>
+<br>
+#include <algorithm><br>
+<br>
+namespace lld {<br>
+namespace elf {<br>
+void ArrayOrderPass::perform(MutableFile &f) {<br>
+  auto definedAtoms = f.definedAtoms();<br>
+  std::stable_sort(definedAtoms.begin(), definedAtoms.end(),<br>
+                   [](const DefinedAtom *left, const DefinedAtom *right) {<br>
+    if (left->sectionChoice() != DefinedAtom::sectionCustomRequired ||<br>
+        right->sectionChoice() != DefinedAtom::sectionCustomRequired)<br>
+      return false;<br>
+<br>
+    StringRef leftSec = left->customSectionName();<br>
+    StringRef rightSec = right->customSectionName();<br>
+<br>
+    // Both sections start with the same array type.<br>
+    if (!(leftSec.startswith(".init_array") &&<br>
+          rightSec.startswith(".init_array")) &&<br>
+        !(leftSec.startswith(".fini_array") &&<br>
+          rightSec.startswith(".fini_array")))<br>
+      return false;<br>
+<br>
+    // Get priortiy<br>
+    uint16_t leftPriority = 0;<br>
+    leftSec.rsplit('.').second.getAsInteger(10, leftPriority);<br>
+    uint16_t rightPriority = 0;<br>
+    rightSec.rsplit('.').second.getAsInteger(10, rightPriority);<br>
+<br>
+    return leftPriority < rightPriority;<br>
+  });<br>
+}<br>
+} // end namespace elf<br>
+} // end namespace lld<br>
<br>
Added: lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h?rev=193451&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h?rev=193451&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h (added)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h Fri Oct 25 18:59:06 2013<br>
@@ -0,0 +1,26 @@<br>
+//===- lib/ReaderWriter/ELF/ArrayOrderPass.h ------------------------------===//<br>
+//<br>
+//                             The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLD_READER_WRITER_ELF_ARRAY_ORDER_PASS_H<br>
+#define LLD_READER_WRITER_ELF_ARRAY_ORDER_PASS_H<br>
+<br>
+#include "lld/Core/Pass.h"<br>
+<br>
+namespace lld {<br>
+namespace elf {<br>
+/// \brief This pass sorts atoms in .{init,fini}_array.<priority> sections.<br>
+class ArrayOrderPass : public Pass {<br>
+public:<br>
+  ArrayOrderPass() : Pass() {}<br>
+  virtual void perform(MutableFile &mergedFile) LLVM_OVERRIDE;<br>
+};<br>
+}<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt Fri Oct 25 18:59:06 2013<br>
@@ -1,4 +1,5 @@<br>
 add_lld_library(lldELF<br>
+  ArrayOrderPass.cpp<br>
   ELFLinkingContext.cpp<br>
   Reader.cpp<br>
   Writer.cpp<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Fri Oct 25 18:59:06 2013<br>
@@ -413,6 +413,8 @@ StringRef DefaultLayout<ELFT>::getSectio<br>
       .StartsWith(".data", ".data")<br>
       .StartsWith(".tdata", ".tdata")<br>
       .StartsWith(".tbss", ".tbss")<br>
+      .StartsWith(".init_array", ".init_array")<br>
+      .StartsWith(".fini_array", ".fini_array")<br>
       .Default(da->customSectionName());<br>
 }<br>
<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Fri Oct 25 18:59:06 2013<br>
@@ -9,6 +9,7 @@<br>
<br>
 #include "lld/ReaderWriter/ELFLinkingContext.h"<br>
<br>
+#include "ArrayOrderPass.h"<br>
 #include "File.h"<br>
 #include "TargetHandler.h"<br>
 #include "Targets.h"<br>
@@ -54,6 +55,7 @@ bool ELFLinkingContext::isLittleEndian()<br>
 void ELFLinkingContext::addPasses(PassManager &pm) const {<br>
   if (_runLayoutPass)<br>
     pm.add(std::unique_ptr<Pass>(new LayoutPass()));<br>
+  pm.add(std::unique_ptr<Pass>(new elf::ArrayOrderPass()));<br>
 }<br>
<br>
 uint16_t ELFLinkingContext::getOutputMachine() const {<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Fri Oct 25 18:59:06 2013<br>
@@ -1039,6 +1039,10 @@ public:<br>
     _dt_strsz = addEntry(dyn);<br>
     dyn.d_tag = DT_SYMENT;<br>
     _dt_syment = addEntry(dyn);<br>
+    dyn.d_tag = DT_FINI_ARRAY;<br>
+    _dt_fini_array = addEntry(dyn);<br>
+    dyn.d_tag = DT_FINI_ARRAYSZ;<br>
+    _dt_fini_arraysz = addEntry(dyn);<br>
     if (_layout->hasDynamicRelocationTable()) {<br>
       dyn.d_tag = DT_RELA;<br>
       _dt_rela = addEntry(dyn);<br>
@@ -1085,6 +1089,11 @@ public:<br>
     _entries[_dt_symtab].d_un.d_val = _dynamicSymbolTable->virtualAddr();<br>
     _entries[_dt_strsz].d_un.d_val = dynamicStringTable->memSize();<br>
     _entries[_dt_syment].d_un.d_val = _dynamicSymbolTable->getEntSize();<br>
+    auto finiArray = _layout->findOutputSection(".fini_array");<br>
+    if (finiArray) {<br>
+      _entries[_dt_fini_array].d_un.d_val = finiArray->virtualAddr();<br>
+      _entries[_dt_fini_arraysz].d_un.d_val = finiArray->memSize();<br>
+    }<br>
     if (_layout->hasDynamicRelocationTable()) {<br>
       auto relaTbl = _layout->getDynamicRelocationTable();<br>
       _entries[_dt_rela].d_un.d_val = relaTbl->virtualAddr();<br>
@@ -1114,6 +1123,8 @@ private:<br>
   std::size_t _dt_pltgot;<br>
   std::size_t _dt_pltrel;<br>
   std::size_t _dt_jmprel;<br>
+  std::size_t _dt_fini_array;<br>
+  std::size_t _dt_fini_arraysz;<br>
   TargetLayout<ELFT> *_layout;<br>
   DynamicSymbolTable<ELFT> *_dynamicSymbolTable;<br>
   HashSection<ELFT> *_hashTable;<br>
<br>
Modified: lld/trunk/test/elf/dynamic.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic.test?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic.test?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/test/elf/dynamic.test (original)<br>
+++ lld/trunk/test/elf/dynamic.test Fri Oct 25 18:59:06 2013<br>
@@ -60,13 +60,15 @@ CHECK-NEXT:     Binding: Global<br>
 CHECK-NEXT:     Type: Function<br>
 CHECK:        }<br>
<br>
-CHECK: DynamicSection [ (15 entries)<br>
+CHECK: DynamicSection [ (17 entries)<br>
 CHECK:   Tag                Type                 Name/Value<br>
 CHECK:   0x0000000000000004 HASH<br>
 CHECK:   0x0000000000000005 STRTAB<br>
 CHECK:   0x0000000000000006 SYMTAB<br>
 CHECK:   0x000000000000000A STRSZ<br>
 CHECK:   0x000000000000000B SYMENT 24<br>
+CHECK:   0x000000000000001A FINI_ARRAY<br>
+CHECK:   0x000000000000001C FINI_ARRAYSZ<br>
 CHECK:   0x0000000000000007 RELA<br>
 CHECK:   0x0000000000000008 RELASZ 24<br>
 CHECK:   0x0000000000000009 RELAENT 24<br>
<br>
Modified: lld/trunk/test/elf/entry.objtxt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/entry.objtxt?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/entry.objtxt?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/test/elf/entry.objtxt (original)<br>
+++ lld/trunk/test/elf/entry.objtxt Fri Oct 25 18:59:06 2013<br>
@@ -12,9 +12,9 @@<br>
 # RUN: llvm-nm -n %t1 | FileCheck %s<br>
 #<br>
 # CHECK:  004001b0 T main<br>
-# CHECK:  00401060 D _DYNAMIC<br>
-# CHECK:  00401060 A _end<br>
-# CHECK:  00401060 A end<br>
+# CHECK:  00401080 D _DYNAMIC<br>
+# CHECK:  00401080 A _end<br>
+# CHECK:  00401080 A end<br>
 # CHECK:           U _entrypoint<br>
<br>
 defined-atoms:<br>
<br>
Added: lld/trunk/test/elf/init_array-order.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/init_array-order.test?rev=193451&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/init_array-order.test?rev=193451&view=auto</a><br>

==============================================================================<br>
--- lld/trunk/test/elf/init_array-order.test (added)<br>
+++ lld/trunk/test/elf/init_array-order.test Fri Oct 25 18:59:06 2013<br>
@@ -0,0 +1,37 @@<br>
+#RUN: yaml2obj -format=elf %s > %t<br>
+#RUN: lld -flavor gnu -target x86_64-linux %t --noinhibit-exec \<br>
+#RUN:   --output-filetype=yaml | FileCheck %s<br>
+<br>
+!ELF<br>
+FileHeader:<br>
+  Class: ELFCLASS64<br>
+  Data: ELFDATA2LSB<br>
+  Type: ET_REL<br>
+  Machine: EM_X86_64<br>
+<br>
+Sections:<br>
+- Name: .init_array.2<br>
+  Type: SHT_INIT_ARRAY<br>
+  Content: "0200000000000000"<br>
+  AddressAlign: 8<br>
+  Flags: [SHF_ALLOC]<br>
+- Name: .init_array.1<br>
+  Type: SHT_INIT_ARRAY<br>
+  Content: "0100000000000000"<br>
+  AddressAlign: 8<br>
+  Flags: [SHF_ALLOC]<br>
+<br>
+Symbols:<br>
+  Local:<br>
+  - Name: .init_array.2<br>
+    Type: STT_SECTION<br>
+    Section: .init_array.2<br>
+  - Name: .init_array.1<br>
+    Type: STT_SECTION<br>
+    Section: .init_array.1<br>
+<br>
+#CHECK: defined-atoms:<br>
+#CHECK:   content: [ 01,<br>
+#CHECK:   section-name: .init_array.1<br>
+#CHECK:   content: [ 02,<br>
+#CHECK:   section-name: .init_array.2<br>
<br>
Modified: lld/trunk/test/elf/phdr.test<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.test?rev=193451&r1=193450&r2=193451&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.test?rev=193451&r1=193450&r2=193451&view=diff</a><br>

==============================================================================<br>
--- lld/trunk/test/elf/phdr.test (original)<br>
+++ lld/trunk/test/elf/phdr.test Fri Oct 25 18:59:06 2013<br>
@@ -36,8 +36,8 @@ I386-NEXT:     Type: PT_LOAD (0x1)<br>
 I386-NEXT:     Offset: 0x0<br>
 I386-NEXT:     VirtualAddress: 0x0<br>
 I386-NEXT:     PhysicalAddress: 0x0<br>
-I386-NEXT:     FileSize: 516<br>
-I386-NEXT:     MemSize: 516<br>
+I386-NEXT:     FileSize: 532<br>
+I386-NEXT:     MemSize: 532<br>
 I386-NEXT:     Flags [ (0x5)<br>
 I386-NEXT:       PF_R (0x4)<br>
 I386-NEXT:       PF_X (0x1)<br>
@@ -75,8 +75,8 @@ I386-NEXT:     Type: PT_DYNAMIC (0x2)<br>
 I386-NEXT:     Offset: 0x1D4<br>
 I386-NEXT:     VirtualAddress: 0x1D4<br>
 I386-NEXT:     PhysicalAddress: 0x1D4<br>
-I386-NEXT:     FileSize: 48<br>
-I386-NEXT:     MemSize: 48<br>
+I386-NEXT:     FileSize: 64<br>
+I386-NEXT:     MemSize: 64<br>
 I386-NEXT:     Flags [ (0x4)<br>
 I386-NEXT:       PF_R (0x4)<br>
 I386-NEXT:     ]<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>