From f9635841f6f4110cdef824a0547f94295fc247d6 Mon Sep 17 00:00:00 2001 From: Nikolai Nosov Date: Sun, 26 Jan 2020 15:36:33 +0400 Subject: [PATCH] right caculation of DW_OP_GNU_entry_value, use caller's information --- framework/dwarf_operations.cpp | 43 +++---- framework/dwarf_operations.h | 13 +-- framework/sysutils.cpp | 199 ++++++++++++++++++++++++--------- framework/sysutils.h | 57 ++++++++-- 4 files changed, 217 insertions(+), 95 deletions(-) diff --git a/framework/dwarf_operations.cpp b/framework/dwarf_operations.cpp index d7576f4..7582049 100644 --- a/framework/dwarf_operations.cpp +++ b/framework/dwarf_operations.cpp @@ -1111,7 +1111,7 @@ bool __dwarf_stack::get_value(uint64_t& value) uint64_t regno = value; int ret = unw_get_reg(ctx->curr_frame, regno, &value); if(ret) { - ctx->log(SEVERITY_ERROR, "Failed to get value of register 0x%X. Error: %d", __PRETTY_FUNCTION__, regno, ret); + ctx->log(SEVERITY_ERROR, "Failed to get value of register 0x%X. Error: %d", regno, ret); return false; } } else if(v->type & DWARF_TYPE_MEMORY_LOC) { @@ -1123,7 +1123,7 @@ bool __dwarf_stack::get_value(uint64_t& value) return true; } -bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr) +bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr, pst_function* fun) { clear(); for (int i = 0; i < expr_len; i++) { @@ -1143,7 +1143,7 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu uint64_t regno = *((uint64_t*)v->value); int ret = unw_get_reg(ctx->curr_frame, regno, &value); if(ret) { - ctx->log(SEVERITY_ERROR, "Failed to ger value of register 0x%X. Error: %d", __PRETTY_FUNCTION__, regno, ret); + ctx->log(SEVERITY_ERROR, "Failed to ger value of register 0x%X. Error: %d", regno, ret); return false; } v->replace(&value, sizeof(value), DWARF_TYPE_GENERIC); @@ -1151,6 +1151,14 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu // handle there because it contains sub-expression of a Location in caller's frame if(map->op_num == DW_OP_GNU_entry_value) { + if(!fun) { + ctx->log(SEVERITY_ERROR, "Cannot calculate DW_OP_GNU_entry_value expression while function is undefined"); + return false; + } + if(!fun->parent) { + ctx->log(SEVERITY_ERROR, "Function has not parent while calculate DW_OP_GNU_entry_value expression"); + return false; + } // This opcode has two operands, the first one is uleb128 length and the second is block of that length, containing either a // simple register or DWARF expression Dwarf_Attribute attr_mem; @@ -1158,26 +1166,19 @@ bool __dwarf_stack::calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribu Dwarf_Op *expr; size_t exprlen; if (dwarf_getlocation(&attr_mem, &expr, &exprlen) == 0) { - // save current frame cursor - unw_cursor_t* cursor = ctx->curr_frame; ctx->curr_frame = ctx->next_frame; - dwarf_stack st(ctx); - char str[1024]; str[0]= 0; - ctx->print_expr_block (expr, exprlen, str, sizeof(str), &attr_mem); - ctx->log(SEVERITY_DEBUG, "Parent frame expression: %s", str); - bool eret = st.calc_expression(expr, exprlen, &attr_mem); - uint64_t val = 0; - bool gret = false; - if(eret) { - gret = st.get_value(val); - } - // restore current frame cursor - ctx->curr_frame = cursor; - if(!eret || !gret) { - ctx->log(SEVERITY_ERROR, "Failed to calculate sub-expression for operation %s(0x%lX, 0x%lX)", map->op_name, exprs[i].number, exprs[i].number2); + pst_call_site* cs = fun->parent->find_call_site(fun); + if(!cs) { + ctx->log(SEVERITY_ERROR, "Failed to find call site while calculate DW_OP_GNU_entry_value expression"); return false; } - ctx->log(SEVERITY_DEBUG, "DW_OP_GNU_entry_value calculated from caller frame = 0x%lX", val); - push(&val, sizeof(val), DWARF_TYPE_GENERIC); + pst_dwarf_expr loc; loc.setup(expr, exprlen); + pst_call_site_param* param = cs->find_param(loc); + if(!param) { + ctx->log(SEVERITY_ERROR, "Failed to find call site parameter while calculate DW_OP_GNU_entry_value expression"); + return false; + } + + push(¶m->value, sizeof(param->value), DWARF_TYPE_GENERIC); continue; } else { diff --git a/framework/dwarf_operations.h b/framework/dwarf_operations.h index bd0428b..c0f1551 100644 --- a/framework/dwarf_operations.h +++ b/framework/dwarf_operations.h @@ -4,16 +4,7 @@ #include "common.h" #include "linkedlist.h" - -// DWARF operation (represents our own DW_OP_XXX) -typedef struct __pst_dwarf_op : public SC_ListNode { - __pst_dwarf_op(uint8_t op, uint64_t a1, uint64_t a2) { - operation = op; arg1 = a1; arg2 = a2; - } - uint8_t operation; - uint64_t arg1; - uint64_t arg2; -} pst_dwarf_op; +#include "sysutils.h" typedef enum { DWARF_TYPE_INVALID = 0, // no type @@ -120,7 +111,7 @@ typedef struct __dwarf_stack : public SC_ListHead { return value; } - bool calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr); + bool calc_expression(Dwarf_Op *exprs, int expr_len, Dwarf_Attribute* attr, pst_function* fun = NULL); bool get_value(uint64_t& value); Dwarf_Attribute* attr; // attribute which expression currently processed diff --git a/framework/sysutils.cpp b/framework/sysutils.cpp index 460818a..8316f11 100644 --- a/framework/sysutils.cpp +++ b/framework/sysutils.cpp @@ -51,35 +51,41 @@ int regname_callback (void *arg, int regno, const char *setname, const char *pre return 0; } -bool handle_location(pst_context* ctx, Dwarf_Attribute* attr, dwarf_stack& stack, Dwarf_Addr pc, char* str, uint32_t strsize) +bool handle_location(pst_context* ctx, Dwarf_Attribute* attr, pst_dwarf_expr& loc, Dwarf_Addr pc, char* str, uint32_t strsize, __pst_function* fun = NULL) { str[0] = 0; Dwarf_Addr offset = pc - ctx->base_addr; + dwarf_stack stack(ctx); + Dwarf_Op *expr; + size_t exprlen; if(dwarf_hasform(attr, DW_FORM_exprloc)) { // Location expression (exprloc class of location in DWARF terms) - Dwarf_Op *expr; - size_t exprlen; if(dwarf_getlocation(attr, &expr, &exprlen) == 0) { + loc.setup(expr, exprlen); ctx->print_expr_block (expr, exprlen, str, strsize, attr); - if(stack.calc_expression(expr, exprlen, attr)) { + if(stack.calc_expression(expr, exprlen, attr, fun) && stack.get_value(loc.value)) { return true; + } else { + return false; } } } else if(dwarf_hasform(attr, DW_FORM_sec_offset)) { // Location list (loclist class of location in DWARF terms) Dwarf_Addr base, start, end; ptrdiff_t off = 0; - Dwarf_Op *expr; - size_t exprlen; // handle list of possible locations of parameter for(int i = 0; (off = dwarf_getlocations (attr, off, &base, &start, &end, &expr, &exprlen)) > 0; ++i) { ctx->print_expr_block (expr, exprlen, str, strsize, attr); if(offset >= start && offset <= end) { + loc.setup(expr, exprlen); // actual location, try to calculate Location expression - if(stack.calc_expression(expr, exprlen, attr)) { + if(stack.calc_expression(expr, exprlen, attr, fun) && stack.get_value(loc.value), fun) { + ctx->log(SEVERITY_DEBUG, "Location expression: (low_offset: 0x%" PRIx64 ", high_offset: 0x%" PRIx64 "), \"%s\" ==> 0x%lX", start, end, str, loc.value); return true; + } else { + return false; } } else { // Location skipped due to don't match current PC offset @@ -91,15 +97,88 @@ bool handle_location(pst_context* ctx, Dwarf_Attribute* attr, dwarf_stack& stack ctx->log(SEVERITY_WARNING, "Unknown location attribute form = 0x%X, code = 0x%X, ", attr->form, attr->code); } + return false; } +bool __pst_dwarf_expr::operator== (__pst_dwarf_expr &rhs) +{ + if(Size() != rhs.Size()) { + return false; + } + + pst_dwarf_op* lop = next_op(NULL); + pst_dwarf_op* rop = rhs.next_op(NULL); + while(lop && rop) { + if(lop->operation == rop->operation && lop->arg1 == rop->arg1 && lop->arg2 == rop->arg2) { + return true; + } + lop = next_op(lop); + rop = rhs.next_op(rop); + } + + return false; +} + +pst_dwarf_op* __pst_dwarf_expr::add_op(uint8_t operation, uint64_t arg1, uint64_t arg2) +{ + pst_dwarf_op* op = new pst_dwarf_op(operation, arg1, arg2); + InsertLast(op); + + return op; +} + +pst_dwarf_op* __pst_dwarf_expr::next_op(pst_dwarf_op* op) +{ + pst_dwarf_op* ret = NULL; + if(!op) { + ret = (pst_dwarf_op*)First(); + } else { + ret = (pst_dwarf_op*)Next(op); + } + + return ret; +} + +bool __pst_dwarf_expr::print_op(const char* fmt, ...) +{ + bool nret = true; + + va_list args; + va_start(args, fmt); + int size = sizeof(buff) - offset; + int ret = vsnprintf(buff + offset, size, fmt, args); + if(ret >= size || ret < 0) { + nret = false; + } + offset += ret; + va_end(args); + + return nret; +} + +void __pst_dwarf_expr::clean() +{ + for(pst_dwarf_op* op = (pst_dwarf_op*)First(); op; op = (pst_dwarf_op*)First()) { + Remove(op); + delete op; + } +} + +void __pst_dwarf_expr::setup(Dwarf_Op* expr, size_t exprlen) +{ + clean(); + for(size_t i = 0; i < exprlen; ++i) { + add_op(expr[i].atom, expr[i].number, expr[i].number2); + } +} + bool __pst_parameter::print_dwarf() { if(types.Size()) { if(!is_return) { if(has_value) { - ctx->print("%s %s = 0x%lX", next_type(NULL)->name.c_str(), name.c_str(), value); + ctx->print("%s %s = 0x%lX", next_type(NULL)->name.c_str(), name.c_str(), location.value); } else { ctx->print("%s %s = ", next_type(NULL)->name.c_str(), name.c_str()); } @@ -108,7 +187,7 @@ bool __pst_parameter::print_dwarf() } } else { if(has_value) { - ctx->print("%s = 0x%lX", name.c_str(), value); + ctx->print("%s = 0x%lX", name.c_str(), location.value); } else { ctx->print("%s = ", name.c_str()); } @@ -224,7 +303,7 @@ pst_type* __pst_parameter::next_type(pst_type* t) return next; } -bool __pst_parameter::handle_dwarf(Dwarf_Die* result) +bool __pst_parameter::handle_dwarf(Dwarf_Die* result, __pst_function* fun) { die = result; @@ -250,13 +329,8 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result) dwarf_stack stack(ctx); char str[1024]; str[0] = 0; - if(handle_location(ctx, attr, stack, pc, str, sizeof(str))) { - if(stack.get_value(value)) { - ctx->log(SEVERITY_DEBUG, "Parameter Location: %s ==> 0x%lX", str, value); - has_value = true; - } else { - ctx->log(SEVERITY_ERROR, "Failed to get value of calculated DW_AT_location expression: %s", str); - } + if(handle_location(ctx, attr, location, pc, str, sizeof(str), fun)) { + has_value = true; } else { ctx->log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", str); } @@ -272,20 +346,20 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result) case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: - dwarf_formudata(attr, &value); + dwarf_formudata(attr, &location.value); has_value = true; break; case DW_FORM_sdata: - dwarf_formsdata(attr, (int64_t*)&value); + dwarf_formsdata(attr, (int64_t*)&location.value); has_value = true; break; case DW_FORM_udata: - dwarf_formudata(attr, &value); + dwarf_formudata(attr, &location.value); has_value = true; break; } if(has_value) { - ctx->log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", value); + ctx->log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", location.value); } } @@ -310,6 +384,11 @@ bool __pst_parameter::handle_dwarf(Dwarf_Die* result) return true; } +void __pst_call_site_param::set_location(Dwarf_Op* expr, size_t exprlen) +{ + location.setup(expr, exprlen); +} + pst_call_site_param* __pst_call_site::add_param() { pst_call_site_param* p = new pst_call_site_param(ctx); @@ -321,6 +400,7 @@ pst_call_site_param* __pst_call_site::add_param() void __pst_call_site::del_param(pst_call_site_param* p) { params.Remove(p); + delete p; } @@ -336,6 +416,17 @@ pst_call_site_param* __pst_call_site::next_param(pst_call_site_param* p) return param; } +pst_call_site_param* __pst_call_site::find_param(pst_dwarf_expr& expr) +{ + for(pst_call_site_param* param = next_param(NULL); param; param = next_param(param)) { + if(param->location == expr) { + return param; + } + } + + return NULL; +} + bool __pst_call_site::handle_dwarf(Dwarf_Die* child) { Dwarf_Attribute attr_mem; @@ -350,19 +441,12 @@ bool __pst_call_site::handle_dwarf(Dwarf_Die* child) char str[1024]; // expression represent where callee parameter will be stored - pst_call_site_param* param = new pst_call_site_param(ctx); + pst_call_site_param* param = add_param(); if(dwarf_hasattr(child, DW_AT_location)) { // handle location expression here // determine location of parameter in stack/heap or CPU registers attr = dwarf_attr(child, DW_AT_location, &attr_mem); - if(handle_location(ctx, attr, param->location, pc, str, sizeof(str))) { - uint64_t value = 0; - if(param->location.get_value(value)) { - ctx->log(SEVERITY_DEBUG, "\tDW_TAG_GNU_call_site_parameter: \"%s\" ==> 0x%lX", str, value); - } else { - ctx->log(SEVERITY_WARNING, "Failed to get value of calculated DW_AT_location expression: %s", str); - } - } else { + if(!handle_location(ctx, attr, param->location, pc, str, sizeof(str))) { ctx->log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", str); del_param(param); return false; @@ -374,14 +458,10 @@ bool __pst_call_site::handle_dwarf(Dwarf_Die* child) // handle value expression here attr = dwarf_attr(child, DW_AT_GNU_call_site_value, &attr_mem); dwarf_stack stack(ctx); - if(handle_location(ctx, attr, stack, pc, str, sizeof(str))) { - if(stack.get_value(param->value)) { - ctx->log(SEVERITY_DEBUG, "\tDW_AT_GNU_call_site_value:\"%s\" ==> 0x%lX", str, param->value); - } else { - ctx->log(SEVERITY_ERROR, "Failed to get value of calculated DW_AT_location expression: %s", str); - del_param(param); - return false; - } + pst_dwarf_expr loc; + if(handle_location(ctx, attr, loc, pc, str, sizeof(str))) { + param->value = loc.value; + ctx->log(SEVERITY_DEBUG, "\tDW_AT_GNU_call_site_value:\"%s\" ==> 0x%lX", str, param->value); } else { ctx->log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", str); del_param(param); @@ -418,6 +498,14 @@ void __pst_function::clear() params.Remove(p); delete p; } + + for(pst_call_site* p = (pst_call_site*)call_sites.First(); p; p = (pst_call_site*)call_sites.First()) { + call_sites.Remove(p); + delete p; + } + + mCallStToTarget.Clean(); + mCallStToTarget.Clean(); } pst_parameter* __pst_function::next_param(pst_parameter* p) @@ -481,6 +569,17 @@ pst_call_site* __pst_function::call_site_by_target(uint64_t target) return (pst_call_site*)mCallStToTarget.Lookup(&target, sizeof(target)); } +pst_call_site* __pst_function::find_call_site(pst_function* callee) +{ + uint64_t start_pc = ctx->base_addr + callee->lowpc; + pst_call_site* cs = (pst_call_site*)mCallStToTarget.Lookup(&start_pc, sizeof(start_pc)); + if(!cs) { + cs = (pst_call_site*)mCallStToOrigin.Lookup(callee->name.c_str(), strlen(callee->name.c_str())); + } + + return cs; +} + bool __pst_function::print_dwarf() { char* at = NULL; @@ -588,7 +687,7 @@ bool __pst_function::handle_lexical_block(Dwarf_Die* result) break; case DW_TAG_variable: { pst_parameter* param = add_param(); - if(!param->handle_dwarf(&child)) { + if(!param->handle_dwarf(&child, this)) { del_param(param); } break; @@ -639,18 +738,11 @@ bool __pst_function::handle_call_site(Dwarf_Die* result) if(dwarf_hasattr (result, DW_AT_GNU_call_site_target)) { attr = dwarf_attr(result, DW_AT_GNU_call_site_target, &attr_mem); if(attr) { - dwarf_stack stack(ctx); char str[1024]; str[0] = 0; - if(handle_location(ctx, &attr_mem, stack, pc, str, sizeof(str))) { - if(stack.get_value(target)) { - ctx->log(SEVERITY_DEBUG, "\tDW_AT_GNU_call_site_target: %s ==> %#lX", str, (void*)target); - } else { - ctx->log(SEVERITY_ERROR, "Failed to get value of calculated DW_AT_GNU_call_site_target expression: %s", str); - return false; - } - } else { - ctx->log(SEVERITY_ERROR, "Failed to calculate DW_AT_GNU_call_site_target expression: %s", str); - return false; + pst_dwarf_expr expr; + if(handle_location(ctx, &attr_mem, expr, pc, str, sizeof(str), this)) { + target = expr.value; + ctx->log(SEVERITY_DEBUG, "\tDW_AT_GNU_call_site_target: %#lX", target); } } } @@ -707,7 +799,7 @@ bool __pst_function::handle_dwarf(Dwarf_Die* d) char str[1024]; str[0] = 0; ctx->print_expr_block (expr, exprlen, str, sizeof(str), attr); dwarf_stack stack(ctx); - if(stack.calc_expression(expr, exprlen, attr)) { + if(stack.calc_expression(expr, exprlen, attr, this)) { uint64_t value; if(stack.get_value(value)) { ctx->log(SEVERITY_DEBUG, "DW_AT_framebase expression: \"%s\" ==> 0x%lX", str, value); @@ -762,7 +854,7 @@ bool __pst_function::handle_dwarf(Dwarf_Die* d) case DW_TAG_formal_parameter: case DW_TAG_variable: { pst_parameter* param = add_param(); - if(!param->handle_dwarf(&result)) { + if(!param->handle_dwarf(&result, this)) { del_param(param); } @@ -1012,7 +1104,8 @@ bool __pst_handler::handle_dwarf() { Dl_info info; - for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) { + //for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) { + for(pst_function* fun = (pst_function*)functions.Last(); fun; fun = (pst_function*)functions.Prev(fun)) { dladdr((void*)(fun->pc), &info); module = dwfl_addrmodule(dwfl, fun->pc); ctx.base_addr = (uint64_t)info.dli_fbase; diff --git a/framework/sysutils.h b/framework/sysutils.h index d553b89..2ce0006 100644 --- a/framework/sysutils.h +++ b/framework/sysutils.h @@ -24,9 +24,43 @@ #include "common.h" #include "dictionary.h" -#include "dwarf_operations.h" +#include "data_entry.h" -typedef struct __pst_function pst_function; + +// DWARF operation (represents our own DW_OP_XXX) +typedef struct __pst_dwarf_op : public SC_ListNode { + __pst_dwarf_op(uint8_t op, uint64_t a1, uint64_t a2) { + operation = op; arg1 = a1; arg2 = a2; + } + uint8_t operation; + uint64_t arg1; + uint64_t arg2; +} pst_dwarf_op; + +typedef struct __pst_dwarf_expr : public SC_ListHead { + __pst_dwarf_expr() { + has_value = false; value = 0; offset = 0; buff[0] = 0; + } + ~__pst_dwarf_expr() { + clean(); + } + pst_dwarf_op* add_op(uint8_t op, uint64_t arg1, uint64_t arg2); + pst_dwarf_op* next_op(pst_dwarf_op* op); + void clean(); + void setup(Dwarf_Op* expr, size_t exprlen); + void set_value(uint64_t v) { + has_value = true; + value = v; + } + bool print_op(const char* fmt, ...); + + bool operator== (__pst_dwarf_expr &rhs); + + bool has_value; + uint64_t value; + char buff[512]; + uint16_t offset; +} pst_dwarf_expr; typedef struct __pst_type : public SC_ListNode { __pst_type(const char* n, uint32_t t) : type(t) { @@ -38,6 +72,8 @@ typedef struct __pst_type : public SC_ListNode { uint32_t type; // DW_AT_XXX type } pst_type; +typedef struct __pst_function pst_function; + typedef struct __pst_parameter : public SC_ListNode { __pst_parameter(pst_context* c) : ctx(c) { @@ -48,7 +84,6 @@ typedef struct __pst_parameter : public SC_ListNode { is_return = false; is_variable = false; has_value = false; - value = 0; line = 0; } @@ -61,7 +96,7 @@ typedef struct __pst_parameter : public SC_ListNode { pst_type* add_type(const char* name, int type); pst_type* next_type(pst_type* t); - bool handle_dwarf(Dwarf_Die* d); + bool handle_dwarf(Dwarf_Die* d, __pst_function* fun); bool handle_type(Dwarf_Attribute* param); bool print_dwarf(); @@ -75,13 +110,13 @@ typedef struct __pst_parameter : public SC_ListNode { bool is_return; // whether this parameter is return value of the function bool is_variable;// whether this parameter is function variable or argument of function bool has_value; // whether we got value of parameter or not - uint64_t value; // value of parameter + pst_dwarf_expr location; pst_context* ctx; } pst_parameter; // DW_TAG_call_site_parameter typedef struct __pst_call_site_param : public SC_ListNode { - __pst_call_site_param(pst_context* ctx) : location(ctx) { + __pst_call_site_param(pst_context* ctx) { param = NULL; name = NULL; value = 0; } @@ -91,9 +126,11 @@ typedef struct __pst_call_site_param : public SC_ListNode { } } + void set_location(Dwarf_Op* expr, size_t exprlen); + Dwarf_Die* param; // reference to parameter DIE in callee (DW_AT_call_parameter) char* name; // name of parameter if present (DW_AT_name) - dwarf_stack location; // DWARF stack containing location expression + pst_dwarf_expr location; // DWARF stack containing location expression uint64_t value; // parameter's value } pst_call_site_param; @@ -120,6 +157,7 @@ typedef struct __pst_call_site : public SC_ListNode { pst_call_site_param* add_param(); void del_param(pst_call_site_param* p); pst_call_site_param* next_param(pst_call_site_param* p); + pst_call_site_param* find_param(pst_dwarf_expr& expr); bool handle_dwarf(Dwarf_Die* die); @@ -130,8 +168,6 @@ typedef struct __pst_call_site : public SC_ListNode { pst_context* ctx; } pst_call_site; -typedef struct __pst_handler pst_handler; - typedef struct __pst_function : public SC_ListNode { __pst_function(pst_context* _ctx, __pst_function* _parent) : ctx(_ctx) { pc = 0; @@ -165,6 +201,7 @@ typedef struct __pst_function : public SC_ListNode { bool print_dwarf(); bool handle_lexical_block(Dwarf_Die* result); bool handle_call_site(Dwarf_Die* result); + pst_call_site* find_call_site(__pst_function* callee); Dwarf_Addr lowpc; // offset to start of the function against base address Dwarf_Addr highpc; // offset to the next address after the end of the function against base address @@ -183,7 +220,7 @@ typedef struct __pst_function : public SC_ListNode { unw_cursor_t cursor; // copy of stack state of the function int line; // line in code where function is defined std::string file; // file name (DWARF Compilation Unit) where function is defined - pst_function* parent; // parent function in call trace (caller) + __pst_function* parent; // parent function in call trace (caller) pst_context* ctx; // context of unwinding } pst_function;