better printing of parameters. export access to parameter's children
This commit is contained in:
@@ -58,7 +58,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* name; ///< parameter's name
|
char* name; ///< parameter's name
|
||||||
char* type_name; ///< name of parameter's type in case of 'PARAM_TYPE_TYPEDEF'
|
char* type_name; ///< name of parameter's type
|
||||||
uint32_t line; ///< line of parameter definition
|
uint32_t line; ///< line of parameter definition
|
||||||
unw_word_t size; ///< size of parameter in bits
|
unw_word_t size; ///< size of parameter in bits
|
||||||
unw_word_t value; ///< value of parameter. use 'size' to determine number of actual bits of 'value'
|
unw_word_t value; ///< value of parameter. use 'size' to determine number of actual bits of 'value'
|
||||||
|
|||||||
+10
-2
@@ -65,7 +65,7 @@ const char* pst_print_simple(pst_handler* handler);
|
|||||||
* @param current pointer to current function. NULL to get first
|
* @param current pointer to current function. NULL to get first
|
||||||
* @return pointer to next function's handle, NULL in case of end of list
|
* @return pointer to next function's handle, NULL in case of end of list
|
||||||
*/
|
*/
|
||||||
const pst_function* pst_get_next_function(pst_handler* handler, pst_function* current);
|
const pst_function* pst_function_next(pst_handler* handler, pst_function* current);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get function's information (name, address, line)
|
* @brief Get function's information (name, address, line)
|
||||||
@@ -80,7 +80,15 @@ const pst_function_info* pst_get_function_info(pst_function* function);
|
|||||||
* @param current pointer to current parameter. NULL to get first
|
* @param current pointer to current parameter. NULL to get first
|
||||||
* @return pointer to next parameter's handle, NULL in case of end of list
|
* @return pointer to next parameter's handle, NULL in case of end of list
|
||||||
*/
|
*/
|
||||||
const pst_parameter* pst_get_next_parameter(pst_function* function, pst_parameter* current);
|
const pst_parameter* pst_parameter_next(pst_function* function, pst_parameter* current);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get next parameter's children parameter (for composite types)
|
||||||
|
* @param parent parent parameter's handler obtained by pst_get_next_parameter()
|
||||||
|
* @param current pointer to current child parameter. NULL to get first
|
||||||
|
* @return pointer to next parameter's handle, NULL in case of end of list
|
||||||
|
*/
|
||||||
|
const pst_parameter* pst_parameter_next_child(pst_parameter* parent, pst_parameter* current);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get parameter's information (name, type, line etc)
|
* @brief Get parameter's information (name, type, line etc)
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ bool handle_lexical_block(pst_function* fn, Dwarf_Die* result)
|
|||||||
break;
|
break;
|
||||||
case DW_TAG_variable: {
|
case DW_TAG_variable: {
|
||||||
pst_parameter* param = add_param(fn);
|
pst_parameter* param = add_param(fn);
|
||||||
if(!pst_parameter_handle_dwarf(param, &child, fn)) {
|
if(!parameter_handle_dwarf(param, &child, fn)) {
|
||||||
del_param(param);
|
del_param(param);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -202,7 +202,7 @@ bool pst_function_print_dwarf(pst_function* fn)
|
|||||||
pst_parameter* param = pst_function_next_parameter(fn, NULL);
|
pst_parameter* param = pst_function_next_parameter(fn, NULL);
|
||||||
if(param && (param->info.flags & PARAM_RETURN)) {
|
if(param && (param->info.flags & PARAM_RETURN)) {
|
||||||
// print return value type, function name and start list of parameters
|
// print return value type, function name and start list of parameters
|
||||||
pst_parameter_print_dwarf(param);
|
parameter_print(param);
|
||||||
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
||||||
param = pst_function_next_parameter(fn, param);
|
param = pst_function_next_parameter(fn, param);
|
||||||
} else {
|
} else {
|
||||||
@@ -213,7 +213,7 @@ bool pst_function_print_dwarf(pst_function* fn)
|
|||||||
for(; param; param = pst_function_next_parameter(fn, param)) {
|
for(; param; param = pst_function_next_parameter(fn, param)) {
|
||||||
if(param->info.flags & PARAM_RETURN) {
|
if(param->info.flags & PARAM_RETURN) {
|
||||||
// print return value type, function name and start list of parameters
|
// print return value type, function name and start list of parameters
|
||||||
pst_parameter_print_dwarf(param);
|
parameter_print(param);
|
||||||
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -229,7 +229,7 @@ bool pst_function_print_dwarf(pst_function* fn)
|
|||||||
} else {
|
} else {
|
||||||
fn->ctx->print(fn->ctx, " ");
|
fn->ctx->print(fn->ctx, " ");
|
||||||
}
|
}
|
||||||
pst_parameter_print_dwarf(param);
|
parameter_print(param);
|
||||||
fn->ctx->print(fn->ctx, ";\n");
|
fn->ctx->print(fn->ctx, ";\n");
|
||||||
} else {
|
} else {
|
||||||
if(first) {
|
if(first) {
|
||||||
@@ -237,7 +237,7 @@ bool pst_function_print_dwarf(pst_function* fn)
|
|||||||
} else {
|
} else {
|
||||||
fn->ctx->print(fn->ctx, ", ");
|
fn->ctx->print(fn->ctx, ", ");
|
||||||
}
|
}
|
||||||
pst_parameter_print_dwarf(param);
|
parameter_print(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,14 +307,13 @@ bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d)
|
|||||||
// Get reference to return attribute type of the function
|
// Get reference to return attribute type of the function
|
||||||
// may be to use dwfl_module_return_value_location() instead
|
// may be to use dwfl_module_return_value_location() instead
|
||||||
pst_parameter* ret_p = add_param(fn); ret_p->info.flags |= PARAM_RETURN;
|
pst_parameter* ret_p = add_param(fn); ret_p->info.flags |= PARAM_RETURN;
|
||||||
attr = dwarf_attr(fn->die, DW_AT_type, &attr_mem);
|
if(dwarf_hasattr(fn->die, DW_AT_type)) {
|
||||||
if(attr) {
|
if(!parameter_handle_type(ret_p, fn->die)) {
|
||||||
if(!pst_parameter_handle_type(ret_p, attr)) {
|
|
||||||
pst_log(SEVERITY_ERROR, "Failed to handle return parameter type for function %s(...)", fn->info.name);
|
pst_log(SEVERITY_ERROR, "Failed to handle return parameter type for function %s(...)", fn->info.name);
|
||||||
del_param(ret_p);
|
del_param(ret_p);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pst_parameter_add_type(ret_p, "void", PARAM_TYPE_VOID);
|
parameter_add_type(ret_p, "void", PARAM_TYPE_VOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle and save additionally these attributes:
|
// handle and save additionally these attributes:
|
||||||
@@ -343,7 +342,7 @@ bool pst_function_handle_dwarf(pst_function * fn, Dwarf_Die* d)
|
|||||||
case DW_TAG_formal_parameter:
|
case DW_TAG_formal_parameter:
|
||||||
case DW_TAG_variable: {
|
case DW_TAG_variable: {
|
||||||
pst_parameter* param = add_param(fn);
|
pst_parameter* param = add_param(fn);
|
||||||
if(!pst_parameter_handle_dwarf(param, &result, fn)) {
|
if(!parameter_handle_dwarf(param, &result, fn)) {
|
||||||
del_param(param);
|
del_param(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+102
-60
@@ -89,36 +89,83 @@ static pst_type* next_type(pst_parameter* param, pst_type* t)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pst_parameter_print_dwarf(pst_parameter* param)
|
static void parameter_print_type(pst_parameter* param)
|
||||||
{
|
{
|
||||||
if(param->info.flags & PARAM_RETURN) {
|
bool is_1st = true;
|
||||||
|
for(pst_type* t = next_type(param, NULL); t; t = next_type(param, t)) {
|
||||||
|
if(is_1st) {
|
||||||
|
switch(t->type) {
|
||||||
|
case PARAM_CONST:
|
||||||
|
param->ctx->print(param->ctx, "%s", "const ");
|
||||||
|
break;
|
||||||
|
case PARAM_TYPE_STRUCT:
|
||||||
|
param->ctx->print(param->ctx, "%s", "struct ");
|
||||||
|
break;
|
||||||
|
case PARAM_TYPE_UNION:
|
||||||
|
param->ctx->print(param->ctx, "%s", "union ");
|
||||||
|
break;
|
||||||
|
case PARAM_TYPE_ENUM:
|
||||||
|
param->ctx->print(param->ctx, "%s", "enum ");
|
||||||
|
break;
|
||||||
|
case PARAM_TYPE_CLASS:
|
||||||
|
param->ctx->print(param->ctx, "%s", "class ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
param->ctx->print(param->ctx, "%s", param->info.type_name ? param->info.type_name : "");
|
param->ctx->print(param->ctx, "%s", param->info.type_name ? param->info.type_name : "");
|
||||||
} else {
|
is_1st = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(t->type) {
|
||||||
|
case PARAM_TYPE_POINTER:
|
||||||
|
if(!(param->info.flags & PARAM_TYPE_FUNCPTR)) {
|
||||||
|
param->ctx->print(param->ctx, "%s", "*");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PARAM_TYPE_REF:
|
||||||
|
param->ctx->print(param->ctx, "%s", "&");
|
||||||
|
break;
|
||||||
|
case PARAM_TYPE_ARRAY:
|
||||||
|
param->ctx->print(param->ctx, "%s", "[]");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void parameter_print(pst_parameter* param)
|
||||||
|
{
|
||||||
|
parameter_print_type(param);
|
||||||
|
if(param->info.flags & PARAM_RETURN) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(param->info.flags & PARAM_TYPE_FUNCPTR) {
|
if(param->info.flags & PARAM_TYPE_FUNCPTR) {
|
||||||
param->ctx->print(param->ctx, "%s (*%s)(", param->info.type_name ? param->info.type_name : "", param->info.name);
|
param->ctx->print(param->ctx, " (*%s)(", param->info.name);
|
||||||
for(pst_parameter* p = pst_parameter_next_child(param, NULL); p; p = pst_parameter_next_child(param, p)) {
|
for(pst_parameter* p = parameter_next_child(param, NULL); p; p = parameter_next_child(param, p)) {
|
||||||
if(p->info.flags & PARAM_RETURN) {
|
if(p->info.flags & PARAM_RETURN) {
|
||||||
// skip return value
|
// skip return value
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
param->ctx->print(param->ctx, "%s%s%s", p->info.type_name ? p->info.type_name : "", p->info.flags & PARAM_TYPE_POINTER ? "*" : "",
|
parameter_print_type(p);
|
||||||
(pst_parameter_next_child(param, p) != NULL) ? ", " : "");
|
param->ctx->print(param->ctx, "%s", (parameter_next_child(param, p) != NULL) ? ", " : "");
|
||||||
}
|
}
|
||||||
param->ctx->print(param->ctx, ") = ");
|
param->ctx->print(param->ctx, ") = ");
|
||||||
} else {
|
} else {
|
||||||
param->ctx->print(param->ctx, "%s%s %s = ", param->info.type_name ? param->info.type_name : "",
|
param->ctx->print(param->ctx, " %s = ", param->info.name);
|
||||||
param->info.flags & PARAM_TYPE_POINTER ? "*" : "", param->info.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(param->info.flags & PARAM_HAS_VALUE) {
|
if(param->info.flags & PARAM_HAS_VALUE) {
|
||||||
param->ctx->print(param->ctx, "0x%lX", param->info.value);
|
param->ctx->print(param->ctx, "0x%lX", param->info.value);
|
||||||
} else {
|
} else {
|
||||||
param->ctx->print(param->ctx, "<undefined>");
|
param->ctx->print(param->ctx, "<undefined>");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pst_type* pst_parameter_add_type(pst_parameter* param, const char* name, pst_param_flags type)
|
pst_type* parameter_add_type(pst_parameter* param, const char* name, pst_param_flags type)
|
||||||
{
|
{
|
||||||
pst_new(pst_type, t, name, type);
|
pst_new(pst_type, t, name, type);
|
||||||
list_add_bottom(¶m->types, &t->node);
|
list_add_bottom(¶m->types, &t->node);
|
||||||
@@ -130,7 +177,7 @@ pst_type* pst_parameter_add_type(pst_parameter* param, const char* name, pst_par
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
pst_parameter* pst_parameter_next_child(pst_parameter* param, pst_parameter* p)
|
pst_parameter* parameter_next_child(pst_parameter* param, pst_parameter* p)
|
||||||
{
|
{
|
||||||
struct list_node* n = (p == NULL) ? list_first(¶m->children) : list_next(&p->node);
|
struct list_node* n = (p == NULL) ? list_first(¶m->children) : list_next(&p->node);
|
||||||
|
|
||||||
@@ -142,7 +189,7 @@ pst_parameter* pst_parameter_next_child(pst_parameter* param, pst_parameter* p)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pst_parameter_handle_subroutine(pst_parameter* param, Dwarf_Die* die)
|
static bool handle_subroutine(pst_parameter* param, Dwarf_Die* die)
|
||||||
{
|
{
|
||||||
// return value
|
// return value
|
||||||
pst_new(pst_parameter, p, param->ctx);
|
pst_new(pst_parameter, p, param->ctx);
|
||||||
@@ -156,13 +203,9 @@ bool pst_parameter_handle_subroutine(pst_parameter* param, Dwarf_Die* die)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reference to attribute type of the parameter/variable
|
parameter_handle_type(param, die);
|
||||||
attr = dwarf_attr(die, DW_AT_type, &attr_mem);
|
|
||||||
if(attr) {
|
|
||||||
pst_parameter_handle_type(param, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hack since DWARF has no ability to determine 'void' it another way
|
// hack since DWARF has no ability to determine 'void' another way
|
||||||
if(!p->info.type_name) {
|
if(!p->info.type_name) {
|
||||||
p->info.type_name = pst_strdup("void");
|
p->info.type_name = pst_strdup("void");
|
||||||
}
|
}
|
||||||
@@ -191,11 +234,7 @@ bool pst_parameter_handle_subroutine(pst_parameter* param, Dwarf_Die* die)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reference to attribute type of the parameter/variable
|
parameter_handle_type(p1, &result);
|
||||||
attr = dwarf_attr(&result, DW_AT_type, &attr_mem);
|
|
||||||
if(attr) {
|
|
||||||
pst_parameter_handle_type(p1, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// hack since DWARF has no ability to determine 'void' it another way
|
// hack since DWARF has no ability to determine 'void' it another way
|
||||||
if(!p1->info.type_name) {
|
if(!p1->info.type_name) {
|
||||||
@@ -221,100 +260,107 @@ bool pst_parameter_handle_subroutine(pst_parameter* param, Dwarf_Die* die)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pst_parameter_handle_type(pst_parameter* param, Dwarf_Attribute* base)
|
bool parameter_handle_type(pst_parameter* param, Dwarf_Die* result)
|
||||||
{
|
{
|
||||||
Dwarf_Attribute attr_mem;
|
Dwarf_Attribute attr_mem;
|
||||||
Dwarf_Attribute* attr;
|
Dwarf_Attribute* attr;
|
||||||
|
|
||||||
// get DIE of return type
|
// get DIE of type
|
||||||
Dwarf_Die ret_die;
|
Dwarf_Die ret_die;
|
||||||
|
|
||||||
if(!dwarf_formref_die(base, &ret_die)) {
|
// Get reference to attribute type of the parameter/variable
|
||||||
pst_log(SEVERITY_ERROR, "Failed to get parameter DIE");
|
attr = dwarf_attr(result, DW_AT_type, &attr_mem);
|
||||||
|
if(!attr) {
|
||||||
|
pst_log(SEVERITY_WARNING, "%s: Failed to determine type of parameter", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dwarf_formref_die(attr, &ret_die)) {
|
||||||
|
pst_log(SEVERITY_ERROR, "Failed to get parameter type DIE");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
param->info.size = 64;
|
param->info.size = 64;
|
||||||
switch (dwarf_tag(&ret_die)) {
|
switch (dwarf_tag(&ret_die)) {
|
||||||
|
// base types
|
||||||
case DW_TAG_base_type: {
|
case DW_TAG_base_type: {
|
||||||
// get Size attribute and it's value
|
// get Size attribute and it's value
|
||||||
attr = dwarf_attr(&ret_die, DW_AT_byte_size, &attr_mem);
|
attr = dwarf_attr(&ret_die, DW_AT_byte_size, &attr_mem);
|
||||||
if(attr) {
|
if(attr) {
|
||||||
dwarf_formudata(attr, ¶m->info.size);
|
dwarf_formudata(attr, ¶m->info.size);
|
||||||
}
|
}
|
||||||
pst_log(SEVERITY_DEBUG, "base type '%s'(%lu)", dwarf_diename(&ret_die), param->info.size);
|
pst_log(SEVERITY_DEBUG, "%s: Base type '%s'(%lu)", __FUNCTION__, dwarf_diename(&ret_die), param->info.size);
|
||||||
pst_parameter_add_type(param, dwarf_diename(&ret_die), DW_TAG_base_type);
|
|
||||||
|
|
||||||
const char* type_name = dwarf_diename(&ret_die);
|
const char* type_name = dwarf_diename(&ret_die);
|
||||||
pst_log(SEVERITY_DEBUG, "type_name = %s", type_name);
|
|
||||||
attr = dwarf_attr(&ret_die, DW_AT_encoding, &attr_mem);
|
attr = dwarf_attr(&ret_die, DW_AT_encoding, &attr_mem);
|
||||||
if(attr) {
|
if(attr) {
|
||||||
Dwarf_Word enc_type = 0;
|
Dwarf_Word enc_type = 0;
|
||||||
dwarf_formudata(attr, &enc_type);
|
dwarf_formudata(attr, &enc_type);
|
||||||
switch (enc_type) {
|
switch (enc_type) {
|
||||||
case DW_ATE_boolean:
|
case DW_ATE_boolean:
|
||||||
pst_parameter_add_type(param, type_name, PARAM_TYPE_BOOL);
|
parameter_add_type(param, type_name, PARAM_TYPE_BOOL);
|
||||||
break;
|
break;
|
||||||
case DW_ATE_address:
|
case DW_ATE_address:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_POINTER);
|
parameter_add_type(param, NULL, PARAM_TYPE_POINTER);
|
||||||
break;
|
break;
|
||||||
case DW_ATE_signed:
|
case DW_ATE_signed:
|
||||||
pst_parameter_add_type(param, type_name, PARAM_TYPE_INT);
|
parameter_add_type(param, type_name, PARAM_TYPE_INT);
|
||||||
break;
|
break;
|
||||||
case DW_ATE_unsigned:
|
case DW_ATE_unsigned:
|
||||||
pst_parameter_add_type(param, type_name, PARAM_TYPE_UINT);
|
parameter_add_type(param, type_name, PARAM_TYPE_UINT);
|
||||||
break;
|
break;
|
||||||
case DW_ATE_signed_char:
|
case DW_ATE_signed_char:
|
||||||
pst_parameter_add_type(param, type_name, PARAM_TYPE_CHAR);
|
parameter_add_type(param, type_name, PARAM_TYPE_CHAR);
|
||||||
break;
|
break;
|
||||||
case DW_ATE_unsigned_char:
|
case DW_ATE_unsigned_char:
|
||||||
pst_parameter_add_type(param, type_name, PARAM_TYPE_UCHAR);
|
parameter_add_type(param, type_name, PARAM_TYPE_UCHAR);
|
||||||
break;
|
break;
|
||||||
case DW_ATE_float:
|
case DW_ATE_float:
|
||||||
case DW_ATE_complex_float:
|
case DW_ATE_complex_float:
|
||||||
case DW_ATE_imaginary_float:
|
case DW_ATE_imaginary_float:
|
||||||
case DW_ATE_decimal_float:
|
case DW_ATE_decimal_float:
|
||||||
pst_parameter_add_type(param, type_name, PARAM_TYPE_FLOAT);
|
parameter_add_type(param, type_name, PARAM_TYPE_FLOAT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// complex types
|
||||||
case DW_TAG_array_type:
|
case DW_TAG_array_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_ARRAY);
|
parameter_add_type(param, NULL, PARAM_TYPE_ARRAY);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_structure_type:
|
case DW_TAG_structure_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_STRUCT);
|
parameter_add_type(param, NULL, PARAM_TYPE_STRUCT);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_union_type:
|
case DW_TAG_union_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_UNION);
|
parameter_add_type(param, NULL, PARAM_TYPE_UNION);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_class_type:
|
case DW_TAG_class_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_CLASS);
|
parameter_add_type(param, NULL, PARAM_TYPE_CLASS);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_pointer_type:
|
case DW_TAG_pointer_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_POINTER);
|
parameter_add_type(param, NULL, PARAM_TYPE_POINTER);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_enumeration_type:
|
case DW_TAG_enumeration_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_ENUM);
|
parameter_add_type(param, NULL, PARAM_TYPE_ENUM);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_const_type:
|
case DW_TAG_const_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_CONST);
|
parameter_add_type(param, NULL, PARAM_CONST);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_subroutine_type:
|
case DW_TAG_subroutine_type:
|
||||||
pst_parameter_handle_subroutine(param, &ret_die);
|
handle_subroutine(param, &ret_die);
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_FUNCPTR);
|
parameter_add_type(param, NULL, PARAM_TYPE_FUNCPTR);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_typedef: {
|
case DW_TAG_typedef: {
|
||||||
pst_parameter_add_type(param, dwarf_diename(&ret_die), PARAM_TYPE_TYPEDEF);
|
parameter_add_type(param, dwarf_diename(&ret_die), PARAM_TYPE_TYPEDEF);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DW_TAG_unspecified_type:
|
case DW_TAG_unspecified_type:
|
||||||
pst_parameter_add_type(param, "void", PARAM_TYPE_VOID);
|
parameter_add_type(param, "void", PARAM_TYPE_VOID);
|
||||||
break;
|
break;
|
||||||
case DW_TAG_reference_type:
|
case DW_TAG_reference_type:
|
||||||
pst_parameter_add_type(param, NULL, PARAM_TYPE_REF);
|
parameter_add_type(param, NULL, PARAM_TYPE_REF);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -322,15 +368,15 @@ bool pst_parameter_handle_type(pst_parameter* param, Dwarf_Attribute* base)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = dwarf_attr(&ret_die, DW_AT_type, &attr_mem);
|
if(dwarf_hasattr(&ret_die, DW_AT_type)) {
|
||||||
if(attr) {
|
// handle parameter's sub-type
|
||||||
return pst_parameter_handle_type(param, attr);
|
return parameter_handle_type(param, &ret_die);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_function* fun)
|
bool parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_function* fun)
|
||||||
{
|
{
|
||||||
param->die = result;
|
param->die = result;
|
||||||
|
|
||||||
@@ -341,12 +387,8 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
|
|||||||
param->info.flags |= (dwarf_tag(result) == DW_TAG_variable) ? PARAM_VARIABLE : 0;
|
param->info.flags |= (dwarf_tag(result) == DW_TAG_variable) ? PARAM_VARIABLE : 0;
|
||||||
|
|
||||||
dwarf_decl_line(result, (int*)¶m->info.line);
|
dwarf_decl_line(result, (int*)¶m->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->info.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) {
|
parameter_handle_type(param, result);
|
||||||
pst_parameter_handle_type(param, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dwarf_hasattr(result, DW_AT_location)) {
|
if(dwarf_hasattr(result, DW_AT_location)) {
|
||||||
// determine location of parameter in stack/heap or CPU registers
|
// determine location of parameter in stack/heap or CPU registers
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ void pst_parameter_init(pst_parameter* param, pst_context* ctx);
|
|||||||
pst_parameter* pst_parameter_new(pst_context* ctx);
|
pst_parameter* pst_parameter_new(pst_context* ctx);
|
||||||
void pst_parameter_fini(pst_parameter* param);
|
void pst_parameter_fini(pst_parameter* param);
|
||||||
|
|
||||||
bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_function* fun);
|
bool parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_function* fun);
|
||||||
bool pst_parameter_print_dwarf(pst_parameter* param);
|
void parameter_print(pst_parameter* param);
|
||||||
bool pst_parameter_handle_type(pst_parameter* param, Dwarf_Attribute* base);
|
bool parameter_handle_type(pst_parameter* param, Dwarf_Die* result);
|
||||||
pst_type* pst_parameter_add_type(pst_parameter* param, const char* name, pst_param_flags type);
|
pst_type* parameter_add_type(pst_parameter* param, const char* name, pst_param_flags type);
|
||||||
pst_parameter* pst_parameter_next_child(pst_parameter* param, pst_parameter* p);
|
pst_parameter* parameter_next_child(pst_parameter* param, pst_parameter* p);
|
||||||
|
|
||||||
#endif /* __PST_DWARF_PARAMETER_H__ */
|
#endif /* __PST_DWARF_PARAMETER_H__ */
|
||||||
|
|||||||
+7
-2
@@ -60,12 +60,17 @@ pst_function_info* pst_get_function_info(pst_function* function)
|
|||||||
return &function->info;
|
return &function->info;
|
||||||
}
|
}
|
||||||
|
|
||||||
pst_function* pst_get_next_function(pst_handler* handler, pst_function* current)
|
pst_function* pst_function_next(pst_handler* handler, pst_function* current)
|
||||||
{
|
{
|
||||||
return pst_handler_next_function(handler, current);
|
return pst_handler_next_function(handler, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
pst_parameter* pst_get_next_parameter(pst_function* function, pst_parameter* current)
|
pst_parameter* pst_parameter_next(pst_function* function, pst_parameter* current)
|
||||||
{
|
{
|
||||||
return pst_function_next_parameter(function, current);
|
return pst_function_next_parameter(function, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pst_parameter* pst_parameter_next_child(pst_parameter* parent, pst_parameter* current)
|
||||||
|
{
|
||||||
|
return parameter_next_child(parent, current);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user