diff --git a/framework/common.cpp b/framework/common.cpp index 440f6a8..1b82306 100644 --- a/framework/common.cpp +++ b/framework/common.cpp @@ -180,6 +180,27 @@ uint32_t __pst_context::print_expr_block (Dwarf_Op *exprs, int len, char* buff, 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) { 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); return false; } + continue; } else { 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; } diff --git a/framework/common.h b/framework/common.h index a6e32bb..29b4a3d 100644 --- a/framework/common.h +++ b/framework/common.h @@ -115,6 +115,7 @@ typedef struct __pst_context { 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); 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 unw_context_t context; // context of stack trace diff --git a/framework/sysutils.cpp b/framework/sysutils.cpp index cd6718c..c2cb758 100644 --- a/framework/sysutils.cpp +++ b/framework/sysutils.cpp @@ -210,9 +210,17 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result) size_t exprlen; if (dwarf_getlocation(attr, &expr, &exprlen) == 0) { char str[1024]; str[0] = 0; - ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr); - ctx->log(SEVERITY_DEBUG, "DW_AT_location expression: %s", str); - ctx->calc_expression(expr, exprlen, attr); + ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr); + if(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)) { 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) { if(offset >= start && offset <= end) { // actual location, try to calculate Location expression and retrieve value of parameter - char str[1024]; str[0] = 0; - 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); - ctx->calc_expression(expr, exprlen, attr); + char str[1024]; str[0] = 0; + ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr); + if(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 { // 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) { char str[1024]; str[0] = 0; ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr); - ctx->log(SEVERITY_DEBUG, "Found DW_AT_framebase expression: %s", str); - ctx->calc_expression(expr, exprlen, attr); + if(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 { ctx->log(SEVERITY_WARNING, "Unknown attribute form = 0x%X, code = 0x%X", attr->form, attr->code); }