X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/95fb9335846db350cf78689df60bdb1a697bc033..4b6ea22affbf2fb45a2e80779c789047121ceff6:/src/mc/mc_dwarf.cpp diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index 1133efac84..ee1b4ee363 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -18,12 +18,20 @@ #include "mc_object_info.h" #include "mc_private.h" -extern "C" { +static void mc_variable_free_voidp(void *t) +{ + delete *(simgrid::mc::Variable**)t; +} + +static void mc_frame_free(void* frame) +{ + delete (simgrid::mc::Frame*)frame; +} -static void MC_dwarf_register_global_variable(mc_object_info_t info, dw_variable_t variable); -static void MC_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); -static void MC_dwarf_register_non_global_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); -static void MC_dwarf_register_variable(mc_object_info_t info, dw_frame_t frame, dw_variable_t variable); +static void MC_dwarf_register_global_variable(mc_object_info_t info, mc_variable_t variable); +static void MC_register_variable(mc_object_info_t info, mc_frame_t frame, mc_variable_t variable); +static void MC_dwarf_register_non_global_variable(mc_object_info_t info, mc_frame_t frame, mc_variable_t variable); +static void MC_dwarf_register_variable(mc_object_info_t info, mc_frame_t frame, mc_variable_t variable); XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing"); @@ -63,13 +71,13 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit); * \param frame containg frame if any */ static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns); /** \brief Process a type DIE */ static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns); /** \brief Calls MC_dwarf_handle_die on all childrend of the given die @@ -80,7 +88,7 @@ static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die * die, * \param frame containg frame if any */ static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns); /** \brief Handle a variable (DW_TAG_variable or other) @@ -91,7 +99,7 @@ static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die, * \param frame containg frame if any */ static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns); /** \brief Get the DW_TAG_type of the DIE @@ -99,37 +107,7 @@ static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die * die, * \param die DIE * \return DW_TAG_type attribute as a new string (NULL if none) */ -static char *MC_dwarf_at_type(Dwarf_Die * die); - -/** \brief Get the name of an attribute (DW_AT_*) from its code - * - * \param attr attribute code (see the DWARF specification) - * \return name of the attribute - */ -const char *MC_dwarf_attrname(int attr) -{ - switch (attr) { -#include "mc_dwarf_attrnames.h" - default: - return "DW_AT_unknown"; - } -} - -/** \brief Get the name of a dwarf tag (DW_TAG_*) from its code - * - * \param tag tag code (see the DWARF specification) - * \return name of the tag - */ -const char *MC_dwarf_tagname(int tag) -{ - switch (tag) { -#include "mc_dwarf_tagnames.h" - case DW_TAG_invalid: - return "DW_TAG_invalid"; - default: - return "DW_TAG_unknown"; - } -} +static std::string MC_dwarf_at_type(Dwarf_Die * die); /** \brief A class of DWARF tags (DW_TAG_*) */ @@ -334,10 +312,16 @@ static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die * die, * \param dit the DIE * \return DW_AT_type reference as a global offset in hexadecimal (or NULL) */ -static char *MC_dwarf_at_type(Dwarf_Die * die) +static +std::string MC_dwarf_at_type(Dwarf_Die * die) { Dwarf_Off offset = MC_dwarf_attr_integrate_dieoffset(die, DW_AT_type); - return offset == 0 ? NULL : bprintf("%" PRIx64, offset); + if (offset == 0) + return std::string(); + char* s = bprintf("%" PRIx64, offset); + std::string res(s); + free(s); + return std::move(res); } static uint64_t MC_dwarf_attr_integrate_addr(Dwarf_Die * die, int attribute) @@ -481,7 +465,7 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit) return result; } -// ***** dw_type_t +// ***** mc_type_t /** \brief Initialize the location of a member of a type * (DW_AT_data_member_location of a DW_TAG_member). @@ -490,7 +474,7 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit) * \param member the member of the type * \param child DIE of the member (DW_TAG_member) */ -static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, +static void MC_dwarf_fill_member_location(mc_type_t type, mc_type_t member, Dwarf_Die * child) { if (dwarf_hasattr(child, DW_AT_data_bit_offset)) { @@ -501,7 +485,8 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, if (type->type != DW_TAG_union_type) { xbt_die ("Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%" - PRIx64 ">%s", member->name, (uint64_t) type->id, type->name); + PRIx64 ">%s", member->name.c_str(), + (uint64_t) type->id, type->name.c_str()); } else { return; } @@ -522,13 +507,9 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, xbt_die ("Could not read location expression DW_AT_data_member_location in DW_TAG_member %s of type <%" PRIx64 ">%s", MC_dwarf_attr_integrate_string(child, DW_AT_name), - (uint64_t) type->id, type->name); - } - if (len == 1 && expr[0].atom == DW_OP_plus_uconst) { - member->offset = expr[0].number; - } else { - mc_dwarf_expression_init(&member->location, len, expr); + (uint64_t) type->id, type->name.c_str()); } + simgrid::mc::DwarfExpression(expr, expr+len); break; } case MC_DW_CLASS_CONSTANT: @@ -536,11 +517,11 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, { Dwarf_Word offset; if (!dwarf_formudata(&attr, &offset)) - member->offset = offset; + member->offset(offset); else xbt_die("Cannot get %s location <%" PRIx64 ">%s", MC_dwarf_attr_integrate_string(child, DW_AT_name), - (uint64_t) type->id, type->name); + (uint64_t) type->id, type->name.c_str()); break; } case MC_DW_CLASS_LOCLISTPTR: @@ -558,7 +539,7 @@ static void MC_dwarf_fill_member_location(dw_type_t type, dw_type_t member, static void dw_type_free_voidp(void *t) { - dw_type_free((dw_type_t) * (void **) t); + delete *(mc_type_t*)t; } /** \brief Populate the list of members of a type @@ -569,13 +550,11 @@ static void dw_type_free_voidp(void *t) * \param type the type */ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_type_t type) + Dwarf_Die * unit, mc_type_t type) { int res; Dwarf_Die child; - xbt_assert(!type->members); - type->members = - xbt_dynar_new(sizeof(dw_type_t), (void (*)(void *)) dw_type_free_voidp); + xbt_assert(type->members.empty()); for (res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) { int tag = dwarf_tag(&child); @@ -590,38 +569,33 @@ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die * die, continue; // 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 = tag; + simgrid::mc::Type member; + member.type = tag; // Global Offset: - member->id = dwarf_dieoffset(&child); + member.id = dwarf_dieoffset(&child); const char *name = MC_dwarf_attr_integrate_string(&child, DW_AT_name); if (name) - member->name = xbt_strdup(name); - else - member->name = NULL; - - member->byte_size = + member.name = name; + member.byte_size = MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0); - member->element_count = -1; - member->dw_type_id = MC_dwarf_at_type(&child); - member->members = NULL; - member->is_pointer_type = 0; - member->offset = 0; + member.element_count = -1; + member.type_id = MC_dwarf_at_type(&child); if (dwarf_hasattr(&child, DW_AT_data_bit_offset)) { xbt_die("Can't groke DW_AT_data_bit_offset."); } - MC_dwarf_fill_member_location(type, member, &child); + MC_dwarf_fill_member_location(type, &member, &child); - if (!member->dw_type_id) { - xbt_die("Missing type for member %s of <%" PRIx64 ">%s", member->name, - (uint64_t) type->id, type->name); + if (member.type_id.empty()) { + xbt_die("Missing type for member %s of <%" PRIx64 ">%s", + member.name.c_str(), + (uint64_t) type->id, type->name.c_str()); } - xbt_dynar_push(type->members, &member); + type->members.push_back(std::move(member)); } } } @@ -633,21 +607,15 @@ static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die * die, * \param unit compilation unit of the current DIE * \return MC representation of the type */ -static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, +static mc_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die * die, + Dwarf_Die * unit, mc_frame_t frame, const char *ns) { - dw_type_t type = xbt_new0(s_dw_type_t, 1); + mc_type_t type = new simgrid::mc::Type(); type->type = -1; - type->id = 0; - type->name = NULL; - type->byte_size = 0; + type->name = std::string(); type->element_count = -1; - type->dw_type_id = NULL; - type->members = NULL; - type->is_pointer_type = 0; - type->offset = 0; type->type = dwarf_tag(die); @@ -671,14 +639,15 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die * die, const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name); if (name != NULL) { - type->name = - ns ? bprintf("%s%s::%s", prefix, ns, - name) : bprintf("%s%s", prefix, name); + char* full_name = ns ? bprintf("%s%s::%s", prefix, ns, name) : + bprintf("%s%s", prefix, name); + type->name = std::string(full_name); + free(full_name); } - type->dw_type_id = MC_dwarf_at_type(die); + type->type_id = MC_dwarf_at_type(die); - // Some compiler do not emit DW_AT_byte_size for pointer_type, + // Some compilers do not emit DW_AT_byte_size for pointer_type, // so we fill this. We currently assume that the model-checked process is in // the same architecture.. if (type->type == DW_TAG_pointer_type) @@ -712,7 +681,7 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die * die, case DW_TAG_union_type: case DW_TAG_class_type: MC_dwarf_add_members(info, die, unit, type); - char *new_ns = ns == NULL ? xbt_strdup(type->name) + char *new_ns = ns == NULL ? xbt_strdup(type->name.c_str()) : bprintf("%s::%s", ns, name); MC_dwarf_handle_children(info, die, unit, frame, new_ns); free(new_ns); @@ -723,24 +692,24 @@ static dw_type_t MC_dwarf_die_to_type(mc_object_info_t info, Dwarf_Die * die, } static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns) { - dw_type_t type = MC_dwarf_die_to_type(info, die, unit, frame, ns); + mc_type_t type = MC_dwarf_die_to_type(info, die, unit, frame, ns); char *key = bprintf("%" PRIx64, (uint64_t) type->id); xbt_dict_set(info->types, key, type, NULL); xbt_free(key); - if (type->name && type->byte_size != 0) { - xbt_dict_set(info->full_types_by_name, type->name, type, NULL); + if (!type->name.empty() && type->byte_size != 0) { + xbt_dict_set(info->full_types_by_name, type->name.c_str(), type, NULL); } } 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, +static mc_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die * die, + Dwarf_Die * unit, mc_frame_t frame, const char *ns) { // Skip declarations: @@ -757,15 +726,15 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die * die, return NULL; } - dw_variable_t variable = xbt_new0(s_dw_variable_t, 1); + simgrid::mc::Variable* variable = new simgrid::mc::Variable(); 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); - - variable->type_origin = MC_dwarf_at_type(die); + if (name) + variable->name = name; + variable->type_id = MC_dwarf_at_type(die); int form = dwarf_whatform(&attr_location); int klass = @@ -779,19 +748,22 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die * die, Dwarf_Op *expr; size_t len; if (dwarf_getlocation(&attr_location, &expr, &len)) { - xbt_die - ("Could not read location expression in DW_AT_location of variable <%" - PRIx64 ">%s", (uint64_t) variable->dwarf_offset, variable->name); + xbt_die( + "Could not read location expression in DW_AT_location " + "of variable <%" PRIx64 ">%s", + (uint64_t) variable->dwarf_offset, + variable->name.c_str()); } if (len == 1 && expr[0].atom == DW_OP_addr) { variable->global = 1; uintptr_t offset = (uintptr_t) expr[0].number; - uintptr_t base = (uintptr_t) MC_object_base_address(info); + uintptr_t base = (uintptr_t) info->base_address(); variable->address = (void *) (base + offset); } else { - mc_dwarf_location_list_init_from_expression(&variable->locations, len, - expr); + simgrid::mc::LocationListEntry entry; + entry.expression = {expr, expr + len}; + variable->location_list = { std::move(entry) }; } break; @@ -799,13 +771,16 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die * die, case MC_DW_CLASS_LOCLISTPTR: case MC_DW_CLASS_CONSTANT: // Reference to location list: - mc_dwarf_location_list_init(&variable->locations, info, die, - &attr_location); + mc_dwarf_location_list_init( + &variable->location_list, info, die, + &attr_location); break; default: - xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location in <%" - PRIx64 ">%s", form, form, klass, klass, - (uint64_t) variable->dwarf_offset, variable->name); + xbt_die("Unexpected form 0x%x (%i), class 0x%x (%i) list for location " + "in <%" PRIx64 ">%s", + form, form, klass, klass, + (uint64_t) variable->dwarf_offset, + variable->name.c_str()); } // Handle start_scope: @@ -830,39 +805,32 @@ static dw_variable_t MC_die_to_variable(mc_object_info_t info, Dwarf_Die * die, } } - if (ns && variable->global) { - char *old_name = variable->name; - variable->name = bprintf("%s::%s", ns, old_name); - free(old_name); - } + if (ns && variable->global) + variable->name = + std::string(ns) + "::" + variable->name; + // The current code needs a variable name, // generate a fake one: - if (!variable->name) { - variable->name = bprintf("@anonymous#%i", mc_anonymous_variable_index++); - } + if (variable->name.empty()) + variable->name = + "@anonymous#" + std::to_string(mc_anonymous_variable_index++); return variable; } static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns) { - dw_variable_t variable = + mc_variable_t variable = MC_die_to_variable(info, die, unit, frame, ns); if (variable == NULL) return; MC_dwarf_register_variable(info, frame, variable); } -static void mc_frame_free_voipd(dw_frame_t * p) -{ - mc_frame_free(*p); - *p = NULL; -} - static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t parent_frame, + Dwarf_Die * unit, mc_frame_t parent_frame, const char *ns) { // TODO, handle DW_TAG_type/DW_TAG_location for DW_TAG_with_stmt @@ -877,7 +845,7 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die, if (klass == mc_tag_scope) xbt_assert(parent_frame, "No parent scope for this scope"); - dw_frame_t frame = xbt_new0(s_dw_frame_t, 1); + mc_frame_t frame = new simgrid::mc::Frame(); frame->tag = tag; frame->id = dwarf_dieoffset(die); @@ -885,8 +853,10 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die, if (klass == mc_tag_subprogram) { const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name); - frame->name = - ns ? bprintf("%s::%s", ns, name) : xbt_strdup(name); + if(ns) + frame->name = std::string(ns) + "::" + name; + else + frame->name = name; } frame->abstract_origin_id = @@ -895,11 +865,7 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die, // This is the base address for DWARF addresses. // Relocated addresses are offset from this base address. // See DWARF4 spec 7.5 - 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); + void *base = info->base_address(); // TODO, support DW_AT_ranges uint64_t low_pc = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc); @@ -944,9 +910,6 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die, &attr_frame_base); } - frame->scopes = - xbt_dynar_new(sizeof(dw_frame_t), (void_f_pvoid_t) mc_frame_free_voipd); - // Register it: if (klass == mc_tag_subprogram) { char *key = bprintf("%" PRIx64, (uint64_t) frame->id); @@ -961,7 +924,7 @@ static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die, static void mc_dwarf_handle_namespace_die(mc_object_info_t info, Dwarf_Die * die, Dwarf_Die * unit, - dw_frame_t frame, + mc_frame_t frame, const char *ns) { const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name); @@ -974,7 +937,7 @@ static void mc_dwarf_handle_namespace_die(mc_object_info_t info, } static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns) { // For each child DIE: @@ -987,7 +950,7 @@ static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die, } static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die * die, - Dwarf_Die * unit, dw_frame_t frame, + Dwarf_Die * unit, mc_frame_t frame, const char *ns) { int tag = dwarf_tag(die); @@ -1062,82 +1025,78 @@ void MC_dwarf_get_variables(mc_object_info_t info) /************************** Free functions *************************/ -void mc_frame_free(dw_frame_t frame) +static void dw_type_free(mc_type_t t) { - xbt_free(frame->name); - mc_dwarf_location_list_clear(&(frame->frame_base)); - xbt_dynar_free(&(frame->variables)); - xbt_dynar_free(&(frame->scopes)); - xbt_free(frame); + delete t; } -void dw_type_free(dw_type_t t) -{ - xbt_free(t->name); - xbt_free(t->dw_type_id); - xbt_dynar_free(&(t->members)); - mc_dwarf_expression_clear(&t->location); - xbt_free(t); -} +// ***** object_info -void dw_variable_free(dw_variable_t v) -{ - if (v) { - xbt_free(v->name); - xbt_free(v->type_origin); +namespace simgrid { +namespace mc { - if (v->locations.locations) - mc_dwarf_location_list_clear(&v->locations); - xbt_free(v); - } +ObjectInformation::ObjectInformation() +{ + this->flags = 0; + this->file_name = nullptr; + this->start = nullptr; + this->end = nullptr; + this->start_exec = nullptr; + this->end_exec = nullptr; + this->start_rw = nullptr; + this->end_rw = nullptr; + this->start_ro = nullptr; + this->end_ro = nullptr; + this->subprograms = xbt_dict_new_homogeneous(mc_frame_free); + this->global_variables = + xbt_dynar_new(sizeof(mc_variable_t), mc_variable_free_voidp); + this->types = xbt_dict_new_homogeneous((void (*)(void *)) dw_type_free); + this->full_types_by_name = xbt_dict_new_homogeneous(NULL); + this->functions_index = nullptr; } -void dw_variable_free_voidp(void *t) +ObjectInformation::~ObjectInformation() { - dw_variable_free((dw_variable_t) * (void **) t); + xbt_free(this->file_name); + xbt_dict_free(&this->subprograms); + xbt_dynar_free(&this->global_variables); + xbt_dict_free(&this->types); + xbt_dict_free(&this->full_types_by_name); + xbt_dynar_free(&this->functions_index); } -// ***** object_info - - - -mc_object_info_t MC_new_object_info(void) +/** Find the DWARF offset for this ELF object + * + * An offset is applied to address found in DWARF: + * + *