Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update copyright notices
[simgrid.git] / src / mc / ObjectInformation.cpp
1 #include "mc/Frame.hpp"
2 #include "mc/ObjectInformation.hpp"
3 #include "mc/Variable.hpp"
4
5 namespace simgrid {
6 namespace mc {
7
8 ObjectInformation::ObjectInformation()
9 {
10   this->flags = 0;
11   this->start = nullptr;
12   this->end = nullptr;
13   this->start_exec = nullptr;
14   this->end_exec = nullptr;
15   this->start_rw = nullptr;
16   this->end_rw = nullptr;
17   this->start_ro = nullptr;
18   this->end_ro = nullptr;
19 }
20
21 /** Find the DWARF offset for this ELF object
22  *
23  *  An offset is applied to address found in DWARF:
24  *
25  *  * for an executable obejct, addresses are virtual address
26  *    (there is no offset) i.e.
27  *    \f$\text{virtual address} = \{dwarf address}\f$;
28  *
29  *  * for a shared object, the addreses are offset from the begining
30  *    of the shared object (the base address of the mapped shared
31  *    object must be used as offset
32  *    i.e. \f$\text{virtual address} = \text{shared object base address}
33  *             + \text{dwarf address}\f$.
34  */
35 void *ObjectInformation::base_address() const
36 {
37   if (this->executable())
38     return nullptr;
39
40   void *result = this->start_exec;
41   if (this->start_rw != NULL && result > (void *) this->start_rw)
42     result = this->start_rw;
43   if (this->start_ro != NULL && result > (void *) this->start_ro)
44     result = this->start_ro;
45   return result;
46 }
47
48 /* Find a function by instruction pointer */
49 simgrid::mc::Frame* ObjectInformation::find_function(const void *ip) const
50 {
51   /* This is implemented by binary search on a sorted array.
52    *
53    * We do quite a lot ot those so we want this to be cache efficient.
54    * We pack the only information we need in the index entries in order
55    * to successfully do the binary search. We do not need the high_pc
56    * during the binary search (only at the end) so it is not included
57    * in the index entry. We could use parallel arrays as well.
58    *
59    * We cannot really use the std:: alogrithm for this.
60    * We could use std::binary_search by including the high_pc inside
61    * the FunctionIndexEntry.
62    */
63   const simgrid::mc::FunctionIndexEntry* base =
64     this->functions_index.data();
65   int i = 0;
66   int j = this->functions_index.size() - 1;
67   while (j >= i) {
68     int k = i + ((j - i) / 2);
69
70     /* In most of the search, we do not dereference the base[k].function.
71      * This way the memory accesses are located in the base[k] array. */
72     if (ip < base[k].low_pc)
73       j = k - 1;
74     else if (k < j && ip >= base[k + 1].low_pc)
75       i = k + 1;
76
77     /* At this point, the search is over.
78      * Either we have found the correct function or we do not know
79      * any function corresponding to this instruction address.
80      * Only at the point do we derefernce the function pointer. */
81     else if (ip < base[k].function->high_pc)
82       return base[k].function;
83     else
84       return nullptr;
85   }
86   return nullptr;
87 }
88
89 simgrid::mc::Variable* ObjectInformation::find_variable(const char* name) const
90 {
91   for (simgrid::mc::Variable& variable : this->global_variables)
92     if(variable.name == name)
93       return &variable;
94   return nullptr;
95 }
96
97 }
98 }