+/** @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_load_dwarf(simgrid::mc::ObjectInformation* info)
+{
+ if (elf_version(EV_CURRENT) == EV_NONE)
+ xbt_die("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());
+ Elf* elf = elf_begin(fd, ELF_C_READ, nullptr);
+ if (elf == nullptr)
+ xbt_die("Not an ELF file");
+ Elf_Kind kind = elf_kind(elf);
+ if (kind != ELF_K_ELF)
+ xbt_die("Not an ELF file");
+
+ // Remember if this is a `ET_EXEC` (fixed location) or `ET_DYN`:
+ Elf64_Half type = get_type(elf);
+ if (type == ET_EXEC)
+ info->flags |= simgrid::mc::ObjectInformation::Executable;
+
+ // Read DWARF debug information in the file:
+ Dwarf* dwarf = dwarf_begin_elf (elf, DWARF_C_READ, nullptr);
+ if (dwarf != nullptr) {
+ read_dwarf_info(info, dwarf);
+ dwarf_end(dwarf);
+ elf_end(elf);
+ close(fd);
+ return;
+ }
+ 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:
+ // * GNU NT_GNU_BUILD_ID
+ // * .gnu_debuglink
+ // See https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
+ // for reference of what we are doing.
+
+ // Try with NT_GNU_BUILD_ID: we find the build ID in the ELF file and then
+ // use this ID to find the file in some known locations in the filesystem.
+ std::vector<char> build_id = get_build_id(elf);
+ if (not build_id.empty()) {
+ elf_end(elf);
+ close(fd);
+
+ // 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());
+ }
+
+ // 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());
+ Dwarf* 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());
+ read_dwarf_info(info, dwarf);
+ dwarf_end(dwarf);
+ close(fd);
+ return;
+ }
+
+ // TODO, try to find DWARF info using .gnu_debuglink.
+
+ elf_end(elf);
+ close(fd);
+ xbt_die("Debugging information not found for %s\n"
+ "Try recompiling with -g\n",
+ info->file_name.c_str());
+}
+
+// ***** Functions index
+