This is used when using C++ inheritance.
} else */
if(current_variable->locations.size != 0){
new_var->address = (void*) mc_dwarf_resolve_locations(¤t_variable->locations,
- &(stack_frame->unw_cursor), (void*)stack_frame->frame_base);
+ &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, NULL);
}
xbt_dynar_push(variables, &new_var);
}
+void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot) {
+
+ // If not in a process state/clone:
+ if(!snapshot) {
+ return (uintptr_t*) addr;
+ }
+
+ // If it is in a snapshot:
+ for(size_t i=0; i!=NB_REGIONS; ++i) {
+ mc_mem_region_t region = snapshot->regions[i];
+ uintptr_t start = (uintptr_t) region->start_addr;
+ uintptr_t end = start + region->size;
+
+ // The address is in this region:
+ if(addr >= start && addr < end) {
+ uintptr_t offset = addr - start;
+ return (void*) ((uintptr_t)region->data + offset);
+ }
+
+ }
+
+ // It is not in a snapshot:
+ return (void*) addr;
+}
+
mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall){
return MC_take_snapshot(1);
}
// Dereference:
case DW_OP_deref_size:
- case DW_OP_deref:
return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
+ case DW_OP_deref:
+ if(state->stack_size==0)
+ return MC_EXPRESSION_E_STACK_UNDERFLOW;
+ {
+ // Computed address:
+ uintptr_t address = (uintptr_t) state->stack[state->stack_size-1];
+ uintptr_t* p = (uintptr_t*)mc_translate_address(address, state->snapshot);
+ state->stack[state->stack_size-1] = *p;
+ }
+ break;
+
// Not handled:
default:
return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
/** \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) {
+Dwarf_Off mc_dwarf_resolve_location(mc_expression_t expression, 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;
if(mc_dwarf_execute_expression(expression->size, expression->ops, &state))
xbt_die("Error evaluating DWARF expression");
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) {
+Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* c, void* frame_pointer_address, mc_snapshot_t snapshot) {
unw_word_t ip;
if(c) {
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);
+ return mc_dwarf_resolve_location(expression, c, frame_pointer_address, snapshot);
}
}
xbt_die("Could not resolve location");
* \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);
+ return (void*) mc_dwarf_resolve_locations(&frame->frame_base, unw_cursor, NULL, NULL);
}
static
XBT_DEBUG("Hash local variable %s", variable->name);
- void* variable_address = (void*) mc_dwarf_resolve_locations(&variable->locations, unw_cursor, frame_pointer);
+ void* variable_address = (void*) mc_dwarf_resolve_locations(&variable->locations, unw_cursor, frame_pointer, NULL);
dw_type_t type = variable->type;
if(type==NULL) {
#define NB_REGIONS 3 /* binary data (data + BSS) (type = 2), libsimgrid data (data + BSS) (type = 1), std_heap (type = 0)*/
typedef struct s_mc_mem_region{
+ // Real address:
void *start_addr;
+ // Copy of the datra:
void *data;
+ // Size of the data region:
size_t size;
} s_mc_mem_region_t, *mc_mem_region_t;
mc_snapshot_t MC_take_snapshot(int num_state);
void MC_restore_snapshot(mc_snapshot_t);
void MC_free_snapshot(mc_snapshot_t);
+void* mc_translate_address(uintptr_t addr, mc_snapshot_t snapshot);
extern xbt_dynar_t mc_checkpoint_ignore;
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);
-Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t* c, void* frame_pointer_address);
+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);
void mc_dwarf_location_list_clear(mc_location_list_t list);
unw_cursor_t* cursor;
void* frame_base;
+ mc_snapshot_t snapshot;
} s_mc_expression_state_t, *mc_expression_state_t;
int mc_dwarf_execute_expression(size_t n, const Dwarf_Op* ops, mc_expression_state_t state);
return NULL;
}
-static void test_local_argument(mc_object_info_t info, const char* function, const char* variable, void* address, unw_cursor_t* cursor) {
+static void test_local_variable(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
assert(var);
void* frame_base = mc_find_frame_base(subprogram, cursor);
- assert((void*)mc_dwarf_resolve_locations(&var->locations, cursor, frame_base) == address);
+ xbt_assert((void*)mc_dwarf_resolve_locations(&var->locations, cursor, frame_base, NULL) == address,
+ "Bad resolution of local variable %s of %s", variable, function);
}
unw_getcontext(&context);
unw_init_local(&cursor, &context);
- test_local_argument(mc_binary_info, "main", "argc", &argc, &cursor);
+ test_local_variable(mc_binary_info, "main", "argc", &argc, &cursor);
_exit(0);
}
assert(state->stack[state->stack_size-2]== b);
}
+int test_deref(mc_expression_state_t state) {
+ uintptr_t foo = 42;
+
+ Dwarf_Op ops[60];
+ ops[0].atom = DW_OP_addr;
+ ops[0].number = (Dwarf_Word) &foo;
+ ops[1].atom = DW_OP_deref;
+ state->stack_size = 0;
+
+ assert(mc_dwarf_execute_expression(2, ops, state) == MC_EXPRESSION_OK);
+ assert(state->stack_size==1);
+ assert(state->stack[state->stack_size-1] == foo);
+}
+
int main(int argc, char** argv) {
s_mc_expression_state_t state;
memset(&state, 0, sizeof(s_mc_expression_state_t));
assert(eval_binary_operation(&state, DW_OP_xor, a, b) == (a ^ b));
}
+ test_deref(&state);
+
return 0;
}