From fa2eac54e690928592a2bd6c1f8ee0f9b1923d5e Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 29 Apr 2013 22:25:40 +0000 Subject: [PATCH] Emit the TLS initialization function pointers into the correct section. 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()'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180737 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/AsmPrinter.h | 1 + lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index c2fd6ce3679..4ecc7ade719 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -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); }; } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 84162ace418..4a71ad33373 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1254,6 +1254,11 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { return true; } + if (GV->getName() == "llvm.tls_init_funcs") { + EmitTLSInitFuncs(cast(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(InitList->getOperand(I)->stripPointerCasts())); +} + //===--------------------------------------------------------------------===// // Emission and print routines //