Skip to content

Commit b814884

Browse files
author
Matheus Marchini
committed
src: add node's internals constants
This commit refactors llv8-constants to make it easier to introduce Node's internals constants. Common code for llv8 and node constants is now on src/constants.h. Also moved the Error class to its own file, removing the dependency on src/llv8.h to use Errors.
1 parent 679055f commit b814884

15 files changed

+613
-273
lines changed

binding.gyp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@
5858
"target_name": "plugin",
5959
"type": "shared_library",
6060
"sources": [
61+
"src/constants.cc",
62+
"src/error.cc",
6163
"src/llnode.cc",
6264
"src/llv8.cc",
6365
"src/llv8-constants.cc",
6466
"src/llscan.cc",
67+
"src/node-constants.cc",
6568
]
6669
}],
6770
}

src/constants.cc

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <cinttypes>
2+
3+
#include <lldb/API/SBExpressionOptions.h>
4+
5+
#include "src/constants.h"
6+
7+
using lldb::SBAddress;
8+
using lldb::SBError;
9+
using lldb::SBSymbol;
10+
using lldb::SBSymbolContext;
11+
using lldb::SBSymbolContextList;
12+
13+
namespace llnode {
14+
15+
template <typename T>
16+
T ReadSymbolFromTarget(SBTarget& target, SBAddress& start, const char* name,
17+
Error& err) {
18+
SBError sberr;
19+
T res = 0;
20+
target.ReadMemory(start, &res, sizeof(T), sberr);
21+
if (!sberr.Fail()) {
22+
err = Error::Ok();
23+
} else {
24+
err = Error::Failure("Failed to read symbol %s", name);
25+
}
26+
return res;
27+
}
28+
29+
int64_t Constants::LookupConstant(SBTarget target, const char* name,
30+
int64_t def, Error& err) {
31+
int64_t res = 0;
32+
res = def;
33+
34+
SBSymbolContextList context_list = target.FindSymbols(name);
35+
36+
if (!context_list.IsValid() || context_list.GetSize() == 0) {
37+
err = Error::Failure("Failed to find symbol %s", name);
38+
return res;
39+
}
40+
41+
SBSymbolContext context = context_list.GetContextAtIndex(0);
42+
SBSymbol symbol = context.GetSymbol();
43+
if (!symbol.IsValid()) {
44+
err = Error::Failure("Failed to fetch symbol %s from context", name);
45+
return res;
46+
}
47+
48+
SBAddress start = symbol.GetStartAddress();
49+
SBAddress end = symbol.GetEndAddress();
50+
uint32_t size = end.GetOffset() - start.GetOffset();
51+
52+
// NOTE: size could be bigger for at the end symbols
53+
if (size >= 8) {
54+
res = ReadSymbolFromTarget<int64_t>(target, start, name, err);
55+
} else if (size == 4) {
56+
int32_t tmp = ReadSymbolFromTarget<int32_t>(target, start, name, err);
57+
res = static_cast<int64_t>(tmp);
58+
} else if (size == 2) {
59+
int16_t tmp = ReadSymbolFromTarget<int16_t>(target, start, name, err);
60+
res = static_cast<int64_t>(tmp);
61+
} else if (size == 1) {
62+
int8_t tmp = ReadSymbolFromTarget<int8_t>(target, start, name, err);
63+
res = static_cast<int64_t>(tmp);
64+
} else {
65+
err = Error::Failure("Unexpected symbol size %" PRIu32 " of symbol %s",
66+
size, name);
67+
}
68+
69+
return res;
70+
}
71+
72+
void Constants::Assign(SBTarget target) {
73+
loaded_ = false;
74+
target_ = target;
75+
}
76+
77+
78+
int64_t Constants::LoadRawConstant(const char* name, int64_t def) {
79+
Error err;
80+
int64_t v = Constants::LookupConstant(target_, name, def, err);
81+
if (err.Fail()) {
82+
Error::PrintInDebugMode(
83+
"Failed to load raw constant %s, default to %" PRId64, name, def);
84+
}
85+
86+
return v;
87+
}
88+
89+
int64_t Constants::LoadConstant(const char* name, Error& err, int64_t def) {
90+
int64_t v = Constants::LookupConstant(
91+
target_, (constant_prefix() + name).c_str(), def, err);
92+
return v;
93+
}
94+
95+
int64_t Constants::LoadConstant(const char* name, int64_t def) {
96+
Error err;
97+
int64_t v = LoadConstant(name, err, def);
98+
if (err.Fail()) {
99+
Error::PrintInDebugMode("Failed to load constant %s, default to %" PRId64,
100+
name, def);
101+
}
102+
103+
return v;
104+
}
105+
106+
int64_t Constants::LoadConstant(const char* name, const char* fallback,
107+
int64_t def) {
108+
Error err;
109+
int64_t v = LoadConstant(name, err, def);
110+
if (err.Fail()) v = LoadConstant(fallback, err, def);
111+
if (err.Fail()) {
112+
Error::PrintInDebugMode(
113+
"Failed to load constant %s, fallback %s, default to %" PRId64, name,
114+
fallback, def);
115+
}
116+
117+
return v;
118+
}
119+
120+
121+
} // namespace llnode

