about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--lib/Core/Executor.cpp6
-rw-r--r--lib/Core/MemoryManager.cpp17
-rw-r--r--lib/Core/MemoryManager.h3
-rw-r--r--test/Feature/32BitAlloc.c15
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;
+}