-
Notifications
You must be signed in to change notification settings - Fork 99
/
Copy pathconstants.cc
141 lines (114 loc) · 3.84 KB
/
constants.cc
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <cinttypes>
#include <initializer_list>
#include <iterator>
#include <sstream>
#include <lldb/API/SBExpressionOptions.h>
#include "src/constants.h"
using lldb::SBAddress;
using lldb::SBError;
using lldb::SBSymbol;
using lldb::SBSymbolContext;
using lldb::SBSymbolContextList;
namespace llnode {
template <typename T>
T ReadSymbolFromTarget(SBTarget& target, SBAddress& start, const char* name,
SBError& sberr) {
T res = 0;
target.ReadMemory(start, &res, sizeof(T), sberr);
return res;
}
Constant<int64_t> Constants::LookupConstant(SBTarget target, const char* name) {
int64_t res;
SBSymbolContextList context_list = target.FindSymbols(name);
if (!context_list.IsValid() || context_list.GetSize() == 0) {
return Constant<int64_t>();
}
SBSymbolContext context = context_list.GetContextAtIndex(0);
SBSymbol symbol = context.GetSymbol();
if (!symbol.IsValid()) {
return Constant<int64_t>();
}
SBAddress start = symbol.GetStartAddress();
SBAddress end = symbol.GetEndAddress();
uint32_t size = end.GetOffset() - start.GetOffset();
// NOTE: size could be bigger for at the end symbols
SBError sberr;
if (size >= 8) {
res = ReadSymbolFromTarget<int64_t>(target, start, name, sberr);
} else if (size == 4) {
int32_t tmp = ReadSymbolFromTarget<int32_t>(target, start, name, sberr);
res = static_cast<int64_t>(tmp);
} else if (size == 2) {
int16_t tmp = ReadSymbolFromTarget<int16_t>(target, start, name, sberr);
res = static_cast<int64_t>(tmp);
} else if (size == 1) {
int8_t tmp = ReadSymbolFromTarget<int8_t>(target, start, name, sberr);
res = static_cast<int64_t>(tmp);
} else {
return Constant<int64_t>();
}
if (sberr.Fail()) return Constant<int64_t>();
return Constant<int64_t>(res, name);
}
void Constants::Assign(SBTarget target) {
loaded_ = false;
target_ = target;
}
int64_t Constants::LoadRawConstant(const char* name, int64_t def) {
auto constant = Constants::LookupConstant(target_, name);
if (!constant.Check()) {
PRINT_DEBUG("Failed to load raw constant %s, default to %" PRId64, name,
def);
return def;
}
return *constant;
}
int64_t Constants::LoadConstant(const char* name, int64_t def) {
auto constant =
Constants::LookupConstant(target_, (constant_prefix() + name).c_str());
if (!constant.Check()) {
PRINT_DEBUG("Failed to load constant %s, default to %" PRId64, name, def);
return def;
}
return *constant;
}
int64_t Constants::LoadConstant(const char* name, const char* fallback,
int64_t def) {
auto constant =
Constants::LookupConstant(target_, (constant_prefix() + name).c_str());
if (!constant.Check())
constant = Constants::LookupConstant(
target_, (constant_prefix() + fallback).c_str());
if (!constant.Check()) {
PRINT_DEBUG("Failed to load constant %s, fallback %s, default to %" PRId64,
name, fallback, def);
return def;
}
return *constant;
}
Constant<int64_t> Constants::LoadConstant(
std::initializer_list<const char*> names) {
for (std::string name : names) {
auto constant =
Constants::LookupConstant(target_, (constant_prefix() + name).c_str());
if (constant.Check()) return constant;
}
if (Error::IsDebugMode()) {
std::string joined = "";
for (std::string name : names) {
joined += (joined.empty() ? "'" : ", '") + name + "'";
}
PRINT_DEBUG("Failed to load constants: %s", joined.c_str());
}
return Constant<int64_t>();
}
Constant<int64_t> Constants::LoadOptionalConstant(
std::initializer_list<const char*> names, int def) {
for (std::string name : names) {
auto constant =
Constants::LookupConstant(target_, (constant_prefix() + name).c_str());
if (constant.Check()) return constant;
}
return Constant<int64_t>(def);
}
} // namespace llnode