Logo AND Algorithmique Numérique Distribuée

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