Skip to content

Commit

Permalink
src: add node's internals constants
Browse files Browse the repository at this point in the history
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.

PR-URL: #204
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
  • Loading branch information
Matheus Marchini committed Jun 22, 2018
1 parent 679055f commit 3c3fb94
Show file tree
Hide file tree
Showing 15 changed files with 620 additions and 274 deletions.
3 changes: 3 additions & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,13 @@
"target_name": "plugin",
"type": "shared_library",
"sources": [
"src/constants.cc",
"src/error.cc",
"src/llnode.cc",
"src/llv8.cc",
"src/llv8-constants.cc",
"src/llscan.cc",
"src/node-constants.cc",
]
}],
}
121 changes: 121 additions & 0 deletions src/constants.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include <cinttypes>

#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,
Error& err) {
SBError sberr;
T res = 0;
target.ReadMemory(start, &res, sizeof(T), sberr);
if (!sberr.Fail()) {
err = Error::Ok();
} else {
err = Error::Failure("Failed to read symbol %s", name);
}
return res;
}

int64_t Constants::LookupConstant(SBTarget target, const char* name,
int64_t def, Error& err) {
int64_t res = 0;
res = def;

SBSymbolContextList context_list = target.FindSymbols(name);

if (!context_list.IsValid() || context_list.GetSize() == 0) {
err = Error::Failure("Failed to find symbol %s", name);
return res;
}

SBSymbolContext context = context_list.GetContextAtIndex(0);
SBSymbol symbol = context.GetSymbol();
if (!symbol.IsValid()) {
err = Error::Failure("Failed to fetch symbol %s from context", name);
return res;
}

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
if (size >= 8) {
res = ReadSymbolFromTarget<int64_t>(target, start, name, err);
} else if (size == 4) {
int32_t tmp = ReadSymbolFromTarget<int32_t>(target, start, name, err);
res = static_cast<int64_t>(tmp);
} else if (size == 2) {
int16_t tmp = ReadSymbolFromTarget<int16_t>(target, start, name, err);
res = static_cast<int64_t>(tmp);
} else if (size == 1) {
int8_t tmp = ReadSymbolFromTarget<int8_t>(target, start, name, err);
res = static_cast<int64_t>(tmp);
} else {
err = Error::Failure("Unexpected symbol size %" PRIu32 " of symbol %s",
size, name);
}

return res;
}

void Constants::Assign(SBTarget target) {
loaded_ = false;
target_ = target;
}


int64_t Constants::LoadRawConstant(const char* name, int64_t def) {
Error err;
int64_t v = Constants::LookupConstant(target_, name, def, err);
if (err.Fail()) {
Error::PrintInDebugMode(
"Failed to load raw constant %s, default to %" PRId64, name, def);
}

return v;
}

int64_t Constants::LoadConstant(const char* name, Error& err, int64_t def) {
int64_t v = Constants::LookupConstant(
target_, (constant_prefix() + name).c_str(), def, err);
return v;
}

int64_t Constants::LoadConstant(const char* name, int64_t def) {
Error err;
int64_t v = LoadConstant(name, err, def);
if (err.Fail()) {
Error::PrintInDebugMode("Failed to load constant %s, default to %" PRId64,
name, def);
}

return v;
}

int64_t Constants::LoadConstant(const char* name, const char* fallback,
int64_t def) {
Error err;
int64_t v = LoadConstant(name, err, def);
if (err.Fail()) v = LoadConstant(fallback, err, def);
if (err.Fail()) {
Error::PrintInDebugMode(
"Failed to load constant %s, fallback %s, default to %" PRId64, name,
fallback, def);
}

return v;
}


} // namespace llnode
47 changes: 47 additions & 0 deletions src/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef SRC_CONSTANTS_H_
#define SRC_CONSTANTS_H_

#include <lldb/API/LLDB.h>
#include <string>

#include "src/error.h"

using lldb::SBTarget;

namespace llnode {

#define CONSTANTS_DEFAULT_METHODS(NAME) \
inline NAME* operator()() { \
if (loaded_) return this; \
loaded_ = true; \
Load(); \
return this; \
}

class Constants {
public:
Constants() : loaded_(false) {}

inline bool is_loaded() const { return loaded_; }

void Assign(lldb::SBTarget target);

inline virtual std::string constant_prefix() { return ""; };

static int64_t LookupConstant(SBTarget target, const char* name, int64_t def,
Error& err);

protected:
int64_t LoadRawConstant(const char* name, int64_t def = -1);
int64_t LoadConstant(const char* name, Error& err, int64_t def = -1);
int64_t LoadConstant(const char* name, int64_t def = -1);
int64_t LoadConstant(const char* name, const char* fallback,
int64_t def = -1);

lldb::SBTarget target_;
bool loaded_;
};

} // namespace llnode

