From f9f26f5f7d8805ae70e0a41eda3a9b95155cc9f6 Mon Sep 17 00:00:00 2001 From: Nikolai Nosov Date: Thu, 16 Apr 2020 13:45:26 +0400 Subject: [PATCH] use bitset for parameter state instead of separate boolean fields --- include/libpst-types.h | 12 ++++++++---- src/dwarf/dwarf_function.c | 8 ++++---- src/dwarf/dwarf_parameter.c | 26 ++++++++++++-------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/include/libpst-types.h b/include/libpst-types.h index bf81b35..0e30da2 100644 --- a/include/libpst-types.h +++ b/include/libpst-types.h @@ -8,7 +8,7 @@ #ifndef INCLUDE_LIBPST_TYPES_H_ #define INCLUDE_LIBPST_TYPES_H_ -#include +#include #include 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 } 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 { char* name; ///< parameter's name uint32_t line; ///< line of parameter definition 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 - 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_param_flags flags; ///< flags of various parameter's options } pst_parameter_info; #endif /* INCLUDE_LIBPST_TYPES_H_ */ diff --git a/src/dwarf/dwarf_function.c b/src/dwarf/dwarf_function.c index 9fb5249..a1d20ce 100644 --- a/src/dwarf/dwarf_function.c +++ b/src/dwarf/dwarf_function.c @@ -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) 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 pst_parameter_print_dwarf(param); 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; 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 pst_parameter_print_dwarf(param); fn->ctx->print(fn->ctx, " %s(", fn->info.name); continue; } - if(param->info.is_variable) { + if(param->info.flags & PARAM_VARIABLE) { if(!start_variable) { fn->ctx->print(fn->ctx, ")%s\n", at); 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 // 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); if(attr) { if(!pst_parameter_handle_type(ret_p, attr)) { diff --git a/src/dwarf/dwarf_parameter.c b/src/dwarf/dwarf_parameter.c index 37bc818..ecf3b98 100644 --- a/src/dwarf/dwarf_parameter.c +++ b/src/dwarf/dwarf_parameter.c @@ -70,17 +70,17 @@ static pst_type* next_type(pst_parameter* param, pst_type* t) bool pst_parameter_print_dwarf(pst_parameter* param) { if(list_count(¶m->types)) { - if(!param->info.is_return) { - if(param->info.has_value) { + if(param->info.flags & PARAM_RETURN) { + 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); } else { param->ctx->print(param->ctx, "%s %s = ", next_type(param, NULL)->name, param->info.name); } - } else { - param->ctx->print(param->ctx, "%s", next_type(param, NULL)->name); } } 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); } else { param->ctx->print(param->ctx, "%s = ", param->info.name); @@ -185,7 +185,7 @@ bool pst_parameter_handle_dwarf(pst_parameter* param, Dwarf_Die* result, pst_fun Dwarf_Attribute* attr; 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); // 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)) { param->info.value = param->location.value; - param->info.has_value = true; + param->info.flags |= PARAM_HAS_VALUE; } else { 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_data8: dwarf_formudata(attr, ¶m->info.value); - param->info.has_value = true; + param->info.flags |= PARAM_HAS_VALUE; break; case DW_FORM_sdata: dwarf_formsdata(attr, (int64_t*)¶m->info.value); - param->info.has_value = true; + param->info.flags |= PARAM_HAS_VALUE; break; case DW_FORM_udata: dwarf_formudata(attr, ¶m->info.value); - param->info.has_value = true; + param->info.flags |= PARAM_HAS_VALUE; 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); } } @@ -265,9 +265,7 @@ void pst_parameter_init(pst_parameter* param, pst_context* ctx) 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->info.flags = 0; param->type = 0; param->enc_type = 0;