Instrumented malloc and free with dummy functions. BUG=https://bugs.chromium.org/p/nativeclient/issues/detail?id=4374 R=kschimpf@google.com, stichnot@chromium.org Review URL: https://codereview.chromium.org/2079723002 .
diff --git a/src/IceASanInstrumentation.cpp b/src/IceASanInstrumentation.cpp index 589bf1a..9bd9555 100644 --- a/src/IceASanInstrumentation.cpp +++ b/src/IceASanInstrumentation.cpp
@@ -22,6 +22,7 @@ #include "IceTypes.h" #include <sstream> +#include <unordered_map> namespace Ice { @@ -30,6 +31,14 @@ const std::string RzPrefix = "__$rz"; const llvm::NaClBitcodeRecord::RecordVector RzContents = llvm::NaClBitcodeRecord::RecordVector(RzSize, 'R'); + +// TODO(tlively): Handle all allocation functions +// In order to instrument the code correctly, the .pexe must not have had its +// symbols stripped. +using string_map = std::unordered_map<std::string, std::string>; +const string_map FuncSubstitutions = {{"malloc", "__asan_malloc"}, + {"free", "__asan_free"}}; + } // end of anonymous namespace // Create redzones around all global variables, ensuring that the initializer @@ -113,16 +122,39 @@ return Rz; } +void ASanInstrumentation::instrumentCall(LoweringContext &Context, + InstCall *Instr) { + auto *CallTarget = + llvm::dyn_cast<ConstantRelocatable>(Instr->getCallTarget()); + if (CallTarget == nullptr) + return; + + std::string TargetName = CallTarget->getName().toStringOrEmpty(); + auto Subst = FuncSubstitutions.find(TargetName); + if (Subst == FuncSubstitutions.end()) + return; + + std::string SubName = Subst->second; + Constant *NewFunc = Ctx->getConstantExternSym(Ctx->getGlobalString(SubName)); + auto *NewCall = + InstCall::create(Context.getNode()->getCfg(), Instr->getNumArgs(), + Instr->getDest(), NewFunc, Instr->isTailcall()); + for (SizeT I = 0, Args = Instr->getNumArgs(); I < Args; ++I) + NewCall->addArg(Instr->getArg(I)); + Context.insert(NewCall); + Instr->setDeleted(); +} + void ASanInstrumentation::instrumentLoad(LoweringContext &Context, - const InstLoad *Inst) { - instrumentAccess(Context, Inst->getSourceAddress(), - typeWidthInBytes(Inst->getDest()->getType())); + InstLoad *Instr) { + instrumentAccess(Context, Instr->getSourceAddress(), + typeWidthInBytes(Instr->getDest()->getType())); } void ASanInstrumentation::instrumentStore(LoweringContext &Context, - const InstStore *Inst) { - instrumentAccess(Context, Inst->getAddr(), - typeWidthInBytes(Inst->getData()->getType())); + InstStore *Instr) { + instrumentAccess(Context, Instr->getAddr(), + typeWidthInBytes(Instr->getData()->getType())); } // TODO(tlively): Take size of access into account as well
diff --git a/src/IceASanInstrumentation.h b/src/IceASanInstrumentation.h index 761a332..e1222b4 100644 --- a/src/IceASanInstrumentation.h +++ b/src/IceASanInstrumentation.h
@@ -40,9 +40,9 @@ VariableDeclaration *RzArray, SizeT &RzArraySize, VariableDeclaration *Global); - void instrumentLoad(LoweringContext &Context, const InstLoad *Inst) override; - void instrumentStore(LoweringContext &Context, - const InstStore *Inst) override; + void instrumentCall(LoweringContext &Context, InstCall *Instr) override; + void instrumentLoad(LoweringContext &Context, InstLoad *Instr) override; + void instrumentStore(LoweringContext &Context, InstStore *Instr) override; void instrumentAccess(LoweringContext &Context, Operand *Op, SizeT Size); void instrumentStart(Cfg *Func) override; bool DidInsertRedZones = false;
diff --git a/src/IceInstrumentation.cpp b/src/IceInstrumentation.cpp index fc2a4a5..b4229f6 100644 --- a/src/IceInstrumentation.cpp +++ b/src/IceInstrumentation.cpp
@@ -29,6 +29,8 @@ assert(Func); assert(!Func->getNodes().empty()); + // TODO(tlively): More selectively instrument functions so that shadow memory + // represents user accessibility more and library accessibility less. LoweringContext Context; Context.init(Func->getNodes().front()); instrumentFuncStart(Context); @@ -42,7 +44,8 @@ } } - if (Func->getFunctionName().toStringOrEmpty() == "_start") + std::string FuncName = Func->getFunctionName().toStringOrEmpty(); + if (FuncName == "_start") instrumentStart(Func); }
diff --git a/src/IceInstrumentation.h b/src/IceInstrumentation.h index 8b7e2e7..d41a7ee 100644 --- a/src/IceInstrumentation.h +++ b/src/IceInstrumentation.h
@@ -48,27 +48,27 @@ void instrumentInst(LoweringContext &Context); virtual void instrumentFuncStart(LoweringContext &) {} virtual void instrumentAlloca(LoweringContext &, const class InstAlloca *) {} - virtual void instrumentArithmetic(LoweringContext &, - const class InstArithmetic *) {} - virtual void instrumentBr(LoweringContext &, const class InstBr *) {} - virtual void instrumentCall(LoweringContext &, const class InstCall *) {} - virtual void instrumentCast(LoweringContext &, const class InstCast *) {} + virtual void instrumentArithmetic(LoweringContext &, class InstArithmetic *) { + } + virtual void instrumentBr(LoweringContext &, class InstBr *) {} + virtual void instrumentCall(LoweringContext &, class InstCall *) {} + virtual void instrumentCast(LoweringContext &, class InstCast *) {} virtual void instrumentExtractElement(LoweringContext &, - const class InstExtractElement *) {} - virtual void instrumentFcmp(LoweringContext &, const class InstFcmp *) {} - virtual void instrumentIcmp(LoweringContext &, const class InstIcmp *) {} + class InstExtractElement *) {} + virtual void instrumentFcmp(LoweringContext &, class InstFcmp *) {} + virtual void instrumentIcmp(LoweringContext &, class InstIcmp *) {} virtual void instrumentInsertElement(LoweringContext &, - const class InstInsertElement *) {} + class InstInsertElement *) {} virtual void instrumentIntrinsicCall(LoweringContext &, - const class InstIntrinsicCall *) {} - virtual void instrumentLoad(LoweringContext &, const class InstLoad *) {} - virtual void instrumentPhi(LoweringContext &, const class InstPhi *) {} - virtual void instrumentRet(LoweringContext &, const class InstRet *) {} - virtual void instrumentSelect(LoweringContext &, const class InstSelect *) {} - virtual void instrumentStore(LoweringContext &, const class InstStore *) {} - virtual void instrumentSwitch(LoweringContext &, const class InstSwitch *) {} + class InstIntrinsicCall *) {} + virtual void instrumentLoad(LoweringContext &, class InstLoad *) {} + virtual void instrumentPhi(LoweringContext &, class InstPhi *) {} + virtual void instrumentRet(LoweringContext &, class InstRet *) {} + virtual void instrumentSelect(LoweringContext &, class InstSelect *) {} + virtual void instrumentStore(LoweringContext &, class InstStore *) {} + virtual void instrumentSwitch(LoweringContext &, class InstSwitch *) {} virtual void instrumentUnreachable(LoweringContext &, - const class InstUnreachable *) {} + class InstUnreachable *) {} virtual void instrumentStart(Cfg *) {} virtual void instrumentLocalVars(Cfg *) {}