llvm.org GIT mirror llvm / 84dedd3
[msan] Put msan constructor in a comdat. MSan adds a constructor to each translation unit that calls __msan_init, and does nothing else. The idea is to run __msan_init before any instrumented code. This results in multiple constructors and multiple .init_array entries in the final binary, one per translation unit. This is absolutely unnecessary; one would be enough. This change moves the constructors to a comdat group in order to drop the extra ones. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260632 91177308-0d34-0410-b5e6-96231b3b80d8 Evgeniy Stepanov 3 years ago
5 changed file(s) with 52 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
3333 /// This wraps the function in the appropriate structure and stores it along
3434 /// side other global constructors. For details see
3535 /// http://llvm.org/docs/LangRef.html#intg_global_ctors
36 void appendToGlobalCtors(Module &M, Function *F, int Priority);
36 void appendToGlobalCtors(Module &M, Function *F, int Priority,
37 Constant *Data = nullptr);
3738
3839 /// Same as appendToGlobalCtors(), but for global dtors.
39 void appendToGlobalDtors(Module &M, Function *F, int Priority);
40 void appendToGlobalDtors(Module &M, Function *F, int Priority,
41 Constant *Data = nullptr);
4042
4143 /// \brief Given "llvm.used" or "llvm.compiler.used" as a global name, collect
4244 /// the initializer elements of that global in Set and return the global itself.
539539 createSanitizerCtorAndInitFunctions(M, kMsanModuleCtorName, kMsanInitName,
540540 /*InitArgTypes=*/{},
541541 /*InitArgs=*/{});
542
543 appendToGlobalCtors(M, MsanCtorFunction, 0);
542 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
543 MsanCtorFunction->setComdat(MsanCtorComdat);
544
545 appendToGlobalCtors(M, MsanCtorFunction, 0, MsanCtorFunction);
544546
545547 if (TrackOrigins)
546548 new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
2020
2121 using namespace llvm;
2222
23 static void appendToGlobalArray(const char *Array,
24 Module &M, Function *F, int Priority) {
23 static void appendToGlobalArray(const char *Array, Module &M, Function *F,
24 int Priority, Constant *Data) {
2525 IRBuilder<> IRB(M.getContext());
2626 FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false);
2727
3030 SmallVector CurrentCtors;
3131 StructType *EltTy;
3232 if (GlobalVariable *GVCtor = M.getNamedGlobal(Array)) {
33 // If there is a global_ctors array, use the existing struct type, which can
34 // have 2 or 3 fields.
3533 ArrayType *ATy = cast(GVCtor->getValueType());
36 EltTy = cast(ATy->getElementType());
34 StructType *OldEltTy = cast(ATy->getElementType());
35 // Upgrade a 2-field global array type to the new 3-field format if needed.
36 if (Data && OldEltTy->getNumElements() < 3)
37 EltTy = StructType::get(IRB.getInt32Ty(), PointerType::getUnqual(FnTy),
38 IRB.getInt8PtrTy(), nullptr);
39 else
40 EltTy = OldEltTy;
3741 if (Constant *Init = GVCtor->getInitializer()) {
3842 unsigned n = Init->getNumOperands();
3943 CurrentCtors.reserve(n + 1);
40 for (unsigned i = 0; i != n; ++i)
41 CurrentCtors.push_back(cast(Init->getOperand(i)));
44 for (unsigned i = 0; i != n; ++i) {
45 auto Ctor = cast(Init->getOperand(i));
46 if (EltTy != OldEltTy)
47 Ctor = ConstantStruct::get(
48 EltTy, Ctor->getAggregateElement((unsigned)0),
49 Ctor->getAggregateElement(1),
50 Constant::getNullValue(IRB.getInt8PtrTy()), nullptr);
51 CurrentCtors.push_back(Ctor);
52 }
4253 }
4354 GVCtor->eraseFromParent();
4455 } else {
5364 CSVals[1] = F;
5465 // FIXME: Drop support for the two element form in LLVM 4.0.
5566 if (EltTy->getNumElements() >= 3)
56 CSVals[2] = llvm::Constant::getNullValue(IRB.getInt8PtrTy());
67 CSVals[2] = Data ? ConstantExpr::getPointerCast(Data, IRB.getInt8PtrTy())
68 : Constant::getNullValue(IRB.getInt8PtrTy());
5769 Constant *RuntimeCtorInit =
5870 ConstantStruct::get(EltTy, makeArrayRef(CSVals, EltTy->getNumElements()));
5971
6981 GlobalValue::AppendingLinkage, NewInit, Array);
7082 }
7183
72 void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) {
73 appendToGlobalArray("llvm.global_ctors", M, F, Priority);
84 void llvm::appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data) {
85 appendToGlobalArray("llvm.global_ctors", M, F, Priority, Data);
7486 }
7587
76 void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) {
77 appendToGlobalArray("llvm.global_dtors", M, F, Priority);
88 void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data) {
89 appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data);
7890 }
7991
8092 GlobalVariable *
131143 }
132144 return std::make_pair(Ctor, InitFunction);
133145 }
134
0 ; MSan converts 2-element global_ctors to 3-element when adding the new entry.
1 ; RUN: opt < %s -msan -S | FileCheck %s
2
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 target triple = "x86_64-unknown-linux-gnu"
5
6 ; CHECK: $msan.module_ctor = comdat any
7 ; CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @f, i8* null }, { i32, void ()*, i8* } { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }]
8
9 @llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @f }]
10
11 define internal void @f() {
12 entry:
13 ret void
14 }
15
16 ; CHECK: define internal void @msan.module_ctor() comdat {
33 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
44 target triple = "x86_64-unknown-linux-gnu"
55
6 ; CHECK: @llvm.global_ctors {{.*}} @msan.module_ctor
6 ; CHECK: $msan.module_ctor = comdat any
7 ; CHECK: @llvm.global_ctors {{.*}} { i32 0, void ()* @msan.module_ctor, i8* bitcast (void ()* @msan.module_ctor to i8*) }
78
89 ; Check the presence and the linkage type of __msan_track_origins and
910 ; other interface symbols.
980981 ; CHECK-NEXT: ret i8*
981982
982983
983 ; CHECK-LABEL: define internal void @msan.module_ctor
984 ; CHECK-LABEL: define internal void @msan.module_ctor() comdat {
984985 ; CHECK: call void @__msan_init()