summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
74ad671)
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
} else */
if(current_variable->locations.size != 0){
new_var->address = (void*) mc_dwarf_resolve_locations(¤t_variable->locations,
} else */
if(current_variable->locations.size != 0){
new_var->address = (void*) mc_dwarf_resolve_locations(¤t_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);
}
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;
}
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);
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);
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);
// 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);
+ 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:
/** \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");
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) {
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");
* \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) {
// ***** 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;
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) {
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);
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;
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 {
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 **********************************/
#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];
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 **********************************/
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);
}
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[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;
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);
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;
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[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);
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[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);
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;