Logo AND Algorithmique Numérique Distribuée

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