-/* Copyright (c) 2008-2019. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2008-2020. 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 "src/mc/inspect/Variable.hpp"
#include "src/mc/inspect/mc_dwarf.hpp"
#include "src/mc/mc_private.hpp"
-#include "src/mc/remote/RemoteClient.hpp"
+#include "src/mc/remote/RemoteSimulation.hpp"
#include <cinttypes>
#include <cstdint>
/** @brief Process a DIE
*
- * @param info the resulting object fot the library/binary file (output)
+ * @param info the resulting object for the library/binary file (output)
* @param die the current DIE
* @param unit the DIE of the compile unit of the current DIE
* @param frame containing frame if any
/** @brief Calls MC_dwarf_handle_die on all children of the given die
*
- * @param info the resulting object fot the library/binary file (output)
+ * @param info the resulting object for the library/binary file (output)
* @param die the current DIE
* @param unit the DIE of the compile unit of the current DIE
* @param frame containing frame if any
/** @brief Handle a variable (DW_TAG_variable or other)
*
- * @param info the resulting object fot the library/binary file (output)
+ * @param info the resulting object for the library/binary file (output)
* @param die the current DIE
* @param unit the DIE of the compile unit of the current DIE
* @param frame containing frame if any
*/
-static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
+static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, const Dwarf_Die* unit,
simgrid::mc::Frame* frame, const char* ns);
/** @brief Get the DW_TAG_type of the DIE
static TagClass classify_tag(int tag)
{
switch (tag) {
-
case DW_TAG_array_type:
case DW_TAG_class_type:
case DW_TAG_enumeration_type:
*/
inline XBT_PRIVATE const char* tagname(Dwarf_Die* die)
{
- return simgrid::dwarf::tagname(dwarf_tag(die));
+ return tagname(dwarf_tag(die));
}
} // namespace dwarf
return 0;
dwarf_attr_integrate(die, attribute, &attr);
Dwarf_Die subtype_die;
- if (dwarf_formref_die(&attr, &subtype_die) == nullptr)
- xbt_die("Could not find DIE");
+ xbt_assert(dwarf_formref_die(&attr, &subtype_die) != nullptr, "Could not find DIE");
return dwarf_dieoffset(&subtype_die);
}
return 0;
dwarf_attr_integrate(die, DW_AT_type, &attr);
Dwarf_Die subtype_die;
- if (dwarf_formref_die(&attr, &subtype_die) == nullptr)
- xbt_die("Could not find DIE");
+ xbt_assert(dwarf_formref_die(&attr, &subtype_die) != nullptr, "Could not find DIE");
return dwarf_dieoffset(&subtype_die);
}
return false;
bool result;
- if (dwarf_formflag(&attr, &result))
- xbt_die("Unexpected form for attribute %s", simgrid::dwarf::attrname(attribute));
+ xbt_assert(not dwarf_formflag(&attr, &result), "Unexpected form for attribute %s",
+ simgrid::dwarf::attrname(attribute));
return result;
}
int result = 1;
Dwarf_Die child;
- int res;
- for (res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) {
+ for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) {
int child_tag = dwarf_tag(&child);
if (child_tag == DW_TAG_subrange_type || child_tag == DW_TAG_enumeration_type)
result *= MC_dwarf_subrange_element_count(&child, unit);
* @param member the member of the type
* @param child DIE of the member (DW_TAG_member)
*/
-static void MC_dwarf_fill_member_location(simgrid::mc::Type* type, simgrid::mc::Member* member, Dwarf_Die* child)
+static void MC_dwarf_fill_member_location(const simgrid::mc::Type* type, simgrid::mc::Member* member, Dwarf_Die* child)
{
- if (dwarf_hasattr(child, DW_AT_data_bit_offset))
- xbt_die("Can't groke DW_AT_data_bit_offset.");
+ xbt_assert(not dwarf_hasattr(child, DW_AT_data_bit_offset), "Can't groke DW_AT_data_bit_offset.");
if (not dwarf_hasattr_integrate(child, DW_AT_data_member_location)) {
if (type->type == DW_TAG_union_type)
{
Dwarf_Op* expr;
size_t 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());
+ xbt_assert(not dwarf_getlocation(&attr, &expr, &len),
+ "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::dwarf::DwarfExpression(expr, expr + len);
break;
}
// Offset from the base address of the object:
{
Dwarf_Word offset;
- if (not dwarf_formudata(&attr, &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.c_str());
+ xbt_assert(not dwarf_formudata(&attr, &offset), "Cannot get %s location <%" PRIx64 ">%s",
+ MC_dwarf_attr_integrate_string(child, DW_AT_name), (uint64_t)type->id, type->name.c_str());
+ member->offset(offset);
break;
}
* @param unit DIE of the compilation unit containing the type DIE
* @param type the type
*/
-static void MC_dwarf_add_members(simgrid::mc::ObjectInformation* /*info*/, Dwarf_Die* die, Dwarf_Die* /*unit*/,
- simgrid::mc::Type* type)
+static void MC_dwarf_add_members(const simgrid::mc::ObjectInformation* /*info*/, Dwarf_Die* die,
+ const Dwarf_Die* /*unit*/, simgrid::mc::Type* type)
{
- int res;
Dwarf_Die child;
xbt_assert(type->members.empty());
- for (res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) {
+ for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child)) {
int tag = dwarf_tag(&child);
if (tag == DW_TAG_member || tag == DW_TAG_inheritance) {
-
// Skip declarations:
if (MC_dwarf_attr_flag(&child, DW_AT_declaration, false))
continue;
member.byte_size = MC_dwarf_attr_integrate_uint(&child, DW_AT_byte_size, 0);
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.");
+ xbt_assert(not dwarf_hasattr(&child, DW_AT_data_bit_offset), "Can't groke DW_AT_data_bit_offset.");
MC_dwarf_fill_member_location(type, &member, &child);
- if (not 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());
+ xbt_assert(member.type_id, "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));
}
static int mc_anonymous_variable_index = 0;
static std::unique_ptr<simgrid::mc::Variable> MC_die_to_variable(simgrid::mc::ObjectInformation* info, Dwarf_Die* die,
- Dwarf_Die* /*unit*/, simgrid::mc::Frame* frame,
- const char* ns)
+ const Dwarf_Die* /*unit*/,
+ const simgrid::mc::Frame* frame, const char* ns)
{
// Skip declarations:
if (MC_dwarf_attr_flag(die, DW_AT_declaration, false))
// 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());
- variable->id = dwarf_dieoffset(die);
- variable->global = frame == nullptr; // Can be override base on DW_AT_location
- variable->object_info = info;
+ auto variable = std::make_unique<simgrid::mc::Variable>();
+ variable->id = dwarf_dieoffset(die);
+ variable->global = frame == nullptr; // Can be override base on DW_AT_location
+ variable->object_info = info;
const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
if (name)
{
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->id, variable->name.c_str());
- }
+ xbt_assert(not dwarf_getlocation(&attr_location, &expr, &len),
+ "Could not read location expression in DW_AT_location "
+ "of variable <%" PRIx64 ">%s",
+ (uint64_t)variable->id, variable->name.c_str());
if (len == 1 && expr[0].atom == DW_OP_addr) {
variable->global = true;
- uintptr_t offset = (uintptr_t)expr[0].number;
- uintptr_t base = (uintptr_t)info->base_address();
- variable->address = (void*)(base + offset);
+ auto offset = static_cast<uintptr_t>(expr[0].number);
+ auto base = reinterpret_cast<uintptr_t>(info->base_address());
+ variable->address = reinterpret_cast<void*>(base + offset);
} else
variable->location_list = {
simgrid::dwarf::LocationListEntry(simgrid::dwarf::DwarfExpression(expr, expr + len))};
return variable;
}
-static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Die* unit,
+static void MC_dwarf_handle_variable_die(simgrid::mc::ObjectInformation* info, Dwarf_Die* die, const Dwarf_Die* unit,
simgrid::mc::Frame* frame, const char* ns)
{
std::unique_ptr<simgrid::mc::Variable> variable = MC_die_to_variable(info, die, unit, frame, ns);
// This is the base address for DWARF addresses.
// Relocated addresses are offset from this base address.
// See DWARF4 spec 7.5
- std::uint64_t base = (std::uint64_t)info->base_address();
+ auto base = reinterpret_cast<std::uint64_t>(info->base_address());
// TODO, support DW_AT_ranges
uint64_t low_pc = MC_dwarf_attr_integrate_addr(die, DW_AT_low_pc);
- frame.range.begin() = low_pc ? (std::uint64_t)base + low_pc : 0;
+ frame.range.begin() = low_pc ? base + low_pc : 0;
if (low_pc) {
// DW_AT_high_pc:
Dwarf_Attribute attr;
- if (not dwarf_attr_integrate(die, DW_AT_high_pc, &attr))
- xbt_die("Missing DW_AT_high_pc matching with DW_AT_low_pc");
+ xbt_assert(dwarf_attr_integrate(die, DW_AT_high_pc, &attr), "Missing DW_AT_high_pc matching with DW_AT_low_pc");
Dwarf_Sword offset;
Dwarf_Addr high_pc;
switch (simgrid::dwarf::classify_form(dwarf_whatform(&attr))) {
-
- // DW_AT_high_pc if an offset from the low_pc:
+ // DW_AT_high_pc if an offset from the low_pc:
case simgrid::dwarf::FormClass::Constant:
- if (dwarf_formsdata(&attr, &offset) != 0)
- xbt_die("Could not read constant");
+ xbt_assert(dwarf_formsdata(&attr, &offset) == 0, "Could not read constant");
frame.range.end() = frame.range.begin() + offset;
break;
// DW_AT_high_pc is a relocatable address:
case simgrid::dwarf::FormClass::Address:
- if (dwarf_formaddr(&attr, &high_pc) != 0)
- xbt_die("Could not read address");
+ xbt_assert(dwarf_formaddr(&attr, &high_pc) == 0, "Could not read address");
frame.range.end() = base + high_pc;
break;
simgrid::mc::Frame* frame, const char* ns)
{
const char* name = MC_dwarf_attr_integrate_string(die, DW_AT_name);
- if (frame)
- xbt_die("Unexpected namespace in a subprogram");
+ xbt_assert(not frame, "Unexpected namespace in a subprogram");
char* new_ns = ns == nullptr ? xbt_strdup(name) : bprintf("%s::%s", ns, name);
MC_dwarf_handle_children(info, die, unit, frame, new_ns);
xbt_free(new_ns);
{
// For each child DIE:
Dwarf_Die child;
- int res;
- for (res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child))
+ for (int res = dwarf_child(die, &child); res == 0; res = dwarf_siblingof(&child, &child))
MC_dwarf_handle_die(info, &child, unit, frame, ns);
}
int tag = dwarf_tag(die);
simgrid::dwarf::TagClass klass = simgrid::dwarf::classify_tag(tag);
switch (klass) {
-
- // Type:
+ // Type:
case simgrid::dwarf::TagClass::Type:
MC_dwarf_handle_type_die(info, die, unit, frame, ns);
break;
static Elf64_Half get_type(Elf* elf)
{
- Elf64_Ehdr* ehdr64 = elf64_getehdr(elf);
+ const Elf64_Ehdr* ehdr64 = elf64_getehdr(elf);
if (ehdr64)
return ehdr64->e_type;
- Elf32_Ehdr* ehdr32 = elf32_getehdr(elf);
+ const Elf32_Ehdr* ehdr32 = elf32_getehdr(elf);
if (ehdr32)
return ehdr32->e_type;
xbt_die("Could not get ELF heeader");
// found in a PT_NOTE entry in the program header table.
size_t phnum;
- if (elf_getphdrnum(elf, &phnum) != 0)
- xbt_die("Could not read program headers");
+ xbt_assert(elf_getphdrnum(elf, &phnum) == 0, "Could not read program headers");
// Iterate over the program headers and find the PT_NOTE ones:
for (size_t i = 0; i < phnum; ++i) {
GElf_Phdr phdr_temp;
- GElf_Phdr* phdr = gelf_getphdr(elf, i, &phdr_temp);
+ const GElf_Phdr* phdr = gelf_getphdr(elf, i, &phdr_temp);
if (phdr->p_type != PT_NOTE)
continue;
memcmp((char*)data->d_buf + name_pos, "GNU", sizeof("GNU")) == 0) {
XBT_DEBUG("Found GNU/NT_GNU_BUILD_ID note");
char* start = (char*)data->d_buf + desc_pos;
- char* end = (char*)start + nhdr.n_descsz;
+ char* end = start + nhdr.n_descsz;
return std::vector<char>(start, end);
}
}
return std::string();
}
-/** @brief Populate the debugging informations of the given ELF object
+/** @brief Populate the debugging information of the given ELF object
*
* Read the DWARf information of the EFFL object and populate the
* lists of types, variables, functions.
*/
static void MC_load_dwarf(simgrid::mc::ObjectInformation* info)
{
- if (elf_version(EV_CURRENT) == EV_NONE)
- xbt_die("libelf initialization error");
+ xbt_assert(elf_version(EV_CURRENT) != EV_NONE, "libelf initialization error");
// Open the ELF file:
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());
+ xbt_assert(fd >= 0, "Could not open file %s", info->file_name.c_str());
Elf* elf = elf_begin(fd, ELF_C_READ, nullptr);
- if (elf == nullptr)
- xbt_die("Not an ELF file");
+ xbt_assert(elf != nullptr, "Not an ELF file");
Elf_Kind kind = elf_kind(elf);
- if (kind != ELF_K_ELF)
- xbt_die("Not an ELF file");
+ xbt_assert(kind == ELF_K_ELF, "Not an ELF file");
// Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN`:
Elf64_Half type = get_type(elf);
dwarf_end(dwarf);
// If there was no DWARF in the file, try to find it in a separate file.
- // Different methods might be used to store the DWARF informations:
+ // Different methods might be used to store the DWARF information:
// * GNU NT_GNU_BUILD_ID
// * .gnu_debuglink
// See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
// Find the debug file using the build id:
std::string debug_file = find_by_build_id(build_id);
- if (debug_file.empty()) {
- std::string hex = to_hex(build_id);
- xbt_die("Missing debug info for %s with build-id %s\n"
- "You might want to install the suitable debugging package.\n",
- info->file_name.c_str(), hex.c_str());
- }
+ xbt_assert(not debug_file.empty(),
+ "Missing debug info for %s with build-id %s\n"
+ "You might want to install the suitable debugging package.\n",
+ info->file_name.c_str(), to_hex(build_id).c_str());
// Load the DWARF info from this file:
XBT_DEBUG("Load DWARF for %s from %s", info->file_name.c_str(), debug_file.c_str());
fd = open(debug_file.c_str(), O_RDONLY);
- if (fd < 0)
- xbt_die("Could not open file %s", debug_file.c_str());
+ xbt_assert(fd >= 0, "Could not open file %s", debug_file.c_str());
dwarf = dwarf_begin(fd, DWARF_C_READ);
- if (dwarf == nullptr)
- xbt_die("No DWARF info in %s for %s", debug_file.c_str(), info->file_name.c_str());
+ xbt_assert(dwarf != nullptr, "No DWARF info in %s for %s", debug_file.c_str(), info->file_name.c_str());
read_dwarf_info(info, dwarf);
dwarf_end(dwarf);
close(fd);
static void mc_post_process_scope(simgrid::mc::ObjectInformation* info, simgrid::mc::Frame* scope)
{
-
if (scope->tag == DW_TAG_inlined_subroutine) {
// Attach correct namespaced name in inlined subroutine:
auto i = info->subprograms.find(scope->abstract_origin_id);
namespace simgrid {
namespace mc {
-/** @brief Finds informations about a given shared object/executable */
-std::shared_ptr<simgrid::mc::ObjectInformation> createObjectInformation(std::vector<simgrid::xbt::VmMap> const& maps,
- const char* name)
+/** @brief Finds information about a given shared object/executable */
+std::shared_ptr<ObjectInformation> createObjectInformation(std::vector<xbt::VmMap> const& maps, const char* name)
{
- std::shared_ptr<simgrid::mc::ObjectInformation> result = std::make_shared<simgrid::mc::ObjectInformation>();
- result->file_name = name;
+ auto result = std::make_shared<ObjectInformation>();
+ result->file_name = name;
simgrid::mc::find_object_address(maps, result.get());
MC_load_dwarf(result.get());
MC_post_process_variables(result.get());
/*************************************************************************/
-void postProcessObjectInformation(simgrid::mc::RemoteClient* process, simgrid::mc::ObjectInformation* info)
+void postProcessObjectInformation(const RemoteSimulation* process, ObjectInformation* info)
{
for (auto& t : info->types) {
-
- simgrid::mc::Type* type = &(t.second);
- simgrid::mc::Type* subtype = type;
+ Type* type = &(t.second);
+ Type* subtype = type;
while (subtype->type == DW_TAG_typedef || subtype->type == DW_TAG_volatile_type ||
subtype->type == DW_TAG_const_type)
if (subtype->subtype)