-
Notifications
You must be signed in to change notification settings - Fork 1
/
memory.cpp
68 lines (57 loc) · 1.61 KB
/
memory.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <clover/clover.h>
using namespace clover;
ConcolicMemory::ConcolicMemory(Solver &_solver)
: solver(_solver)
{
return;
}
void
ConcolicMemory::reset(void)
{
data.clear();
}
std::shared_ptr<ConcolicValue>
ConcolicMemory::load(Addr addr, unsigned bytesize)
{
std::shared_ptr<ConcolicValue> result = nullptr;
for (uint32_t off = 0; off < bytesize; off++) {
auto read_addr = addr + off;
std::shared_ptr<ConcolicValue> byte;
if (data.count(read_addr)) {
byte = data.at(read_addr);
} else {
std::cerr << "WARNING: Uninitialized memory accessed at 0x"
<< std::hex << read_addr << " initializing with zero" << std::endl;
byte = solver.BVC(std::nullopt, (uint8_t)0);
}
if (!result) {
result = byte;
} else {
result = byte->concat(result);
}
}
return result;
}
std::shared_ptr<ConcolicValue>
ConcolicMemory::load(std::shared_ptr<ConcolicValue> addr, unsigned bytesize)
{
auto base_addr = solver.getValue<ConcolicMemory::Addr>(addr->concrete);
return load(base_addr, bytesize);
}
void
ConcolicMemory::store(Addr addr, std::shared_ptr<ConcolicValue> value, unsigned bytesize)
{
if (value->getWidth() < bytesize * 8)
value = value->zext(bytesize * 8);
for (size_t off = 0; off < bytesize; off++) {
// Extract expression works on bit indicies, not bytes.
data[addr + off] = value->extract(off * 8, klee::Expr::Int8);
}
}
void
ConcolicMemory::store(std::shared_ptr<ConcolicValue> addr, std::shared_ptr<ConcolicValue> value, unsigned bytesize)
{
auto base_addr = solver.getValue<ConcolicMemory::Addr>(addr->concrete);
return store(base_addr, value, bytesize);
}