From: Gabriel Corona Date: Fri, 7 Mar 2014 13:07:36 +0000 (+0100) Subject: [mc] Use new expression evaluation code frame_base X-Git-Tag: v3_11~199^2~2^2~15 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/f6e8576ae0221324ccba0eb542504e2d7bd9f766 [mc] Use new expression evaluation code frame_base --- diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index 6e86b8118d..eaf8566d9a 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -327,7 +327,7 @@ static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) { if(frame) { stack_frame->frame_name = xbt_strdup(frame->name); - stack_frame->frame_base = (unw_word_t)mc_find_frame_base((void*)ip, frame, &c); + stack_frame->frame_base = (unw_word_t)mc_find_frame_base(frame, &c); } else { stack_frame->frame_base = 0; } diff --git a/src/mc/mc_dwarf.c b/src/mc/mc_dwarf.c index 9395335dd6..972d3e9607 100644 --- a/src/mc/mc_dwarf.c +++ b/src/mc/mc_dwarf.c @@ -309,31 +309,6 @@ static dw_location_t MC_dwarf_get_location_list(mc_object_info_t info, Dwarf_Die } } -/** \brief Find the frame base of a given frame - * - * \param ip Instruction pointer - * \param frame - * \param unw_cursor - */ -void* mc_find_frame_base(void* ip, dw_frame_t frame, unw_cursor_t* unw_cursor) { - switch(frame->frame_base->type) { - case e_dw_loclist: - { - int loclist_cursor; - for(loclist_cursor=0; loclist_cursor < xbt_dynar_length(frame->frame_base->location.loclist); loclist_cursor++){ - dw_location_entry_t entry = xbt_dynar_get_as(frame->frame_base->location.loclist, loclist_cursor, dw_location_entry_t); - if((ip >= entry->lowpc) && (ip < entry->highpc)){ - return (void*) MC_dwarf_resolve_location(unw_cursor, entry->location, NULL); - } - } - return NULL; - } - // Not handled: - default: - return NULL; - } -} - /** \brief Get the location expression or location list from an attribute * * Processes direct expressions as well as location lists. @@ -1008,6 +983,22 @@ static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die* die, } static void MC_dwarf_handle_subprogram_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t parent_frame, const char* namespace) { + + // (Template) Subprogram declaration: + if (MC_dwarf_attr_flag(die, DW_AT_declaration, false)) + return; + + // Abstract inline instance (DW_AT_inline != DW_INL_not_inlined): + if (dwarf_func_inline(die)) + return; + + // This is probably not a concrete instance: + // DWARF2/3 and DWARF4 do not agree on the meaning of DW_INL_not_inlined. + // For DWARF2/3, the subprogram is abstract. + // For DARF4, the subprogram is not abstract. + if(!dwarf_hasattr_integrate(die, DW_AT_low_pc)) + return; + dw_frame_t frame = xbt_new0(s_dw_frame_t, 1); frame->start = dwarf_dieoffset(die); @@ -1024,7 +1015,15 @@ static void MC_dwarf_handle_subprogram_die(mc_object_info_t info, Dwarf_Die* die frame->variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp); frame->high_pc = ((char*) base) + MC_dwarf_attr_addr(die, DW_AT_high_pc); frame->low_pc = ((char*) base) + MC_dwarf_attr_addr(die, DW_AT_low_pc); - frame->frame_base = MC_dwarf_at_location(info, die, DW_AT_frame_base); + + if(frame->high_pc==0 || frame->low_pc==0) + xbt_die("Could not resolve highpc/lowpc"); + + Dwarf_Attribute attr_frame_base; + if (!dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base)) + xbt_die("Coult not find DW_AT_frame_base for subprogram %s %p", frame->name, frame->start); + mc_dwarf_location_list_init(&frame->frame_base, info, die, &attr_frame_base); + frame->end = -1; // This one is now useless: // Register it: diff --git a/src/mc/mc_dwarf_expression.c b/src/mc/mc_dwarf_expression.c index 54183b4bb9..7aadf06578 100644 --- a/src/mc/mc_dwarf_expression.c +++ b/src/mc/mc_dwarf_expression.c @@ -279,6 +279,15 @@ Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* xbt_die("Could not resolve location"); } +/** \brief Find the frame base of a given frame + * + * \param frame + * \param unw_cursor + */ +void* mc_find_frame_base(dw_frame_t frame, unw_cursor_t* unw_cursor) { + return (void*) mc_dwarf_resolve_locations(&frame->frame_base, unw_cursor, NULL); +} + static void mc_dwarf_expression_clear(mc_expression_t expression) { free(expression->ops); @@ -344,8 +353,10 @@ void mc_dwarf_location_list_init(mc_location_list_t list, mc_object_info_t info, void* base = info->flags & MC_OBJECT_INFO_EXECUTABLE ? 0 : MC_object_base_address(info); mc_dwarf_expression_init(expression, len, ops); - expression->lowpc = (char*) base + start; - expression->highpc = (char*) base + end; + + // If start == 0, this is not a location list: + expression->lowpc = start == 0 ? NULL : (char*) base + start; + expression->highpc = start == 0 ? NULL : (char*) base + end; } } diff --git a/src/mc/mc_hash.c b/src/mc/mc_hash.c index 87e724a3ae..a6b9ae5147 100644 --- a/src/mc/mc_hash.c +++ b/src/mc/mc_hash.c @@ -240,7 +240,7 @@ static void mc_hash_stack_frame( XBT_DEBUG("Hash local variable %s", variable->name); - void* variable_address = (void*) mc_dwarf_resolve_location(&variable->locations, unw_cursor, frame_pointer); + void* variable_address = (void*) mc_dwarf_resolve_locations(&variable->locations, unw_cursor, frame_pointer); dw_type_t type = variable->type; if(type==NULL) { diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 63a4b3851a..9672142970 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -479,7 +479,7 @@ struct s_dw_frame{ char *name; void *low_pc; void *high_pc; - dw_location_t frame_base; + s_mc_location_list_t frame_base; xbt_dynar_t /* */ variables; /* Cannot use dict, there may be several variables with the same name (in different lexical blocks)*/ unsigned long int start; /* DWARF offset of the subprogram */ unsigned long int end; /* Dwarf offset of the next sibling */ @@ -503,7 +503,6 @@ void* MC_object_base_address(mc_object_info_t info); /********************************** DWARF **********************************/ Dwarf_Off MC_dwarf_resolve_location(unw_cursor_t* c, dw_location_t location, void* frame_pointer_address); -void* mc_find_frame_base(void* ip, dw_frame_t frame, unw_cursor_t* unw_cursor); #define MC_EXPRESSION_STACK_SIZE 64 @@ -524,6 +523,8 @@ typedef struct s_mc_expression_state { int mc_dwarf_execute_expression(size_t n, const Dwarf_Op* ops, mc_expression_state_t state); +void* mc_find_frame_base(dw_frame_t frame, unw_cursor_t* unw_cursor); + /********************************** Miscellaneous **********************************/ typedef struct s_local_variable{ diff --git a/testsuite/mc/dwarf.c b/testsuite/mc/dwarf.c index eecba82871..1d8ac45f82 100644 --- a/testsuite/mc/dwarf.c +++ b/testsuite/mc/dwarf.c @@ -37,6 +37,41 @@ static dw_variable_t find_global_variable_by_name(mc_object_info_t info, const c return NULL; } +static dw_frame_t find_function_by_name(mc_object_info_t info, const char* name) { + unsigned int cursor = 0; + dw_frame_t subprogram; + xbt_dynar_foreach(info->subprograms, cursor, subprogram){ + if(!strcmp(name, subprogram->name)) + return subprogram; + } + + return NULL; +} + +static dw_variable_t find_local_variable(dw_frame_t frame, const char* argument_name) { + unsigned int cursor = 0; + dw_variable_t variable; + xbt_dynar_foreach(frame->variables, cursor, variable){ + if(!strcmp(argument_name, variable->name)) + return variable; + } + + return NULL; +} + +static void test_local_argument(mc_object_info_t info, const char* function, const char* variable, void* address, unw_cursor_t* cursor) { + dw_frame_t subprogram = find_function_by_name(info, function); + assert(subprogram); + // TODO, Lookup frame by IP and test against name instead + + dw_variable_t var = find_local_variable(subprogram, variable); + assert(var); + + void* frame_base = mc_find_frame_base(subprogram, cursor); + assert((void*)mc_dwarf_resolve_locations(&var->locations, cursor, frame_base) == address); + +} + static dw_variable_t test_global_variable(mc_object_info_t info, const char* name, void* address, long byte_size) { dw_variable_t variable = find_global_variable_by_name(info, name); xbt_assert(variable, "Global variable %s was not found", name); @@ -85,5 +120,12 @@ int main(int argc, char** argv) { assert(find_type(mc_binary_info, "second", type)->offset == ((const char*)&test_some_struct.second) - (const char*)&test_some_struct); + unw_context_t context; + unw_cursor_t cursor; + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + test_local_argument(mc_binary_info, "main", "argc", &argc, &cursor); + _exit(0); }