Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Move libdw binding code in its own file
[simgrid.git] / src / mc / mc_location.h
1 /* Copyright (c) 2004-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_LOCATION_H
8 #define SIMGRID_MC_OBJECT_LOCATION_H
9
10 #include <stdint.h>
11
12 #include <vector>
13
14 #include <libunwind.h>
15 #include <dwarf.h>
16 #include <elfutils/libdw.h>
17
18 #include <simgrid_config.h>
19 #include "mc_base.h"
20 #include "mc_forward.hpp"
21 #include "AddressSpace.hpp"
22
23 namespace simgrid {
24 namespace mc {
25
26 typedef struct
27 {
28   uint8_t atom;
29   std::uint64_t number;
30   std::uint64_t number2;
31   std::uint64_t offset;
32 } DwarfInstruction;
33
34 typedef std::vector<DwarfInstruction> DwarfExpression;
35
36 /** \brief A DWARF expression with optional validity contraints */
37 class LocationListEntry {
38 public:
39   DwarfExpression expression;
40   void* lowpc, *highpc;
41
42   LocationListEntry() : lowpc(nullptr), highpc(nullptr) {}
43
44   bool valid_for_ip(unw_word_t ip)
45   {
46     return (this->lowpc == nullptr && this->highpc == nullptr)
47         || (ip >= (unw_word_t) this->lowpc
48             && ip < (unw_word_t) this->highpc);
49   }
50 };
51
52 typedef std::vector<LocationListEntry> LocationList;
53
54 }
55 }
56
57 SG_BEGIN_DECL()
58
59 /** A location is either a location in memory of a register location
60  *
61  *  Usage:
62  *
63  *    * mc_dwarf_resolve_locations or mc_dwarf_resolve_location is used
64  *      to find the location of a given location expression or location list;
65  *
66  *    * mc_get_location_type MUST be used to find the location type;
67  *
68  *    * for MC_LOCATION_TYPE_ADDRESS, memory_address is the resulting address
69  *
70  *    * for MC_LOCATION_TYPE_REGISTER, unw_get_reg(l.cursor, l.register_id, value)
71  *        and unw_get_reg(l.cursor, l.register_id, value) can be used to read/write
72  *        the value.
73  *  </ul>
74  */
75 typedef struct s_mc_location {
76   void* memory_location;
77   unw_cursor_t* cursor;
78   int register_id;
79 } s_mc_location_t, *mc_location_t;
80
81 /** Type of a given location
82  *
83  *  Use `mc_get_location_type(location)` to find the type.
84  * */
85 typedef enum mc_location_type {
86   MC_LOCATION_TYPE_ADDRESS,
87   MC_LOCATION_TYPE_REGISTER
88 } mc_location_type;
89
90 /** Find the type of a location */
91 static inline __attribute__ ((always_inline))
92 enum mc_location_type mc_get_location_type(mc_location_t location) {
93   if (location->cursor) {
94     return MC_LOCATION_TYPE_REGISTER;
95   } else {
96     return MC_LOCATION_TYPE_ADDRESS;
97   }
98 }
99
100 XBT_INTERNAL void mc_dwarf_resolve_location(
101   mc_location_t location, simgrid::mc::DwarfExpression* expression,
102   simgrid::mc::ObjectInformation* object_info, unw_cursor_t* c,
103   void* frame_pointer_address, simgrid::mc::AddressSpace* address_space,
104   int process_index);
105 MC_SHOULD_BE_INTERNAL void mc_dwarf_resolve_locations(
106   mc_location_t location, simgrid::mc::LocationList* locations,
107   simgrid::mc::ObjectInformation* object_info, unw_cursor_t* c,
108   void* frame_pointer_address, simgrid::mc::AddressSpace* address_space,
109   int process_index);
110
111 #define MC_EXPRESSION_STACK_SIZE 64
112
113 #define MC_EXPRESSION_OK 0
114 #define MC_EXPRESSION_E_UNSUPPORTED_OPERATION 1
115 #define MC_EXPRESSION_E_STACK_OVERFLOW 2
116 #define MC_EXPRESSION_E_STACK_UNDERFLOW 3
117 #define MC_EXPRESSION_E_MISSING_STACK_CONTEXT 4
118 #define MC_EXPRESSION_E_MISSING_FRAME_BASE 5
119 #define MC_EXPRESSION_E_NO_BASE_ADDRESS 6
120
121 typedef struct s_mc_expression_state {
122   uintptr_t stack[MC_EXPRESSION_STACK_SIZE];
123   size_t stack_size;
124
125   unw_cursor_t* cursor;
126   void* frame_base;
127   simgrid::mc::AddressSpace* address_space;
128   simgrid::mc::ObjectInformation* object_info;
129   int process_index;
130 } s_mc_expression_state_t, *mc_expression_state_t;
131
132 MC_SHOULD_BE_INTERNAL int mc_dwarf_execute_expression(
133   size_t n, const simgrid::mc::DwarfInstruction* ops, mc_expression_state_t state);
134
135 MC_SHOULD_BE_INTERNAL void* mc_find_frame_base(
136   simgrid::mc::Frame* frame, simgrid::mc::ObjectInformation* object_info, unw_cursor_t* unw_cursor);
137
138 SG_END_DECL()
139
140 namespace simgrid {
141 namespace mc {
142
143 inline
144 int execute(DwarfExpression const& expression, mc_expression_state_t state)
145 {
146   return mc_dwarf_execute_expression(
147     expression.size(), expression.data(), state);
148 }
149
150 }
151 }
152
153 #endif