Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 59 additions & 39 deletions src/constants.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include <cinttypes>
#include <initializer_list>
#include <iterator>
#include <sstream>

#include <lldb/API/SBExpressionOptions.h>

Expand All @@ -14,59 +17,52 @@ namespace llnode {

template <typename T>
T ReadSymbolFromTarget(SBTarget& target, SBAddress& start, const char* name,
Error& err) {
SBError sberr;
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) {
std::pair<int64_t, bool> Constants::LookupConstant(SBTarget target,
const char* name,
int64_t def) {
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;
return {res, false};
}

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;
return {res, false};
}

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

return res;
return {res, !sberr.Fail()};
}

void Constants::Assign(SBTarget target) {
Expand All @@ -76,44 +72,68 @@ void Constants::Assign(SBTarget 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()) {
auto v = Constants::LookupConstant(target_, name, def);
if (!v.second) {
PRINT_DEBUG("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;
return v.first;
}

int64_t Constants::LoadConstant(const char* name, int64_t def) {
Error err;
int64_t v = LoadConstant(name, err, def);
if (err.Fail()) {
auto v = Constants::LookupConstant(target_,
(constant_prefix() + name).c_str(), def);
if (!v.second) {
PRINT_DEBUG("Failed to load constant %s, default to %" PRId64, name, def);
}

return v;
return v.first;
}

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()) {
auto v = Constants::LookupConstant(target_,
(constant_prefix() + name).c_str(), def);
if (!v.second)
v = Constants::LookupConstant(target_,
(constant_prefix() + fallback).c_str(), def);
if (!v.second) {
PRINT_DEBUG("Failed to load constant %s, fallback %s, default to %" PRId64,
name, fallback, def);
}

return v;
return v.first;
}

Constant<int64_t> Constants::LoadConstant(
std::initializer_list<const char*> names) {
for (std::string name : names) {
auto v = Constants::LookupConstant(target_,
(constant_prefix() + name).c_str(), -1);
if (v.second) return Constant<int64_t>(v.first, name);
}

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 v = Constants::LookupConstant(target_,
(constant_prefix() + name).c_str(), -1);
if (v.second) return Constant<int64_t>(v.first, name);
}

return Constant<int64_t>(def);
}

} // namespace llnode
35 changes: 32 additions & 3 deletions src/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@ using lldb::SBTarget;

namespace llnode {

template <typename T>
class Constant {
public:
Constant() : value_(-1), valid_(false), loaded_(false) {}
explicit Constant(T value)
: value_(value), valid_(true), loaded_(false), name_("") {}
Constant(T value, std::string name)
: value_(value), valid_(true), loaded_(true), name_(name) {}

inline bool Check() { return valid_; }

inline bool Loaded() { return loaded_; }

T operator*() {
// TODO(mmarchini): Check()
return value_;
}

inline std::string name() { return name_; }

protected:
T value_;
bool valid_;
bool loaded_;
std::string name_;
};

#define CONSTANTS_DEFAULT_METHODS(NAME) \
inline NAME* operator()() { \
if (loaded_) return this; \
Expand All @@ -28,15 +55,17 @@ class Constants {

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

static int64_t LookupConstant(SBTarget target, const char* name, int64_t def,
Error& err);
static std::pair<int64_t, bool> LookupConstant(SBTarget target,
const char* name, int64_t def);

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);
Constant<int64_t> LoadConstant(std::initializer_list<const char*> names);
Constant<int64_t> LoadOptionalConstant(
std::initializer_list<const char*> names, int def);

lldb::SBTarget target_;
bool loaded_;
Expand Down
1 change: 1 addition & 0 deletions src/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Error {
inline const char* GetMessage() { return msg_.c_str(); }

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

private:
bool failed_;
Expand Down
6 changes: 3 additions & 3 deletions src/llscan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,7 @@ bool FindJSObjectsVisitor::MapCacheEntry::Load(v8::Map map,
if (is_histogram) type_name = heap_object.GetTypeName(err);

v8::HeapObject descriptors_obj = map.InstanceDescriptors(err);
if (err.Fail()) return false;
RETURN_IF_INVALID(descriptors_obj, false);

v8::DescriptorArray descriptors(descriptors_obj);
own_descriptors_count_ = map.NumberOfOwnDescriptors(err);
Expand All @@ -1579,8 +1579,8 @@ bool FindJSObjectsVisitor::MapCacheEntry::Load(v8::Map map,
}

for (uint64_t i = 0; i < own_descriptors_count_; i++) {
v8::Value key = descriptors.GetKey(i, err);
if (err.Fail()) continue;
v8::Value key = descriptors.GetKey(i);
if (!key.Check()) continue;
properties_.emplace_back(key.ToString(err));
}

Expand Down
Loading