Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] DW_OP_deref
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 10 Mar 2014 09:24:26 +0000 (10:24 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Mon, 10 Mar 2014 09:35:53 +0000 (10:35 +0100)
This is used when using C++ inheritance.

src/mc/mc_checkpoint.c
src/mc/mc_dwarf_expression.c
src/mc/mc_hash.c
src/mc/mc_private.h
testsuite/mc/dwarf.c
testsuite/mc/dwarf_expression.c

index eaf8566..765bfdd 100644 (file)
@@ -277,7 +277,7 @@ static xbt_dynar_t MC_get_local_variables_values(xbt_dynar_t stack_frames){
       } else */
       if(current_variable->locations.size != 0){
         new_var->address = (void*) mc_dwarf_resolve_locations(&current_variable->locations,
       } else */
       if(current_variable->locations.size != 0){
         new_var->address = (void*) mc_dwarf_resolve_locations(&current_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);
       }
 
       xbt_dynar_push(variables, &new_var);
@@ -453,6 +453,31 @@ void MC_restore_snapshot(mc_snapshot_t snapshot){
 
 }
 
 
 }
 
+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);
 }
 mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall){
   return MC_take_snapshot(1);
 }
index 7aadf06..b45645e 100644 (file)
@@ -229,9 +229,19 @@ int mc_dwarf_execute_expression(
 
     // Dereference:
     case DW_OP_deref_size:
 
     // Dereference:
     case DW_OP_deref_size:
-    case DW_OP_deref:
       return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
 
       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;
     // Not handled:
     default:
      return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
@@ -247,11 +257,12 @@ int mc_dwarf_execute_expression(
 /** \brief Resolve a location expression
  *  \deprecated Use mc_dwarf_resolve_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) {
+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;
   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");
 
   if(mc_dwarf_execute_expression(expression->size, expression->ops, &state))
     xbt_die("Error evaluating DWARF expression");
@@ -261,7 +272,7 @@ Dwarf_Off mc_dwarf_resolve_location(mc_expression_t expression, unw_cursor_t* c,
     return (Dwarf_Off) state.stack[state.stack_size-1];
 }
 
     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) {
 
   unw_word_t ip;
   if(c) {
@@ -273,7 +284,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)) {
     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");
     }
   }
   xbt_die("Could not resolve location");
@@ -285,7 +296,7 @@ Dwarf_Off mc_dwarf_resolve_locations(mc_location_list_t locations, unw_cursor_t*
  *  \param unw_cursor
  */
 void* mc_find_frame_base(dw_frame_t frame, unw_cursor_t* unw_cursor) {
  *  \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
 }
 
 static
index a6b9ae5..2916ed2 100644 (file)
@@ -240,7 +240,7 @@ static void mc_hash_stack_frame(
 
     XBT_DEBUG("Hash local variable %s", variable->name);
 
 
     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) {
 
     dw_type_t type = variable->type;
     if(type==NULL) {
index 6f53d84..ae9bad1 100644 (file)
@@ -36,8 +36,11 @@ typedef struct s_mc_function_index_item s_mc_function_index_item_t, *mc_function
 #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{
 #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;
   void *start_addr;
+  // Copy of the datra:
   void *data;
   void *data;
+  // Size of the data region:
   size_t size;
 } s_mc_mem_region_t, *mc_mem_region_t;
 
   size_t size;
 } s_mc_mem_region_t, *mc_mem_region_t;
 
@@ -91,6 +94,7 @@ mc_snapshot_t SIMIX_pre_mc_snapshot(smx_simcall_t simcall);
 mc_snapshot_t MC_take_snapshot(int num_state);
 void MC_restore_snapshot(mc_snapshot_t);
 void MC_free_snapshot(mc_snapshot_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;
 
 
 extern xbt_dynar_t mc_checkpoint_ignore;
 
@@ -386,8 +390,8 @@ typedef struct s_mc_location_list {
   mc_expression_t locations;
 } s_mc_location_list_t, *mc_location_list_t;
 
   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);
 
 
 void mc_dwarf_location_list_clear(mc_location_list_t list);
 
@@ -453,6 +457,7 @@ typedef struct s_mc_expression_state {
 
   unw_cursor_t* cursor;
   void* frame_base;
 
   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);
 } 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);
index 1d8ac45..08b93a3 100644 (file)
@@ -59,7 +59,7 @@ static dw_variable_t find_local_variable(dw_frame_t frame, const char* argument_
   return NULL;
 }
 
   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
   dw_frame_t subprogram = find_function_by_name(info, function);
   assert(subprogram);
   // TODO, Lookup frame by IP and test against name instead
@@ -68,7 +68,8 @@ static void test_local_argument(mc_object_info_t info, const char* function, con
   assert(var);
 
   void* frame_base = mc_find_frame_base(subprogram, cursor);
   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);
 
 }
 
 
 }
 
@@ -125,7 +126,7 @@ int main(int argc, char** argv) {
   unw_getcontext(&context);
   unw_init_local(&cursor, &context);
 
   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);
 }
 
   _exit(0);
 }
index 1ff04d5..719c73b 100644 (file)
@@ -88,6 +88,20 @@ void basic_test(mc_expression_state_t state) {
   assert(state->stack[state->stack_size-2]== b);
 }
 
   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));
 int main(int argc, char** argv) {
   s_mc_expression_state_t state;
   memset(&state, 0, sizeof(s_mc_expression_state_t));
@@ -118,5 +132,7 @@ int main(int argc, char** argv) {
     assert(eval_binary_operation(&state, DW_OP_xor, a, b) == (a ^ b));
   }
 
     assert(eval_binary_operation(&state, DW_OP_xor, a, b) == (a ^ b));
   }
 
+  test_deref(&state);
+
   return 0;
 }
   return 0;
 }