move out value retrieval from expression evaluation. add get_value()
This commit is contained in:
+22
-19
@@ -180,6 +180,27 @@ uint32_t __pst_context::print_expr_block (Dwarf_Op *exprs, int len, char* buff,
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool __pst_context::get_value(uint64_t& value)
|
||||||
|
{
|
||||||
|
if(!stack.Size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = 0;
|
||||||
|
dwarf_value* v = stack.get();
|
||||||
|
v->get_uint(value);
|
||||||
|
if(v->type & DWARF_TYPE_REGISTER_LOC) {
|
||||||
|
// dereference register location
|
||||||
|
uint64_t regno = value;
|
||||||
|
if(unw_get_reg(&cursor, regno, &value)) {
|
||||||
|
log(SEVERITY_ERROR, "Failed to get value of register 0x%lX", regno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool __pst_context::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr)
|
bool __pst_context::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr)
|
||||||
{
|
{
|
||||||
stack.clear();
|
stack.clear();
|
||||||
@@ -217,6 +238,7 @@ bool __pst_context::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
|
|||||||
log(SEVERITY_ERROR, "Failed to calculate sub-expression for operation %s(0x%lX, 0x%lX)", map->op_name, exprs[i].number, exprs[i].number2);
|
log(SEVERITY_ERROR, "Failed to calculate sub-expression for operation %s(0x%lX, 0x%lX)", map->op_name, exprs[i].number, exprs[i].number2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr location");
|
log(SEVERITY_ERROR, "Failed to get DW_OP_GNU_entry_value attr location");
|
||||||
}
|
}
|
||||||
@@ -232,25 +254,6 @@ bool __pst_context::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stack.Size()) {
|
|
||||||
unw_word_t value = 0;
|
|
||||||
dwarf_value* v = stack.get();
|
|
||||||
v->get_uint(value);
|
|
||||||
if(v->type & DWARF_TYPE_REGISTER_LOC) {
|
|
||||||
// dereference register location
|
|
||||||
uint64_t regno = value;
|
|
||||||
if(unw_get_reg(&cursor, regno, &value)) {
|
|
||||||
log(SEVERITY_ERROR, "Failed to get value of register 0x%lX", regno);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log(SEVERITY_INFO, "Found 0x%X value of location expression", value);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
log(SEVERITY_ERROR, "No value found for location expression");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ typedef struct __pst_context {
|
|||||||
void log(SC_LogSeverity severity, const char*fmt, ...);
|
void log(SC_LogSeverity severity, const char*fmt, ...);
|
||||||
uint32_t print_expr_block(Dwarf_Op *exprs, int len, char* buff, uint32_t buff_size, Dwarf_Attribute* attr = 0);
|
uint32_t print_expr_block(Dwarf_Op *exprs, int len, char* buff, uint32_t buff_size, Dwarf_Attribute* attr = 0);
|
||||||
bool calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr);
|
bool calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr);
|
||||||
|
bool get_value(uint64_t& value);
|
||||||
|
|
||||||
ucontext_t* hcontext; // context of signal handler
|
ucontext_t* hcontext; // context of signal handler
|
||||||
unw_context_t context; // context of stack trace
|
unw_context_t context; // context of stack trace
|
||||||
|
|||||||
+36
-9
@@ -210,9 +210,17 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result)
|
|||||||
size_t exprlen;
|
size_t exprlen;
|
||||||
if (dwarf_getlocation(attr, &expr, &exprlen) == 0) {
|
if (dwarf_getlocation(attr, &expr, &exprlen) == 0) {
|
||||||
char str[1024]; str[0] = 0;
|
char str[1024]; str[0] = 0;
|
||||||
ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr);
|
ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr);
|
||||||
ctx->log(SEVERITY_DEBUG, "DW_AT_location expression: %s", str);
|
if(ctx->calc_expression(expr, exprlen, attr)) {
|
||||||
ctx->calc_expression(expr, exprlen, attr);
|
uint64_t value;
|
||||||
|
if(ctx->get_value(value)) {
|
||||||
|
ctx->log(SEVERITY_DEBUG, "DW_AT_location expression: \"%s\" ==> 0x%lX", str, value);
|
||||||
|
} else {
|
||||||
|
ctx->log(SEVERITY_ERROR, "Failed to get value of calculated DW_AT_location expression: %s", str);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx->log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(dwarf_hasform(attr, DW_FORM_sec_offset)) {
|
} else if(dwarf_hasform(attr, DW_FORM_sec_offset)) {
|
||||||
Dwarf_Addr base, start, end;
|
Dwarf_Addr base, start, end;
|
||||||
@@ -224,10 +232,21 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result)
|
|||||||
for(int i = 0; (off = dwarf_getlocations (attr, off, &base, &start, &end, &expr, &exprlen)) > 0; ++i) {
|
for(int i = 0; (off = dwarf_getlocations (attr, off, &base, &start, &end, &expr, &exprlen)) > 0; ++i) {
|
||||||
if(offset >= start && offset <= end) {
|
if(offset >= start && offset <= end) {
|
||||||
// actual location, try to calculate Location expression and retrieve value of parameter
|
// actual location, try to calculate Location expression and retrieve value of parameter
|
||||||
char str[1024]; str[0] = 0;
|
char str[1024]; str[0] = 0;
|
||||||
ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr);
|
ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr);
|
||||||
ctx->log(SEVERITY_DEBUG, "Location list expression: [%d] low_offset: 0x%" PRIx64 ", high_offset: 0x%" PRIx64 " ==> %s", i, start, end, str);
|
if(ctx->calc_expression(expr, exprlen, attr)) {
|
||||||
ctx->calc_expression(expr, exprlen, attr);
|
uint64_t value;
|
||||||
|
if(ctx->get_value(value)) {
|
||||||
|
ctx->log(SEVERITY_DEBUG, "Location list expression: [%d] (low_offset: 0x%" PRIx64 ", high_offset: 0x%" PRIx64"), \"%s\" ==> 0x%lX", i, start, end, str, value);
|
||||||
|
} else {
|
||||||
|
ctx->log(SEVERITY_DEBUG, "Failed to get value of calculated Location list expression: [%d] (low_offset: 0x%" PRIx64 ", high_offset: 0x%" PRIx64 "), \"%s\" ==> 0x%lX",
|
||||||
|
i, start, end, str, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx->log(SEVERITY_DEBUG, "Failed to calculate Location list expression: [%d] (low_offset: 0x%" PRIx64 ", high_offset: 0x%" PRIx64 "), \"%s\" ==> 0x%lX",
|
||||||
|
i, start, end, str, value);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Location skipped due to don't match current PC offset
|
// Location skipped due to don't match current PC offset
|
||||||
}
|
}
|
||||||
@@ -274,8 +293,16 @@ bool __pst_function::handle_dwarf(Dwarf_Die* d)
|
|||||||
if (dwarf_getlocation (attr, &expr, &exprlen) == 0) {
|
if (dwarf_getlocation (attr, &expr, &exprlen) == 0) {
|
||||||
char str[1024]; str[0] = 0;
|
char str[1024]; str[0] = 0;
|
||||||
ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr);
|
ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr);
|
||||||
ctx->log(SEVERITY_DEBUG, "Found DW_AT_framebase expression: %s", str);
|
if(ctx->calc_expression(expr, exprlen, attr)) {
|
||||||
ctx->calc_expression(expr, exprlen, attr);
|
uint64_t value;
|
||||||
|
if(ctx->get_value(value)) {
|
||||||
|
ctx->log(SEVERITY_DEBUG, "DW_AT_framebase expression: \"%s\"==> 0x%lX", str, value);
|
||||||
|
} else {
|
||||||
|
ctx->log(SEVERITY_ERROR, "Failed to get value of calculated DW_AT_framebase expression: %s", str);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx->log(SEVERITY_ERROR, "Failed to calculate DW_AT_framebase expression: %s", str);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx->log(SEVERITY_WARNING, "Unknown attribute form = 0x%X, code = 0x%X", attr->form, attr->code);
|
ctx->log(SEVERITY_WARNING, "Unknown attribute form = 0x%X, code = 0x%X", attr->form, attr->code);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user