#endif
46 changes: 46 additions & 0 deletions src/error.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <cstdarg>

#include "error.h"

namespace llnode {
bool Error::is_debug_mode = false;

Error::Error(bool failed, const char* format, ...) {
failed_ = failed;
char tmp[kMaxMessageLength];
va_list arglist;
va_start(arglist, format);
vsnprintf(tmp, sizeof(tmp), format, arglist);
va_end(arglist);
msg_ = tmp;
}


void Error::PrintInDebugMode(const char* format, ...) {
if (!is_debug_mode) {
return;
}
char fmt[kMaxMessageLength];
snprintf(fmt, sizeof(fmt), "[llv8] %s\n", format);
va_list arglist;
va_start(arglist, format);
vfprintf(stderr, fmt, arglist);
va_end(arglist);
}


Error Error::Failure(std::string msg) {
PrintInDebugMode("%s", msg.c_str());
return Error(true, msg);
}


Error Error::Failure(const char* format, ...) {
char tmp[kMaxMessageLength];
va_list arglist;
va_start(arglist, format);
vsnprintf(tmp, sizeof(tmp), format, arglist);
va_end(arglist);
return Error::Failure(std::string(tmp));
}
} // namespace llnode
37 changes: 37 additions & 0 deletions src/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef SRC_ERROR_H_
#define SRC_ERROR_H_

#include <string>

namespace llnode {

class Error {
public:
Error() : failed_(false), msg_("") {}
Error(bool failed, std::string msg) : failed_(failed), msg_(msg) {}
Error(bool failed, const char* format, ...)
__attribute__((format(printf, 3, 4)));

static inline Error Ok() { return Error(false, "ok"); }
static Error Failure(std::string msg);
static Error Failure(const char* format, ...)
__attribute__((format(printf, 1, 2)));
static void PrintInDebugMode(const char* format, ...)
__attribute__((format(printf, 1, 2)));

inline bool Success() const { return !Fail(); }
inline bool Fail() const { return failed_; }

inline const char* GetMessage() { return msg_.c_str(); }

static void SetDebugMode(bool mode) { is_debug_mode = mode; }

private:
bool failed_;
std::string msg_;
static const size_t kMaxMessageLength = 128;
static bool is_debug_mode;
};
} // namespace llnode

#endif
11 changes: 6 additions & 5 deletions src/llnode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <lldb/API/SBExpressionOptions.h>

#include "src/error.h"
#include "src/llnode.h"
#include "src/llscan.h"
#include "src/llv8.h"
Expand Down Expand Up @@ -121,15 +122,15 @@ bool BacktraceCmd::DoExecute(SBDebugger d, char** cmd,
const uint64_t pc = frame.GetPC();

if (!frame.GetSymbol().IsValid()) {
v8::Error err;
Error err;
v8::JSFrame v8_frame(llv8_, static_cast<int64_t>(frame.GetFP()));
std::string res = v8_frame.Inspect(true, err);
if (err.Success()) {
result.Printf(" %c frame #%u: 0x%016" PRIx64 " %s\n", star, i, pc,
res.c_str());
continue;
} else {
v8::Error::PrintInDebugMode("%s", err.GetMessage());
Error::PrintInDebugMode("%s", err.GetMessage());
}
}

Expand Down Expand Up @@ -199,7 +200,7 @@ bool PrintCmd::DoExecute(SBDebugger d, char** cmd,
llv8_->Load(target);

v8::Value v8_value(llv8_, value.GetValueAsSigned());
v8::Error err;
Error err;
std::string res = v8_value.Inspect(&inspect_options, err);
if (err.Fail()) {
result.SetError(err.GetMessage());
Expand Down Expand Up @@ -278,7 +279,7 @@ bool ListCmd::DoExecute(SBDebugger d, char** cmd,
}

// V8 frame
v8::Error err;
Error err;
v8::JSFrame v8_frame(llv8_, static_cast<int64_t>(frame.GetFP()));

const static uint32_t kDisplayLines = 4;
Expand Down Expand Up @@ -309,7 +310,7 @@ void InitDebugMode() {
is_debug_mode = true;
}

v8::Error::SetDebugMode(is_debug_mode);
Error::SetDebugMode(is_debug_mode);
}

} // namespace llnode
Expand Down
Loading

0 comments on commit 3c3fb94

Please sign in to comment.