Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Fix DW_OP_addr to translate address into virtual address space
authorGabriel Corona <gabriel.corona@loria.fr>
Tue, 25 Mar 2014 10:12:39 +0000 (11:12 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Tue, 25 Mar 2014 10:12:39 +0000 (11:12 +0100)
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
src/mc/mc_dwarf.c
src/mc/mc_dwarf_expression.c
src/mc/mc_global.c
src/mc/mc_hash.c
src/mc/mc_private.h
testsuite/mc/dwarf.c
testsuite/mc/dwarf_expression.c

index c57a4f5..cece2e8 100644 (file)
@@ -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(&current_variable->locations,
     } else */
     if(current_variable->locations.size != 0){
       new_var->address = (void*) mc_dwarf_resolve_locations(&current_variable->locations,
+        current_variable->object_info,
         &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, NULL);
     }
 
         &(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);
 
     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;
     }
     } else {
       stack_frame->frame_base = 0;
     }
index d73e13f..6b38000 100644 (file)
@@ -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
   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);
 
   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;
       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);
         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->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);
 
   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
   // 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);
 
   // 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);
index 92570ca..caaf932 100644 (file)
@@ -88,6 +88,13 @@ int mc_dwarf_execute_expression(
       break;
 
     case DW_OP_addr:
       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:
     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
  */
 /** \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;
   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");
 
   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];
 }
 
     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) {
 
   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)) {
     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");
     }
   }
   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
  */
  *  \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) {
 }
 
 void mc_dwarf_expression_clear(mc_expression_t expression) {
index 7bba6ff..0457aa9 100644 (file)
@@ -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) {
 // ***** 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;
   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;
index dc2add0..c4ba6c6 100644 (file)
@@ -241,7 +241,8 @@ 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, 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) {
 
     dw_type_t type = variable->type;
     if(type==NULL) {
index 2ae9141..6b2ae33 100644 (file)
@@ -416,8 +416,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, 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);
 
 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;
   void* address;
 
   size_t start_scope;
+  mc_object_info_t object_info;
 
 }s_dw_variable_t, *dw_variable_t;
 
 
 }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 /* <dw_frame_t> */ scopes;
   Dwarf_Off abstract_origin_id;
   unsigned long int id; /* DWARF offset of the subprogram */
   xbt_dynar_t /* <dw_frame_t> */ scopes;
   Dwarf_Off abstract_origin_id;
+  mc_object_info_t object_info;
 };
 
 struct s_mc_function_index_item {
 };
 
 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);
 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:
