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 *) {}