diff options
author | Dan Liew <daniel.liew@imperial.ac.uk> | 2015-10-17 18:32:19 +0100 |
---|---|---|
committer | Dan Liew <daniel.liew@imperial.ac.uk> | 2015-10-17 18:46:34 +0100 |
commit | 2a7c7f81a70f1266cf67471861bffc8f2192ce18 (patch) | |
tree | 10b1702040e82d859cde6fffa460244ea6b627df | |
parent | 50b9e95064a8a312c365fda57ed5729cd91706ba (diff) | |
download | klee-2a7c7f81a70f1266cf67471861bffc8f2192ce18.tar.gz |
Implement gross hack to make it possible to execute code compiled
with -m32 (i.e. for i386). Previously if this was attempt allocations in the program being executed by KLEE would hit an assertion because malloc() would return an address that doesn't fit in a 32-bit pointer. The interface of MemoryManager has been changed so that it is necessary to specify the pointer size on creation. The implementation has been changed to use a MASSIVE HACK when the pointer width is less than 64-bits.
-rw-r--r-- | lib/Core/Executor.cpp | 6 | ||||
-rw-r--r-- | lib/Core/MemoryManager.cpp | 17 | ||||
-rw-r--r-- | lib/Core/MemoryManager.h | 3 | ||||
-rw-r--r-- | test/Feature/32BitAlloc.c | 15 |
4 files changed, 37 insertions, 4 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 49e526f5..29e6486f 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -276,6 +276,7 @@ Executor::Executor(const InterpreterOptions &opts, interpreterHandler(ih), searcher(0), externalDispatcher(new ExternalDispatcher()), + memory(0), // Can't be initialised until we know the pointer size statsTracker(0), pathWriter(0), symPathWriter(0), @@ -337,7 +338,6 @@ Executor::Executor(const InterpreterOptions &opts, this->solver = new TimingSolver(solver, EqualitySubstitution); - memory = new MemoryManager(); } @@ -355,7 +355,7 @@ const Module *Executor::setModule(llvm::Module *module, #endif Context::initialize(TD->isLittleEndian(), (Expr::Width) TD->getPointerSizeInBits()); - + memory = new MemoryManager(TD->getPointerSizeInBits()); specialFunctionHandler = new SpecialFunctionHandler(*this); specialFunctionHandler->prepare(); @@ -3415,7 +3415,7 @@ void Executor::runFunctionAsMain(Function *f, // hack to clear memory objects delete memory; - memory = new MemoryManager(); + memory = new MemoryManager(Context::get().getPointerWidth()); globalObjects.clear(); globalAddresses.clear(); diff --git a/lib/Core/MemoryManager.cpp b/lib/Core/MemoryManager.cpp index a1198007..0caa504d 100644 --- a/lib/Core/MemoryManager.cpp +++ b/lib/Core/MemoryManager.cpp @@ -12,16 +12,33 @@ #include "CoreStats.h" #include "Memory.h" #include "MemoryManager.h" +#include "Context.h" #include "klee/ExecutionState.h" #include "klee/Expr.h" #include "klee/Solver.h" #include "llvm/Support/CommandLine.h" +#include "malloc.h" using namespace klee; /***/ +MemoryManager::MemoryManager(size_t pointerBitWidth) : + pointerBitWidth(pointerBitWidth) { + if (pointerBitWidth < 64) { + // FIXME: KLEE should implement it's own memory manager for + // the program we are executing and not invoke malloc so + // we have finer control over the addresses we use. + // HACK: + // Try make sure malloc() gives us back + // addresses that fit in a 32-bit integer when running + // 32-bit code. + // This works by preventing malloc() from using mmap() + // so it uses sbrk() instead... gross + mallopt(M_MMAP_MAX, 0); + } +} MemoryManager::~MemoryManager() { while (!objects.empty()) { diff --git a/lib/Core/MemoryManager.h b/lib/Core/MemoryManager.h index f398db62..d87ebe41 100644 --- a/lib/Core/MemoryManager.h +++ b/lib/Core/MemoryManager.h @@ -24,9 +24,10 @@ namespace klee { private: typedef std::set<MemoryObject*> objects_ty; objects_ty objects; + size_t pointerBitWidth; public: - MemoryManager() {} + MemoryManager(size_t pointerBitWidth); ~MemoryManager(); MemoryObject *allocate(uint64_t size, bool isLocal, bool isGlobal, diff --git a/test/Feature/32BitAlloc.c b/test/Feature/32BitAlloc.c new file mode 100644 index 00000000..311dc239 --- /dev/null +++ b/test/Feature/32BitAlloc.c @@ -0,0 +1,15 @@ +// RUN: %llvmgcc %s -emit-llvm -m32 -O0 -c -o %t1.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee --output-dir=%t.klee-out %t1.bc + +// This simply tests that allocation works when +// running 32-bit code + +// FIXME: This test only needs to run on x86_64 +int main() { + int a[100000]; + for (int i=0; i < 5000; ++i) { + a[i] = i; + } + return 0; +} |