fixed several bugs related to refactoring
This commit is contained in:
@@ -73,11 +73,6 @@ bool print(pst_context* ctx, const char* fmt, ...)
|
||||
return nret;
|
||||
}
|
||||
|
||||
void log(SC_LogSeverity severity, const char* fmt, ...)
|
||||
{
|
||||
pst_log(severity, fmt);
|
||||
}
|
||||
|
||||
bool print_expr_block (pst_context* ctx, Dwarf_Op *exprs, int exprlen, Dwarf_Attribute* attr)
|
||||
{
|
||||
ctx->clean_print(ctx);
|
||||
@@ -162,14 +157,12 @@ void pst_context_init(pst_context* ctx, ucontext_t* hctx)
|
||||
// methods
|
||||
ctx->clean_print = clean_print;
|
||||
ctx->print = print;
|
||||
ctx->log = log;
|
||||
ctx->print_expr = print_expr_block;
|
||||
ctx->print_registers = print_registers;
|
||||
ctx->print_stack = print_stack;
|
||||
|
||||
// fields
|
||||
ctx->hcontext = hctx;
|
||||
ctx->clean_print(ctx);
|
||||
ctx->base_addr = 0;
|
||||
ctx->sp = 0;
|
||||
ctx->cfa = 0;
|
||||
|
||||
@@ -31,7 +31,6 @@ typedef struct pst_context {
|
||||
// methods
|
||||
void (*clean_print) (pst_context* ctx);
|
||||
bool (*print) (pst_context* ctx, const char* fmt, ...);
|
||||
void (*log) (SC_LogSeverity severity, const char*fmt, ...);
|
||||
bool (*print_expr) (pst_context* ctx, Dwarf_Op *exprs, int exprlen, Dwarf_Attribute* attr);
|
||||
void (*print_registers) (pst_context* ctx, int from, int to);
|
||||
void (*print_stack) (pst_context* ctx, int max, uint64_t next_cfa);
|
||||
|
||||
@@ -150,7 +150,11 @@ bool site_handle_dwarf(pst_call_site* site, Dwarf_Die* child)
|
||||
void pst_call_site_init(pst_call_site* site, pst_context* c, uint64_t tgt, const char* orn)
|
||||
{
|
||||
// methods
|
||||
|
||||
site->add_param = site_add_param;
|
||||
site->del_param = site_del_param;
|
||||
site->next_param = site_next_param;
|
||||
site->find_param = site_find_param;
|
||||
site->handle_dwarf = site_handle_dwarf;
|
||||
|
||||
// fields
|
||||
list_node_init(&site->node);
|
||||
@@ -330,6 +334,14 @@ pst_call_site* storage_find_call_site(pst_call_site_storage* storage, pst_functi
|
||||
|
||||
void pst_call_site_storage_init(pst_call_site_storage* storage, pst_context* ctx)
|
||||
{
|
||||
// methods
|
||||
storage->handle_dwarf = storage_handle_dwarf;
|
||||
storage->add_call_site = storage_add_call_site;
|
||||
storage->del_call_site = storage_del_call_site;
|
||||
storage->find_call_site = storage_find_call_site;
|
||||
storage->next_call_site = storage_next_call_site;
|
||||
|
||||
// fields
|
||||
storage->ctx = ctx;
|
||||
list_head_init(&storage->call_sites);
|
||||
hash_head_init(&storage->cs_to_target);
|
||||
|
||||
@@ -57,7 +57,7 @@ typedef struct pst_call_site {
|
||||
pst_call_site_param* (*add_param) (pst_call_site* site);
|
||||
void (*del_param) (pst_call_site* site, pst_call_site_param* p);
|
||||
pst_call_site_param* (*next_param) (pst_call_site* site, pst_call_site_param* p);
|
||||
pst_call_site_param* (*find_param) (pst_call_site* site, pst_dwarf_expr& expr);
|
||||
pst_call_site_param* (*find_param) (pst_call_site* site, pst_dwarf_expr* expr);
|
||||
bool (*handle_dwarf) (pst_call_site* site, Dwarf_Die* die);
|
||||
|
||||
// fields
|
||||
@@ -78,7 +78,7 @@ typedef struct __pst_function pst_function;
|
||||
// -----------------------------------------------------------------------------------
|
||||
typedef struct pst_call_site_storage {
|
||||
// methods
|
||||
bool (*handle_dwarf) (pst_call_site_storage* storage, Dwarf_Die* result);
|
||||
bool (*handle_dwarf) (pst_call_site_storage* storage, Dwarf_Die* result, pst_function* info);
|
||||
pst_call_site* (*add_call_site) (pst_call_site_storage* storage, uint64_t target, const char* origin);
|
||||
void (*del_call_site) (pst_call_site_storage* storage, pst_call_site* site);
|
||||
pst_call_site* (*find_call_site) (pst_call_site_storage* storage, pst_function* callee);
|
||||
|
||||
@@ -167,7 +167,7 @@ bool fn_handle_lexical_block(pst_function* fn, Dwarf_Die* result)
|
||||
break;
|
||||
}
|
||||
case DW_TAG_GNU_call_site:
|
||||
fn->call_sites.handle_dwarf(&fn->call_sites, &child);
|
||||
fn->call_sites.handle_dwarf(&fn->call_sites, &child, fn);
|
||||
break;
|
||||
case DW_TAG_inlined_subroutine:
|
||||
pst_log(SEVERITY_DEBUG, "Skipping Lexical block tag 'DW_TAG_inlined_subroutine'");
|
||||
@@ -281,7 +281,7 @@ bool fn_handle_dwarf(pst_function * fn, Dwarf_Die* d)
|
||||
break;
|
||||
}
|
||||
case DW_TAG_GNU_call_site:
|
||||
fn->call_sites.handle_dwarf(&fn->call_sites, &result);
|
||||
fn->call_sites.handle_dwarf(&fn->call_sites, &result, fn);
|
||||
break;
|
||||
|
||||
// case DW_TAG_inlined_subroutine:
|
||||
@@ -344,7 +344,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr)
|
||||
if(str) {
|
||||
*str = 0;
|
||||
}
|
||||
fn->name = function_name;
|
||||
fn->name = pst_strdup(function_name);
|
||||
free(function_name);
|
||||
}
|
||||
|
||||
@@ -352,6 +352,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr)
|
||||
free(demangle_name);
|
||||
}
|
||||
|
||||
pst_log(SEVERITY_DEBUG, "func_name = %s", fn->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -407,8 +408,9 @@ bool fn_get_frame(pst_function* fn)
|
||||
}
|
||||
|
||||
fn->ctx->print_expr(fn->ctx, cfa_ops, cfa_nops, NULL);
|
||||
|
||||
pst_decl(pst_dwarf_stack, stack, fn->ctx);
|
||||
if(stack.calc(&stack, cfa_ops, cfa_nops, NULL, fn) && stack.get_value(&stack, &fn->cfa)) {
|
||||
if(stack.calc(&stack, cfa_ops, cfa_nops, NULL, NULL) && stack.get_value(&stack, &fn->cfa)) {
|
||||
pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->name, fn->ctx->buff, fn->cfa);
|
||||
|
||||
// setup context to match CFA for frame
|
||||
@@ -444,7 +446,7 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, __pst_function* _par
|
||||
fn->die = NULL;
|
||||
fn->name = NULL;
|
||||
list_head_init(&fn->params);
|
||||
pst_call_site_storage_init(&fn->call_sites, fn->ctx);
|
||||
pst_call_site_storage_init(&fn->call_sites, _ctx);
|
||||
|
||||
fn->sp = 0;
|
||||
fn->cfa = 0;
|
||||
|
||||
@@ -227,7 +227,7 @@ bool stack_calc(pst_dwarf_stack* st, Dwarf_Op *exprs, int expr_len, Dwarf_Attrib
|
||||
pst_dwarf_expr loc;
|
||||
pst_dwarf_expr_init(&loc);
|
||||
loc.setup(&loc, expr, exprlen);
|
||||
pst_call_site_param* param = cs->find_param(cs, loc);
|
||||
pst_call_site_param* param = cs->find_param(cs, &loc);
|
||||
pst_dwarf_expr_fini(&loc);
|
||||
if(!param) {
|
||||
pst_log(SEVERITY_ERROR, "Failed to find call site parameter while calculate DW_OP_GNU_entry_value expression");
|
||||
@@ -261,6 +261,7 @@ void pst_dwarf_stack_init(pst_dwarf_stack* st, pst_context* ctx)
|
||||
{
|
||||
pst_assert(st && ctx);
|
||||
|
||||
list_head_init(&st->expr);
|
||||
list_head_init(&st->values);
|
||||
st->push = stack_push;
|
||||
st->push_value = stack_push_value;
|
||||
|
||||
+15
-11
@@ -42,18 +42,18 @@ bool handler_get_dwarf_function(pst_handler* h, pst_function* fun)
|
||||
Dwarf_Die* cdie = dwfl_module_addrdie(h->ctx.module, fun->pc, &mod_cu);
|
||||
//Dwarf_Die* cdie = dwfl_addrdie(dwfl, addr, &mod_bias);
|
||||
if(!cdie) {
|
||||
h->ctx.log(SEVERITY_INFO, "Failed to find DWARF DIE for address %X", fun->pc);
|
||||
pst_log(SEVERITY_INFO, "Failed to find DWARF DIE for address %X", fun->pc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(dwarf_tag(cdie) != DW_TAG_compile_unit) {
|
||||
h->ctx.log(SEVERITY_DEBUG, "Skipping non-cu die. DWARF tag: 0x%X, name = %s", dwarf_tag(cdie), dwarf_diename(cdie));
|
||||
pst_log(SEVERITY_DEBUG, "Skipping non-cu die. DWARF tag: 0x%X, name = %s", dwarf_tag(cdie), dwarf_diename(cdie));
|
||||
return false;
|
||||
}
|
||||
|
||||
Dwarf_Die result;
|
||||
if(dwarf_child(cdie, &result)) {
|
||||
h->ctx.log(SEVERITY_ERROR, "No child DIE found for CU %s", dwarf_diename(cdie));
|
||||
pst_log(SEVERITY_ERROR, "No child DIE found for CU %s", dwarf_diename(cdie));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -134,9 +134,9 @@ bool handler_handle_dwarf(pst_handler* h)
|
||||
Dl_info info;
|
||||
|
||||
//for(pst_function* fun = next_function(NULL); fun; fun = next_function(fun)) {
|
||||
for(pst_function* fun = (pst_function*)handler_last_function(h); fun; fun = h->prev_function(h, fun)) {
|
||||
for(pst_function* fun = handler_last_function(h); fun; fun = h->prev_function(h, fun)) {
|
||||
dladdr((void*)(fun->pc), &info);
|
||||
h->ctx.log(SEVERITY_INFO, "Function %s(...): module name: %s, base address: %p, CFA: %#lX", fun->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->name, info.dli_fname, info.dli_fbase, fun->parent ? fun->parent->sp : 0);
|
||||
|
||||
// setup context
|
||||
h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc);
|
||||
@@ -180,7 +180,7 @@ bool handler_unwind(pst_handler* h)
|
||||
#ifdef REG_RIP // x86_64
|
||||
h->caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP];
|
||||
h->ctx.sp = h->ctx.hcontext->uc_mcontext.gregs[REG_RSP];
|
||||
h->ctx.log(SEVERITY_DEBUG, "Original caller's SP: %#lX", h->ctx.sp);
|
||||
pst_log(SEVERITY_DEBUG, "Original caller's SP: %#lX", h->ctx.sp);
|
||||
#elif defined(REG_EIP) // x86_32
|
||||
caller_address = (void *) uctx->uc_mcontext.gregs[REG_EIP]);
|
||||
#elif defined(__arm__)
|
||||
@@ -201,7 +201,7 @@ bool handler_unwind(pst_handler* h)
|
||||
Dl_info info;
|
||||
dladdr(h->caller, &info);
|
||||
h->ctx.base_addr = (uint64_t)info.dli_fbase;
|
||||
h->ctx.log(SEVERITY_INFO, "Process address information: PC address: %p, base address: %p, object name: %s", h->caller, info.dli_fbase, info.dli_fname);
|
||||
pst_log(SEVERITY_INFO, "Process address information: PC address: %p, base address: %p, object name: %s", h->caller, info.dli_fbase, info.dli_fname);
|
||||
|
||||
h->ctx.dwfl = dwfl_begin(&callbacks);
|
||||
if(h->ctx.dwfl == NULL) {
|
||||
@@ -221,19 +221,19 @@ bool handler_unwind(pst_handler* h)
|
||||
h->ctx.curr_frame = &h->ctx.cursor;
|
||||
for(int i = 0, skip = 1; unw_step(h->ctx.curr_frame) > 0; ++i) {
|
||||
if(unw_get_reg(h->ctx.curr_frame, UNW_REG_IP, &h->addr)) {
|
||||
h->ctx.log(SEVERITY_DEBUG, "Failed to get IP value");
|
||||
pst_log(SEVERITY_DEBUG, "Failed to get IP value");
|
||||
continue;
|
||||
}
|
||||
unw_word_t sp;
|
||||
if(unw_get_reg(h->ctx.curr_frame, UNW_REG_SP, &sp)) {
|
||||
h->ctx.log(SEVERITY_DEBUG, "Failed to get SP value");
|
||||
pst_log(SEVERITY_DEBUG, "Failed to get SP value");
|
||||
continue;
|
||||
}
|
||||
|
||||
if(h->addr == (uint64_t)h->caller) {
|
||||
skip = 0;
|
||||
} else if(skip) {
|
||||
h->ctx.log(SEVERITY_DEBUG, "Skipping frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp);
|
||||
pst_log(SEVERITY_DEBUG, "Skipping frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ bool handler_unwind(pst_handler* h)
|
||||
pst_function* last = handler_last_function(h);
|
||||
pst_function* fn = h->add_function(h, NULL);
|
||||
fn->sp = sp;
|
||||
h->ctx.log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp);
|
||||
pst_log(SEVERITY_DEBUG, "Analyze frame #%d: PC = %#lX, SP = %#lX", i, h->addr, sp);
|
||||
if(!fn->unwind(fn, h->addr)) {
|
||||
h->del_function(fn);
|
||||
} else {
|
||||
@@ -251,6 +251,7 @@ bool handler_unwind(pst_handler* h)
|
||||
}
|
||||
//get_frame(fun);
|
||||
}
|
||||
pst_log(SEVERITY_DEBUG, "fname = %s", fn->name);
|
||||
h->ctx.print(&h->ctx, "\n");
|
||||
}
|
||||
|
||||
@@ -265,6 +266,9 @@ void pst_handler_init(pst_handler* h, ucontext_t* hctx)
|
||||
h->del_function = handler_del_function;
|
||||
h->next_function = handler_next_function;
|
||||
h->prev_function = handler_prev_function;
|
||||
h->handle_dwarf = handler_handle_dwarf;
|
||||
h->print_dwarf = handler_print_dwarf;
|
||||
h->unwind = handler_unwind;
|
||||
|
||||
// fields
|
||||
pst_context_init(&h->ctx, hctx);
|
||||
|
||||
Reference in New Issue
Block a user