From: Gabriel Corona Date: Mon, 13 Oct 2014 09:13:15 +0000 (+0200) Subject: [mc] Prepare support for register location in DWARF location expression evaluation... X-Git-Tag: v3_12~732^2~288^2~2 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/652cac70b147e9868fc5bf60608ee0c327adaf30 [mc] Prepare support for register location in DWARF location expression evaluation code This is needed in order to support this: DW_AT_frame_base : 1 byte block: 56 (DW_OP_reg6 (rbp)) --- diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index 9b21eb1e73..5bc84646fa 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -389,12 +389,22 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, if (current_variable->address != NULL) { new_var->address = current_variable->address; } else if (current_variable->locations.size != 0) { - new_var->address = - (void *) mc_dwarf_resolve_locations(¤t_variable->locations, + s_mc_location_t location; + mc_dwarf_resolve_locations(&location, ¤t_variable->locations, current_variable->object_info, &(stack_frame->unw_cursor), (void *) stack_frame->frame_base, NULL, process_index); + + switch(mc_get_location_type(&location)) { + case MC_LOCATION_TYPE_ADDRESS: + new_var->address = location.memory_location; + break; + case MC_LOCATION_TYPE_REGISTER: + default: + xbt_die("Cannot handle non-address variable"); + } + } else { xbt_die("No address"); } diff --git a/src/mc/mc_dwarf_expression.c b/src/mc/mc_dwarf_expression.c index 3b6c9a4deb..c0bb110e12 100644 --- a/src/mc/mc_dwarf_expression.c +++ b/src/mc/mc_dwarf_expression.c @@ -403,11 +403,12 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, /** \brief Resolve a location expression * \deprecated Use mc_dwarf_resolve_expression */ -uintptr_t mc_dwarf_resolve_location(mc_expression_t expression, - mc_object_info_t object_info, - unw_cursor_t * c, - void *frame_pointer_address, - mc_snapshot_t snapshot, int process_index) +void mc_dwarf_resolve_location(mc_location_t location, + mc_expression_t expression, + mc_object_info_t object_info, + unw_cursor_t * c, + void *frame_pointer_address, + mc_snapshot_t snapshot, int process_index) { s_mc_expression_state_t state; memset(&state, 0, sizeof(s_mc_expression_state_t)); @@ -417,37 +418,53 @@ uintptr_t mc_dwarf_resolve_location(mc_expression_t expression, state.object_info = object_info; state.process_index = process_index; + // TODO, handle register + if (mc_dwarf_execute_expression(expression->size, expression->ops, &state)) xbt_die("Error evaluating DWARF expression"); if (state.stack_size == 0) xbt_die("No value on the stack"); - else - return state.stack[state.stack_size - 1]; + else { + location->memory_location = (void*) state.stack[state.stack_size - 1]; + location->cursor = NULL; + location->register_id = 0; + } } -uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations, +static mc_expression_t mc_find_expression(mc_location_list_t locations, unw_word_t ip) { + for (size_t i = 0; i != locations->size; ++i) { + mc_expression_t expression = locations->locations + i; + if ((expression->lowpc == NULL && expression->highpc == NULL) + || (ip && ip >= (unw_word_t) expression->lowpc + && ip < (unw_word_t) expression->highpc)) { + return expression; + } + } + return NULL; +} + +void mc_dwarf_resolve_locations(mc_location_t location, + mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t * c, void *frame_pointer_address, mc_snapshot_t snapshot, int process_index) { - unw_word_t ip; + unw_word_t ip = 0; if (c) { if (unw_get_reg(c, UNW_REG_IP, &ip)) xbt_die("Could not resolve IP"); } - for (size_t i = 0; i != locations->size; ++i) { - mc_expression_t expression = locations->locations + i; - if ((expression->lowpc == NULL && expression->highpc == NULL) - || (c && ip >= (unw_word_t) expression->lowpc - && ip < (unw_word_t) expression->highpc)) { - return mc_dwarf_resolve_location(expression, object_info, c, - frame_pointer_address, snapshot, process_index); - } + mc_expression_t expression = mc_find_expression(locations, ip); + if (expression) { + mc_dwarf_resolve_location(location, + expression, object_info, c, + frame_pointer_address, snapshot, process_index); + } else { + xbt_die("Could not resolve location"); } - xbt_die("Could not resolve location"); } /** \brief Find the frame base of a given frame @@ -458,8 +475,18 @@ uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations, void *mc_find_frame_base(dw_frame_t frame, mc_object_info_t object_info, unw_cursor_t * unw_cursor) { - return (void *) mc_dwarf_resolve_locations(&frame->frame_base, object_info, - unw_cursor, NULL, NULL, -1); + s_mc_location_t location; + mc_dwarf_resolve_locations(&location, + &frame->frame_base, object_info, + unw_cursor, NULL, NULL, -1); + switch(mc_get_location_type(&location)) { + case MC_LOCATION_TYPE_ADDRESS: + return location.memory_location; + break; + case MC_LOCATION_TYPE_REGISTER: + default: + xbt_die("Cannot handle non-address frame base"); + } } void mc_dwarf_expression_clear(mc_expression_t expression) diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 1147044e5b..cac81a812c 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -518,8 +518,49 @@ typedef struct s_mc_location_list { mc_expression_t locations; } s_mc_location_list_t, *mc_location_list_t; -uintptr_t mc_dwarf_resolve_location(mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index); -uintptr_t mc_dwarf_resolve_locations(mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index); +/** A location is either a location in memory of a register location + * + * Usage: + * + * * mc_dwarf_resolve_locations or mc_dwarf_resolve_location is used + * to find the location of a given location expression or location list; + * + * * mc_get_location_type MUST be used to find the location type; + * + * * for MC_LOCATION_TYPE_ADDRESS, memory_address is the resulting address + * + * * for MC_LOCATION_TYPE_REGISTER, unw_get_reg(l.cursor, l.register_id, value) + * and unw_get_reg(l.cursor, l.register_id, value) can be used to read/write + * the value. + * + */ +typedef struct s_mc_location { + void* memory_location; + unw_cursor_t* cursor; + int register_id; +} s_mc_location_t, *mc_location_t; + +/** Type of a given location + * + * Use `mc_get_location_type(location)` to find the type. + * */ +typedef enum mc_location_type { + MC_LOCATION_TYPE_ADDRESS, + MC_LOCATION_TYPE_REGISTER +} mc_location_type; + +/** Find the type of a location */ +static inline __attribute__ ((always_inline)) +enum mc_location_type mc_get_location_type(mc_location_t location) { + if (location->cursor) { + return MC_LOCATION_TYPE_REGISTER; + } else { + return MC_LOCATION_TYPE_ADDRESS; + } +} + +void mc_dwarf_resolve_location(mc_location_t location, mc_expression_t expression, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index); +void mc_dwarf_resolve_locations(mc_location_t location, mc_location_list_t locations, mc_object_info_t object_info, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot, int process_index); void mc_dwarf_expression_clear(mc_expression_t expression); void mc_dwarf_expression_init(mc_expression_t expression, size_t len, Dwarf_Op* ops); diff --git a/teshsuite/mc/dwarf/dwarf.c b/teshsuite/mc/dwarf/dwarf.c index ab52f5b882..7378579efd 100644 --- a/teshsuite/mc/dwarf/dwarf.c +++ b/teshsuite/mc/dwarf/dwarf.c @@ -82,7 +82,15 @@ static void test_local_variable(mc_object_info_t info, const char* function, con assert(var); void* frame_base = mc_find_frame_base(subprogram, info, cursor); - xbt_assert((void*)mc_dwarf_resolve_locations(&var->locations, info, cursor, frame_base, NULL, -1) == address, + s_mc_location_t location; + + mc_dwarf_resolve_locations(&location, + &var->locations, info, cursor, frame_base, NULL, -1); + + xbt_assert(mc_get_location_type(&location)==MC_LOCATION_TYPE_ADDRESS, + "Unexpected location type for variable %s of %s", variable, function); + + xbt_assert(location.memory_location == address, "Bad resolution of local variable %s of %s", variable, function); }