+ *
+ *  <ul>
+ *    <li>for an executable obejct, addresses are virtual address
+ *        (there is no offset) i.e. \f$\text{virtual address} = \{dwarf address}\f$;</li>
+ *    <li>for a shared object, the addreses are offset from the begining
+ *        of the shared object (the base address of the mapped shared
+ *        object must be used as offset
+ *        i.e. \f$\text{virtual address} = \text{shared object base address}
+ *             + \text{dwarf address}\f$.</li>
+ *
+ */
 void* MC_object_base_address(mc_object_info_t info);
 
 /********************************** DWARF **********************************/
 void* MC_object_base_address(mc_object_info_t info);
 
 /********************************** DWARF **********************************/
@@ -504,6 +521,7 @@ void* MC_object_base_address(mc_object_info_t info);
 #define MC_EXPRESSION_E_STACK_UNDERFLOW 3
 #define MC_EXPRESSION_E_MISSING_STACK_CONTEXT 4
 #define MC_EXPRESSION_E_MISSING_FRAME_BASE 5
 #define MC_EXPRESSION_E_STACK_UNDERFLOW 3
 #define MC_EXPRESSION_E_MISSING_STACK_CONTEXT 4
 #define MC_EXPRESSION_E_MISSING_FRAME_BASE 5
+#define MC_EXPRESSION_E_NO_BASE_ADDRESS 6
 
 typedef struct s_mc_expression_state {
   uintptr_t stack[MC_EXPRESSION_STACK_SIZE];
 
 typedef struct s_mc_expression_state {
   uintptr_t stack[MC_EXPRESSION_STACK_SIZE];
@@ -512,11 +530,12 @@ typedef struct s_mc_expression_state {
   unw_cursor_t* cursor;
   void* frame_base;
   mc_snapshot_t snapshot;
   unw_cursor_t* cursor;
   void* frame_base;
   mc_snapshot_t snapshot;
+  mc_object_info_t object_info;
 } 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);
 
-void* mc_find_frame_base(dw_frame_t frame, unw_cursor_t* unw_cursor);
+void* mc_find_frame_base(dw_frame_t frame, mc_object_info_t object_info, unw_cursor_t* unw_cursor);
 
 /********************************** Miscellaneous **********************************/
 
 
 /********************************** Miscellaneous **********************************/
 
index fc85de4..c935a12 100644 (file)
@@ -68,8 +68,8 @@ static void test_local_variable(mc_object_info_t info, const char* function, con
   dw_variable_t var = find_local_variable(subprogram, variable);
   assert(var);
 
   dw_variable_t var = find_local_variable(subprogram, variable);
   assert(var);
 
-  void* frame_base = mc_find_frame_base(subprogram, cursor);
-  xbt_assert((void*)mc_dwarf_resolve_locations(&var->locations, cursor, frame_base, NULL) == address,
+  void* frame_base = mc_find_frame_base(subprogram, info, cursor);
+  xbt_assert((void*)mc_dwarf_resolve_locations(&var->locations, info, cursor, frame_base, NULL) == address,
     "Bad resolution of local variable %s of %s", variable, function);
 
 }
     "Bad resolution of local variable %s of %s", variable, function);
 
 }
index 98ee29a..7def465 100644 (file)
@@ -13,9 +13,9 @@ uintptr_t eval_binary_operation(mc_expression_state_t state, int op, uintptr_t a
   state->stack_size = 0;
 
   Dwarf_Op ops[15];
   state->stack_size = 0;
 
   Dwarf_Op ops[15];
-  ops[0].atom = DW_OP_addr;
+  ops[0].atom = DW_OP_const8u;
   ops[0].number = a;
   ops[0].number = a;
-  ops[1].atom = DW_OP_addr;
+  ops[1].atom = DW_OP_const8u;
   ops[1].number = b;
   ops[2].atom = op;
 
   ops[1].number = b;
   ops[2].atom = op;
 
@@ -39,7 +39,7 @@ void basic_test(mc_expression_state_t state) {
   assert(state->stack_size==1);
   assert(state->stack[state->stack_size-1]==21);
 
   assert(state->stack_size==1);
   assert(state->stack[state->stack_size-1]==21);
 
-  ops[0].atom = DW_OP_addr;
+  ops[0].atom = DW_OP_const8u;
   ops[0].number = a;
   assert(mc_dwarf_execute_expression(1, ops, state) == MC_EXPRESSION_OK);
   assert(state->stack_size==2);
   ops[0].number = a;
   assert(mc_dwarf_execute_expression(1, ops, state) == MC_EXPRESSION_OK);
   assert(state->stack_size==2);
@@ -58,7 +58,7 @@ void basic_test(mc_expression_state_t state) {
   assert(state->stack[state->stack_size-1]== a + 21);
 
   state->stack_size = 0;
   assert(state->stack[state->stack_size-1]== a + 21);
 
   state->stack_size = 0;
-  ops[0].atom = DW_OP_addr;
+  ops[0].atom = DW_OP_const8u;
   ops[0].number = a;
   ops[1].atom = DW_OP_dup;
   ops[2].atom = DW_OP_plus;
   ops[0].number = a;
   ops[1].atom = DW_OP_dup;
   ops[2].atom = DW_OP_plus;
@@ -67,9 +67,9 @@ void basic_test(mc_expression_state_t state) {
   assert(state->stack[state->stack_size-1]== a + a);
 
   state->stack_size = 0;
   assert(state->stack[state->stack_size-1]== a + a);
 
   state->stack_size = 0;
-  ops[0].atom = DW_OP_addr;
+  ops[0].atom = DW_OP_const8u;
   ops[0].number = a;
   ops[0].number = a;
-  ops[1].atom = DW_OP_addr;
+  ops[1].atom = DW_OP_const8u;
   ops[1].number = b;
   ops[2].atom = DW_OP_over;
   assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK);
   ops[1].number = b;
   ops[2].atom = DW_OP_over;
   assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK);
@@ -79,9 +79,9 @@ void basic_test(mc_expression_state_t state) {
   assert(state->stack[state->stack_size-3]== a);
 
   state->stack_size = 0;
   assert(state->stack[state->stack_size-3]== a);
 
   state->stack_size = 0;
-  ops[0].atom = DW_OP_addr;
+  ops[0].atom = DW_OP_const8u;
   ops[0].number = a;
   ops[0].number = a;
-  ops[1].atom = DW_OP_addr;
+  ops[1].atom = DW_OP_const8u;
   ops[1].number = b;
   ops[2].atom = DW_OP_swap;
   assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK);
   ops[1].number = b;
   ops[2].atom = DW_OP_swap;
   assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK);
@@ -95,7 +95,7 @@ void test_deref(mc_expression_state_t state) {
   uintptr_t foo = 42;
 
   Dwarf_Op ops[60];
   uintptr_t foo = 42;
 
   Dwarf_Op ops[60];
-  ops[0].atom = DW_OP_addr;
+  ops[0].atom = DW_OP_const8u;
   ops[0].number = (Dwarf_Word) &foo;
   ops[1].atom = DW_OP_deref;
   state->stack_size = 0;
   ops[0].number = (Dwarf_Word) &foo;
   ops[1].atom = DW_OP_deref;
   state->stack_size = 0;