Merged in the release_32 branch of SAFECode on July 5, 2013.
llvm-svn: 185750
diff --git a/safecode/lib/CommonMemorySafety/InstrumentMemoryAccesses.cpp b/safecode/lib/CommonMemorySafety/InstrumentMemoryAccesses.cpp
index 1ec2e5f..efe6dba 100644
--- a/safecode/lib/CommonMemorySafety/InstrumentMemoryAccesses.cpp
+++ b/safecode/lib/CommonMemorySafety/InstrumentMemoryAccesses.cpp
@@ -30,6 +30,7 @@
STATISTIC(LoadsInstrumented, "Loads instrumented");
STATISTIC(StoresInstrumented, "Stores instrumented");
STATISTIC(AtomicsInstrumented, "Atomic memory intrinsics instrumented");
+STATISTIC(IntrinsicsInstrumented, "Block memory intrinsics instrumented");
namespace {
class InstrumentMemoryAccesses : public FunctionPass,
@@ -66,6 +67,7 @@
void visitStoreInst(StoreInst &SI);
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I);
void visitAtomicRMWInst(AtomicRMWInst &I);
+ void visitMemIntrinsic(MemIntrinsic &MI);
};
} // end anon namespace
@@ -149,3 +151,15 @@
++AtomicsInstrumented;
}
+void InstrumentMemoryAccesses::visitMemIntrinsic(MemIntrinsic &MI) {
+ // Instrument llvm.mem[set|cpy|move].* calls with load/store checks.
+ Builder->SetInsertPoint(&MI);
+ Value *AccessSize = Builder->CreateIntCast(MI.getLength(), SizeTy,
+ /*isSigned=*/false);
+
+ // memcpy and memmove have a source memory area but memset doesn't
+ if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(&MI))
+ instrument(MTI->getSource(), AccessSize, LoadCheckFunction, MI);
+ instrument(MI.getDest(), AccessSize, StoreCheckFunction, MI);
+ ++IntrinsicsInstrumented;
+}
diff --git a/safecode/runtime/DebugRuntime/ExactCheck.cpp b/safecode/runtime/DebugRuntime/ExactCheck.cpp
index 426cb14..568a631 100755
--- a/safecode/runtime/DebugRuntime/ExactCheck.cpp
+++ b/safecode/runtime/DebugRuntime/ExactCheck.cpp
@@ -89,6 +89,13 @@
}
}
+ /*
+ * If the memory access accesses zero bytes, don't report an error. This can
+ * happen with load/store checks on memcpy()/memset() calls.
+ */
+ if (!lslen)
+ return;
+
failLSCheck (base, result, size, "unknown", 0);
return;
}
@@ -122,6 +129,13 @@
}
}
+ /*
+ * If the memory access accesses zero bytes, don't report an error. This can
+ * happen with load/store checks on memcpy()/memset() calls.
+ */
+ if (!lslen)
+ return;
+
failLSCheck (base, result, size, SourceFile, lineno);
return;
}
diff --git a/safecode/runtime/DebugRuntime/RuntimeChecks.cpp b/safecode/runtime/DebugRuntime/RuntimeChecks.cpp
index e236293..4a3638d 100755
--- a/safecode/runtime/DebugRuntime/RuntimeChecks.cpp
+++ b/safecode/runtime/DebugRuntime/RuntimeChecks.cpp
@@ -185,6 +185,14 @@
const char * SourceFilep,
unsigned lineno) {
//
+ // If the memory access is zero bytes in length, don't report an error.
+ // This can happen on memcpy() and memset() calls that are instrumented
+ // with load/store checks.
+ //
+ if (length == 0)
+ return;
+
+ //
// Check to see if the pointer points to an object within the pool. If it
// does, check to see if the last byte read/written will be within the same
// object. If so, then the check succeeds, so just return to the caller.
@@ -377,6 +385,14 @@
const char * SourceFilep,
unsigned lineno) {
//
+ // If the memory access is zero bytes in length, don't report an error.
+ // This can happen on memcpy() and memset() calls that are instrumented
+ // with load/store checks.
+ //
+ if (length == 0)
+ return;
+
+ //
// Check to see if the pointer points to an object within the pool. If it
// does, check to see if the last byte read/written will be within the same
// object. If so, then the check succeeds, so just return to the caller.
diff --git a/safecode/test/cstdlib/memcpy-004.c b/safecode/test/cstdlib/memcpy-004.c
new file mode 100644
index 0000000..a395247
--- /dev/null
+++ b/safecode/test/cstdlib/memcpy-004.c
@@ -0,0 +1,15 @@
+// RUN: test.sh -p -t %t %s
+#include <string.h>
+#include <assert.h>
+
+// Example of a memcpy() with zero length and bad input pointers
+
+int main()
+{
+ char src[] = "aaaaaaaaaab";
+ char dst[100];
+ volatile char * p;
+ p = memcpy(0, 0, 0);
+ printf ("%p\n", p);
+ return 0;
+}