[lld] r249175 - Add static initialization/finalization array support.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 12:37:56 PDT 2015


Author: rafael
Date: Fri Oct  2 14:37:55 2015
New Revision: 249175

URL: http://llvm.org/viewvc/llvm-project?rev=249175&view=rev
Log:
Add static initialization/finalization array support.

This adds entries in the dynamic table for .init_array, .fini_array and
.preinit_array.

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/init_array.s

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249175&r1=249174&r2=249175&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Oct  2 14:37:55 2015
@@ -211,6 +211,13 @@ template <class ELFT> void DynamicSectio
     DynStrSec.add(Config->SoName);
   }
 
+  if (PreInitArraySec)
+    NumEntries += 2;
+  if (InitArraySec)
+    NumEntries += 2;
+  if (FiniArraySec)
+    NumEntries += 2;
+
   const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
       SymTab.getSharedFiles();
   for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)
@@ -257,6 +264,17 @@ template <class ELFT> void DynamicSectio
   if (!Config->SoName.empty())
     WriteVal(DT_SONAME, DynStrSec.getFileOff(Config->SoName));
 
+  auto WriteArray = [&](int32_t T1, int32_t T2,
+                        const OutputSection<ELFT> *Sec) {
+    if (!Sec)
+      return;
+    WritePtr(T1, Sec->getVA());
+    WriteVal(T2, Sec->getSize());
+  };
+  WriteArray(DT_PREINIT_ARRAY, DT_PREINIT_ARRAYSZ, PreInitArraySec);
+  WriteArray(DT_INIT_ARRAY, DT_INIT_ARRAYSZ, InitArraySec);
+  WriteArray(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, FiniArraySec);
+
   const std::vector<std::unique_ptr<SharedFileBase>> &SharedFiles =
       SymTab.getSharedFiles();
   for (const std::unique_ptr<SharedFileBase> &File : SharedFiles)

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=249175&r1=249174&r2=249175&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Oct  2 14:37:55 2015
@@ -70,7 +70,7 @@ public:
   void setSectionIndex(unsigned I) { SectionIndex = I; }
 
   // Returns the size of the section in the output file.
-  uintX_t getSize() { return Header.sh_size; }
+  uintX_t getSize() const { return Header.sh_size; }
   void setSize(uintX_t Val) { Header.sh_size = Val; }
   uintX_t getFlags() { return Header.sh_flags; }
   uintX_t getFileOff() { return Header.sh_offset; }
@@ -324,6 +324,10 @@ public:
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
 
+  OutputSection<ELFT> *PreInitArraySec = nullptr;
+  OutputSection<ELFT> *InitArraySec = nullptr;
+  OutputSection<ELFT> *FiniArraySec = nullptr;
+
 private:
   HashTableSection<ELFT> &HashSec;
   SymbolTableSection<ELFT> &DynSymSec;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249175&r1=249174&r2=249175&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Oct  2 14:37:55 2015
@@ -328,8 +328,14 @@ template <class ELFT> void Writer<ELFT>:
     }
   }
 
