[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