Emit the TLS initialization function pointers into the correct section.
authorBill Wendling <isanbard@gmail.com>
Mon, 29 Apr 2013 22:25:40 +0000 (22:25 +0000)
committerBill Wendling <isanbard@gmail.com>
Mon, 29 Apr 2013 22:25:40 +0000 (22:25 +0000)
The `llvm.tls_init_funcs' (created by the front-end) holds pointers to the TLS
initialization functions. These need to be placed into the correct section so
that they are run before `main()'.

<rdar://problem/13733006>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180737 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp

index c2fd6ce3679cc09ede23441f1259293a0fe30574..4ecc7ade719fe58113e69a0072147352e5a61e18 100644 (file)
@@ -486,6 +486,7 @@ namespace llvm {
                             unsigned uid) const;
     void EmitLLVMUsedList(const ConstantArray *InitList);
     void EmitXXStructorList(const Constant *List, bool isCtor);
+    void EmitTLSInitFuncs(const ConstantArray *InitList);
     GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
   };
 }
index 84162ace4188b5d070e995f5498e5d56b5db2a81..4a71ad333730bcab1f293a7bd74fe5c419e43e94 100644 (file)
@@ -1254,6 +1254,11 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
     return true;
   }
 
+  if (GV->getName() == "llvm.tls_init_funcs") {
+    EmitTLSInitFuncs(cast<ConstantArray>(GV->getInitializer()));
+    return true;
+  }
+
   return false;
 }
 
@@ -1320,6 +1325,16 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
   }
 }
 
+/// EmitTLSInitFuncs - Emit the TLS initialization functions.
+void AsmPrinter::EmitTLSInitFuncs(const ConstantArray *InitList) {
+  const DataLayout *TD = TM.getDataLayout();
+  OutStreamer.SwitchSection(getObjFileLowering().getTLSThreadInitSection());
+  EmitAlignment(Log2_32(TD->getPointerPrefAlignment()));
+  for (unsigned I = 0, E = InitList->getNumOperands(); I != E; ++I)
+    EmitGlobalConstant(
+      dyn_cast<Constant>(InitList->getOperand(I)->stripPointerCasts()));
+}
+
 //===--------------------------------------------------------------------===//
 // Emission and print routines
 //