use bitset for parameter state instead of separate boolean fields
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
#ifndef INCLUDE_LIBPST_TYPES_H_
|
#ifndef INCLUDE_LIBPST_TYPES_H_
|
||||||
#define INCLUDE_LIBPST_TYPES_H_
|
#define INCLUDE_LIBPST_TYPES_H_
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdint.h>
|
||||||
#include <libunwind.h>
|
#include <libunwind.h>
|
||||||
|
|
||||||
typedef struct pst_function_info {
|
typedef struct pst_function_info {
|
||||||
@@ -18,14 +18,18 @@ typedef struct pst_function_info {
|
|||||||
unw_word_t pc; ///< address between LowPC & HighPC (plus base address offset). actually, address of currently executed command in function
|
unw_word_t pc; ///< address between LowPC & HighPC (plus base address offset). actually, address of currently executed command in function
|
||||||
} pst_function_info;
|
} pst_function_info;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PARAM_RETURN = 1, ///< parameter is return value of a function
|
||||||
|
PARAM_VARIABLE = 2, ///< parameter is variable inside of a function
|
||||||
|
PARAM_HAS_VALUE = 4 ///< parameter has a valid value (if not set, then value is undefined)
|
||||||
|
} pst_param_flags;
|
||||||
|
|
||||||
typedef struct pst_parameter_info {
|
typedef struct pst_parameter_info {
|
||||||
char* name; ///< parameter's name
|
char* name; ///< parameter's name
|
||||||
uint32_t line; ///< line of parameter definition
|
uint32_t line; ///< line of parameter definition
|
||||||
unw_word_t size; ///< size of parameter in bytes
|
unw_word_t size; ///< size of parameter in bytes
|
||||||
unw_word_t value; ///< value of parameter. currently only base types supported. use 'size' to determine number of actual bytes of value
|
unw_word_t value; ///< value of parameter. currently only base types supported. use 'size' to determine number of actual bytes of value
|
||||||
bool is_return; ///< whether this parameter is return value of the function
|
pst_param_flags flags; ///< flags of various parameter's options
|
||||||
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_parameter_info;
|
} pst_parameter_info;
|
||||||
|
|
||||||
#endif /* INCLUDE_LIBPST_TYPES_H_ */
|
#endif /* INCLUDE_LIBPST_TYPES_H_ */
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ bool pst_function_print_dwarf(pst_function* fn)
|
|||||||
|
|
||||||
// handle return parameter and be safe if function haven't parameters (for example, dwar info for function is absent)
|
// handle return parameter and be safe if function haven't parameters (for example, dwar info for function is absent)
|
||||||
pst_parameter* param = pst_function_next_parameter(fn, NULL);
|
pst_parameter* param = pst_function_next_parameter(fn, NULL);
|
||||||
if(param && param->info.is_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);
|
pst_parameter_print_dwarf(param);
|
||||||
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
||||||
@@ -211,14 +211,14 @@ bool pst_function_print_dwarf(pst_function* fn)
|
|||||||
|
|
||||||
bool first = true; bool start_variable = false;
|
bool first = true; bool start_variable = false;
|
||||||
for(; param; param = pst_function_next_parameter(fn, param)) {
|
for(; param; param = pst_function_next_parameter(fn, param)) {
|
||||||
if(param->info.is_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);
|
pst_parameter_print_dwarf(param);
|
||||||
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
fn->ctx->print(fn->ctx, " %s(", fn->info.name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(param->info.is_variable) {
|
if(param->info.flags & PARAM_VARIABLE) {
|
||||||
if(!start_variable) {
|
if(!start_variable) {
|
||||||
fn->ctx->print(fn->ctx, ")%s\n", at);
|
fn->ctx->print(fn->ctx, ")%s\n", at);
|
||||||
fn->ctx->print(fn->ctx, "{\n");
|
fn->ctx->print(fn->ctx, "{\n");
|
||||||
@@ -306,7 +306,7 @@ 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.is_return = true;
|
pst_parameter* ret_p = add_param(fn); ret_p->info.flags |= PARAM_RETURN;
|
||||||
attr = dwarf_attr(fn->die, DW_AT_type, &attr_mem);
|
attr = dwarf_attr(fn->die, DW_AT_type, &attr_mem);
|
||||||
if(attr) {
|
if(attr) {
|
||||||
if(!pst_parameter_handle_type(ret_p, attr)) {
|
if(!pst_parameter_handle_type(ret_p, attr)) {
|
||||||
|
|||||||
+12
-14
@@ -70,17 +70,17 @@ static pst_type* next_type(pst_parameter* param, pst_type* t)
|
|||||||
bool pst_parameter_print_dwarf(pst_parameter* param)
|
bool pst_parameter_print_dwarf(pst_parameter* param)
|
||||||
{
|
{
|
||||||
if(list_count(¶m->types)) {
|
if(list_count(¶m->types)) {
|
||||||
if(!param->info.is_return) {
|
if(param->info.flags & PARAM_RETURN) {
|
||||||
if(param->info.has_value) {
|
param->ctx->print(param->ctx, "%s", next_type(param, NULL)->name);
|
||||||
|
} else {
|
||||||
|
if(param->info.flags & PARAM_HAS_VALUE) {
|
||||||
param->ctx->print(param->ctx, "%s %s = 0x%lX", next_type(param, NULL)->name, param->info.name, param->info.value);
|
param->ctx->print(param->ctx, "%s %s = 0x%lX", next_type(param, NULL)->name, param->info.name, param->info.value);
|
||||||
} else {
|
} else {
|
||||||
param->ctx->print(param->ctx, "%s %s = <undefined>", next_type(param, NULL)->name, param->info.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 {
|
} else {
|
||||||
if(param->info.has_value) {
|
if(param->info.flags & PARAM_HAS_VALUE) {
|
||||||
param->ctx->print(param->ctx, "%s = 0x%lX", param->info.name, param->info.value);
|
param->ctx->print(param->ctx, "%s = 0x%lX", param->info.name, param->info.value);
|
||||||
} else {
|
} else {
|
||||||
param->ctx->print(param->ctx, "%s = <undefined>", param->info.name);
|
param->ctx->print(param->ctx, "%s = <undefined>", param->info.name);
|
||||||
@@ -185,7 +185,7 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
|
|||||||
Dwarf_Attribute* attr;
|
Dwarf_Attribute* attr;
|
||||||
|
|
||||||
param->info.name = pst_strdup(dwarf_diename(result));
|
param->info.name = pst_strdup(dwarf_diename(result));
|
||||||
param->info.is_variable = (dwarf_tag(result) == DW_TAG_variable);
|
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
|
// Get reference to attribute type of the parameter/variable
|
||||||
@@ -203,7 +203,7 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
|
|||||||
|
|
||||||
if(handle_location(param->ctx, attr, ¶m->location, pc, fun)) {
|
if(handle_location(param->ctx, attr, ¶m->location, pc, fun)) {
|
||||||
param->info.value = param->location.value;
|
param->info.value = param->location.value;
|
||||||
param->info.has_value = true;
|
param->info.flags |= PARAM_HAS_VALUE;
|
||||||
} else {
|
} else {
|
||||||
pst_log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", param->ctx->buff);
|
pst_log(SEVERITY_ERROR, "Failed to calculate DW_AT_location expression: %s", param->ctx->buff);
|
||||||
}
|
}
|
||||||
@@ -220,18 +220,18 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun
|
|||||||
case DW_FORM_data4:
|
case DW_FORM_data4:
|
||||||
case DW_FORM_data8:
|
case DW_FORM_data8:
|
||||||
dwarf_formudata(attr, ¶m->info.value);
|
dwarf_formudata(attr, ¶m->info.value);
|
||||||
param->info.has_value = true;
|
param->info.flags |= PARAM_HAS_VALUE;
|
||||||
break;
|
break;
|
||||||
case DW_FORM_sdata:
|
case DW_FORM_sdata:
|
||||||
dwarf_formsdata(attr, (int64_t*)¶m->info.value);
|
dwarf_formsdata(attr, (int64_t*)¶m->info.value);
|
||||||
param->info.has_value = true;
|
param->info.flags |= PARAM_HAS_VALUE;
|
||||||
break;
|
break;
|
||||||
case DW_FORM_udata:
|
case DW_FORM_udata:
|
||||||
dwarf_formudata(attr, ¶m->info.value);
|
dwarf_formudata(attr, ¶m->info.value);
|
||||||
param->info.has_value = true;
|
param->info.flags |= PARAM_HAS_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(param->info.has_value) {
|
if(param->info.flags & PARAM_HAS_VALUE) {
|
||||||
pst_log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", param->info.value);
|
pst_log(SEVERITY_DEBUG, "Parameter constant value: 0x%lX", param->info.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,9 +265,7 @@ void pst_parameter_init(pst_parameter* param, pst_context* ctx)
|
|||||||
param->info.name = NULL;
|
param->info.name = NULL;
|
||||||
param->info.line = 0;
|
param->info.line = 0;
|
||||||
param->info.size = 0;
|
param->info.size = 0;
|
||||||
param->info.is_return = false;
|
param->info.flags = 0;
|
||||||
param->info.is_variable = false;
|
|
||||||
param->info.has_value = false;
|
|
||||||
|
|
||||||
param->type = 0;
|
param->type = 0;
|
||||||
param->enc_type = 0;
|
param->enc_type = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user