1 /* Copyright (c) 2008-2015. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
13 #define DW_LANG_Objc DW_LANG_ObjC /* fix spelling error in older dwarf.h */
15 #include <simgrid/util.hpp>
17 #include <xbt/sysdep.h>
19 #include <simgrid/util.hpp>
21 #include "mc/mc_dwarf.hpp"
22 #include "mc/mc_dwarf.hpp"
23 #include "mc/mc_private.h"
24 #include "mc/mc_process.h"
26 #include "mc/ObjectInformation.hpp"
27 #include "mc/Variable.hpp"
29 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing");
31 // ***** Functions index
33 static int MC_compare_frame_index_items(simgrid::mc::FunctionIndexEntry* a,
34 simgrid::mc::FunctionIndexEntry* b)
36 if (a->low_pc < b->low_pc)
38 else if (a->low_pc == b->low_pc)
44 static void MC_make_functions_index(simgrid::mc::ObjectInformation* info)
46 info->functions_index.clear();
48 for (auto& e : info->subprograms) {
49 if (e.second.low_pc == nullptr)
51 simgrid::mc::FunctionIndexEntry entry;
52 entry.low_pc = e.second.low_pc;
53 entry.function = &e.second;
54 info->functions_index.push_back(entry);
57 info->functions_index.shrink_to_fit();
59 // Sort the array by low_pc:
60 std::sort(info->functions_index.begin(), info->functions_index.end(),
61 [](simgrid::mc::FunctionIndexEntry const& a,
62 simgrid::mc::FunctionIndexEntry const& b)
64 return a.low_pc < b.low_pc;
68 static void MC_post_process_variables(simgrid::mc::ObjectInformation* info)
70 // Someone needs this to be sorted but who?
71 std::sort(info->global_variables.begin(), info->global_variables.end(),
74 for(simgrid::mc::Variable& variable : info->global_variables)
76 variable.type = simgrid::util::find_map_ptr(
77 info->types, variable.type_id);
80 static void mc_post_process_scope(
81 simgrid::mc::ObjectInformation* info, simgrid::mc::Frame* scope)
84 if (scope->tag == DW_TAG_inlined_subroutine) {
85 // Attach correct namespaced name in inlined subroutine:
86 auto i = info->subprograms.find(scope->abstract_origin_id);
87 xbt_assert(i != info->subprograms.end(),
88 "Could not lookup abstract origin %" PRIx64,
89 (uint64_t) scope->abstract_origin_id);
90 scope->name = i->second.name;
94 for (simgrid::mc::Variable& variable : scope->variables)
96 variable.type = simgrid::util::find_map_ptr(
97 info->types, variable.type_id);
99 // Recursive post-processing of nested-scopes:
100 for (simgrid::mc::Frame& nested_scope : scope->scopes)
101 mc_post_process_scope(info, &nested_scope);
105 /** \brief Fill/lookup the "subtype" field.
107 static void MC_resolve_subtype(
108 simgrid::mc::ObjectInformation* info, simgrid::mc::Type* type)
112 type->subtype = simgrid::util::find_map_ptr(info->types, type->type_id);
113 if (type->subtype == nullptr)
115 if (type->subtype->byte_size != 0)
117 if (type->subtype->name.empty())
119 // Try to find a more complete description of the type:
120 // We need to fix in order to support C++.
121 simgrid::mc::Type** subtype = simgrid::util::find_map_ptr(
122 info->full_types_by_name, type->subtype->name);
124 type->subtype = *subtype;
127 static void MC_post_process_types(simgrid::mc::ObjectInformation* info)
129 // Lookup "subtype" field:
130 for(auto& i : info->types) {
131 MC_resolve_subtype(info, &(i.second));
132 for (simgrid::mc::Type& member : i.second.members)
133 MC_resolve_subtype(info, &member);
137 /** \brief Finds informations about a given shared object/executable */
138 std::shared_ptr<simgrid::mc::ObjectInformation> MC_find_object_info(
139 std::vector<simgrid::mc::VmMap> const& maps, const char *name, int executable)
141 std::shared_ptr<simgrid::mc::ObjectInformation> result =
142 std::make_shared<simgrid::mc::ObjectInformation>();
144 result->flags |= simgrid::mc::ObjectInformation::Executable;
145 result->file_name = name;
146 MC_find_object_address(maps, result.get());
147 MC_dwarf_get_variables(result.get());
148 MC_post_process_variables(result.get());
149 MC_post_process_types(result.get());
150 for (auto& entry : result.get()->subprograms)
151 mc_post_process_scope(result.get(), &entry.second);
152 MC_make_functions_index(result.get());
153 return std::move(result);
156 /*************************************************************************/
158 void MC_post_process_object_info(simgrid::mc::Process* process, simgrid::mc::ObjectInformation* info)
160 for (auto& i : info->types) {
162 simgrid::mc::Type* type = &(i.second);
163 simgrid::mc::Type* subtype = type;
164 while (subtype->type == DW_TAG_typedef
165 || subtype->type == DW_TAG_volatile_type
166 || subtype->type == DW_TAG_const_type)
167 if (subtype->subtype)
168 subtype = subtype->subtype;
172 // Resolve full_type:
173 if (!subtype->name.empty() && subtype->byte_size == 0) {
174 for (auto const& object_info : process->object_infos) {
175 auto i = object_info->full_types_by_name.find(subtype->name);
176 if (i != object_info->full_types_by_name.end()
177 && !i->second->name.empty() && i->second->byte_size) {
178 type->full_type = i->second;
182 } else type->full_type = subtype;