From 4fd2f97dd395fdec3a097054bb19ab70e7e99380 Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Tue, 25 Mar 2014 11:12:39 +0100 Subject: [PATCH 1/1] [mc] Fix DW_OP_addr to translate address into virtual address space For shared objects, the address is in fact an offset from the base address of the mapped shared object: real_address = shared_object_address + address --- src/mc/mc_checkpoint.c | 3 ++- src/mc/mc_dwarf.c | 7 ++++--- src/mc/mc_dwarf_expression.c | 18 +++++++++++++----- src/mc/mc_global.c | 2 ++ src/mc/mc_hash.c | 3 ++- src/mc/mc_private.h | 25 ++++++++++++++++++++++--- testsuite/mc/dwarf.c | 4 ++-- testsuite/mc/dwarf_expression.c | 18 +++++++++--------- 8 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/mc/mc_checkpoint.c b/src/mc/mc_checkpoint.c index c57a4f5750..cece2e82ad 100644 --- a/src/mc/mc_checkpoint.c +++ b/src/mc/mc_checkpoint.c @@ -283,6 +283,7 @@ static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_fram } else */ if(current_variable->locations.size != 0){ new_var->address = (void*) mc_dwarf_resolve_locations(¤t_variable->locations, + current_variable->object_info, &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, NULL); } @@ -344,7 +345,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(frame, &c); + stack_frame->frame_base = (unw_word_t)mc_find_frame_base(frame, frame->object_info, &c); } else { stack_frame->frame_base = 0; } diff --git a/src/mc/mc_dwarf.c b/src/mc/mc_dwarf.c index d73e13fc25..6b380001b2 100644 --- a/src/mc/mc_dwarf.c +++ b/src/mc/mc_dwarf.c @@ -690,6 +690,7 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, D dw_variable_t variable = xbt_new0(s_dw_variable_t, 1); variable->dwarf_offset = dwarf_dieoffset(die); variable->global = frame == NULL; // Can be override base on DW_AT_location + variable->object_info = info; const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name); variable->name = xbt_strdup(name); @@ -714,8 +715,7 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, D if (len==1 && expr[0].atom == DW_OP_addr) { variable->global = 1; Dwarf_Off offset = expr[0].number; - // TODO, Why is this different base on the object? - Dwarf_Off base = strcmp(info->file_name, xbt_binary_name) !=0 ? (Dwarf_Off) info->start_exec : 0; + Dwarf_Off base = (Dwarf_Off) MC_object_base_address(info); variable->address = (void*) (base + offset); } else { mc_dwarf_location_list_init_from_expression(&variable->locations, len, expr); @@ -795,6 +795,7 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die* die, Dwa frame->tag = tag; frame->id = dwarf_dieoffset(die); + frame->object_info = info; if(klass==mc_tag_subprogram) { const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name); @@ -806,7 +807,7 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die* die, Dwa // This is the base address for DWARF addresses. // Relocated addresses are offset from this base address. // See DWARF4 spec 7.5 - void* base = info->flags & MC_OBJECT_INFO_EXECUTABLE ? 0 : MC_object_base_address(info); + void* base = MC_object_base_address(info); // Variables are filled in the (recursive) call of MC_dwarf_handle_children: frame->variables = xbt_dynar_new(sizeof(dw_variable_t), dw_variable_free_voidp); diff --git a/src/mc/mc_dwarf_expression.c b/src/mc/mc_dwarf_expression.c index 92570ca9a8..caaf9322ce 100644 --- a/src/mc/mc_dwarf_expression.c +++ b/src/mc/mc_dwarf_expression.c @@ -88,6 +88,13 @@ int mc_dwarf_execute_expression( break; case DW_OP_addr: + if(!state->object_info) + return MC_EXPRESSION_E_NO_BASE_ADDRESS; + if(state->stack_size==MC_EXPRESSION_STACK_SIZE) + return MC_EXPRESSION_E_STACK_OVERFLOW; + error = mc_dwarf_push_value(state, (Dwarf_Off)MC_object_base_address(state->object_info) + op->number); + break; + case DW_OP_const1u: case DW_OP_const2u: case DW_OP_const4u: @@ -253,12 +260,13 @@ int mc_dwarf_execute_expression( /** \brief Resolve a location expression * \deprecated Use mc_dwarf_resolve_expression */ -Dwarf_Off mc_dwarf_resolve_location(mc_expression_t expression, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot) { +Dwarf_Off 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) { s_mc_expression_state_t state; memset(&state, 0, sizeof(s_mc_expression_state_t)); state.frame_base = frame_pointer_address; state.cursor = c; state.snapshot = snapshot; + state.object_info = object_info; if(mc_dwarf_execute_expression(expression->size, expression->ops, &state)) xbt_die("Error evaluating DWARF expression"); @@ -268,7 +276,7 @@ Dwarf_Off mc_dwarf_resolve_location(mc_expression_t expression, unw_cursor_t* c, return (Dwarf_Off) state.stack[state.stack_size-1]; } -Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot) { +Dwarf_Off 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) { unw_word_t ip; if(c) { @@ -280,7 +288,7 @@ Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* 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, c, frame_pointer_address, snapshot); + return mc_dwarf_resolve_location(expression, object_info, c, frame_pointer_address, snapshot); } } xbt_die("Could not resolve location"); @@ -291,8 +299,8 @@ Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* * \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, NULL); +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); } void mc_dwarf_expression_clear(mc_expression_t expression) { diff --git a/src/mc/mc_global.c b/src/mc/mc_global.c index 7bba6ff764..0457aa97c7 100644 --- a/src/mc/mc_global.c +++ b/src/mc/mc_global.c @@ -213,6 +213,8 @@ void MC_free_object_info(mc_object_info_t* info) { // ***** Helpers void* MC_object_base_address(mc_object_info_t info) { + if(info->flags & MC_OBJECT_INFO_EXECUTABLE) + return 0; void* result = info->start_exec; if(info->start_rw!=NULL && result > (void*) info->start_rw) result = info->start_rw; if(info->start_ro!=NULL && result > (void*) info->start_ro) result = info->start_ro; diff --git a/src/mc/mc_hash.c b/src/mc/mc_hash.c index dc2add04ee..c4ba6c6294 100644 --- a/src/mc/mc_hash.c +++ b/src/mc/mc_hash.c @@ -241,7 +241,8 @@ static void mc_hash_stack_frame( XBT_DEBUG("Hash local variable %s", variable->name); - void* variable_address = (void*) mc_dwarf_resolve_locations(&variable->locations, unw_cursor, frame_pointer, NULL); + void* variable_address = (void*) mc_dwarf_resolve_locations( + &variable->locations, variable->object_info, unw_cursor, frame_pointer, NULL); dw_type_t type = variable->type; if(type==NULL) { diff --git a/src/mc/mc_private.h b/src/mc/mc_private.h index 2ae91410fd..6b2ae33224 100644 --- a/src/mc/mc_private.h +++ b/src/mc/mc_private.h @@ -416,8 +416,8 @@ typedef struct s_mc_location_list { mc_expression_t locations; } s_mc_location_list_t, *mc_location_list_t; -Dwarf_Off mc_dwarf_resolve_location(mc_expression_t expression, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot); -Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot); +Dwarf_Off 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); +Dwarf_Off 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); void mc_dwarf_expression_clear(mc_expression_t expression); void mc_dwarf_expression_init(mc_expression_t expression, size_t len, Dwarf_Op* ops); @@ -462,6 +462,7 @@ typedef struct s_dw_variable{ void* address; size_t start_scope; + mc_object_info_t object_info; }s_dw_variable_t, *dw_variable_t; @@ -475,6 +476,7 @@ struct s_dw_frame{ unsigned long int id; /* DWARF offset of the subprogram */ xbt_dynar_t /* */ scopes; Dwarf_Off abstract_origin_id; + mc_object_info_t object_info; }; struct s_mc_function_index_item { @@ -492,6 +494,21 @@ void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t vari void MC_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); void MC_dwarf_register_non_global_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); + +/** Find the DWARF offset for this ELF object + * + * An offset is applied to address found in DWARF: + * + *