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; +}