X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/251bbe5068a2a7b23a23a4df11fc1b785dce6ff4..4e194aa6e85bdaafc9d69876bd7d2e79c74d5502:/src/mc/mc_dwarf_expression.c diff --git a/src/mc/mc_dwarf_expression.c b/src/mc/mc_dwarf_expression.c index b1f0ac5a40..92e4e47bfc 100644 --- a/src/mc/mc_dwarf_expression.c +++ b/src/mc/mc_dwarf_expression.c @@ -10,6 +10,7 @@ #include #include +#include "mc_object_info.h" #include "mc_private.h" static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value) @@ -21,6 +22,12 @@ static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value) return 0; } +/** Convert a DWARF register into a libunwind register + * + * DWARF and libunwind does not use the same convention for numbering the + * registers on some architectures. The function makes the necessary + * convertion. + */ static int mc_dwarf_register_to_libunwind(int dwarf_register) { #if defined(UNW_TARGET_X86_64) @@ -82,7 +89,7 @@ static int mc_dwarf_register_to_libunwind(int dwarf_register) xbt_die("Bad/unknown register number."); } #else -#error This architecture is not supported yet. +#error This architecture is not supported yet for DWARF expression evaluation. #endif } @@ -166,15 +173,16 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, { if (!state->frame_base) return MC_EXPRESSION_E_MISSING_FRAME_BASE; - error = - mc_dwarf_push_value(state, - ((uintptr_t) state->frame_base) + op->number); + uintptr_t fb = ((uintptr_t) state->frame_base) + op->number; + error = mc_dwarf_push_value(state, fb); break; } - // Constants: + // ***** Constants: + // Short constant literals: + // DW_OP_lit15 pushed the 15 on the stack. case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: @@ -210,17 +218,20 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, error = mc_dwarf_push_value(state, atom - DW_OP_lit0); break; + // Address from the base address of this ELF object. + // Push the address on the stack (base_address + argument). 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) (uintptr_t) - MC_object_base_address(state->object_info) + - op->number); + Dwarf_Off addr = (Dwarf_Off) (uintptr_t) + MC_object_base_address(state->object_info) + op->number; + error = mc_dwarf_push_value(state, addr); break; + // General constants: + // Push the constant argument on the stack. case DW_OP_const1u: case DW_OP_const2u: case DW_OP_const4u: @@ -236,9 +247,9 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, error = mc_dwarf_push_value(state, op->number); break; - // Stack manipulation: + // ***** Stack manipulation: - // Push the value at the top of the stack: + // Push another copy/duplicate the value at the top of the stack: case DW_OP_dup: if (state->stack_size == 0) return MC_EXPRESSION_E_STACK_UNDERFLOW; @@ -246,6 +257,7 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, error = mc_dwarf_push_value(state, state->stack[state->stack_size - 1]); break; + // Pop/drop the top of the stack: case DW_OP_drop: if (state->stack_size == 0) return MC_EXPRESSION_E_STACK_UNDERFLOW; @@ -253,6 +265,7 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, state->stack_size--; break; + // Swap the two top-most value of the stack: case DW_OP_swap: if (state->stack_size < 2) return MC_EXPRESSION_E_STACK_UNDERFLOW; @@ -264,13 +277,17 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, } break; + // Duplicate the value under the top of the stack: case DW_OP_over: if (state->stack_size < 2) return MC_EXPRESSION_E_STACK_UNDERFLOW; error = mc_dwarf_push_value(state, state->stack[state->stack_size - 2]); break; - // Operations: + // ***** Operations: + // Those usually take the top of the stack and the next value as argument + // and replace the top of the stack with the computed value + // (stack.top() += stack.before_top()). case DW_OP_plus: if (state->stack_size < 2) @@ -371,7 +388,8 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, case DW_OP_nop: break; - // Dereference: + // ***** Deference (memory fetch) + case DW_OP_deref_size: return MC_EXPRESSION_E_UNSUPPORTED_OPERATION; @@ -381,9 +399,19 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, { // Computed address: uintptr_t address = (uintptr_t) state->stack[state->stack_size - 1]; - uintptr_t temp; - uintptr_t* res = (uintptr_t*) mc_snapshot_read((void*) address, state->snapshot, &temp, sizeof(uintptr_t)); - state->stack[state->stack_size - 1] = *res; + uintptr_t value; + if (state->address_space) { + uintptr_t temp; + const uintptr_t* res = (uintptr_t*) MC_address_space_read( + state->address_space, MC_ADDRESS_SPACE_READ_FLAGS_LAZY, + &temp, (const void*) address, sizeof(uintptr_t), state->process_index); + value = *res; + } + else { + // TODO, use a mc_process representing the current process instead of this + value = *(const uintptr_t*) address; + } + state->stack[state->stack_size - 1] = value; } break; @@ -403,50 +431,77 @@ 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) +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_address_space_t address_space, int process_index) { 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.address_space = address_space; state.object_info = object_info; + state.process_index = process_index; + + if (expression->size >= 1 + && expression->ops[0].atom >=DW_OP_reg0 && expression->ops[0].atom <= DW_OP_reg31) { + int dwarf_register = expression->ops[0].atom - DW_OP_reg0; + xbt_assert(c, "Missing frame context for register operation DW_OP_reg%i", + dwarf_register); + location->memory_location = NULL; + location->cursor = c; + location->register_id = mc_dwarf_register_to_libunwind(dwarf_register); + return; + } 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) + mc_address_space_t address_space, 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); - } + mc_expression_t expression = mc_find_expression(locations, ip); + if (expression) { + mc_dwarf_resolve_location(location, + expression, object_info, c, + frame_pointer_address, address_space, process_index); + } else { + xbt_die("Could not resolve location"); } - xbt_die("Could not resolve location"); } /** \brief Find the frame base of a given frame @@ -457,8 +512,29 @@ 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); + 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; + + case MC_LOCATION_TYPE_REGISTER: { + // This is a special case. + // The register if not the location of the frame base + // (a frame base cannot be located in a register) + // Instead, DWARF defines this to mean that the register + // contains the address of the frame base. + unw_word_t word; + unw_get_reg(location.cursor, location.register_id, &word); + return (void*) word; + } + + default: + xbt_die("Cannot handle non-address frame base"); + return NULL; // Unreachable + } } void mc_dwarf_expression_clear(mc_expression_t expression)