Index: src/IceASanInstrumentation.cpp |
diff --git a/src/IceASanInstrumentation.cpp b/src/IceASanInstrumentation.cpp |
index 589bf1a04f3090c3db04824db05317a8e6a8e145..c1b1bccfe35899956f14d62eb0c79ebd34d98463 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 @@ constexpr SizeT RzSize = 32; |
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,40 @@ ASanInstrumentation::createRz(VariableDeclarationList *List, |
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 |