-  if (OutputSection<ELFT> *OS =
-          Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC})) {
+  DynamicSec.PreInitArraySec =
+      Map.lookup({".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC});
+  DynamicSec.InitArraySec =
+      Map.lookup({".init_array", SHT_INIT_ARRAY, SHF_WRITE | SHF_ALLOC});
+  DynamicSec.FiniArraySec =
+      Map.lookup({".fini_array", SHT_FINI_ARRAY, SHF_WRITE | SHF_ALLOC});
+
+  if (OutputSection<ELFT> *OS = DynamicSec.InitArraySec) {
     Symtab.addSyntheticSym<ELFT>("__init_array_start", *OS, 0);
     Symtab.addSyntheticSym<ELFT>("__init_array_end", *OS, OS->getSize());
   } else {

Modified: lld/trunk/test/elf2/init_array.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/init_array.s?rev=249175&r1=249174&r2=249175&view=diff
==============================================================================
--- lld/trunk/test/elf2/init_array.s (original)
+++ lld/trunk/test/elf2/init_array.s Fri Oct  2 14:37:55 2015
@@ -1,6 +1,8 @@
 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-// RUN: lld -flavor gnu2 %t -o %t2
-// RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2
+// RUN: lld -flavor gnu2 %t2 -o t2.so -shared
+// RUN: lld -flavor gnu2 %t t2.so -o %t2
+// RUN: llvm-readobj -symbols -sections -dynamic-table %t2 | FileCheck %s
 // RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
 // REQUIRES: x86
 
@@ -13,6 +15,13 @@ _start:
 .section .init_array,"aw", at init_array
   .quad 0
 
+.section .preinit_array,"aw", at preinit_array
+        .quad 0
+        .byte 0
+
+.section .fini_array,"aw", at fini_array
+        .quad 0
+        .short 0
 
 // CHECK:      Name: .init_array
 // CHECK-NEXT: Type: SHT_INIT_ARRAY
@@ -20,12 +29,34 @@ _start:
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Address: [[INIT_ADDR:.*]]
 // CHECK-NEXT: Offset:
-// CHECK-NEXT: Size: 8
+// CHECK-NEXT: Size: [[INIT_SIZE:.*]]
+
+
+// CHECK:     Name: .preinit_array
+// CHECK-NEXT: Type: SHT_PREINIT_ARRAY
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT:    ]
+// CHECK-NEXT: Address: [[PREINIT_ADDR:.*]]
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: [[PREINIT_SIZE:.*]]
+
+
+// CHECK:      Name: .fini_array
+// CHECK-NEXT: Type: SHT_FINI_ARRAY
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: [[FINI_ADDR:.*]]
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: [[FINI_SIZE:.*]]
 
 // CHECK:        Name: __init_array_end
-// CHECK-NEXT:   Value: 0x12008
+// CHECK-NEXT:   Value: 0x13008
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Local
 // CHECK-NEXT:   Type: None
@@ -34,7 +65,7 @@ _start:
 // CHECK-NEXT: }
 // CHECK-NEXT: Symbol {
 // CHECK-NEXT:   Name: __init_array_start
-// CHECK-NEXT:   Value: 0x12000
+// CHECK-NEXT:   Value: [[INIT_ADDR]]
 // CHECK-NEXT:   Size: 0
 // CHECK-NEXT:   Binding: Local
 // CHECK-NEXT:   Type: None
@@ -42,8 +73,18 @@ _start:
 // CHECK-NEXT:   Section: .init_array
 // CHECK-NEXT: }
 
-// 0x12000 - (0x11000 + 5) = 4091
-// 0x12008 - (0x11005 + 5) = 4094
+
+// CHECK: DynamicSection
+// CHECK: PREINIT_ARRAY        [[PREINIT_ADDR]]
+// CHECK: PREINIT_ARRAYSZ      [[PREINIT_SIZE]] (bytes)
+// CHECK: INIT_ARRAY           [[INIT_ADDR]]
+// CHECK: INIT_ARRAYSZ         [[INIT_SIZE]] (bytes)
+// CHECK: FINI_ARRAY           [[FINI_ADDR]]
+// CHECK: FINI_ARRAYSZ         [[FINI_SIZE]] (bytes)
+
+
+// 0x13000 - (0x12000 + 5) = 4091
+// 0x13008 - (0x12005 + 5) = 4094
 // DISASM:      _start:
-// DISASM-NEXT:   11000:  e8 fb 0f 00 00  callq  4091
-// DISASM-NEXT:   11005:  e8 fe 0f 00 00  callq  4094
+// DISASM-NEXT:   12000:  e8 fb 0f 00 00  callq  4091
+// DISASM-NEXT:   12005:  e8 fe 0f 00 00  callq  4094




More information about the llvm-commits mailing list