exprt next_function, next_parameter function_info, parameter_info to

external interface of the library
This commit is contained in:
2020-04-05 14:59:41 +04:00
parent e2e7535149
commit 3317cd212b
12 changed files with 193 additions and 117 deletions
+3 -3
View File
@@ -195,7 +195,7 @@ void pst_call_site_fini(pst_call_site* site)
// DW_TAG_GNU_call_site_parameter is defined under child DIE of DW_TAG_GNU_call_site and defines value of subroutine before calling it
// relates to DW_OP_GNU_entry_value() handling in callee function to determine the value of an argument/variable of the callee
// get DIE of return type
bool pst_call_site_storage_handle_dwarf(pst_call_site_storage* storage, Dwarf_Die* result, pst_function* info)
bool pst_call_site_storage_handle_dwarf(pst_call_site_storage* storage, Dwarf_Die* result, pst_function* fn)
{
Dwarf_Die origin;
Dwarf_Attribute attr_mem;
@@ -216,7 +216,7 @@ bool pst_call_site_storage_handle_dwarf(pst_call_site_storage* storage, Dwarf_Di
attr = dwarf_attr(result, DW_AT_GNU_call_site_target, &attr_mem);
if(attr) {
pst_decl0(pst_dwarf_expr, expr);
if(handle_location(storage->ctx, &attr_mem, &expr, info->pc, info)) {
if(handle_location(storage->ctx, &attr_mem, &expr, fn->info.pc, fn)) {
target = expr.value;
pst_log(SEVERITY_DEBUG, "DW_AT_GNU_call_site_target: %#lX", target);
}
@@ -310,7 +310,7 @@ pst_call_site* pst_call_site_storage_find(pst_call_site_storage* storage, pst_fu
uint64_t start_pc = storage->ctx->base_addr + callee->lowpc;
pst_call_site* cs = storage_call_site_by_target(storage, start_pc);
if(!cs) {
cs = storage_call_site_by_origin(storage, callee->name);
cs = storage_call_site_by_origin(storage, callee->info.name);
}
return cs;
+1 -1
View File
@@ -64,7 +64,7 @@ void pst_call_site_fini(pst_call_site* site);
pst_call_site_param* pst_call_site_find(pst_call_site* site, pst_dwarf_expr* expr);
bool pst_call_site_handle_dwarf(pst_call_site* site, Dwarf_Die* child);
typedef struct __pst_function pst_function;
typedef struct pst_function pst_function;
// -----------------------------------------------------------------------------------
// storage for all of function's call sites
// -----------------------------------------------------------------------------------
+37 -37
View File
@@ -34,7 +34,7 @@ static bool get_frame(pst_function* fn)
}
// get frame of CFI for address
int result = dwarf_cfi_addrframe (cfi, fn->pc - mod_bias, &fn->frame);
int result = dwarf_cfi_addrframe (cfi, fn->info.pc - mod_bias, &fn->frame);
if (result != 0) {
pst_log(SEVERITY_ERROR, "Failed to find CFI frame for module");
return false;
@@ -44,8 +44,8 @@ static bool get_frame(pst_function* fn)
fn->ctx->frame = fn->frame;
// get return register and PC range for function
Dwarf_Addr start = fn->pc;
Dwarf_Addr end = fn->pc;
Dwarf_Addr start = fn->info.pc;
Dwarf_Addr end = fn->info.pc;
bool signalp;
int ra_regno = dwarf_frame_info (fn->frame, &start, &end, &signalp);
if(ra_regno >= 0) {
@@ -54,7 +54,7 @@ static bool get_frame(pst_function* fn)
reginfo info; info.regno = ra_regno;
dwfl_module_register_names(fn->ctx->module, regname_callback, &info);
pst_log(SEVERITY_INFO, "Function %s(...): '.eh/debug frame' info: PC range: => [%#" PRIx64 ", %#" PRIx64 "], return register: %s, in_signal = %s",
fn->name, start, end, info.regname, signalp ? "true" : "false");
fn->info.name, start, end, info.regname, signalp ? "true" : "false");
} else {
pst_log(SEVERITY_WARNING, "Return address register info unavailable (%s)", dwarf_errmsg(0));
}
@@ -75,7 +75,7 @@ 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->name, fn->ctx->buff, fn->cfa);
pst_log(SEVERITY_INFO, "Function %s(...): CFA expression: %s ==> %#lX", fn->info.name, fn->ctx->buff, fn->cfa);
// setup context to match CFA for frame
fn->ctx->cfa = fn->cfa;
@@ -115,7 +115,7 @@ static void clear(pst_function* fn)
pst_call_site_storage_fini(&fn->call_sites);
}
static pst_parameter* next_param(pst_function* fn, pst_parameter* p)
pst_parameter* pst_function_next_parameter(pst_function* fn, pst_parameter* p)
{
struct list_node* n = (p == NULL) ? list_first(&fn->params) : list_next(&p->node);
@@ -191,41 +191,41 @@ bool handle_lexical_block(pst_function* fn, Dwarf_Die* result)
bool pst_function_print_dwarf(pst_function* fn)
{
char* at = NULL;
if(fn->file) {
if(!asprintf(&at, " at %s:%d, %p", fn->file, fn->line, (void*)fn->pc))
if(fn->info.file) {
if(!asprintf(&at, " at %s:%d, %p", fn->info.file, fn->info.line, (void*)fn->info.pc))
return false;
} else if(!asprintf(&at, " at %p", (void*)fn->pc)){
} else if(!asprintf(&at, " at %p", (void*)fn->info.pc)){
return false;
}
// handle return parameter and be safe if function haven't parameters (for example, dwar info for function is absent)
pst_parameter* param = next_param(fn, NULL);
if(param && param->is_return) {
pst_parameter* param = pst_function_next_parameter(fn, NULL);
if(param && param->info.is_return) {
// print return value type, function name and start list of parameters
pst_parameter_print_dwarf(param);
fn->ctx->print(fn->ctx, " %s(", fn->name);
param = next_param(fn, param);
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
param = pst_function_next_parameter(fn, param);
} else {
fn->ctx->print(fn->ctx, "%s(", fn->name);
fn->ctx->print(fn->ctx, "%s(", fn->info.name);
}
bool first = true; bool start_variable = false;
for(; param; param = next_param(fn, param)) {
if(param->is_return) {
for(; param; param = pst_function_next_parameter(fn, param)) {
if(param->info.is_return) {
// print return value type, function name and start list of parameters
pst_parameter_print_dwarf(param);
fn->ctx->print(fn->ctx, " %s(", fn->name);
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
continue;
}
if(param->is_variable) {
if(param->info.is_variable) {
if(!start_variable) {
fn->ctx->print(fn->ctx, ")%s\n", at);
fn->ctx->print(fn->ctx, "{\n");
start_variable = true;
}
if(param->line) {
fn->ctx->print(fn->ctx, "%04u: ", param->line);
if(param->info.line) {
fn->ctx->print(fn->ctx, "%04u: ", param->info.line);
} else {
fn->ctx->print(fn->ctx, " ");
}
@@ -273,7 +273,7 @@ bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d)
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->pc - fn->ctx->base_addr, info.start_ip, info.start_ip - fn->ctx->base_addr);
dwarf_diename(d), fn->lowpc, fn->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(...): %s", dwarf_diename(d), fn->ctx->buff);
@@ -306,11 +306,11 @@ bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d)
// Get reference to return attribute type of the function
// may be to use dwfl_module_return_value_location() instead
pst_parameter* ret_p = add_param(fn); ret_p->is_return = true;
pst_parameter* ret_p = add_param(fn); ret_p->info.is_return = true;
attr = dwarf_attr(fn->die, DW_AT_type, &attr_mem);
if(attr) {
if(!pst_parameter_handle_type(ret_p, attr)) {
pst_log(SEVERITY_ERROR, "Failed to handle return parameter type for function %s(...)", fn->name);
pst_log(SEVERITY_ERROR, "Failed to handle return parameter type for function %s(...)", fn->info.name);
del_param(ret_p);
}
} else {
@@ -375,9 +375,9 @@ bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d)
bool pst_function_unwind(pst_function* fn)
{
Dwfl_Line *dwline = dwfl_getsrc(fn->ctx->dwfl, fn->pc);
Dwfl_Line *dwline = dwfl_getsrc(fn->ctx->dwfl, fn->info.pc);
if(dwline != NULL) {
const char* filename = dwfl_lineinfo (dwline, &fn->pc, &fn->line, NULL, NULL, NULL);
const char* filename = dwfl_lineinfo (dwline, &fn->info.pc, &fn->info.line, NULL, NULL, NULL);
if(filename) {
const char* file = strrchr(filename, '/');
if(file && *file != 0) {
@@ -385,12 +385,12 @@ bool pst_function_unwind(pst_function* fn)
} else {
file = filename;
}
fn->file = pst_strdup(file);
fn->info.file = pst_strdup(file);
}
}
Dwfl_Module* module = dwfl_addrmodule(fn->ctx->dwfl, fn->pc);
const char* addrname = dwfl_module_addrname(module, fn->pc);
Dwfl_Module* module = dwfl_addrmodule(fn->ctx->dwfl, fn->info.pc);
const char* addrname = dwfl_module_addrname(module, fn->info.pc);
if(addrname) {
char* demangle_name = cplus_demangle(addrname, 0);
char* function_name = NULL;
@@ -403,7 +403,7 @@ bool pst_function_unwind(pst_function* fn)
if(str) {
*str = 0;
}
fn->name = pst_strdup(function_name);
fn->info.name = pst_strdup(function_name);
free(function_name);
if(demangle_name) {
@@ -421,17 +421,17 @@ void pst_function_init(pst_function* fn, pst_context* _ctx, pst_function* _paren
// fields
fn->lowpc = 0;
fn->highpc = 0;
fn->pc = 0;
fn->info.pc = 0;
fn->info.name = NULL;
fn->info.line = -1;
fn->info.file = NULL;
fn->die = NULL;
fn->name = 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));
fn->line = -1;
fn->file = NULL;
fn->parent = _parent;
fn->frame = NULL;
fn->ctx = _ctx;
@@ -458,12 +458,12 @@ void pst_function_fini(pst_function* fn)
free(fn->frame);
}
if(fn->name) {
pst_free(fn->name);
if(fn->info.name) {
pst_free(fn->info.name);
}
if(fn->file) {
pst_free(fn->file);
if(fn->info.file) {
pst_free(fn->info.file);
}
if(fn->allocated) {
+5 -6
View File
@@ -11,6 +11,7 @@
#include <elfutils/libdw.h>
#include <libunwind.h>
#include "libpst-types.h"
#include "utils/list_head.h"
#include "context.h"
#include "dwarf_call_site.h"
@@ -20,23 +21,20 @@
// -----------------------------------------------------------------------------------
// pst_function
// -----------------------------------------------------------------------------------
typedef struct __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
unw_word_t pc; // address between LowPC & HighPC (plus base address offset). actually, currently executed command
Dwarf_Die* die; // DWARF DIE containing definition of the function
char* name; // function's name
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
int line; // line in code where function is defined
char* file; // file name (DWARF Compilation Unit) where function is defined
struct __pst_function* parent; // parent function in call trace (caller)
pst_function* parent; // parent function in call trace (caller)
Dwarf_Frame* frame; // function's stack frame
pst_context* ctx; // context of unwinding
bool allocated; // whether this object was allocated or not
@@ -48,5 +46,6 @@ void pst_function_fini(pst_function* fn);
bool pst_function_unwind(pst_function* fn);
bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d);
bool pst_function_print_dwarf(pst_function* fn);
pst_parameter* pst_function_next_parameter(pst_function* fn, pst_parameter* p);
#endif /* __PST_DWARF_FUNCTION_H__ */
+15 -15
View File
@@ -42,11 +42,11 @@ bool get_dwarf_function(pst_handler* h, pst_function* fun)
{
Dwarf_Addr mod_cu = 0;
// get CU(Compilation Unit) debug definition
h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc);
Dwarf_Die* cdie = dwfl_module_addrdie(h->ctx.module, fun->pc, &mod_cu);
h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->info.pc);
Dwarf_Die* cdie = dwfl_module_addrdie(h->ctx.module, fun->info.pc, &mod_cu);
//Dwarf_Die* cdie = dwfl_addrdie(dwfl, addr, &mod_bias);
if(!cdie) {
pst_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->info.pc);
return false;
}
@@ -67,7 +67,7 @@ bool get_dwarf_function(pst_handler* h, pst_function* fun)
int tag = dwarf_tag(&result);
if(tag == DW_TAG_subprogram || tag == DW_TAG_entry_point || tag == DW_TAG_inlined_subroutine) {
//ctx.log(SEVERITY_DEBUG, "function die name %s", dwarf_diename(&result));
if(!strcmp(fun->name, dwarf_diename(&result))) {
if(!strcmp(fun->info.name, dwarf_diename(&result))) {
return pst_function_handle_dwarf(fun, &result);
}
}
@@ -100,7 +100,7 @@ static void clear(pst_handler* h)
}
}
static pst_function* next_function(pst_handler* h, pst_function* fn)
pst_function* pst_handler_next_function(pst_handler* h, pst_function* fn)
{
list_node* n = (fn == NULL) ? list_first(&h->functions) : list_next(&fn->node);
pst_function* ret = NULL;
@@ -139,11 +139,11 @@ 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->pc), &info);
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);
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);
// setup context
h->ctx.module = dwfl_addrmodule(h->ctx.dwfl, fun->pc);
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;
@@ -161,7 +161,7 @@ const char* pst_print_pretty(pst_handler* h)
h->ctx.clean_print(&h->ctx);
h->ctx.print(&h->ctx, "DWARF-based stack trace information:\n");
uint32_t idx = 0;
for(pst_function* fn = next_function(h, NULL); fn; fn = next_function(h, fn)) {
for(pst_function* fn = pst_handler_next_function(h, NULL); fn; fn = pst_handler_next_function(h, fn)) {
h->ctx.print(&h->ctx, "[%-2u] ", idx); idx++;
pst_function_print_dwarf(fn);
h->ctx.print(&h->ctx, "\n");
@@ -184,13 +184,13 @@ const char* pst_print_simple(pst_handler* h)
h->ctx.clean_print(&h->ctx);
h->ctx.print(&h->ctx, "Simple unwind-based stack trace:\n");
uint32_t idx = 0;
for(pst_function* fn = next_function(h, NULL); fn; fn = next_function(h, fn)) {
for(pst_function* fn = pst_handler_next_function(h, NULL); fn; fn = pst_handler_next_function(h, fn)) {
h->ctx.print(&h->ctx, "[%-2d] ", idx);
h->ctx.print(fn->ctx, "%s() ", fn->name);
if(fn->file) {
h->ctx.print(fn->ctx, "at %s:%d, %p", fn->file, fn->line, (void*)fn->pc);
h->ctx.print(fn->ctx, "%s() ", fn->info.name);
if(fn->info.file) {
h->ctx.print(fn->ctx, "at %s:%d, %p", fn->info.file, fn->info.line, (void*)fn->info.pc);
} else {
h->ctx.print(fn->ctx, "at %p", (void*)fn->pc);
h->ctx.print(fn->ctx, "at %p", (void*)fn->info.pc);
}
h->ctx.print(&h->ctx, "\n");
idx++;
@@ -276,7 +276,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->pc = pc; fn->sp = sp;
fn->info.pc = pc; fn->sp = sp;
if(!pst_function_unwind(fn)) {
del_function(fn);
} else if(last) {
+1
View File
@@ -28,5 +28,6 @@ void pst_handler_fini(pst_handler* h);
bool pst_handler_handle_dwarf(pst_handler* h);
bool pst_handler_unwind(pst_handler* h);
pst_function* pst_handler_next_function(pst_handler* h, pst_function* fn);
#endif /* __PST_DWARF_HANDLER_H__ */
+34 -31
View File
@@ -70,20 +70,20 @@ static pst_type* next_type(pst_parameter* param, pst_type* t)
bool pst_parameter_print_dwarf(pst_parameter* param)
{
if(list_count(&param->types)) {
if(!param->is_return) {
if(param->has_value) {
param->ctx->print(param->ctx, "%s %s = 0x%lX", next_type(param, NULL)->name, param->name, param->location.value);
if(!param->info.is_return) {
if(param->info.has_value) {
param->ctx->print(param->ctx, "%s %s = 0x%lX", next_type(param, NULL)->name, param->info.name, param->info.value);
} else {
param->ctx->print(param->ctx, "%s %s = <undefined>", next_type(param, NULL)->name, param->name);
param->ctx->print(param->ctx, "%s %s = <undefined>", next_type(param, NULL)->name, param->info.name);
}
} else {
param->ctx->print(param->ctx, "%s", next_type(param, NULL)->name);
}
} else {
if(param->has_value) {
param->ctx->print(param->ctx, "%s = 0x%lX", param->name, param->location.value);
if(param->info.has_value) {
param->ctx->print(param->ctx, "%s = 0x%lX", param->info.name, param->info.value);
} else {
param->ctx->print(param->ctx, "%s = <undefined>", param->name);
param->ctx->print(param->ctx, "%s = <undefined>", param->info.name);
}
}
return true;
@@ -113,12 +113,12 @@ bool pst_parameter_handle_type(pst_parameter* param, Dwarf_Attribute* base)
switch (dwarf_tag(&ret_die)) {
case DW_TAG_base_type: {
// get Size attribute and it's value
param->size = 0;
param->info.size = 0;
attr = dwarf_attr(&ret_die, DW_AT_byte_size, &attr_mem);
if(attr) {
dwarf_formudata(attr, &param->size);
dwarf_formudata(attr, &param->info.size);
}
pst_log(SEVERITY_DEBUG, "base type '%s'(%lu)", dwarf_diename(&ret_die), param->size);
pst_log(SEVERITY_DEBUG, "base type '%s'(%lu)", dwarf_diename(&ret_die), param->info.size);
pst_parameter_add_type(param, dwarf_diename(&ret_die), DW_TAG_base_type);
param->type = DW_TAG_base_type;
@@ -184,13 +184,13 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
Dwarf_Attribute attr_mem;
Dwarf_Attribute* attr;
param->name = pst_strdup(dwarf_diename(result));
param->is_variable = (dwarf_tag(result) == DW_TAG_variable);
param->info.name = pst_strdup(dwarf_diename(result));
param->info.is_variable = (dwarf_tag(result) == DW_TAG_variable);
dwarf_decl_line(result, (int*)&param->line);
dwarf_decl_line(result, (int*)&param->info.line);
// Get reference to attribute type of the parameter/variable
attr = dwarf_attr(result, DW_AT_type, &attr_mem);
pst_log(SEVERITY_DEBUG, "---> Handle '%s' %s", param->name, dwarf_tag(result) == DW_TAG_formal_parameter ? "parameter" : "variable");
pst_log(SEVERITY_DEBUG, "---> Handle '%s' %s", param->info.name, dwarf_tag(result) == DW_TAG_formal_parameter ? "parameter" : "variable");
if(attr) {
pst_parameter_handle_type(param, attr);
}
@@ -202,7 +202,8 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
unw_get_reg(param->ctx->curr_frame, UNW_REG_IP, &pc);
if(handle_location(param->ctx, attr, &param->location, pc, fun)) {
param->has_value = true;
param->info.value = param->location.value;
param->info.has_value = true;
} else {
pst_log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", param->ctx->buff);
}
@@ -218,20 +219,20 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
case DW_FORM_data2:
case DW_FORM_data4:
case DW_FORM_data8:
dwarf_formudata(attr, &param->location.value);
param->has_value = true;
dwarf_formudata(attr, &param->info.value);
param->info.has_value = true;
break;
case DW_FORM_sdata:
dwarf_formsdata(attr, (int64_t*)&param->location.value);
param->has_value = true;
dwarf_formsdata(attr, (int64_t*)&param->info.value);
param->info.has_value = true;
break;
case DW_FORM_udata:
dwarf_formudata(attr, &param->location.value);
param->has_value = true;
dwarf_formudata(attr, &param->info.value);
param->info.has_value = true;
break;
}
if(param->has_value) {
pst_log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", param->location.value);
if(param->info.has_value) {
pst_log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", param->info.value);
}
}
@@ -260,15 +261,17 @@ void pst_parameter_init(pst_parameter* param, pst_context* ctx)
{
list_node_init(&param->node);
param->die = NULL;
param->name = NULL;
param->line = 0;
param->size = 0;
// info field
param->info.name = NULL;
param->info.line = 0;
param->info.size = 0;
param->info.is_return = false;
param->info.is_variable = false;
param->info.has_value = false;
param->type = 0;
param->enc_type = 0;
list_head_init(&param->types);
param->is_return = false;
param->is_variable = false;
param->has_value = false;
param->ctx = ctx;
pst_dwarf_expr_init(&param->location);
param->allocated = false;
@@ -287,8 +290,8 @@ pst_parameter* pst_parameter_new(pst_context* ctx)
void pst_parameter_fini(pst_parameter* param)
{
clear(param);
if(param->name) {
pst_free(param->name);
if(param->info.name) {
pst_free(param->info.name);
}
if(param->allocated) {
pst_free(param);
+9 -14
View File
@@ -26,26 +26,21 @@ void pst_type_init(pst_type* t, const char* name, uint32_t type);
pst_type* pst_type_new(const char* name, uint32_t type);
void pst_type_fini(pst_type* t);
typedef struct __pst_function pst_function;
typedef struct pst_function pst_function;
typedef struct pst_parameter{
list_node node; // uplink. !!! must be first !!!
// fields
Dwarf_Die* die; // DWARF DIE containing parameter's definition
char* name; // parameter's name
uint32_t line; // line of parameter definition
Dwarf_Word size; // size of parameter in bytes
int type; // type of parameter in DW_TAG_XXX types enumeration
Dwarf_Word enc_type; // if 'type' is DW_TAG_Base_type, then 'base_type' holds DW_AT_ATE_XXX base type encoding type
list_head types; // list of parameter's definitions i.e. 'typedef', 'uint32_t'
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
pst_context* ctx;
pst_dwarf_expr location;
Dwarf_Die* die; // DWARF DIE containing parameter's definition
pst_parameter_info info;
int type; // type of parameter in DW_TAG_XXX types enumeration
Dwarf_Word enc_type; // if 'type' is DW_TAG_Base_type, then 'base_type' holds DW_AT_ATE_XXX base type encoding type
list_head types; // list of parameter's definitions i.e. 'typedef', 'uint32_t'
pst_context* ctx;
pst_dwarf_expr location;
bool allocated;
bool allocated;
} pst_parameter;
void pst_parameter_init(pst_parameter* param, pst_context* ctx);
pst_parameter* pst_parameter_new(pst_context* ctx);