Logo AND Algorithmique Numérique Distribuée

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