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. */
14 #define DW_LANG_Objc DW_LANG_ObjC /* fix spelling error in older dwarf.h */
16 #include <simgrid/util.hpp>
18 #include <xbt/sysdep.h>
20 #include <simgrid/util.hpp>
22 #include "mc/mc_dwarf.hpp"
23 #include "mc/mc_dwarf.hpp"
24 #include "mc/mc_private.h"
25 #include "mc/mc_process.h"
27 #include "mc/ObjectInformation.hpp"
28 #include "mc/Variable.hpp"
30 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing");
32 // ***** Functions index
34 static int MC_compare_frame_index_items(simgrid::mc::FunctionIndexEntry* a,
35 simgrid::mc::FunctionIndexEntry* b)
37 if (a->low_pc < b->low_pc)
39 else if (a->low_pc == b->low_pc)
45 static void MC_make_functions_index(simgrid::mc::ObjectInformation* info)
47 info->functions_index.clear();
49 for (auto& e : info->subprograms) {
50 if (e.second.low_pc == nullptr)
52 simgrid::mc::FunctionIndexEntry entry;
53 entry.low_pc = e.second.low_pc;
54 entry.function = &e.second;
55 info->functions_index.push_back(entry);
58 info->functions_index.shrink_to_fit();
60 // Sort the array by low_pc:
61 std::sort(info->functions_index.begin(), info->functions_index.end(),
62 [](simgrid::mc::FunctionIndexEntry const& a,
63 simgrid::mc::FunctionIndexEntry const& b)
65 return a.low_pc < b.low_pc;
69 static void MC_post_process_variables(simgrid::mc::ObjectInformation* info)
71 // Someone needs this to be sorted but who?
72 std::sort(info->global_variables.begin(), info->global_variables.end(),
75 for(simgrid::mc::Variable& variable : info->global_variables)
77 variable.type = simgrid::util::find_map_ptr(
78 info->types, variable.type_id);
81 static void mc_post_process_scope(
82 simgrid::mc::ObjectInformation* info, simgrid::mc::Frame* scope)
85 if (scope->tag == DW_TAG_inlined_subroutine) {
86 // Attach correct namespaced name in inlined subroutine:
87 auto i = info->subprograms.find(scope->abstract_origin_id);
88 xbt_assert(i != info->subprograms.end(),
89 "Could not lookup abstract origin %" PRIx64,
90 (std::uint64_t) scope->abstract_origin_id);
91 scope->name = i->second.name;
95 for (simgrid::mc::Variable& variable : scope->variables)
97 variable.type = simgrid::util::find_map_ptr(
98 info->types, variable.type_id);
100 // Recursive post-processing of nested-scopes:
101 for (simgrid::mc::Frame& nested_scope : scope->scopes)
102 mc_post_process_scope(info, &nested_scope);
106 /** \brief Fill/lookup the "subtype" field.
108 static void MC_resolve_subtype(
109 simgrid::mc::ObjectInformation* info, simgrid::mc::Type* type)
113 type->subtype = simgrid::util::find_map_ptr(info->types, type->type_id);
114 if (type->subtype == nullptr)
116 if (type->subtype->byte_size != 0)
118 if (type->subtype->name.empty())
120 // Try to find a more complete description of the type:
121 // We need to fix in order to support C++.
122 simgrid::mc::Type** subtype = simgrid::util::find_map_ptr(
123 info->full_types_by_name, type->subtype->name);
125 type->subtype = *subtype;
128 static void MC_post_process_types(simgrid::mc::ObjectInformation* info)
130 // Lookup "subtype" field:
131 for(auto& i : info->types) {
132 MC_resolve_subtype(info, &(i.second));
133 for (simgrid::mc::Type& member : i.second.members)
134 MC_resolve_subtype(info, &member);
138 /** \brief Finds informations about a given shared object/executable */
139 std::shared_ptr<simgrid::mc::ObjectInformation> MC_find_object_info(
140 std::vector<simgrid::mc::VmMap> const& maps, const char *name, int executable)
142 std::shared_ptr<simgrid::mc::ObjectInformation> result =
143 std::make_shared<simgrid::mc::ObjectInformation>();
145 result->flags |= simgrid::mc::ObjectInformation::Executable;
146 result->file_name = name;
147 MC_find_object_address(maps, result.get());
148 MC_dwarf_get_variables(result.get());
149 MC_post_process_variables(result.get());
150 MC_post_process_types(result.get());
151 for (auto& entry : result.get()->subprograms)
152 mc_post_process_scope(result.get(), &entry.second);
153 MC_make_functions_index(result.get());
154 return std::move(result);
157 /*************************************************************************/
159 void MC_post_process_object_info(simgrid::mc::Process* process, simgrid::mc::ObjectInformation* info)
161 for (auto& i : info->types) {
163 simgrid::mc::Type* type = &(i.second);
164 simgrid::mc::Type* subtype = type;
165 while (subtype->type == DW_TAG_typedef
166 || subtype->type == DW_TAG_volatile_type
167 || subtype->type == DW_TAG_const_type)
168 if (subtype->subtype)
169 subtype = subtype->subtype;
173 // Resolve full_type:
174 if (!subtype->name.empty() && subtype->byte_size == 0) {
175 for (auto const& object_info : process->object_infos) {
176 auto i = object_info->full_types_by_name.find(subtype->name);
177 if (i != object_info->full_types_by_name.end()
178 && !i->second->name.empty() && i->second->byte_size) {
179 type->full_type = i->second;
183 } else type->full_type = subtype;