X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/f6e8576ae0221324ccba0eb542504e2d7bd9f766..986f00b8a57d82825f9e419d48e44c7ca47af7c5:/src/mc/mc_dwarf.c diff --git a/src/mc/mc_dwarf.c b/src/mc/mc_dwarf.c index 972d3e9607..67eccc48b4 100644 --- a/src/mc/mc_dwarf.c +++ b/src/mc/mc_dwarf.c @@ -74,14 +74,6 @@ static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die* die, Dwar */ static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace); -/** \brief Convert a libdw DWARF expression into a MC representation of the location - * - * \param expr array of DWARf operations - * \param len number of elements - * \return a new MC expression - */ -static dw_location_t MC_dwarf_get_expression(Dwarf_Op* expr, size_t len); - /** \brief Get the DW_TAG_type of the DIE * * \param die DIE @@ -269,112 +261,6 @@ static const char* MC_dwarf_at_linkage_name(Dwarf_Die* die) { return name; } -/** \brief Create a location list from a given attribute - * - * \param die the DIE - * \param attr the attribute - * \return MC specific representation of the location list represented by the given attribute - * of the given die - */ -static dw_location_t MC_dwarf_get_location_list(mc_object_info_t info, Dwarf_Die* die, Dwarf_Attribute* attr) { - - dw_location_t location = xbt_new0(s_dw_location_t, 1); - location->type = e_dw_loclist; - xbt_dynar_t loclist = xbt_dynar_new(sizeof(dw_location_entry_t), NULL); - location->location.loclist = loclist; - - ptrdiff_t offset = 0; - Dwarf_Addr base, start, end; - Dwarf_Op *expr; - size_t len; - - while (1) { - - offset = dwarf_getlocations(attr, offset, &base, &start, &end, &expr, &len); - if (offset==0) - return location; - else if (offset==-1) - xbt_die("Error while loading location list"); - - dw_location_entry_t new_entry = xbt_new0(s_dw_location_entry_t, 1); - - void* base = info->flags & MC_OBJECT_INFO_EXECUTABLE ? 0 : MC_object_base_address(info); - - new_entry->lowpc = (char*) base + start; - new_entry->highpc = (char*) base + end; - new_entry->location = MC_dwarf_get_expression(expr, len); - - xbt_dynar_push(loclist, &new_entry); - - } -} - -/** \brief Get the location expression or location list from an attribute - * - * Processes direct expressions as well as location lists. - * - * \param die the DIE - * \param attr the attribute - * \return MC specific representation of the location represented by the given attribute - * of the given die - */ -static dw_location_t MC_dwarf_get_location(mc_object_info_t info, Dwarf_Die* die, Dwarf_Attribute* attr) { - int form = dwarf_whatform(attr); - switch (form) { - - // The attribute is an DWARF location expression: - case DW_FORM_exprloc: - case DW_FORM_block1: // not in the spec - case DW_FORM_block2: - case DW_FORM_block4: - case DW_FORM_block: - { - Dwarf_Op* expr; - size_t len; - if (dwarf_getlocation(attr, &expr, &len)) - xbt_die("Could not read location expression"); - return MC_dwarf_get_expression(expr, len); - } - - // The attribute is a reference to a location list entry: - case DW_FORM_sec_offset: - case DW_FORM_data1: - case DW_FORM_data2: - case DW_FORM_data4: - case DW_FORM_data8: - { - return MC_dwarf_get_location_list(info, die, attr); - } - break; - - default: - xbt_die("Unexpected form %i list for location in attribute %s of <%p>%s", - form, - MC_dwarf_attrname(attr->code), - (void*) dwarf_dieoffset(die), - MC_dwarf_attr_string(die, DW_AT_name)); - return NULL; - } -} - -/** \brief Get the location expression or location list from an attribute - * - * Processes direct expressions as well as location lists. - * - * \param die the DIE - * \param attribute the attribute code - * \return MC specific representation of the location represented by the given attribute - * of the given die - */ -static dw_location_t MC_dwarf_at_location(mc_object_info_t info, Dwarf_Die* die, int attribute) { - if(!dwarf_hasattr_integrate(die, attribute)) - return xbt_new0(s_dw_location_t, 1); - - Dwarf_Attribute attr; - dwarf_attr_integrate(die, attribute, &attr); - return MC_dwarf_get_location(info, die, &attr); -} - static char* MC_dwarf_at_type(Dwarf_Die* die) { Dwarf_Attribute attr; if (dwarf_hasattr_integrate(die, DW_AT_type)) { @@ -493,35 +379,6 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die* die, Dwarf_Die* unit) { return result; } -// ***** Location - -Dwarf_Off MC_dwarf_resolve_location(unw_cursor_t* c, dw_location_t location, void* frame_pointer_address) { - unw_word_t res; - switch (location->type){ - case e_dw_compose: - if (xbt_dynar_length(location->location.compose) > 1){ - return 0; /* TODO : location list with optimizations enabled */ - } - dw_location_t location_entry = xbt_dynar_get_as(location->location.compose, 0, dw_location_t); - switch (location_entry->type){ - case e_dw_bregister_op: - unw_get_reg(c, location_entry->location.breg_op.reg, &res); - return (Dwarf_Off) ((long)res + location_entry->location.breg_op.offset); - break; - case e_dw_fbregister_op: - if (frame_pointer_address != NULL) - return (Dwarf_Off)((char *)frame_pointer_address + location_entry->location.fbreg_op); - else - return 0; - default: - return 0; /* FIXME : implement other cases (with optimizations enabled) */ - } - break; - default: - return 0; - } -} - // ***** dw_type_t static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, Dwarf_Die* child) { @@ -559,7 +416,7 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, Dwar if (len==1 && expr[0].atom == DW_OP_plus_uconst) { member->offset = expr[0].number; } else { - xbt_die("Can't groke this location expression yet."); + mc_dwarf_expression_init(&member->location, len, expr); } break; } @@ -595,7 +452,8 @@ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die* die, Dwarf_Di xbt_assert(!type->members); type->members = xbt_dynar_new(sizeof(dw_type_t), (void(*)(void*))dw_type_free); for (res=dwarf_child(die, &child); res==0; res=dwarf_siblingof(&child,&child)) { - if (dwarf_tag(&child)==DW_TAG_member) { + int tag = dwarf_tag(&child); + if (tag==DW_TAG_member || tag==DW_TAG_inheritance) { // Skip declarations: if (MC_dwarf_attr_flag(&child, DW_AT_declaration, false)) @@ -607,8 +465,10 @@ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die* die, Dwarf_Di // TODO, we should use another type (because is is not a type but a member) dw_type_t member = xbt_new0(s_dw_type_t, 1); - member->type = -1; - member->id = NULL; + member->type = tag; + + // Global Offset: + member->id = (void *) dwarf_dieoffset(&child); const char* name = MC_dwarf_attr_string(&child, DW_AT_name); if(name) @@ -663,9 +523,24 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwa // Global Offset type->id = (void *) dwarf_dieoffset(die); + const char* prefix = ""; + switch (type->type) { + case DW_TAG_structure_type: + prefix = "struct "; + break; + case DW_TAG_union_type: + prefix = "union "; + break; + case DW_TAG_class_type: + prefix = "class "; + break; + default: + prefix = ""; + } + const char* name = MC_dwarf_attr_string(die, DW_AT_name); if (name!=NULL) { - type->name = xbt_strdup(name); + type->name = namespace ? bprintf("%s%s::%s", prefix, namespace, name) : bprintf("%s%s", prefix, name); } XBT_DEBUG("Processing type <%p>%s", type->id, type->name); @@ -699,7 +574,7 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die* die, Dwa case DW_TAG_class_type: MC_dwarf_add_members(info, die, unit, type); char* new_namespace = namespace == NULL ? xbt_strdup(type->name) - : bprintf("%s::%s", namespace, type->name); + : bprintf("%s::%s", namespace, name); MC_dwarf_handle_children(info, die, unit, frame, new_namespace); free(new_namespace); break; @@ -715,169 +590,10 @@ static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die* die, Dwar xbt_dict_set(info->types, key, type, NULL); if(type->name && type->byte_size!=0) { - xbt_dict_set(info->types_by_name, type->name, type, NULL); + xbt_dict_set(info->full_types_by_name, type->name, type, NULL); } } -/** \brief Convert libdw location expresion elment into native one (or NULL in some cases) */ -static dw_location_t MC_dwarf_get_expression_element(Dwarf_Op* op) { - dw_location_t element = xbt_new0(s_dw_location_t, 1); - uint8_t atom = op->atom; - if (atom >= DW_OP_reg0 && atom<= DW_OP_reg31) { - element->type = e_dw_register; - element->location.reg = atom - DW_OP_reg0; - } - else if (atom >= DW_OP_breg0 && atom<= DW_OP_breg31) { - element->type = e_dw_bregister_op; - element->location.reg = atom - DW_OP_breg0; - element->location.breg_op.offset = op->number; - } - else if (atom >= DW_OP_lit0 && atom<= DW_OP_lit31) { - element->type = e_dw_lit; - element->location.reg = atom - DW_OP_lit0; - } - else switch (atom) { - case DW_OP_fbreg: - element->type = e_dw_fbregister_op; - element->location.fbreg_op = op->number; - break; - case DW_OP_piece: - element->type = e_dw_piece; - element->location.piece = op->number; - break; - case DW_OP_plus_uconst: - element->type = e_dw_plus_uconst; - element->location.plus_uconst = op->number; - break; - case DW_OP_abs: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("abs"); - break; - case DW_OP_and: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("and"); - break; - case DW_OP_div: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("div"); - break; - case DW_OP_minus: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("minus"); - break; - case DW_OP_mod: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("mod"); - break; - case DW_OP_mul: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("mul"); - break; - case DW_OP_neg: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("neg"); - break; - case DW_OP_not: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("not"); - break; - case DW_OP_or: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("or"); - break; - case DW_OP_plus: - element->type = e_dw_arithmetic; - element->location.arithmetic = xbt_strdup("plus"); - break; - - case DW_OP_stack_value: - // Why nothing here? - xbt_free(element); - return NULL; - - case DW_OP_deref_size: - element->type = e_dw_deref; - element->location.deref_size = (unsigned int short) op->number; - break; - case DW_OP_deref: - element->type = e_dw_deref; - element->location.deref_size = sizeof(void *); - break; - case DW_OP_constu: - element->type = e_dw_uconstant; - element->location.uconstant.bytes = 1; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_consts: - element->type = e_dw_sconstant; - element->location.uconstant.bytes = 1; - element->location.uconstant.value = (unsigned long int) op->number; - break; - - case DW_OP_const1u: - element->type = e_dw_uconstant; - element->location.uconstant.bytes = 1; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_const2u: - element->type = e_dw_uconstant; - element->location.uconstant.bytes = 2; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_const4u: - element->type = e_dw_uconstant; - element->location.uconstant.bytes = 4; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_const8u: - element->type = e_dw_uconstant; - element->location.uconstant.bytes = 8; - element->location.uconstant.value = (unsigned long int) op->number; - break; - - case DW_OP_const1s: - element->type = e_dw_sconstant; - element->location.uconstant.bytes = 1; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_const2s: - element->type = e_dw_sconstant; - element->location.uconstant.bytes = 2; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_const4s: - element->type = e_dw_sconstant; - element->location.uconstant.bytes = 4; - element->location.uconstant.value = (unsigned long int) op->number; - break; - case DW_OP_const8s: - element->type = e_dw_sconstant; - element->location.uconstant.bytes = 8; - element->location.uconstant.value = (unsigned long int) op->number; - break; - default: - element->type = e_dw_unsupported; - break; - } - return element; -} - -/** \brief Convert libdw location expresion into native one */ -static dw_location_t MC_dwarf_get_expression(Dwarf_Op* expr, size_t len) { - dw_location_t loc = xbt_new0(s_dw_location_t, 1); - loc->type = e_dw_compose; - loc->location.compose = xbt_dynar_new(sizeof(dw_location_t), NULL); - - int i; - for (i=0; i!=len; ++i) { - dw_location_t element = MC_dwarf_get_expression_element(expr+i); - if (element) - xbt_dynar_push(loc->location.compose, &element); - } - - return loc; -} - static int mc_anonymous_variable_index = 0; static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die* die, Dwarf_Die* unit, dw_frame_t frame, const char* namespace) { @@ -988,17 +704,6 @@ static void MC_dwarf_handle_subprogram_die(mc_object_info_t info, Dwarf_Die* die if (MC_dwarf_attr_flag(die, DW_AT_declaration, false)) return; - // Abstract inline instance (DW_AT_inline != DW_INL_not_inlined): - if (dwarf_func_inline(die)) - return; - - // This is probably not a concrete instance: - // DWARF2/3 and DWARF4 do not agree on the meaning of DW_INL_not_inlined. - // For DWARF2/3, the subprogram is abstract. - // For DARF4, the subprogram is not abstract. - if(!dwarf_hasattr_integrate(die, DW_AT_low_pc)) - return; - dw_frame_t frame = xbt_new0(s_dw_frame_t, 1); frame->start = dwarf_dieoffset(die); @@ -1016,18 +721,15 @@ static void MC_dwarf_handle_subprogram_die(mc_object_info_t info, Dwarf_Die* die frame->high_pc = ((char*) base) + MC_dwarf_attr_addr(die, DW_AT_high_pc); frame->low_pc = ((char*) base) + MC_dwarf_attr_addr(die, DW_AT_low_pc); - if(frame->high_pc==0 || frame->low_pc==0) - xbt_die("Could not resolve highpc/lowpc"); - Dwarf_Attribute attr_frame_base; - if (!dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base)) - xbt_die("Coult not find DW_AT_frame_base for subprogram %s %p", frame->name, frame->start); - mc_dwarf_location_list_init(&frame->frame_base, info, die, &attr_frame_base); + if (dwarf_attr_integrate(die, DW_AT_frame_base, &attr_frame_base)) + mc_dwarf_location_list_init(&frame->frame_base, info, die, &attr_frame_base); frame->end = -1; // This one is now useless: // Register it: - xbt_dynar_push(info->subprograms, &frame); + const char* key = bprintf("%" PRIx64, (uint64_t) frame->start); + xbt_dict_set(info->subprograms, key, frame, NULL); // Handle children: MC_dwarf_handle_children(info, die, unit, frame, namespace);