src/constants.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#ifndef SRC_CONSTANTS_H_
2+
#define SRC_CONSTANTS_H_
3+
4+
#include <lldb/API/LLDB.h>
5+
#include <string>
6+
7+
#include "src/error.h"
8+
9+
using lldb::SBTarget;
10+
11+
namespace llnode {
12+
13+
#define CONSTANTS_DEFAULT_METHODS(NAME) \
14+
inline NAME* operator()() { \
15+
if (loaded_) return this; \
16+
loaded_ = true; \
17+
Load(); \
18+
return this; \
19+
}
20+
21+
class Constants {
22+
public:
23+
Constants() : loaded_(false) {}
24+
25+
inline bool is_loaded() const { return loaded_; }
26+
27+
void Assign(lldb::SBTarget target);
28+
29+
inline virtual std::string constant_prefix() { return ""; };
30+
31+
static int64_t LookupConstant(SBTarget target, const char* name, int64_t def,
32+
Error& err);
33+
34+
protected:
35+
int64_t LoadRawConstant(const char* name, int64_t def = -1);
36+
int64_t LoadConstant(const char* name, Error& err, int64_t def = -1);
37+
int64_t LoadConstant(const char* name, int64_t def = -1);
38+
int64_t LoadConstant(const char* name, const char* fallback,
39+
int64_t def = -1);
40+
41+
lldb::SBTarget target_;
42+
bool loaded_;
43+
};
44+
45+
} // namespace llnode
46+
47+
#endif

src/error.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <cstdarg>
2+
3+
#include "error.h"
4+
5+
namespace llnode {
6+
bool Error::is_debug_mode = false;
7+
8+
Error::Error(bool failed, const char* format, ...) {
9+
failed_ = failed;
10+
char tmp[kMaxMessageLength];
11+
va_list arglist;
12+
va_start(arglist, format);
13+
vsnprintf(tmp, sizeof(tmp), format, arglist);
14+
va_end(arglist);
15+
msg_ = tmp;
16+
}
17+
18+
19+
void Error::PrintInDebugMode(const char* format, ...) {
20+
if (!is_debug_mode) {
21+
return;
22+
}
23+
char fmt[kMaxMessageLength];
24+
snprintf(fmt, sizeof(fmt), "[llv8] %s\n", format);
25+
va_list arglist;
26+
va_start(arglist, format);
27+
vfprintf(stderr, fmt, arglist);
28+
va_end(arglist);
29+
}
30+
31+
32+
Error Error::Failure(std::string msg) {
33+
PrintInDebugMode("%s", msg.c_str());
34+
return Error(true, msg);
35+
}
36+
37+
38+
Error Error::Failure(const char* format, ...) {
39+
char tmp[kMaxMessageLength];
40+
va_list arglist;
41+
va_start(arglist, format);
42+
vsnprintf(tmp, sizeof(tmp), format, arglist);
43+
va_end(arglist);
44+
return Error::Failure(std::string(tmp));
45+
}
46+
} // namespace llnode

src/error.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#ifndef SRC_ERROR_H_
2+
#define SRC_ERROR_H_
3+
4+
#include <string>
5+
6+
namespace llnode {
7+
8+
class Error {
9+
public:
10+
Error() : failed_(false), msg_("") {}
11+
Error(bool failed, std::string msg) : failed_(failed), msg_(msg) {}
12+
Error(bool failed, const char* format, ...)
13+
__attribute__((format(printf, 3, 4)));
14+
15+
static inline Error Ok() { return Error(false, "ok"); }
16+
static Error Failure(std::string msg);
17+
static Error Failure(const char* format, ...)
18+
__attribute__((format(printf, 1, 2)));
19+
static void PrintInDebugMode(const char* format, ...)
20+
__attribute__((format(printf, 1, 2)));
21+
22+
inline bool Success() const { return !Fail(); }
23+
inline bool Fail() const { return failed_; }
24+
25+
inline const char* GetMessage() { return msg_.c_str(); }
26+
27+
static void SetDebugMode(bool mode) { is_debug_mode = mode; }
28+
29+
private:
30+
bool failed_;
31+
std::string msg_;
32+
static const size_t kMaxMessageLength = 128;
33+
static bool is_debug_mode;
34+
};
35+
} // namespace llnode
36+
37+
#endif

src/llnode.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <lldb/API/SBExpressionOptions.h>
99

10+
#include "src/error.h"
1011
#include "src/llnode.h"
1112
#include "src/llscan.h"
1213
#include "src/llv8.h"
@@ -121,7 +122,7 @@ bool BacktraceCmd::DoExecute(SBDebugger d, char** cmd,
121122
const uint64_t pc = frame.GetPC();
122123

123124
if (!frame.GetSymbol().IsValid()) {
124-
v8::Error err;
125+
Error err;
125126
v8::JSFrame v8_frame(llv8_, static_cast<int64_t>(frame.GetFP()));
126127
std::string res = v8_frame.Inspect(true, err);
127128
if (err.Success()) {
@@ -199,7 +200,7 @@ bool PrintCmd::DoExecute(SBDebugger d, char** cmd,
199200
llv8_->Load(target);
200201

201202
v8::Value v8_value(llv8_, value.GetValueAsSigned());
202-
v8::Error err;
203+
Error err;
203204
std::string res = v8_value.Inspect(&inspect_options, err);
204205
if (err.Fail()) {
205206
result.SetError(err.GetMessage());
@@ -278,7 +279,7 @@ bool ListCmd::DoExecute(SBDebugger d, char** cmd,
278279
}
279280

280281
// V8 frame
281-
v8::Error err;
282+
Error err;
282283
v8::JSFrame v8_frame(llv8_, static_cast<int64_t>(frame.GetFP()));
283284

284285
const static uint32_t kDisplayLines = 4;
@@ -309,7 +310,7 @@ void InitDebugMode() {
309310
is_debug_mode = true;
310311
}
311312

312-
v8::Error::SetDebugMode(is_debug_mode);
313+
Error::SetDebugMode(is_debug_mode);
313314
}
314315

315316
} // namespace llnode

0 commit comments

Comments
 (0)