X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/652cac70b147e9868fc5bf60608ee0c327adaf30..4e194aa6e85bdaafc9d69876bd7d2e79c74d5502:/src/mc/mc_dwarf_expression.c diff --git a/src/mc/mc_dwarf_expression.c b/src/mc/mc_dwarf_expression.c index c0bb110e12..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, state->process_index, &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; @@ -408,17 +436,26 @@ void mc_dwarf_resolve_location(mc_location_t location, mc_object_info_t object_info, unw_cursor_t * c, void *frame_pointer_address, - mc_snapshot_t snapshot, int process_index) + 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; - // TODO, handle register + 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"); @@ -448,7 +485,7 @@ void mc_dwarf_resolve_locations(mc_location_t location, mc_object_info_t object_info, unw_cursor_t * c, void *frame_pointer_address, - mc_snapshot_t snapshot, int process_index) + mc_address_space_t address_space, int process_index) { unw_word_t ip = 0; @@ -461,7 +498,7 @@ void mc_dwarf_resolve_locations(mc_location_t location, if (expression) { mc_dwarf_resolve_location(location, expression, object_info, c, - frame_pointer_address, snapshot, process_index); + frame_pointer_address, address_space, process_index); } else { xbt_die("Could not resolve location"); } @@ -482,10 +519,21 @@ void *mc_find_frame_base(dw_frame_t frame, mc_object_info_t object_info, switch(mc_get_location_type(&location)) { case MC_LOCATION_TYPE_ADDRESS: return location.memory_location; - break; - case MC_LOCATION_TYPE_REGISTER: + + 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 } }