X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/a57327d86b9fb16acacc71a3359817acd2a2816b..1944008aba63f42a611ec5fd36a681d474cb6e64:/src/mc/inspect/ObjectInformation.cpp diff --git a/src/mc/inspect/ObjectInformation.cpp b/src/mc/inspect/ObjectInformation.cpp index 7d3229ca74..a2440d954b 100644 --- a/src/mc/inspect/ObjectInformation.cpp +++ b/src/mc/inspect/ObjectInformation.cpp @@ -1,16 +1,17 @@ -/* Copyright (c) 2014-2019. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2014-2019. 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 - +#include // PROT_READ and friends #include #include "src/mc/inspect/Frame.hpp" #include "src/mc/inspect/ObjectInformation.hpp" #include "src/mc/inspect/Variable.hpp" +#include "src/mc/mc_private.hpp" +#include "xbt/file.hpp" namespace simgrid { namespace mc { @@ -19,7 +20,7 @@ namespace mc { * (there is no offset) i.e. * \f$\text{virtual address} = \{dwarf address}\f$ * - * For a shared object, the addreses are offset from the begining + * For a shared object, the addresses are offset from the begining * of the shared object (the base address of the mapped shared * object must be used as offset * i.e. \f$\text{virtual address} = \text{shared object base address} @@ -31,7 +32,7 @@ void* ObjectInformation::base_address() const if (this->executable()) return nullptr; - // For an a shared-object (ET_DYN, including position-independant executables) + // For an a shared-object (ET_DYN, including position-independent executables) // the base address is its lowest address: void* result = this->start_exec; if (this->start_rw != nullptr && result > (void*)this->start_rw) @@ -186,5 +187,75 @@ void ObjectInformation::remove_local_variable(const char* var_name, const char* simgrid::mc::remove_local_variable(entry.second, var_name, subprogram_name, entry.second); } +/** @brief Fills the position of the segments (executable, read-only, read/write) */ +// TODO, use the ELF segment information for more robustness +void find_object_address(std::vector const& maps, simgrid::mc::ObjectInformation* result) +{ + const int PROT_RW = PROT_READ | PROT_WRITE; + const int PROT_RX = PROT_READ | PROT_EXEC; + + std::string name = simgrid::xbt::Path(result->file_name).get_base_name(); + + for (size_t i = 0; i < maps.size(); ++i) { + simgrid::xbt::VmMap const& reg = maps[i]; + if (maps[i].pathname.empty()) + continue; + std::string map_basename = simgrid::xbt::Path(maps[i].pathname).get_base_name(); + if (map_basename != name) + continue; + + // This is the non-GNU_RELRO-part of the data segment: + if (reg.prot == PROT_RW) { + xbt_assert(not result->start_rw, "Multiple read-write segments for %s, not supported", maps[i].pathname.c_str()); + result->start_rw = (char*)reg.start_addr; + result->end_rw = (char*)reg.end_addr; + + // The next VMA might be end of the data segment: + if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW && + maps[i + 1].start_addr == reg.end_addr) + result->end_rw = (char*)maps[i + 1].end_addr; + } + + // This is the text segment: + else if (reg.prot == PROT_RX) { + xbt_assert(not result->start_exec, "Multiple executable segments for %s, not supported", + maps[i].pathname.c_str()); + result->start_exec = (char*)reg.start_addr; + result->end_exec = (char*)reg.end_addr; + + // The next VMA might be end of the data segment: + if (i + 1 < maps.size() && maps[i + 1].pathname.empty() && maps[i + 1].prot == PROT_RW && + maps[i + 1].start_addr == reg.end_addr) { + result->start_rw = (char*)maps[i + 1].start_addr; + result->end_rw = (char*)maps[i + 1].end_addr; + } + } + + // This is the GNU_RELRO-part of the data segment: + else if (reg.prot == PROT_READ) { + xbt_assert(not result->start_ro, + "Multiple read-only segments for %s, not supported. Compiling with the following may help: -Wl,-z " + "-Wl,noseparate-code", + maps[i].pathname.c_str()); + result->start_ro = (char*)reg.start_addr; + result->end_ro = (char*)reg.end_addr; + } + } + + result->start = result->start_rw; + if ((const void*)result->start_ro < result->start) + result->start = result->start_ro; + if ((const void*)result->start_exec < result->start) + result->start = result->start_exec; + + result->end = result->end_rw; + if (result->end_ro && (const void*)result->end_ro > result->end) + result->end = result->end_ro; + if (result->end_exec && (const void*)result->end_exec > result->end) + result->end = result->end_exec; + + xbt_assert(result->start_exec || result->start_rw || result->start_ro); +} + } // namespace mc } // namespace simgrid