-/* Copyright (c) 2008-2014. The SimGrid Team.
+/* Copyright (c) 2008-2015. The SimGrid Team.
* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <cinttypes>
+#include <cstdint>
#include <algorithm>
#include <memory>
#include <elfutils/libdw.h>
#include <simgrid_config.h>
+#include <simgrid/util.hpp>
#include <xbt/log.h>
#include <xbt/sysdep.h>
+#include <simgrid/util.hpp>
+
#include "mc_object_info.h"
#include "mc_private.h"
+#include "mc_process.h"
+
+#include "mc/ObjectInformation.hpp"
+#include "mc/Variable.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dwarf, mc, "DWARF processing");
* \param unit the DIE of the compile unit of the current DIE
* \param frame containg frame if any
*/
-static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* 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, mc_frame_t frame,
+static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns);
/** \brief Calls MC_dwarf_handle_die on all childrend of the given die
* \param unit the DIE of the compile unit of the current DIE
* \param frame containg frame if any
*/
-static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns);
/** \brief Handle a variable (DW_TAG_variable or other)
* \param unit the DIE of the compile unit of the current 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, mc_frame_t frame,
+static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns);
/** \brief Get the DW_TAG_type of the DIE
static Dwarf_Off MC_dwarf_attr_dieoffset(Dwarf_Die * die, int attribute)
{
Dwarf_Attribute attr;
- if (dwarf_hasattr_integrate(die, attribute)) {
- dwarf_attr_integrate(die, attribute, &attr);
- Dwarf_Die subtype_die;
- if (dwarf_formref_die(&attr, &subtype_die) == NULL) {
- xbt_die("Could not find DIE");
- }
- return dwarf_dieoffset(&subtype_die);
- } else
+ if (dwarf_hasattr_integrate(die, attribute) == 0)
return 0;
+ dwarf_attr_integrate(die, attribute, &attr);
+ Dwarf_Die subtype_die;
+ if (dwarf_formref_die(&attr, &subtype_die) == NULL)
+ xbt_die("Could not find DIE");
+ return dwarf_dieoffset(&subtype_die);
}
static Dwarf_Off MC_dwarf_attr_integrate_dieoffset(Dwarf_Die * die,
int attribute)
{
Dwarf_Attribute attr;
- if (dwarf_hasattr_integrate(die, attribute)) {
- dwarf_attr_integrate(die, DW_AT_type, &attr);
- Dwarf_Die subtype_die;
- if (dwarf_formref_die(&attr, &subtype_die) == NULL) {
- xbt_die("Could not find DIE");
- }
- return dwarf_dieoffset(&subtype_die);
- } else
+ if (dwarf_hasattr_integrate(die, attribute) == 0)
return 0;
+ dwarf_attr_integrate(die, DW_AT_type, &attr);
+ Dwarf_Die subtype_die;
+ if (dwarf_formref_die(&attr, &subtype_die) == NULL)
+ xbt_die("Could not find DIE");
+ return dwarf_dieoffset(&subtype_die);
}
/** \brief Find the type/subtype (DW_AT_type) for a DIE
MC_dwarf_die_tagname(die));
// Use DW_TAG_count if present:
- if (dwarf_hasattr_integrate(die, DW_AT_count)) {
+ if (dwarf_hasattr_integrate(die, DW_AT_count))
return MC_dwarf_attr_integrate_uint(die, DW_AT_count, 0);
- }
// Otherwise compute DW_TAG_upper_bound-DW_TAG_lower_bound + 1:
- if (!dwarf_hasattr_integrate(die, DW_AT_upper_bound)) {
+ if (!dwarf_hasattr_integrate(die, DW_AT_upper_bound))
// This is not really 0, but the code expects this (we do not know):
return 0;
- }
+
uint64_t upper_bound =
MC_dwarf_attr_integrate_uint(die, DW_AT_upper_bound, -1);
uint64_t lower_bound = 0;
- if (dwarf_hasattr_integrate(die, DW_AT_lower_bound)) {
+ if (dwarf_hasattr_integrate(die, DW_AT_lower_bound))
lower_bound = MC_dwarf_attr_integrate_uint(die, DW_AT_lower_bound, -1);
- } else {
+ else
lower_bound = MC_dwarf_default_lower_bound(dwarf_srclang(unit));
- }
return upper_bound - lower_bound + 1;
}
res = dwarf_siblingof(&child, &child)) {
int child_tag = dwarf_tag(&child);
if (child_tag == DW_TAG_subrange_type
- || child_tag == DW_TAG_enumeration_type) {
+ || child_tag == DW_TAG_enumeration_type)
result *= MC_dwarf_subrange_element_count(&child, unit);
- }
}
return result;
}
return a.address < b.address;
}
-// ***** mc_type_t
+// ***** simgrid::mc::Type*
/** \brief Initialize the location of a member of a type
* (DW_AT_data_member_location of a DW_TAG_member).
* \param member the member of the type
* \param child DIE of the member (DW_TAG_member)
*/
-static void MC_dwarf_fill_member_location(mc_type_t type, mc_type_t member,
+static void MC_dwarf_fill_member_location(simgrid::mc::Type* type, simgrid::mc::Type* member,
Dwarf_Die * child)
{
- if (dwarf_hasattr(child, DW_AT_data_bit_offset)) {
+ if (dwarf_hasattr(child, DW_AT_data_bit_offset))
xbt_die("Can't groke DW_AT_data_bit_offset.");
- }
if (!dwarf_hasattr_integrate(child, DW_AT_data_member_location)) {
- 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.c_str(),
- (uint64_t) type->id, type->name.c_str());
- } else {
+ if (type->type == DW_TAG_union_type)
return;
- }
+ xbt_die
+ ("Missing DW_AT_data_member_location field in DW_TAG_member %s of type <%"
+ PRIx64 ">%s", member->name.c_str(),
+ (uint64_t) type->id, type->name.c_str());
}
Dwarf_Attribute attr;
{
Dwarf_Op *expr;
size_t len;
- if (dwarf_getlocation(&attr, &expr, &len)) {
+ if (dwarf_getlocation(&attr, &expr, &len))
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.c_str());
- }
simgrid::mc::DwarfExpression(expr, expr+len);
break;
}
}
-static void dw_type_free_voidp(void *t)
-{
- delete *(mc_type_t*)t;
-}
-
/** \brief Populate the list of members of a type
*
* \param info ELF object containing the type DIE
* \param unit DIE of the compilation unit containing the type DIE
* \param type the type
*/
-static void MC_dwarf_add_members(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_type_t type)
+static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Type* type)
{
int res;
Dwarf_Die child;
member.element_count = -1;
member.type_id = MC_dwarf_at_type(&child);
- if (dwarf_hasattr(&child, DW_AT_data_bit_offset)) {
+ 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);
- if (!member.type_id) {
+ if (!member.type_id)
xbt_die("Missing type for member %s of <%" PRIx64 ">%s",
member.name.c_str(),
(uint64_t) type->id, type->name.c_str());
- }
type->members.push_back(std::move(member));
}
* \return MC representation of the type
*/
static simgrid::mc::Type MC_dwarf_die_to_type(
- mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+ simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns)
{
-
simgrid::mc::Type type;
- type.type = -1;
+ type.type = dwarf_tag(die);
type.name = std::string();
type.element_count = -1;
- type.type = dwarf_tag(die);
-
// Global Offset
type.id = dwarf_dieoffset(die);
|| type.type == DW_TAG_structure_type
|| type.type == DW_TAG_class_type) {
Dwarf_Word size;
- if (dwarf_aggregate_size(die, &size) == 0) {
+ if (dwarf_aggregate_size(die, &size) == 0)
type.byte_size = size;
- }
}
switch (type.type) {
return std::move(type);
}
-static void MC_dwarf_handle_type_die(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+static void MC_dwarf_handle_type_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns)
{
simgrid::mc::Type type = MC_dwarf_die_to_type(info, die, unit, frame, ns);
static int mc_anonymous_variable_index = 0;
static std::unique_ptr<simgrid::mc::Variable> MC_die_to_variable(
- mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+ simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns)
{
// Skip declarations:
return nullptr;
Dwarf_Attribute attr_location;
- if (dwarf_attr(die, DW_AT_location, &attr_location) == NULL) {
+ if (dwarf_attr(die, DW_AT_location, &attr_location) == NULL)
// No location: do not add it ?
return nullptr;
- }
std::unique_ptr<simgrid::mc::Variable> variable =
std::unique_ptr<simgrid::mc::Variable>(new simgrid::mc::Variable());
return std::move(variable);
}
-static void MC_dwarf_handle_variable_die(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns)
{
std::unique_ptr<simgrid::mc::Variable> variable =
xbt_die("No frame for this local variable");
}
-static void MC_dwarf_handle_scope_die(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t parent_frame,
+static void MC_dwarf_handle_scope_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* parent_frame,
const char *ns)
{
// TODO, handle DW_TAG_type/DW_TAG_location for DW_TAG_with_stmt
const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
if(ns)
frame.name = std::string(ns) + "::" + name;
- else
+ else if (name)
frame.name = name;
+ else
+ frame.name.clear();
}
frame.abstract_origin_id =
parent_frame->scopes.push_back(std::move(frame));
}
-static void mc_dwarf_handle_namespace_die(mc_object_info_t info,
+static void mc_dwarf_handle_namespace_die(simgrid::mc::ObjectInformation* info,
Dwarf_Die * die, Dwarf_Die * unit,
- mc_frame_t frame,
+ simgrid::mc::Frame* frame,
const char *ns)
{
const char *name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
xbt_free(new_ns);
}
-static void MC_dwarf_handle_children(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+static void MC_dwarf_handle_children(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns)
{
// For each child DIE:
}
}
-static void MC_dwarf_handle_die(mc_object_info_t info, Dwarf_Die * die,
- Dwarf_Die * unit, mc_frame_t frame,
+static void MC_dwarf_handle_die(simgrid::mc::ObjectInformation* info, Dwarf_Die * die,
+ Dwarf_Die * unit, simgrid::mc::Frame* frame,
const char *ns)
{
int tag = dwarf_tag(die);
* Read the DWARf information of the EFFL object and populate the
* lists of types, variables, functions.
*/
-void MC_dwarf_get_variables(mc_object_info_t info)
+void MC_dwarf_get_variables(simgrid::mc::ObjectInformation* info)
{
int fd = open(info->file_name.c_str(), O_RDONLY);
if (fd < 0)
xbt_die("Could not open file %s", info->file_name.c_str());
Dwarf *dwarf = dwarf_begin(fd, DWARF_C_READ);
if (dwarf == NULL)
- xbt_die("Your program must be compiled with -g (%s)",
+ xbt_die("Missing debugging information in %s\n"
+ "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());
// For each compilation unit:
Dwarf_Off offset = 0;
Dwarf_Off next_offset = 0;
size_t length;
+
while (dwarf_nextcu(dwarf, offset, &next_offset, &length, NULL, NULL, NULL) ==
0) {
Dwarf_Die unit_die;
- if (dwarf_offdie(dwarf, offset + length, &unit_die) != NULL) {
-
- // For each child DIE:
- Dwarf_Die child;
- int res;
- for (res = dwarf_child(&unit_die, &child); res == 0;
- res = dwarf_siblingof(&child, &child)) {
- MC_dwarf_handle_die(info, &child, &unit_die, NULL, NULL);
- }
-
- }
+ if (dwarf_offdie(dwarf, offset + length, &unit_die) != NULL)
+ MC_dwarf_handle_children(info, &unit_die, &unit_die, NULL, NULL);
offset = next_offset;
}
return 1;
}
-static void MC_make_functions_index(mc_object_info_t info)
+static void MC_make_functions_index(simgrid::mc::ObjectInformation* info)
{
info->functions_index.clear();
// Sort the array by low_pc:
std::sort(info->functions_index.begin(), info->functions_index.end(),
- [](simgrid::mc::FunctionIndexEntry& a,
- simgrid::mc::FunctionIndexEntry& b)
+ [](simgrid::mc::FunctionIndexEntry const& a,
+ simgrid::mc::FunctionIndexEntry const& b)
{
return a.low_pc < b.low_pc;
});
}
-static void MC_post_process_variables(mc_object_info_t info)
+static void MC_post_process_variables(simgrid::mc::ObjectInformation* info)
{
// Someone needs this to be sorted but who?
std::sort(info->global_variables.begin(), info->global_variables.end(),
MC_compare_variable);
for(simgrid::mc::Variable& variable : info->global_variables)
- if (variable.type_id) {
- auto i = info->types.find(variable.type_id);
- if (i != info->types.end())
- variable.type = &(i->second);
- else
- variable.type = nullptr;
- }
+ if (variable.type_id)
+ variable.type = simgrid::util::find_map_ptr(
+ info->types, variable.type_id);
}
-static void mc_post_process_scope(mc_object_info_t info, mc_frame_t scope)
+static void mc_post_process_scope(simgrid::mc::ObjectInformation* info, simgrid::mc::Frame* scope)
{
if (scope->tag == DW_TAG_inlined_subroutine) {
auto i = info->subprograms.find(scope->abstract_origin_id);
xbt_assert(i != info->subprograms.end(),
"Could not lookup abstract origin %" PRIx64,
- (uint64_t) scope->abstract_origin_id);
+ (std::uint64_t) scope->abstract_origin_id);
scope->name = i->second.name;
}
// Direct:
for (simgrid::mc::Variable& variable : scope->variables)
- if (variable.type_id) {
- auto i = info->types.find(variable.type_id);
- if (i != info->types.end())
- variable.type = &(i->second);
- else
- variable.type = nullptr;
- }
+ if (variable.type_id)
+ variable.type = simgrid::util::find_map_ptr(
+ info->types, variable.type_id);
// Recursive post-processing of nested-scopes:
for (simgrid::mc::Frame& nested_scope : scope->scopes)
/** \brief Fill/lookup the "subtype" field.
*/
-static void MC_resolve_subtype(mc_object_info_t info, mc_type_t type)
+static void MC_resolve_subtype(simgrid::mc::ObjectInformation* info, simgrid::mc::Type* type)
{
if (!type->type_id)
return;
- auto i = info->types.find(type->type_id);
- if (i != info->types.end())
- type->subtype = &(i->second);
- else {
- type->subtype = nullptr;
+ type->subtype = simgrid::util::find_map_ptr(info->types, type->type_id);
+ if (type->subtype == nullptr)
return;
- }
if (type->subtype->byte_size != 0)
return;
if (type->subtype->name.empty())
return;
// Try to find a more complete description of the type:
// We need to fix in order to support C++.
-
- auto j = info->full_types_by_name.find(type->subtype->name);
- if (j != info->full_types_by_name.end())
- type->subtype = j->second;
+ simgrid::mc::Type** subtype = simgrid::util::find_map_ptr(
+ info->full_types_by_name, type->subtype->name);
+ if (subtype)
+ type->subtype = *subtype;
}
-static void MC_post_process_types(mc_object_info_t info)
+static void MC_post_process_types(simgrid::mc::ObjectInformation* info)
{
// Lookup "subtype" field:
for(auto& i : info->types) {
}
/** \brief Finds informations about a given shared object/executable */
-std::shared_ptr<s_mc_object_info_t> MC_find_object_info(
+std::shared_ptr<simgrid::mc::ObjectInformation> MC_find_object_info(
std::vector<simgrid::mc::VmMap> const& maps, const char *name, int executable)
{
- std::shared_ptr<s_mc_object_info_t> result =
- std::make_shared<s_mc_object_info_t>();
+ std::shared_ptr<simgrid::mc::ObjectInformation> result =
+ std::make_shared<simgrid::mc::ObjectInformation>();
if (executable)
- result->flags |= MC_OBJECT_INFO_EXECUTABLE;
+ result->flags |= simgrid::mc::ObjectInformation::Executable;
result->file_name = name;
MC_find_object_address(maps, result.get());
MC_dwarf_get_variables(result.get());
/*************************************************************************/
-void MC_post_process_object_info(mc_process_t process, mc_object_info_t info)
+void MC_post_process_object_info(simgrid::mc::Process* process, simgrid::mc::ObjectInformation* info)
{
for (auto& i : info->types) {
- mc_type_t type = &(i.second);
- mc_type_t subtype = type;
- while (subtype->type == DW_TAG_typedef || subtype->type == DW_TAG_volatile_type
- || subtype->type == DW_TAG_const_type) {
+ simgrid::mc::Type* type = &(i.second);
+ simgrid::mc::Type* subtype = type;
+ while (subtype->type == DW_TAG_typedef
+ || subtype->type == DW_TAG_volatile_type
+ || subtype->type == DW_TAG_const_type)
if (subtype->subtype)
subtype = subtype->subtype;
else
break;
- }
// Resolve full_type:
if (!subtype->name.empty() && subtype->byte_size == 0) {