From: Evgeniy Stepanov Date: Thu, 27 Nov 2014 14:54:02 +0000 (+0000) Subject: [msan] Remove indirect call wrapping code. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e402d9ef4c85abde9f72913c43bf5b7e466ed5f2;p=platform%2Fupstream%2Fllvm.git [msan] Remove indirect call wrapping code. This functionality was only used in MSanDR, which is deprecated. llvm-svn: 222889 --- diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 1261259..fecf5be 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -187,18 +187,6 @@ static cl::opt ClInstrumentationWithCallThreshold( "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500)); -// Experimental. Wraps all indirect calls in the instrumented code with -// a call to the given function. This is needed to assist the dynamic -// helper tool (MSanDR) to regain control on transition between instrumented and -// non-instrumented code. -static cl::opt ClWrapIndirectCalls("msan-wrap-indirect-calls", - cl::desc("Wrap indirect calls with a given function"), - cl::Hidden); - -static cl::opt ClWrapIndirectCallsFast("msan-wrap-indirect-calls-fast", - cl::desc("Do not wrap indirect calls with target in the same module"), - cl::Hidden, cl::init(true)); - // This is an experiment to enable handling of cases where shadow is a non-zero // compile-time constant. For some unexplainable reason they were silently // ignored in the instrumentation. @@ -219,8 +207,7 @@ class MemorySanitizer : public FunctionPass { : FunctionPass(ID), TrackOrigins(std::max(TrackOrigins, (int)ClTrackOrigins)), DL(nullptr), - WarningFn(nullptr), - WrapIndirectCalls(!ClWrapIndirectCalls.empty()) {} + WarningFn(nullptr) {} const char *getPassName() const override { return "MemorySanitizer"; } bool runOnFunction(Function &F) override; bool doInitialization(Module &M) override; @@ -254,9 +241,6 @@ class MemorySanitizer : public FunctionPass { /// function. GlobalVariable *OriginTLS; - GlobalVariable *MsandrModuleStart; - GlobalVariable *MsandrModuleEnd; - /// \brief The run-time callback to print a warning. Value *WarningFn; // These arrays are indexed by log2(AccessSize). @@ -287,12 +271,6 @@ class MemorySanitizer : public FunctionPass { /// \brief An empty volatile inline asm that prevents callback merge. InlineAsm *EmptyAsm; - bool WrapIndirectCalls; - /// \brief Run-time wrapper for indirect calls. - Value *IndirectCallWrapperFn; - // Argument and return type of IndirectCallWrapperFn: void (*f)(void). - Type *AnyFunctionPtrTy; - friend struct MemorySanitizerVisitor; friend struct VarArgAMD64Helper; }; @@ -400,24 +378,6 @@ void MemorySanitizer::initializeCallbacks(Module &M) { EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), StringRef(""), StringRef(""), /*hasSideEffects=*/true); - - if (WrapIndirectCalls) { - AnyFunctionPtrTy = - PointerType::getUnqual(FunctionType::get(IRB.getVoidTy(), false)); - IndirectCallWrapperFn = M.getOrInsertFunction( - ClWrapIndirectCalls, AnyFunctionPtrTy, AnyFunctionPtrTy, nullptr); - } - - if (WrapIndirectCalls && ClWrapIndirectCallsFast) { - MsandrModuleStart = new GlobalVariable( - M, IRB.getInt32Ty(), false, GlobalValue::ExternalLinkage, - nullptr, "__executable_start"); - MsandrModuleStart->setVisibility(GlobalVariable::HiddenVisibility); - MsandrModuleEnd = new GlobalVariable( - M, IRB.getInt32Ty(), false, GlobalValue::ExternalLinkage, - nullptr, "_end"); - MsandrModuleEnd->setVisibility(GlobalVariable::HiddenVisibility); - } } /// \brief Module-level initialization. @@ -537,7 +497,6 @@ struct MemorySanitizerVisitor : public InstVisitor { }; SmallVector InstrumentationList; SmallVector StoreList; - SmallVector IndirectCallList; MemorySanitizerVisitor(Function &F, MemorySanitizer &MS) : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) { @@ -669,47 +628,6 @@ struct MemorySanitizerVisitor : public InstVisitor { DEBUG(dbgs() << "DONE:\n" << F); } - void materializeIndirectCalls() { - for (auto &CS : IndirectCallList) { - Instruction *I = CS.getInstruction(); - BasicBlock *B = I->getParent(); - IRBuilder<> IRB(I); - Value *Fn0 = CS.getCalledValue(); - Value *Fn = IRB.CreateBitCast(Fn0, MS.AnyFunctionPtrTy); - - if (ClWrapIndirectCallsFast) { - // Check that call target is inside this module limits. - Value *Start = - IRB.CreateBitCast(MS.MsandrModuleStart, MS.AnyFunctionPtrTy); - Value *End = IRB.CreateBitCast(MS.MsandrModuleEnd, MS.AnyFunctionPtrTy); - - Value *NotInThisModule = IRB.CreateOr(IRB.CreateICmpULT(Fn, Start), - IRB.CreateICmpUGE(Fn, End)); - - PHINode *NewFnPhi = - IRB.CreatePHI(Fn0->getType(), 2, "msandr.indirect_target"); - - Instruction *CheckTerm = SplitBlockAndInsertIfThen( - NotInThisModule, NewFnPhi, - /* Unreachable */ false, MS.ColdCallWeights); - - IRB.SetInsertPoint(CheckTerm); - // Slow path: call wrapper function to possibly transform the call - // target. - Value *NewFn = IRB.CreateBitCast( - IRB.CreateCall(MS.IndirectCallWrapperFn, Fn), Fn0->getType()); - - NewFnPhi->addIncoming(Fn0, B); - NewFnPhi->addIncoming(NewFn, dyn_cast(NewFn)->getParent()); - CS.setCalledFunction(NewFnPhi); - } else { - Value *NewFn = IRB.CreateBitCast( - IRB.CreateCall(MS.IndirectCallWrapperFn, Fn), Fn0->getType()); - CS.setCalledFunction(NewFn); - } - } - } - /// \brief Add MemorySanitizer instrumentation to a function. bool runOnFunction() { MS.initializeCallbacks(*F.getParent()); @@ -752,9 +670,6 @@ struct MemorySanitizerVisitor : public InstVisitor { // Insert shadow value checks. materializeChecks(InstrumentWithCalls); - // Wrap indirect calls. - materializeIndirectCalls(); - return true; } @@ -2337,9 +2252,6 @@ struct MemorySanitizerVisitor : public InstVisitor { } IRBuilder<> IRB(&I); - if (MS.WrapIndirectCalls && !CS.getCalledFunction()) - IndirectCallList.push_back(CS); - unsigned ArgOffset = 0; DEBUG(dbgs() << " CallSite: " << I << "\n"); for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end(); diff --git a/llvm/test/Instrumentation/MemorySanitizer/do-not-emit-module-limits.ll b/llvm/test/Instrumentation/MemorySanitizer/do-not-emit-module-limits.ll deleted file mode 100644 index 7d0a62a..0000000 --- a/llvm/test/Instrumentation/MemorySanitizer/do-not-emit-module-limits.ll +++ /dev/null @@ -1,21 +0,0 @@ -; Test that MSan does not emit undefined symbol __executable_start when it is -; not needed (i.e. without -msan-wrap-indirect-calls). - -; RUN: opt < %s -msan -S | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; Function Attrs: nounwind uwtable -define void @_Z1fv() #0 { -entry: - ret void -} - -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } - -!llvm.ident = !{!0} - -!0 = metadata !{metadata !"clang version 3.5.0 (208165)"} - -; CHECK-NOT: __executable_start diff --git a/llvm/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll b/llvm/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll deleted file mode 100644 index 65037cb..0000000 --- a/llvm/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll +++ /dev/null @@ -1,60 +0,0 @@ -; RUN: opt < %s -msan -msan-check-access-address=0 -msan-wrap-indirect-calls=zzz -msan-wrap-indirect-calls-fast=0 -S | FileCheck %s -; RUN: opt < %s -msan -msan-check-access-address=0 -msan-wrap-indirect-calls=zzz -msan-wrap-indirect-calls-fast=1 -S | FileCheck -check-prefix=CHECK-FAST %s -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" -target triple = "x86_64-unknown-linux-gnu" - -; Test for -msan-wrap-indirect-calls functionality. -; Replaces indirect call to %f with a call to whatever is returned from the -; wrapper function. - -; This does not depend on the sanitize_memory attribute. -define i32 @func1(i32 (i32, i32)* nocapture %f, i32 %x, i32 %y) { -entry: - %call = tail call i32 %f(i32 %x, i32 %y) - ret i32 %call -} - -; CHECK: @func1 -; CHECK: bitcast i32 (i32, i32)* %f to void ()* -; CHECK: call void ()* (void ()*)* @zzz(void ()* -; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i32 (i32, i32)* -; CHECK: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}}) -; CHECK: ret i32 - -; CHECK-FAST: @func1 -; CHECK-FAST: bitcast i32 (i32, i32)* %f to void ()* -; CHECK-FAST-DAG: icmp ult void ()* {{.*}}, bitcast (i32* @__executable_start to void ()*) -; CHECK-FAST-DAG: icmp uge void ()* {{.*}}, bitcast (i32* @_end to void ()*) -; CHECK-FAST: or i1 -; CHECK-FAST: br i1 -; CHECK-FAST: call void ()* (void ()*)* @zzz(void ()* -; CHECK-FAST: br label -; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i32 (i32, i32)* [ %f, %entry ], [ {{.*}} ] -; CHECK-FAST: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}}) -; CHECK-FAST: ret i32 - - -; The same test, but with a complex expression as the call target. - -declare i8* @callee(i32) - -define i8* @func2(i64 %x) #1 { -entry: - %call = tail call i8* bitcast (i8* (i32)* @callee to i8* (i64)*)(i64 %x) - ret i8* %call -} - -; CHECK: @func2 -; CHECK: call {{.*}} @zzz -; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i8* (i64)* -; CHECK: call i8* {{.*}}[[A]](i64 {{.*}}) -; CHECK: ret i8* - -; CHECK-FAST: @func2 -; CHECK-FAST: {{br i1 or .* icmp ult .* bitcast .* @callee .* @__executable_start.* icmp uge .* bitcast .* @callee .* @_end}} -; CHECK-FAST: {{call .* @zzz.* bitcast .*@callee}} -; CHECK-FAST: bitcast void ()* {{.*}} to i8* (i64)* -; CHECK-FAST: br label -; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i8* (i64)* [{{.*bitcast .* @callee.*, %entry.*}}], [ {{.*}} ] -; CHECK-FAST: call i8* {{.*}}[[A]](i64 {{.*}}) -; CHECK-FAST: ret i8*