Skip to content

Commit 9e1a8b8

Browse files
authored
Merge pull request #107 from S2E/issue/xxx-executor-ref1
Various refactorings (round #1)
2 parents a623eca + 4d2d759 commit 9e1a8b8

File tree

90 files changed

+3388
-1083
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+3388
-1083
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ FROM ubuntu:22.04 AS s2e-build-env
2626
# The unzip and libgomp1 dependencies are needed to unzip and run binary Z3
2727
# distributions.
2828

29-
RUN dpkg --add-architecture i386 && apt-get update && \
29+
RUN apt-get update && dpkg --add-architecture i386 && apt-get update && \
3030
apt-get -y install sudo git ca-certificates build-essential cmake curl wget texinfo flex bison \
3131
python-is-python3 python3-dev python3-venv python3-distro mingw-w64 lsb-release \
3232
autoconf libtool libprotobuf-dev protobuf-compiler protobuf-c-compiler \

guest/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ include_directories("common/include")
3939

4040
# Determine the architecture to build for. By default build for 64-bit
4141
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=gnu99 -Werror -g")
42-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++17 -Werror -g")
42+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++20 -Werror -g")
4343
if(NOT BITS)
4444
message(FATAL_ERROR "BITS is not set")
4545
endif()

klee/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,11 @@ endif()
211211
# C++ version
212212
################################################################################
213213

214-
message(STATUS "Enabling C++17")
214+
message(STATUS "Enabling C++20")
215215
# FIXME: Use CMake's own mechanism for managing C++ version.
216216
# Set globally because it is unlikely we would want to compile
217217
# using mixed C++ versions.
218-
add_global_cxx_flag("-std=c++17" REQUIRED)
218+
add_global_cxx_flag("-std=c++20" REQUIRED)
219219

220220
# Uncomment this to enable code coverage recording
221221
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")

klee/include/klee/AddressSpace.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class AddressSpace {
8282
using IterateWriteCb = std::function<bool(ObjectStatePtr &, unsigned offset, unsigned size)>;
8383
bool iterateWrite(uintptr_t hostAddress, size_t size, IterateWriteCb cb, AddressTranslator tr);
8484

85+
/// ExecutionState that owns this AddressSpace
86+
IAddressSpaceNotification *m_state = nullptr;
87+
8588
protected:
8689
/// Unsupported, use copy constructor
8790
AddressSpace &operator=(const AddressSpace &);
@@ -103,19 +106,20 @@ class AddressSpace {
103106
/// \invariant forall o in objects, o->copyOnWriteOwner <= cowKey
104107
MemoryMap objects;
105108

106-
/// ExecutionState that owns this AddressSpace
107-
IAddressSpaceNotification *state;
108-
109109
public:
110-
AddressSpace(IAddressSpaceNotification *_state) : cowKey(1), state(_state) {
110+
AddressSpace(IAddressSpaceNotification *state) : cowKey(1), m_state(state) {
111111
}
112112

113-
AddressSpace(const AddressSpace &b) : cowKey(++b.cowKey), objects(b.objects) {
113+
AddressSpace(const AddressSpace &b) : cowKey(++b.cowKey), m_state(b.m_state), objects(b.objects) {
114114
}
115115

116116
~AddressSpace() {
117117
}
118118

119+
void setState(IAddressSpaceNotification *state) {
120+
m_state = state;
121+
}
122+
119123
/// Add a binding to the address space.
120124
void bindObject(const ObjectStatePtr &os);
121125

klee/include/klee/ExecutionState.h

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include "klee/util/Assignment.h"
2424
#include "IAddressSpaceNotification.h"
2525

26+
#include "IExecutionState.h"
27+
#include "LLVMExecutionState.h"
28+
2629
#include <map>
2730
#include <set>
2831
#include <vector>
@@ -34,88 +37,74 @@ struct KInstruction;
3437

3538
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const MemoryMap &mm);
3639

37-
struct StackFrame {
38-
KInstIterator caller;
39-
KFunction *kf;
40-
41-
llvm::SmallVector<ObjectKey, 16> allocas;
42-
llvm::SmallVector<Cell, 16> locals;
43-
44-
// For vararg functions: arguments not passed via parameter are
45-
// stored (packed tightly) in a local (alloca) memory object. This
46-
// is setup to match the way the front-end generates vaarg code (it
47-
// does not pass vaarg through as expected). VACopy is lowered inside
48-
// of intrinsic lowering.
49-
std::vector<ObjectKey> varargs;
50-
51-
StackFrame(KInstIterator _caller, KFunction *_kf) : caller(_caller), kf(_kf), varargs(0) {
52-
locals.resize(kf->getNumRegisters());
53-
}
54-
};
55-
56-
class ExecutionState : public IAddressSpaceNotification {
57-
friend class AddressSpace;
58-
40+
class ExecutionState : public IExecutionState, public IAddressSpaceNotification {
5941
public:
60-
typedef llvm::SmallVector<StackFrame, 16> stack_ty;
61-
6242
/// Set of objects that should not be merged by the base merge function.
6343
/// Overloaded functions will take care of it.
6444
static std::set<ObjectKey, ObjectKeyLTS> s_ignoredMergeObjects;
6545

6646
private:
6747
SolverPtr m_solver;
48+
AddressSpace m_addressSpace;
6849

69-
public:
70-
// pc - pointer to current instruction stream
71-
KInstIterator pc, prevPC;
72-
stack_ty stack;
73-
AddressSpace addressSpace;
74-
75-
/// Disables forking, set by user code.
76-
bool forkDisabled;
77-
78-
/// ordered list of symbolics: used to generate test cases.
79-
std::vector<ArrayPtr> symbolics;
80-
81-
AssignmentPtr concolics;
82-
83-
unsigned incomingBBIndex;
84-
85-
private:
8650
/// Simplifier user to simplify expressions when adding them
8751
static BitfieldSimplifier s_simplifier;
8852

8953
ConstraintManager m_constraints;
9054

91-
ExecutionState() : addressSpace(this) {
55+
ExecutionState() : m_addressSpace(this), llvm(this) {
9256
}
9357

9458
protected:
59+
/// ordered list of symbolics: used to generate test cases.
60+
std::vector<ArrayPtr> m_symbolics;
61+
AssignmentPtr m_concolics;
62+
9563
virtual void addressSpaceChange(const klee::ObjectKey &key, const ObjectStateConstPtr &oldState,
9664
const ObjectStatePtr &newState);
9765

9866
virtual void addressSpaceObjectSplit(const ObjectStateConstPtr &oldObject,
9967
const std::vector<ObjectStatePtr> &newObjects);
10068

10169
public:
70+
/// Disables forking, set by user code.
71+
bool forkDisabled;
72+
LLVMExecutionState llvm;
73+
74+
virtual SolverPtr solver() {
75+
return m_solver;
76+
}
77+
78+
virtual AddressSpace &addressSpace() {
79+
return m_addressSpace;
80+
}
81+
82+
virtual const AddressSpace &addressSpace() const {
83+
return m_addressSpace;
84+
}
85+
86+
virtual const std::vector<ArrayPtr> &symbolics() const {
87+
return m_symbolics;
88+
}
89+
90+
virtual const AssignmentPtr concolics() const {
91+
return m_concolics;
92+
}
93+
94+
virtual void setConcolics(AssignmentPtr concolics) {
95+
m_concolics = concolics;
96+
}
97+
10298
// Fired whenever an object becomes all concrete or gets at least one symbolic byte.
10399
// Only fired in the context of a memory operation (load/store)
104100
virtual void addressSpaceSymbolicStatusChange(const ObjectStatePtr &object, bool becameConcrete);
105101

106102
ExecutionState(KFunction *kf);
107103

108-
// XXX total hack, just used to make a state so solver can
109-
// use on structure
110-
ExecutionState(const std::vector<ref<Expr>> &assumptions);
111-
112104
virtual ~ExecutionState();
113105

114106
virtual ExecutionState *clone();
115107

116-
void pushFrame(KInstIterator caller, KFunction *kf);
117-
void popFrame();
118-
119108
const ConstraintManager &constraints() const {
120109
return m_constraints;
121110
}
@@ -145,8 +134,6 @@ class ExecutionState : public IAddressSpaceNotification {
145134

146135
virtual bool merge(const ExecutionState &b);
147136

148-
void printStack(std::stringstream &msg) const;
149-
150137
bool getSymbolicSolution(std::vector<std::pair<std::string, std::vector<unsigned char>>> &res);
151138

152139
ref<Expr> simplifyExpr(const ref<Expr> &e) const;
@@ -168,13 +155,6 @@ class ExecutionState : public IAddressSpaceNotification {
168155

169156
SolverPtr solver() const;
170157

171-
Cell &getArgumentCell(KFunction *kf, unsigned index);
172-
Cell &getDestCell(KInstruction *target);
173-
174-
void bindLocal(KInstruction *target, ref<Expr> value);
175-
void bindArgument(KFunction *kf, unsigned index, ref<Expr> value);
176-
void stepInstruction();
177-
178158
// Given a concrete object in our [klee's] address space, add it to
179159
// objects checked code can reference.
180160
ObjectStatePtr addExternalObject(void *addr, unsigned size, bool isReadOnly, bool isSharedConcrete = false);
@@ -203,7 +183,8 @@ class ExecutionState : public IAddressSpaceNotification {
203183
void executeAlloc(ref<Expr> size, bool isLocal, KInstruction *target, bool zeroMemory = false,
204184
const ObjectStatePtr &reallocFrom = nullptr);
205185

206-
void transferToBasicBlock(llvm::BasicBlock *dst, llvm::BasicBlock *src);
186+
ref<Expr> executeMemoryRead(uint64_t concreteAddress, unsigned bytes);
187+
void executeMemoryWrite(uint64_t concreteAddress, const ref<Expr> &value);
207188
};
208189
} // namespace klee
209190

klee/include/klee/Executor.h

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -60,42 +60,52 @@ class BitfieldSimplifier;
6060
class SolverFactory;
6161
template <class T> class ref;
6262

63+
class LLVMExecutorException : public std::runtime_error {
64+
public:
65+
LLVMExecutorException(const std::string &msg) : std::runtime_error(msg) {
66+
}
67+
};
68+
6369
class Executor {
6470
public:
6571
typedef std::pair<ExecutionState *, ExecutionState *> StatePair;
6672

6773
protected:
68-
KModulePtr kmodule;
69-
Searcher *searcher;
74+
// ======= LLVM management =======
75+
KModulePtr m_kmodule;
76+
/// The set of functions that must be handled via custom function handlers
77+
/// instead of being called directly.
78+
std::set<llvm::Function *> m_overridenInternalFunctions;
79+
80+
/// Map of globals to their bound address. This also includes
81+
/// globals that have no representative object (i.e. functions).
82+
GlobalAddresses m_globalAddresses;
83+
84+
/// Map of globals to their representative memory object.
85+
std::map<const llvm::GlobalValue *, ObjectKey> m_globalObjects;
86+
87+
/// Map of predefined global values
88+
std::map<std::string, void *> m_predefinedSymbols;
89+
90+
std::unique_ptr<SpecialFunctionHandler> m_specialFunctionHandler;
91+
92+
// ======= Misc =======
7093

71-
ExternalDispatcher *externalDispatcher;
72-
StateSet states;
73-
SpecialFunctionHandler *specialFunctionHandler;
94+
std::unique_ptr<ExternalDispatcher> m_externalDispatcher;
7495

96+
// ======= Execution state management =======
97+
Searcher *m_searcher;
98+
StateSet m_states;
7599
/// Used to track states that have been added during the current
76100
/// instructions step.
77101
/// \invariant \ref addedStates is a subset of \ref states.
78102
/// \invariant \ref addedStates and \ref removedStates are disjoint.
79-
StateSet addedStates;
103+
StateSet m_addedStates;
80104
/// Used to track states that have been removed during the current
81105
/// instructions step.
82106
/// \invariant \ref removedStates is a subset of \ref states.
83107
/// \invariant \ref addedStates and \ref removedStates are disjoint.
84-
StateSet removedStates;
85-
86-
/// Map of predefined global values
87-
std::map<std::string, void *> predefinedSymbols;
88-
89-
/// Map of globals to their representative memory object.
90-
std::map<const llvm::GlobalValue *, ObjectKey> globalObjects;
91-
92-
/// Map of globals to their bound address. This also includes
93-
/// globals that have no representative object (i.e. functions).
94-
GlobalAddresses globalAddresses;
95-
96-
/// The set of functions that must be handled via custom function handlers
97-
/// instead of being called directly.
98-
std::set<llvm::Function *> overridenInternalFunctions;
108+
StateSet m_removedStates;
99109

100110
llvm::Function *getTargetFunction(llvm::Value *calledVal);
101111

@@ -112,9 +122,6 @@ class Executor {
112122

113123
void executeCall(ExecutionState &state, KInstruction *ki, llvm::Function *f, std::vector<ref<Expr>> &arguments);
114124

115-
ref<Expr> executeMemoryOperation(ExecutionState &state, bool isWrite, uint64_t concreteAddress,
116-
ref<Expr> value /* undef if read */, unsigned bytes);
117-
118125
// do address resolution / object binding / out of bounds checking
119126
// and perform the operation
120127
void executeMemoryOperation(ExecutionState &state, bool isWrite, ref<Expr> address,
@@ -131,13 +138,11 @@ class Executor {
131138
/// allows plugins to kill states and exit to the CPU loop safely.
132139
virtual void notifyFork(ExecutionState &originalState, ref<Expr> &condition, Executor::StatePair &targets);
133140

134-
const Cell &eval(KInstruction *ki, unsigned index, ExecutionState &state) const;
141+
const Cell &eval(KInstruction *ki, unsigned index, LLVMExecutionState &state) const;
135142

136143
// delete the state (called internally by terminateState and updateStates)
137144
virtual void deleteState(ExecutionState *state);
138145

139-
void handlePointsToObj(ExecutionState &state, KInstruction *target, const std::vector<ref<Expr>> &arguments);
140-
141146
typedef void (*FunctionHandler)(Executor *executor, ExecutionState *state, KInstruction *target,
142147
std::vector<ref<Expr>> &arguments);
143148

@@ -170,26 +175,22 @@ class Executor {
170175

171176
/*** State accessor methods ***/
172177
size_t getStatesCount() const {
173-
return states.size();
178+
return m_states.size();
174179
}
175180
const StateSet &getStates() {
176-
return states;
181+
return m_states;
177182
}
178183

179184
const StateSet &getAddedStates() {
180-
return addedStates;
185+
return m_addedStates;
181186
}
182187

183188
const StateSet &getRemovedStates() {
184-
return removedStates;
185-
}
186-
187-
ExternalDispatcher *getDispatcher() const {
188-
return externalDispatcher;
189+
return m_removedStates;
189190
}
190191

191192
KModulePtr getModule() const {
192-
return kmodule;
193+
return m_kmodule;
193194
}
194195
};
195196

0 commit comments

Comments
 (0)