[lld] r193451 - [ELF] Implement .{init,fini}_array ordering.

Michael J. Spencer bigcheesegs at gmail.com
Fri Oct 25 16:59:07 PDT 2013


Author: mspencer
Date: Fri Oct 25 18:59:06 2013
New Revision: 193451

URL: http://llvm.org/viewvc/llvm-project?rev=193451&view=rev
Log:
[ELF] Implement .{init,fini}_array ordering.

Added:
    lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/ArrayOrderPass.h
    lld/trunk/test/elf/init_array-order.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/test/elf/dynamic.test
    lld/trunk/test/elf/entry.objtxt
    lld/trunk/test/elf/phdr.test

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

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

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

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

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

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

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

Modified: lld/trunk/test/elf/entry.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/entry.objtxt?rev=193451&r1=193450&r2=193451&view=diff
==============================================================================
--- lld/trunk/test/elf/entry.objtxt (original)
+++ lld/trunk/test/elf/entry.objtxt Fri Oct 25 18:59:06 2013
@@ -12,9 +12,9 @@
 # RUN: llvm-nm -n %t1 | FileCheck %s
 # 
 # CHECK:  004001b0 T main
-# CHECK:  00401060 D _DYNAMIC
-# CHECK:  00401060 A _end
-# CHECK:  00401060 A end
+# CHECK:  00401080 D _DYNAMIC
+# CHECK:  00401080 A _end
+# CHECK:  00401080 A end
 # CHECK:           U _entrypoint
 
 defined-atoms:   

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

Modified: lld/trunk/test/elf/phdr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/phdr.test?rev=193451&r1=193450&r2=193451&view=diff
==============================================================================
--- lld/trunk/test/elf/phdr.test (original)
+++ lld/trunk/test/elf/phdr.test Fri Oct 25 18:59:06 2013
@@ -36,8 +36,8 @@ I386-NEXT:     Type: PT_LOAD (0x1)
 I386-NEXT:     Offset: 0x0
 I386-NEXT:     VirtualAddress: 0x0
 I386-NEXT:     PhysicalAddress: 0x0
-I386-NEXT:     FileSize: 516
-I386-NEXT:     MemSize: 516
+I386-NEXT:     FileSize: 532
+I386-NEXT:     MemSize: 532
 I386-NEXT:     Flags [ (0x5)
 I386-NEXT:       PF_R (0x4)
 I386-NEXT:       PF_X (0x1)
@@ -75,8 +75,8 @@ I386-NEXT:     Type: PT_DYNAMIC (0x2)
 I386-NEXT:     Offset: 0x1D4
 I386-NEXT:     VirtualAddress: 0x1D4
 I386-NEXT:     PhysicalAddress: 0x1D4
-I386-NEXT:     FileSize: 48
-I386-NEXT:     MemSize: 48
+I386-NEXT:     FileSize: 64
+I386-NEXT:     MemSize: 64
 I386-NEXT:     Flags [ (0x4)
 I386-NEXT:       PF_R (0x4)
 I386-NEXT:     ]





More information about the llvm-commits mailing list