Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of framagit.org:simgrid/simgrid
[simgrid.git] / src / mc / inspect / ObjectInformation.hpp
1 /* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_MC_OBJECT_INFORMATION_HPP
7 #define SIMGRID_MC_OBJECT_INFORMATION_HPP
8
9 #include <memory>
10 #include <string>
11 #include <unordered_map>
12 #include <vector>
13
14 #include "src/mc/inspect/Frame.hpp"
15 #include "src/mc/inspect/Type.hpp"
16 #include "src/mc/mc_forward.hpp"
17 #include "src/xbt/memory_map.hpp"
18
19 #include "src/smpi/include/private.hpp"
20
21 namespace simgrid::mc {
22
23 /** An entry in the functions index
24  *
25  *  See the code of ObjectInformation::find_function.
26  */
27 struct FunctionIndexEntry {
28   void* low_pc;
29   simgrid::mc::Frame* function;
30 };
31
32 /** Information about an ELF module (executable or shared object)
33  *
34  *  This contains all the information we need about an executable or
35  *  shared-object in the model-checked process:
36  *
37  *  - where it is located in the virtual address space;
38  *
39  *  - where are located its different memory mappings in the the
40  *    virtual address space;
41  *
42  *  - all the debugging (DWARF) information
43  *    - types,
44  *    - location of the functions and their local variables,
45  *    - global variables,
46  *
47  *  - etc.
48  */
49 class ObjectInformation {
50   bool dwarf_loaded = false; // Lazily loads the dwarf info
51
52 public:
53   void ensure_dwarf_loaded(); // Used by functions that need the dwarf
54   ObjectInformation() = default;
55
56   // Not copiable:
57   ObjectInformation(ObjectInformation const&) = delete;
58   ObjectInformation& operator=(ObjectInformation const&) = delete;
59
60   // Flag:
61   static const int Executable = 1;
62
63   /** Bitfield of flags */
64   int flags = 0;
65   std::string file_name;
66   const void* start = nullptr;
67   const void* end   = nullptr;
68   // Location of its text segment:
69   char* start_exec = nullptr;
70   char* end_exec   = nullptr;
71   // Location of the read-only part of its data segment:
72   char* start_rw = nullptr;
73   char* end_rw   = nullptr;
74   // Location of the read/write part of its data segment:
75   char* start_ro = nullptr;
76   char* end_ro   = nullptr;
77
78   /** All of its subprograms indexed by their address */
79   std::unordered_map<std::uint64_t, simgrid::mc::Frame> subprograms;
80
81   /** Index of functions by instruction address
82    *
83    * We need to efficiently find the function from any given instruction
84    * address inside its range. This index is sorted by low_pc
85    *
86    * The entries are sorted by low_pc and a binary search can be used to look
87    * them up. In order to have a better cache locality, we only keep the
88    * information we need for the lookup in this vector. We could probably
89    * replace subprograms by an ordered vector of Frame and replace this one b
90    * a parallel `std::vector<void*>`.
91    */
92   std::vector<FunctionIndexEntry> functions_index;
93
94   std::vector<simgrid::mc::Variable> global_variables;
95
96   /** Types indexed by DWARF ID */
97   std::unordered_map<std::uint64_t, simgrid::mc::Type> types;
98
99   /** Types indexed by name
100    *
101    *  Different compilation units have their separate type definitions
102    *  (for the same type). When we find an opaque type in one compilation unit,
103    *  we use this in order to try to find its definition in another compilation
104    *  unit.
105    */
106   std::unordered_map<std::string, simgrid::mc::Type*> full_types_by_name;
107
108   /** Whether this module is an executable
109    *
110    *  More precisely we check if this is an ET_EXE ELF. These ELF files
111    *  use fixed addresses instead of base-address relative addresses.
112    *  Position independent executables are in fact ET_DYN.
113    */
114   bool executable() const { return this->flags & simgrid::mc::ObjectInformation::Executable; }
115
116   /** Base address of the module
117    *
118    *  All the location information in ELF and DWARF are expressed as an offsets
119    *  from this base address:
120    *
121    *  - location of the functions and global variables
122    *
123    *  - the DWARF instruction `OP_addr` pushes this on the DWARF stack.
124    **/
125   void* base_address() const;
126
127   /** Find a function by instruction address
128    *
129    *  Loads the dwarf information on need.
130    *
131    *  @param ip instruction address
132    *  @return corresponding function (if any) or nullptr
133    */
134   simgrid::mc::Frame* find_function(const void* ip);
135
136   /** Find a global variable by name
137    *
138    *  Loads the dwarf information on need.
139    *
140    *  This is used to ignore global variables and to find well-known variables
141    *  (`__mmalloc_default_mdp`).
142    *
143    *  @param name scopes name of the global variable (`myproject::Foo::count`)
144    *  @return corresponding variable (if any) or nullptr
145    */
146   const simgrid::mc::Variable* find_variable(const char* name);
147
148   /** Remove a global variable (in order to ignore it)
149    *
150    *  This is used to ignore a global variable for the snapshot comparison.
151    */
152   void remove_global_variable(const char* name);
153
154   /** Remove a local variables (in order to ignore it)
155    *
156    *  @param name Name of the local variable
157    *  @param scope scopes name name of the function (myproject::Foo::count) or null for all functions
158    */
159   void remove_local_variable(const char* name, const char* scope);
160 };
161
162 XBT_PRIVATE std::shared_ptr<ObjectInformation> createObjectInformation(std::vector<simgrid::xbt::VmMap> const& maps,
163                                                                        const char* name);
164
165 /** Augment the current module with information about the other ones */
166 XBT_PRIVATE void postProcessObjectInformation(const simgrid::mc::RemoteProcessMemory* process,
167                                               simgrid::mc::ObjectInformation* info);
168 } // namespace simgrid::mc
169
170 #endif