Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
39654 views
1
//===-- HexagonDYLDRendezvous.h ---------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H
10
#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H
11
12
#include <limits.h>
13
#include <list>
14
#include <map>
15
#include <string>
16
17
#include "lldb/lldb-defines.h"
18
#include "lldb/lldb-types.h"
19
20
namespace lldb_private {
21
class Process;
22
}
23
24
/// \class HexagonDYLDRendezvous
25
/// Interface to the runtime linker.
26
///
27
/// A structure is present in a processes memory space which is updated by the
28
/// runtime liker each time a module is loaded or unloaded. This class
29
/// provides an interface to this structure and maintains a consistent
30
/// snapshot of the currently loaded modules.
31
class HexagonDYLDRendezvous {
32
33
// This structure is used to hold the contents of the debug rendezvous
34
// information (struct r_debug) as found in the inferiors memory. Note that
35
// the layout of this struct is not binary compatible, it is simply large
36
// enough to hold the information on both 32 and 64 bit platforms.
37
struct Rendezvous {
38
uint64_t version = 0;
39
lldb::addr_t map_addr = LLDB_INVALID_ADDRESS;
40
lldb::addr_t brk = LLDB_INVALID_ADDRESS;
41
uint64_t state = 0;
42
lldb::addr_t ldbase = 0;
43
44
Rendezvous() = default;
45
};
46
47
public:
48
// Various metadata supplied by the inferior's threading library to describe
49
// the per-thread state.
50
struct ThreadInfo {
51
bool valid; // whether we read valid metadata
52
uint32_t dtv_offset; // offset of DTV pointer within pthread
53
uint32_t dtv_slot_size; // size of one DTV slot
54
uint32_t modid_offset; // offset of module ID within link_map
55
uint32_t tls_offset; // offset of TLS pointer within DTV slot
56
};
57
58
HexagonDYLDRendezvous(lldb_private::Process *process);
59
60
/// Update the internal snapshot of runtime linker rendezvous and recompute
61
/// the currently loaded modules.
62
///
63
/// This method should be called once one start up, then once each time the
64
/// runtime linker enters the function given by GetBreakAddress().
65
///
66
/// \returns true on success and false on failure.
67
///
68
/// \see GetBreakAddress().
69
bool Resolve();
70
71
/// \returns true if this rendezvous has been located in the inferiors
72
/// address space and false otherwise.
73
bool IsValid();
74
75
/// \returns the address of the rendezvous structure in the inferiors
76
/// address space.
77
lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
78
79
/// Provide the dyld structure address
80
void SetRendezvousAddress(lldb::addr_t);
81
82
/// \returns the version of the rendezvous protocol being used.
83
uint64_t GetVersion() const { return m_current.version; }
84
85
/// \returns address in the inferiors address space containing the linked
86
/// list of shared object descriptors.
87
lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
88
89
/// A breakpoint should be set at this address and Resolve called on each
90
/// hit.
91
///
92
/// \returns the address of a function called by the runtime linker each
93
/// time a module is loaded/unloaded, or about to be loaded/unloaded.
94
///
95
/// \see Resolve()
96
lldb::addr_t GetBreakAddress() const { return m_current.brk; }
97
98
/// In hexagon it is possible that we can know the dyld breakpoint without
99
/// having to find it from the rendezvous structure
100
///
101
void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
102
103
/// Returns the current state of the rendezvous structure.
104
uint64_t GetState() const { return m_current.state; }
105
106
/// \returns the base address of the runtime linker in the inferiors address
107
/// space.
108
lldb::addr_t GetLDBase() const { return m_current.ldbase; }
109
110
/// \returns the thread layout metadata from the inferiors thread library.
111
const ThreadInfo &GetThreadInfo();
112
113
/// \returns true if modules have been loaded into the inferior since the
114
/// last call to Resolve().
115
bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
116
117
/// \returns true if modules have been unloaded from the inferior since the
118
/// last call to Resolve().
119
bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
120
121
void DumpToLog(lldb_private::Log *log) const;
122
123
/// Constants describing the state of the rendezvous.
124
///
125
/// \see GetState().
126
enum RendezvousState {
127
eConsistent = 0,
128
eAdd,
129
eDelete,
130
};
131
132
/// Structure representing the shared objects currently loaded into the
133
/// inferior process.
134
///
135
/// This object is a rough analogue to the struct link_map object which
136
/// actually lives in the inferiors memory.
137
struct SOEntry {
138
lldb::addr_t link_addr; ///< Address of this link_map.
139
lldb::addr_t base_addr; ///< Base address of the loaded object.
140
lldb::addr_t path_addr; ///< String naming the shared object.
141
lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
142
lldb::addr_t next; ///< Address of next so_entry.
143
lldb::addr_t prev; ///< Address of previous so_entry.
144
std::string path; ///< File name of shared object.
145
146
SOEntry() { clear(); }
147
148
bool operator==(const SOEntry &entry) { return this->path == entry.path; }
149
150
void clear() {
151
link_addr = 0;
152
base_addr = 0;
153
path_addr = 0;
154
dyn_addr = 0;
155
next = 0;
156
prev = 0;
157
path.clear();
158
}
159
};
160
161
protected:
162
typedef std::list<SOEntry> SOEntryList;
163
164
public:
165
typedef SOEntryList::const_iterator iterator;
166
167
/// Iterators over all currently loaded modules.
168
iterator begin() const { return m_soentries.begin(); }
169
iterator end() const { return m_soentries.end(); }
170
171
/// Iterators over all modules loaded into the inferior since the last call
172
/// to Resolve().
173
iterator loaded_begin() const { return m_added_soentries.begin(); }
174
iterator loaded_end() const { return m_added_soentries.end(); }
175
176
/// Iterators over all modules unloaded from the inferior since the last
177
/// call to Resolve().
178
iterator unloaded_begin() const { return m_removed_soentries.begin(); }
179
iterator unloaded_end() const { return m_removed_soentries.end(); }
180
181
protected:
182
lldb_private::Process *m_process;
183
184
// Cached copy of executable pathname
185
char m_exe_path[PATH_MAX];
186
187
/// Location of the r_debug structure in the inferiors address space.
188
lldb::addr_t m_rendezvous_addr;
189
190
/// Current and previous snapshots of the rendezvous structure.
191
Rendezvous m_current;
192
Rendezvous m_previous;
193
194
/// List of SOEntry objects corresponding to the current link map state.
195
SOEntryList m_soentries;
196
197
/// List of SOEntry's added to the link map since the last call to
198
/// Resolve().
199
SOEntryList m_added_soentries;
200
201
/// List of SOEntry's removed from the link map since the last call to
202
/// Resolve().
203
SOEntryList m_removed_soentries;
204
205
/// Threading metadata read from the inferior.
206
ThreadInfo m_thread_info;
207
208
/// Reads an unsigned integer of \p size bytes from the inferior's address
209
/// space starting at \p addr.
210
///
211
/// \returns addr + size if the read was successful and false otherwise.
212
lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
213
214
/// Reads an address from the inferior's address space starting at \p addr.
215
///
216
/// \returns addr + target address size if the read was successful and
217
/// 0 otherwise.
218
lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
219
220
/// Reads a null-terminated C string from the memory location starting at @p
221
/// addr.
222
std::string ReadStringFromMemory(lldb::addr_t addr);
223
224
/// Reads an SOEntry starting at \p addr.
225
bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
226
227
/// Updates the current set of SOEntries, the set of added entries, and the
228
/// set of removed entries.
229
bool UpdateSOEntries();
230
231
bool UpdateSOEntriesForAddition();
232
233
bool UpdateSOEntriesForDeletion();
234
235
/// Reads the current list of shared objects according to the link map
236
/// supplied by the runtime linker.
237
bool TakeSnapshot(SOEntryList &entry_list);
238
239
enum PThreadField { eSize, eNElem, eOffset };
240
241
bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
242
};
243
244
#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H
245
246