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;
|
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)
|
bool print_expr_block (pst_context* ctx, Dwarf_Op *exprs, int exprlen, Dwarf_Attribute* attr)
|
||||||
{
|
{
|
||||||
ctx->clean_print(ctx);
|
ctx->clean_print(ctx);
|
||||||
@@ -162,14 +157,12 @@ void pst_context_init(pst_context* ctx, ucontext_t* hctx)
|
|||||||
// methods
|
// methods
|
||||||
ctx->clean_print = clean_print;
|
ctx->clean_print = clean_print;
|
||||||
ctx->print = print;
|
ctx->print = print;
|
||||||
ctx->log = log;
|
|
||||||
ctx->print_expr = print_expr_block;
|
ctx->print_expr = print_expr_block;
|
||||||
ctx->print_registers = print_registers;
|
ctx->print_registers = print_registers;
|
||||||
ctx->print_stack = print_stack;
|
ctx->print_stack = print_stack;
|
||||||
|
|
||||||
// fields
|
// fields
|
||||||
ctx->hcontext = hctx;
|
ctx->hcontext = hctx;
|
||||||
ctx->clean_print(ctx);
|
|
||||||
ctx->base_addr = 0;
|
ctx->base_addr = 0;
|
||||||
ctx->sp = 0;
|
ctx->sp = 0;
|
||||||
ctx->cfa = 0;
|
ctx->cfa = 0;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ typedef struct pst_context {
|
|||||||
// methods
|
// methods
|
||||||
void (*clean_print) (pst_context* ctx);
|
void (*clean_print) (pst_context* ctx);
|
||||||
bool (*print) (pst_context* ctx, const char* fmt, ...);
|
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);
|
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_registers) (pst_context* ctx, int from, int to);
|
||||||
void (*print_stack) (pst_context* ctx, int max, uint64_t next_cfa);
|
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)
|
void pst_call_site_init(pst_call_site* site, pst_context* c, uint64_t tgt, const char* orn)
|
||||||
{
|
{
|
||||||
// methods
|
// 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
|
// fields
|
||||||
list_node_init(&site->node);
|
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)
|
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;
|
storage->ctx = ctx;
|
||||||
list_head_init(&storage->call_sites);
|
list_head_init(&storage->call_sites);
|
||||||
hash_head_init(&storage->cs_to_target);
|
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);
|
pst_call_site_param* (*add_param) (pst_call_site* site);
|
||||||
void (*del_param) (pst_call_site* site, pst_call_site_param* p);
|
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* (*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);
|
bool (*handle_dwarf) (pst_call_site* site, Dwarf_Die* die);
|
||||||
|
|
||||||
// fields
|
// fields
|
||||||
@@ -78,7 +78,7 @@ typedef struct __pst_function pst_function;
|
|||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
typedef struct pst_call_site_storage {
|
typedef struct pst_call_site_storage {
|
||||||
// methods
|
// 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);
|
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);
|
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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case DW_TAG_GNU_call_site:
|
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;
|
break;
|
||||||
case DW_TAG_inlined_subroutine:
|
case DW_TAG_inlined_subroutine:
|
||||||
pst_log(SEVERITY_DEBUG, "Skipping Lexical block tag '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;
|
break;
|
||||||
}
|
}
|
||||||
case DW_TAG_GNU_call_site:
|
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;
|
break;
|
||||||
|
|
||||||
// case DW_TAG_inlined_subroutine:
|
// case DW_TAG_inlined_subroutine:
|
||||||
@@ -344,7 +344,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr)
|
|||||||
if(str) {
|
if(str) {
|
||||||
*str = 0;
|
*str = 0;
|
||||||
}
|
}
|
||||||
fn->name = function_name;
|
fn->name = pst_strdup(function_name);
|
||||||
free(function_name);
|
free(function_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,6 +352,7 @@ bool fn_unwind(pst_function* fn, Dwarf_Addr addr)
|
|||||||
free(demangle_name);
|
free(demangle_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pst_log(SEVERITY_DEBUG, "func_name = %s", fn->name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,8 +408,9 @@ bool fn_get_frame(pst_function* fn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn->ctx->print_expr(fn->ctx, cfa_ops, cfa_nops, NULL);
|
fn->ctx->print_expr(fn->ctx, cfa_ops, cfa_nops, NULL);
|
||||||
|
|
||||||
pst_decl(pst_dwarf_stack, stack, fn->ctx);
|
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);
|
pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->name, fn->ctx->buff, fn->cfa);
|
||||||
|
|
||||||
// setup context to match CFA for frame
|
// 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->die = NULL;
|
||||||
fn->name = NULL;
|
fn->name = NULL;
|
||||||
list_head_init(&fn->params);
|
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->sp = 0;
|
||||||
fn->cfa = 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 loc;
|
||||||
pst_dwarf_expr_init(&loc);
|
pst_dwarf_expr_init(&loc);
|
||||||
loc.setup(&loc, expr, exprlen);
|
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);
|
pst_dwarf_expr_fini(&loc);
|
||||||
if(!param) {
|
if(!param) {
|
||||||
pst_log(SEVERITY_ERROR, "Failed to find call site parameter while calculate DW_OP_GNU_entry_value expression");
|
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);
|
pst_assert(st && ctx);
|
||||||
|
|
||||||
|
list_head_init(&st->expr);
|
||||||
list_head_init(&st->values);
|
list_head_init(&st->values);
|
||||||
st->push = stack_push;
|
st->push = stack_push;
|
||||||
st->push_value = stack_push_value;
|
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_module_addrdie(h->ctx.module, fun->pc, &mod_cu);
|
||||||
//Dwarf_Die* cdie = dwfl_addrdie(dwfl, addr, &mod_bias);
|
//Dwarf_Die* cdie = dwfl_addrdie(dwfl, addr, &mod_bias);
|
||||||
if(!cdie) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dwarf_tag(cdie) != DW_TAG_compile_unit) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dwarf_Die result;
|
Dwarf_Die result;
|
||||||
if(dwarf_child(cdie, &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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,9 +134,9 @@ bool handler_handle_dwarf(pst_handler* h)
|
|||||||
Dl_info info;
|
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*)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);
|
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
|
// setup context
|
||||||
h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc);
|
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
|
#ifdef REG_RIP // x86_64
|
||||||
h->caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP];
|
h->caller = (void *) h->ctx.hcontext->uc_mcontext.gregs[REG_RIP];
|
||||||
h->ctx.sp = h->ctx.hcontext->uc_mcontext.gregs[REG_RSP];
|
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
|
#elif defined(REG_EIP) // x86_32
|
||||||
caller_address = (void *) uctx->uc_mcontext.gregs[REG_EIP]);
|
caller_address = (void *) uctx->uc_mcontext.gregs[REG_EIP]);
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
@@ -201,7 +201,7 @@ bool handler_unwind(pst_handler* h)
|
|||||||
Dl_info info;
|
Dl_info info;
|
||||||
dladdr(h->caller, &info);
|
dladdr(h->caller, &info);
|
||||||
h->ctx.base_addr = (uint64_t)info.dli_fbase;
|
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);
|
h->ctx.dwfl = dwfl_begin(&callbacks);
|
||||||
if(h->ctx.dwfl == NULL) {
|
if(h->ctx.dwfl == NULL) {
|
||||||
@@ -221,19 +221,19 @@ bool handler_unwind(pst_handler* h)
|
|||||||
h->ctx.curr_frame = &h->ctx.cursor;
|
h->ctx.curr_frame = &h->ctx.cursor;
|
||||||
for(int i = 0, skip = 1; unw_step(h->ctx.curr_frame) > 0; ++i) {
|
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)) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
unw_word_t sp;
|
unw_word_t sp;
|
||||||
if(unw_get_reg(h->ctx.curr_frame, UNW_REG_SP, &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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(h->addr == (uint64_t)h->caller) {
|
if(h->addr == (uint64_t)h->caller) {
|
||||||
skip = 0;
|
skip = 0;
|
||||||
} else if(skip) {
|
} 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ bool handler_unwind(pst_handler* h)
|
|||||||
pst_function* last = handler_last_function(h);
|
pst_function* last = handler_last_function(h);
|
||||||
pst_function* fn = h->add_function(h, NULL);
|
pst_function* fn = h->add_function(h, NULL);
|
||||||
fn->sp = sp;
|
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)) {
|
if(!fn->unwind(fn, h->addr)) {
|
||||||
h->del_function(fn);
|
h->del_function(fn);
|
||||||
} else {
|
} else {
|
||||||
@@ -251,6 +251,7 @@ bool handler_unwind(pst_handler* h)
|
|||||||
}
|
}
|
||||||
//get_frame(fun);
|
//get_frame(fun);
|
||||||
}
|
}
|
||||||
|
pst_log(SEVERITY_DEBUG, "fname = %s", fn->name);
|
||||||
h->ctx.print(&h->ctx, "\n");
|
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->del_function = handler_del_function;
|
||||||
h->next_function = handler_next_function;
|
h->next_function = handler_next_function;
|
||||||
h->prev_function = handler_prev_function;
|
h->prev_function = handler_prev_function;
|
||||||
|
h->handle_dwarf = handler_handle_dwarf;
|
||||||
|
h->print_dwarf = handler_print_dwarf;
|
||||||
|
h->unwind = handler_unwind;
|
||||||
|
|
||||||
// fields
|
// fields
|
||||||
pst_context_init(&h->ctx, hctx);
|
pst_context_init(&h->ctx, hctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user