make visible to user libunwind function's context, SP register and CFA

This commit is contained in:
2020-04-16 20:54:53 +04:00
parent a36d8ff7b9
commit a0475eeda7
5 changed files with 37 additions and 37 deletions
+1 -1
View File
@@ -307,7 +307,7 @@ void pst_call_site_storage_del(pst_call_site_storage* storage, pst_call_site* st
pst_call_site* pst_call_site_storage_find(pst_call_site_storage* storage, pst_function* callee)
{
uint64_t start_pc = storage->ctx->base_addr + callee->lowpc;
uint64_t start_pc = storage->ctx->base_addr + callee->info.lowpc;
pst_call_site* cs = storage_call_site_by_target(storage, start_pc);
if(!cs) {
cs = storage_call_site_by_origin(storage, callee->info.name);
+16 -14
View File
@@ -74,11 +74,11 @@ static bool get_frame(pst_function* fn)
bool nret = true;
pst_decl(pst_dwarf_stack, stack, fn->ctx);
if(pst_dwarf_stack_calc(&stack, cfa_ops, cfa_nops, NULL, NULL) && pst_dwarf_stack_get_value(&stack, &fn->cfa)) {
pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->info.name, fn->ctx->buff, fn->cfa);
if(pst_dwarf_stack_calc(&stack, cfa_ops, cfa_nops, NULL, NULL) && pst_dwarf_stack_get_value(&stack, &fn->info.cfa)) {
pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->info.name, fn->ctx->buff, fn->info.cfa);
// setup context to match CFA for frame
fn->ctx->cfa = fn->cfa;
fn->ctx->cfa = fn->info.cfa;
} else {
nret = false;
pst_log(SEVERITY_ERROR, "Failed to calculate CFA expression");
@@ -261,21 +261,21 @@ bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d)
// get list of offsets from process base address of continuous memory ranges where function's code resides
// if(dwarf_haspc(d, pc)) {
dwarf_lowpc(d, &fn->lowpc);
dwarf_highpc(d, &fn->highpc);
dwarf_lowpc(d, &fn->info.lowpc);
dwarf_highpc(d, &fn->info.highpc);
// } else {
// pst_log(SEVERITY_ERROR, "Function's '%s' DIE hasn't definitions of memory offsets of function's code", dwarf_diename(d));
// return false;
// }
unw_proc_info_t info;
unw_get_proc_info(&fn->cursor, &info);
unw_get_proc_info(&fn->info.context, &info);
fn->ctx->clean_print(fn->ctx);
pst_log(SEVERITY_INFO, "Function %s(...): LOW_PC = %#lX, HIGH_PC = %#lX, offset from base address: 0x%lX, START_PC = 0x%lX, offset from start of function: 0x%lX",
dwarf_diename(d), fn->lowpc, fn->highpc, fn->info.pc - fn->ctx->base_addr, info.start_ip, info.start_ip - fn->ctx->base_addr);
dwarf_diename(d), fn->info.lowpc, fn->info.highpc, fn->info.pc - fn->ctx->base_addr, info.start_ip, info.start_ip - fn->ctx->base_addr);
fn->ctx->print_registers(fn->ctx, 0x0, 0x10);
pst_log(SEVERITY_INFO, "Function %s(...): CFA: %#lX %s", dwarf_diename(d), fn->parent ? fn->parent->sp : 0, fn->ctx->buff);
pst_log(SEVERITY_INFO, "Function %s(...): CFA: %#lX %s", dwarf_diename(d), fn->parent ? fn->parent->info.sp : 0, fn->ctx->buff);
pst_log(SEVERITY_INFO, "Function %s(...): %s", dwarf_diename(d), fn->ctx->buff);
// determine function's stack frame base
@@ -418,20 +418,22 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, pst_function* _paren
{
list_node_init(&fn->node);
// fields
fn->lowpc = 0;
fn->highpc = 0;
// user visible fields
fn->info.pc = 0;
fn->info.lowpc = 0;
fn->info.highpc = 0;
bzero(&fn->info.context, sizeof(fn->info.context));
fn->info.name = NULL;
fn->info.line = -1;
fn->info.file = NULL;
fn->info.sp = 0;
// internal fields
fn->die = NULL;
list_head_init(&fn->params);
pst_call_site_storage_init(&fn->call_sites, _ctx);
fn->sp = 0;
fn->cfa = 0;
memcpy(&fn->cursor, &_ctx->cursor, sizeof(fn->cursor));
memcpy(&fn->info.context, &_ctx->cursor, sizeof(fn->info.context));
fn->parent = _parent;
fn->frame = NULL;
fn->ctx = _ctx;
+4 -11
View File
@@ -22,18 +22,11 @@
// pst_function
// -----------------------------------------------------------------------------------
typedef struct pst_function {
list_node node;
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
list_node node; // uplink
Dwarf_Die* die; // DWARF DIE containing definition of the function
pst_function_info info;
list_head params; // function's parameters
pst_call_site_storage call_sites;
unw_word_t sp; // SP register in function's frame
unw_word_t cfa; // CFA (Canonical Frame Address) of the function
unw_cursor_t cursor; // copy of stack state of the function
pst_function_info info; // information about the function itself
list_head params; // parameters of the function
pst_call_site_storage call_sites; // call-sites of the function
pst_function* parent; // parent function in call trace (caller)
Dwarf_Frame* frame; // function's stack frame
pst_context* ctx; // context of unwinding
+6 -6
View File
@@ -146,15 +146,15 @@ bool pst_handler_handle_dwarf(pst_handler* h)
//for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) {
for(pst_function* fun = last_function(h); fun; fun = prev_function(h, fun)) {
dladdr((void*)(fun->info.pc), &info);
pst_log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->info.name, info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0);
pst_log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX",
fun->info.name, info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->info.sp : 0);
// setup context
h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->info.pc);
h->ctx.base_addr = (uint64_t)info.dli_fbase;
h->ctx.curr_frame = &fun->cursor;
h->ctx.sp = fun->sp;
h->ctx.cfa = fun->cfa;
h->ctx.curr_frame = &fun->cursor;
h->ctx.curr_frame = &fun->info.context;
h->ctx.sp = fun->info.sp;
h->ctx.cfa = fun->info.cfa;
get_dwarf_function(h, fun);
}
@@ -282,7 +282,7 @@ bool pst_handler_unwind(pst_handler* h)
pst_log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, pc, sp);
pst_function* last = last_function(h);
pst_function* fn = add_function(h, NULL);
fn->info.pc = pc; fn->sp = sp;
fn->info.pc = pc; fn->info.sp = sp;
if(!pst_function_unwind(fn)) {
del_function(fn);
} else if(last) {