X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/7d14b2ed9eb8cf0be6e693b3914030b02f0509f1..2145c35adaa6d63728ab13e26566044a8eb6dc9b:/src/mc/mc_dwarf.cpp diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index b312366e8f..e7a7b6c0b3 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -16,18 +16,17 @@ #include #include -#include +#include "src/simgrid/util.hpp" #include #include -#include +#include "src/mc/mc_object_info.h" +#include "src/mc/mc_private.h" +#include "src/mc/mc_dwarf.hpp" -#include "mc_object_info.h" -#include "mc_private.h" - -#include "mc/Process.hpp" -#include "mc/ObjectInformation.hpp" -#include "mc/Variable.hpp" +#include "src/mc/Process.hpp" +#include "src/mc/ObjectInformation.hpp" +#include "src/mc/Variable.hpp" XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing"); @@ -133,8 +132,7 @@ enum class FormClass { RangeListPtr }; -namespace { - +XBT_PRIVATE TagClass classify_tag(int tag) { switch (tag) { @@ -193,6 +191,7 @@ TagClass classify_tag(int tag) * \param form The form (values taken from the DWARF spec) * \return An internal representation for the corresponding class * */ +XBT_PRIVATE FormClass classify_form(int form) { switch (form) { @@ -232,18 +231,18 @@ FormClass classify_form(int form) } } -} -} -} - /** \brief Get the name of the tag of a given DIE * * \param die DIE * \return name of the tag of this DIE */ -static inline const char *MC_dwarf_die_tagname(Dwarf_Die * die) +inline XBT_PRIVATE +const char *tagname(Dwarf_Die * die) { - return MC_dwarf_tagname(dwarf_tag(die)); + return simgrid::dwarf::tagname(dwarf_tag(die)); +} + +} } // ***** Attributes @@ -351,7 +350,8 @@ static bool MC_dwarf_attr_flag(Dwarf_Die * die, int attribute, bool integrate) bool result; if (dwarf_formflag(&attr, &result)) - xbt_die("Unexpected form for attribute %s", MC_dwarf_attrname(attribute)); + xbt_die("Unexpected form for attribute %s", + simgrid::dwarf::attrname(attribute)); return result; } @@ -407,7 +407,7 @@ static uint64_t MC_dwarf_subrange_element_count(Dwarf_Die * die, xbt_assert(dwarf_tag(die) == DW_TAG_enumeration_type || dwarf_tag(die) == DW_TAG_subrange_type, "MC_dwarf_subrange_element_count called with DIE of type %s", - MC_dwarf_die_tagname(die)); + simgrid::dwarf::tagname(die)); // Use DW_TAG_count if present: if (dwarf_hasattr_integrate(die, DW_AT_count)) @@ -442,7 +442,7 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit) { xbt_assert(dwarf_tag(die) == DW_TAG_array_type, "MC_dwarf_array_element_count called with DIE of type %s", - MC_dwarf_die_tagname(die)); + simgrid::dwarf::tagname(die)); int result = 1; Dwarf_Die child; @@ -515,7 +515,7 @@ static void MC_dwarf_fill_member_location( ("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.c_str()); - member->location_expression = simgrid::mc::DwarfExpression(expr, expr+len); + member->location_expression = simgrid::dwarf::DwarfExpression(expr, expr+len); break; } case simgrid::dwarf::FormClass::Constant: @@ -751,7 +751,7 @@ static std::unique_ptr MC_die_to_variable( uintptr_t base = (uintptr_t) info->base_address(); variable->address = (void *) (base + offset); } else { - simgrid::mc::LocationListEntry entry; + simgrid::dwarf::LocationListEntry entry; entry.expression = {expr, expr + len}; variable->location_list = { std::move(entry) }; } @@ -762,9 +762,8 @@ static std::unique_ptr MC_die_to_variable( case simgrid::dwarf::FormClass::LocListPtr: case simgrid::dwarf::FormClass::Constant: // Reference to location list: - mc_dwarf_location_list_init( - &variable->location_list, info, die, - &attr_location); + variable->location_list = simgrid::dwarf::location_list( + *info, attr_location); break; default: @@ -907,8 +906,8 @@ static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwar if (klass == simgrid::dwarf::TagClass::Subprogram) { Dwarf_Attribute 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.frame_base_location = simgrid::dwarf::location_list(*info, + attr_frame_base); } // Handle children: @@ -986,11 +985,25 @@ static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die } } +static +Elf64_Half MC_dwarf_elf_type(Dwarf* dwarf) +{ + Elf* elf = dwarf_getelf(dwarf); + Elf64_Ehdr* ehdr64 = elf64_getehdr(elf); + if (ehdr64) + return ehdr64->e_type; + Elf32_Ehdr* ehdr32 = elf32_getehdr(elf); + if (ehdr32) + return ehdr32->e_type; + xbt_die("Could not get ELF heeader"); +} + /** \brief Populate the debugging informations of the given ELF object * * Read the DWARf information of the EFFL object and populate the * lists of types, variables, functions. */ +static void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) { int fd = open(info->file_name.c_str(), O_RDONLY); @@ -1002,6 +1015,11 @@ void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info) "Your program and its dependencies must have debugging information.\n" "You might want to recompile with -g or install the suitable debugging package.\n", info->file_name.c_str()); + + Elf64_Half elf_type = MC_dwarf_elf_type(dwarf); + if (elf_type == ET_EXEC) + info->flags |= simgrid::mc::ObjectInformation::Executable; + // For each compilation unit: Dwarf_Off offset = 0; Dwarf_Off next_offset = 0; @@ -1131,12 +1149,10 @@ static void MC_post_process_types(simgrid::mc::ObjectInformation* info) /** \brief Finds informations about a given shared object/executable */ std::shared_ptr MC_find_object_info( - std::vector const& maps, const char *name, int executable) + std::vector const& maps, const char *name) { std::shared_ptr result = std::make_shared(); - if (executable) - result->flags |= simgrid::mc::ObjectInformation::Executable; result->file_name = name; MC_find_object_address(maps, result.get()); MC_dwarf_get_variables(result.get()); @@ -1178,3 +1194,80 @@ void MC_post_process_object_info(simgrid::mc::Process* process, simgrid::mc::Obj } } + +namespace simgrid { +namespace dwarf { + +/** Convert a DWARF register into a libunwind register + * + * DWARF and libunwind does not use the same convention for numbering the + * registers on some architectures. The function makes the necessary + * convertion. + */ +int dwarf_register_to_libunwind(int dwarf_register) +{ +#if defined(__x86_64__) + // It seems for this arch, DWARF and libunwind agree in the numbering: + return dwarf_register; +#elif defined(__i386__) + // Could't find the authoritative source of information for this. + // This is inspired from http://source.winehq.org/source/dlls/dbghelp/cpu_i386.c#L517. + switch (dwarf_register) { + case 0: + return UNW_X86_EAX; + case 1: + return UNW_X86_ECX; + case 2: + return UNW_X86_EDX; + case 3: + return UNW_X86_EBX; + case 4: + return UNW_X86_ESP; + case 5: + return UNW_X86_EBP; + case 6: + return UNW_X86_ESI; + case 7: + return UNW_X86_EDI; + case 8: + return UNW_X86_EIP; + case 9: + return UNW_X86_EFLAGS; + case 10: + return UNW_X86_CS; + case 11: + return UNW_X86_SS; + case 12: + return UNW_X86_DS; + case 13: + return UNW_X86_ES; + case 14: + return UNW_X86_FS; + case 15: + return UNW_X86_GS; + case 16: + return UNW_X86_ST0; + case 17: + return UNW_X86_ST1; + case 18: + return UNW_X86_ST2; + case 19: + return UNW_X86_ST3; + case 20: + return UNW_X86_ST4; + case 21: + return UNW_X86_ST5; + case 22: + return UNW_X86_ST6; + case 23: + return UNW_X86_ST7; + default: + xbt_die("Bad/unknown register number."); + } +#else +#error This architecture is not supported yet for DWARF expression evaluation. +#endif +} + +} +} \ No newline at end of file