LLDB  mainline
DYLDRendezvous.h
Go to the documentation of this file.
1 //===-- DYLDRendezvous.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_POSIX_DYLD_DYLDRENDEZVOUS_H
10 #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_POSIX_DYLD_DYLDRENDEZVOUS_H
11 
12 #include <list>
13 #include <string>
14 
15 #include "lldb/Utility/FileSpec.h"
16 #include "lldb/lldb-defines.h"
17 #include "lldb/lldb-types.h"
18 
20 
22 
23 namespace lldb_private {
24 class Process;
25 }
26 
27 /// \class DYLDRendezvous
28 /// Interface to the runtime linker.
29 ///
30 /// A structure is present in a processes memory space which is updated by the
31 /// runtime liker each time a module is loaded or unloaded. This class
32 /// provides an interface to this structure and maintains a consistent
33 /// snapshot of the currently loaded modules.
35 
36  // This structure is used to hold the contents of the debug rendezvous
37  // information (struct r_debug) as found in the inferiors memory. Note that
38  // the layout of this struct is not binary compatible, it is simply large
39  // enough to hold the information on both 32 and 64 bit platforms.
40  struct Rendezvous {
41  uint64_t version = 0;
44  uint64_t state = 0;
46 
47  Rendezvous() = default;
48  };
49 
50  /// Locates the address of the rendezvous structure. It updates
51  /// m_executable_interpreter if address is extracted from _r_debug.
52  ///
53  /// \returns address on success and LLDB_INVALID_ADDRESS on failure.
55 
56 public:
57  // Various metadata supplied by the inferior's threading library to describe
58  // the per-thread state.
59  struct ThreadInfo {
60  bool valid; // whether we read valid metadata
61  uint32_t dtv_offset; // offset of DTV pointer within pthread
62  uint32_t dtv_slot_size; // size of one DTV slot
63  uint32_t modid_offset; // offset of module ID within link_map
64  uint32_t tls_offset; // offset of TLS pointer within DTV slot
65  };
66 
68 
69  /// Update the cached executable path.
70  void UpdateExecutablePath();
71 
72  /// Update the internal snapshot of runtime linker rendezvous and recompute
73  /// the currently loaded modules.
74  ///
75  /// This method should be called once one start up, then once each time the
76  /// runtime linker enters the function given by GetBreakAddress().
77  ///
78  /// \returns true on success and false on failure.
79  ///
80  /// \see GetBreakAddress().
81  bool Resolve();
82 
83  /// \returns true if this rendezvous has been located in the inferiors
84  /// address space and false otherwise.
85  bool IsValid();
86 
87  /// \returns the address of the rendezvous structure in the inferiors
88  /// address space.
90 
91  /// \returns the version of the rendezvous protocol being used.
92  uint64_t GetVersion() const { return m_current.version; }
93 
94  /// \returns address in the inferiors address space containing the linked
95  /// list of shared object descriptors.
97 
98  /// A breakpoint should be set at this address and Resolve called on each
99  /// hit.
100  ///
101  /// \returns the address of a function called by the runtime linker each
102  /// time a module is loaded/unloaded, or about to be loaded/unloaded.
103  ///
104  /// \see Resolve()
106 
107  /// Returns the current state of the rendezvous structure.
108  uint64_t GetState() const { return m_current.state; }
109 
110  /// \returns the base address of the runtime linker in the inferiors address
111  /// space.
113 
114  /// \returns the thread layout metadata from the inferiors thread library.
115  const ThreadInfo &GetThreadInfo();
116 
117  /// \returns true if modules have been loaded into the inferior since the
118  /// last call to Resolve().
119  bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
120 
121  /// \returns true if modules have been unloaded from the inferior since the
122  /// last call to Resolve().
123  bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
124 
125  void DumpToLog(lldb_private::Log *log) const;
126 
127  /// Constants describing the state of the rendezvous.
128  ///
129  /// \see GetState().
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  lldb_private::FileSpec file_spec; ///< File spec of shared object.
145 
146  SOEntry() { clear(); }
147 
148  bool operator==(const SOEntry &entry) {
149  return file_spec == entry.file_spec;
150  }
151 
152  void clear() {
153  link_addr = 0;
154  base_addr = 0;
155  path_addr = 0;
156  dyn_addr = 0;
157  next = 0;
158  prev = 0;
159  file_spec.Clear();
160  }
161  };
162 
163 protected:
164  typedef std::list<SOEntry> SOEntryList;
165 
166 public:
167  typedef SOEntryList::const_iterator iterator;
168 
169  /// Iterators over all currently loaded modules.
170  iterator begin() const { return m_soentries.begin(); }
171  iterator end() const { return m_soentries.end(); }
172 
173  /// Iterators over all modules loaded into the inferior since the last call
174  /// to Resolve().
175  iterator loaded_begin() const { return m_added_soentries.begin(); }
176  iterator loaded_end() const { return m_added_soentries.end(); }
177 
178  /// Iterators over all modules unloaded from the inferior since the last
179  /// call to Resolve().
180  iterator unloaded_begin() const { return m_removed_soentries.begin(); }
181  iterator unloaded_end() const { return m_removed_soentries.end(); }
182 
183 protected:
185 
186  // Cached copy of executable file spec
188 
189  /// Location of the r_debug structure in the inferiors address space.
191 
192  // True if the main program is the dynamic linker/loader/program interpreter.
194 
195  /// Current and previous snapshots of the rendezvous structure.
198 
199  /// List of currently loaded SO modules
201 
202  /// List of SOEntry objects corresponding to the current link map state.
204 
205  /// List of SOEntry's added to the link map since the last call to
206  /// Resolve().
208 
209  /// List of SOEntry's removed from the link map since the last call to
210  /// Resolve().
212 
213  /// Threading metadata read from the inferior.
215 
216  /// Reads an unsigned integer of \p size bytes from the inferior's address
217  /// space starting at \p addr.
218  ///
219  /// \returns addr + size if the read was successful and false otherwise.
220  lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
221 
222  /// Reads an address from the inferior's address space starting at \p addr.
223  ///
224  /// \returns addr + target address size if the read was successful and
225  /// 0 otherwise.
227 
228  /// Reads a null-terminated C string from the memory location starting at @p
229  /// addr.
231 
232  /// Reads an SOEntry starting at \p addr.
233  bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
234 
235  /// Updates the current set of SOEntries, the set of added entries, and the
236  /// set of removed entries.
237  bool UpdateSOEntries();
238 
239  /// Same as UpdateSOEntries but it gets the list of loaded modules from the
240  /// remote debug server (faster when supported).
242 
244  LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry);
245 
246  bool SaveSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
247 
248  bool AddSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
249 
250  bool RemoveSOEntriesFromRemote(const LoadedModuleInfoList &module_list);
251 
252  bool AddSOEntries();
253 
254  bool RemoveSOEntries();
255 
256  void UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
257 
258  void UpdateFileSpecIfNecessary(SOEntry &entry);
259 
260  bool SOEntryIsMainExecutable(const SOEntry &entry);
261 
262  /// Reads the current list of shared objects according to the link map
263  /// supplied by the runtime linker.
264  bool TakeSnapshot(SOEntryList &entry_list);
265 
267 
268  bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
269 
275  };
276 
277  /// Returns the current action to be taken given the current and previous
278  /// state
279  RendezvousAction GetAction() const;
280 };
281 
282 #endif
DYLDRendezvous::eAdd
@ eAdd
Definition: DYLDRendezvous.h:130
DYLDRendezvous::ModulesDidLoad
bool ModulesDidLoad() const
Definition: DYLDRendezvous.h:119
DYLDRendezvous::m_added_soentries
SOEntryList m_added_soentries
List of SOEntry's added to the link map since the last call to Resolve().
Definition: DYLDRendezvous.h:207
DYLDRendezvous::ThreadInfo
Definition: DYLDRendezvous.h:59
DYLDRendezvous::SaveSOEntriesFromRemote
bool SaveSOEntriesFromRemote(const LoadedModuleInfoList &module_list)
Definition: DYLDRendezvous.cpp:305
DYLDRendezvous::eNoAction
@ eNoAction
Definition: DYLDRendezvous.h:271
DYLDRendezvous::loaded_begin
iterator loaded_begin() const
Iterators over all modules loaded into the inferior since the last call to Resolve().
Definition: DYLDRendezvous.h:175
DYLDRendezvous::UpdateExecutablePath
void UpdateExecutablePath()
Update the cached executable path.
Definition: DYLDRendezvous.cpp:114
DYLDRendezvous::GetLDBase
lldb::addr_t GetLDBase() const
Definition: DYLDRendezvous.h:112
DYLDRendezvous::end
iterator end() const
Definition: DYLDRendezvous.h:171
DYLDRendezvous::m_process
lldb_private::Process * m_process
Definition: DYLDRendezvous.h:184
DYLDRendezvous::DYLDRendezvous
DYLDRendezvous(lldb_private::Process *process)
Definition: DYLDRendezvous.cpp:27
DYLDRendezvous::UpdateFileSpecIfNecessary
void UpdateFileSpecIfNecessary(SOEntry &entry)
Definition: DYLDRendezvous.cpp:540
lldb-defines.h
DYLDRendezvous::SOEntryIsMainExecutable
bool SOEntryIsMainExecutable(const SOEntry &entry)
Definition: DYLDRendezvous.cpp:434
DYLDRendezvous::ThreadInfo::modid_offset
uint32_t modid_offset
Definition: DYLDRendezvous.h:63
DYLDRendezvous::RemoveSOEntries
bool RemoveSOEntries()
Definition: DYLDRendezvous.cpp:415
DYLDRendezvous::eSize
@ eSize
Definition: DYLDRendezvous.h:266
DYLDRendezvous::iterator
SOEntryList::const_iterator iterator
Definition: DYLDRendezvous.h:167
lldb_private::Process
Definition: Process.h:340
DYLDRendezvous::eConsistent
@ eConsistent
Definition: DYLDRendezvous.h:130
DYLDRendezvous::begin
iterator begin() const
Iterators over all currently loaded modules.
Definition: DYLDRendezvous.h:170
DYLDRendezvous::ThreadInfo::dtv_slot_size
uint32_t dtv_slot_size
Definition: DYLDRendezvous.h:62
DYLDRendezvous::PThreadField
PThreadField
Definition: DYLDRendezvous.h:266
DYLDRendezvous::SOEntry::prev
lldb::addr_t prev
Address of previous so_entry.
Definition: DYLDRendezvous.h:143
DYLDRendezvous::AddSOEntriesFromRemote
bool AddSOEntriesFromRemote(const LoadedModuleInfoList &module_list)
Definition: DYLDRendezvous.cpp:323
DYLDRendezvous::m_exe_file_spec
lldb_private::FileSpec m_exe_file_spec
Definition: DYLDRendezvous.h:187
DYLDRendezvous::ThreadInfo::dtv_offset
uint32_t dtv_offset
Definition: DYLDRendezvous.h:61
DYLDRendezvous::SOEntry::next
lldb::addr_t next
Address of next so_entry.
Definition: DYLDRendezvous.h:142
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::LoadedModuleInfoList
Definition: LoadedModuleInfoList.h:21
DYLDRendezvous::ReadPointer
lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst)
Reads an address from the inferior's address space starting at addr.
Definition: DYLDRendezvous.cpp:491
DYLDRendezvous::DumpToLog
void DumpToLog(lldb_private::Log *log) const
Definition: DYLDRendezvous.cpp:642
DYLDRendezvous::ReadStringFromMemory
std::string ReadStringFromMemory(lldb::addr_t addr)
Reads a null-terminated C string from the memory location starting at addr.
Definition: DYLDRendezvous.cpp:501
DYLDRendezvous::SOEntry::base_addr
lldb::addr_t base_addr
Base address of the loaded object.
Definition: DYLDRendezvous.h:139
DYLDRendezvous::m_previous
Rendezvous m_previous
Definition: DYLDRendezvous.h:197
DYLDRendezvous::eNElem
@ eNElem
Definition: DYLDRendezvous.h:266
DYLDRendezvous::eOffset
@ eOffset
Definition: DYLDRendezvous.h:266
DYLDRendezvous::eAddModules
@ eAddModules
Definition: DYLDRendezvous.h:273
DYLDRendezvous::ModulesDidUnload
bool ModulesDidUnload() const
Definition: DYLDRendezvous.h:123
DYLDRendezvous::FindMetadata
bool FindMetadata(const char *name, PThreadField field, uint32_t &value)
Definition: DYLDRendezvous.cpp:595
lldb_private::FileSpec
Definition: FileSpec.h:56
DYLDRendezvous::Rendezvous
Definition: DYLDRendezvous.h:40
DYLDRendezvous::GetThreadInfo
const ThreadInfo & GetThreadInfo()
Definition: DYLDRendezvous.cpp:622
DYLDRendezvous::UpdateBaseAddrIfNecessary
void UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path)
Definition: DYLDRendezvous.cpp:526
DYLDRendezvous::ThreadInfo::valid
bool valid
Definition: DYLDRendezvous.h:60
DYLDRendezvous::GetBreakAddress
lldb::addr_t GetBreakAddress() const
A breakpoint should be set at this address and Resolve called on each hit.
Definition: DYLDRendezvous.h:105
DYLDRendezvous::Rendezvous::state
uint64_t state
Definition: DYLDRendezvous.h:44
DYLDRendezvous::unloaded_end
iterator unloaded_end() const
Definition: DYLDRendezvous.h:181
DYLDRendezvous::Rendezvous::version
uint64_t version
Definition: DYLDRendezvous.h:41
DYLDRendezvous::Rendezvous::brk
lldb::addr_t brk
Definition: DYLDRendezvous.h:43
DYLDRendezvous::eTakeSnapshot
@ eTakeSnapshot
Definition: DYLDRendezvous.h:272
DYLDRendezvous::RendezvousAction
RendezvousAction
Definition: DYLDRendezvous.h:270
DYLDRendezvous::TakeSnapshot
bool TakeSnapshot(SOEntryList &entry_list)
Reads the current list of shared objects according to the link map supplied by the runtime linker.
Definition: DYLDRendezvous.cpp:456
DYLDRendezvous::Rendezvous::ldbase
lldb::addr_t ldbase
Definition: DYLDRendezvous.h:45
DYLDRendezvous::Rendezvous::map_addr
lldb::addr_t map_addr
Definition: DYLDRendezvous.h:42
DYLDRendezvous::RemoveSOEntriesFromRemote
bool RemoveSOEntriesFromRemote(const LoadedModuleInfoList &module_list)
Definition: DYLDRendezvous.cpp:353
DYLDRendezvous::SOEntry::operator==
bool operator==(const SOEntry &entry)
Definition: DYLDRendezvous.h:148
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
DYLDRendezvous::IsValid
bool IsValid()
Definition: DYLDRendezvous.cpp:187
DYLDRendezvous::unloaded_begin
iterator unloaded_begin() const
Iterators over all modules unloaded from the inferior since the last call to Resolve().
Definition: DYLDRendezvous.h:180
DYLDRendezvous::RendezvousState
RendezvousState
Constants describing the state of the rendezvous.
Definition: DYLDRendezvous.h:130
LoadedModuleInfoList.h
DYLDRendezvous::FillSOEntryFromModuleInfo
bool FillSOEntryFromModuleInfo(LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry)
Definition: DYLDRendezvous.cpp:278
lldb-types.h
lldb_private::FileSpec::Clear
void Clear()
Clears the object state.
Definition: FileSpec.cpp:261
DYLDRendezvous::m_thread_info
ThreadInfo m_thread_info
Threading metadata read from the inferior.
Definition: DYLDRendezvous.h:214
DYLDRendezvous::UpdateSOEntriesFromRemote
bool UpdateSOEntriesFromRemote()
Same as UpdateSOEntries but it gets the list of loaded modules from the remote debug server (faster w...
Definition: DYLDRendezvous.cpp:225
uint32_t
DYLDRendezvous::ReadSOEntryFromMemory
bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
Reads an SOEntry starting at addr.
Definition: DYLDRendezvous.cpp:553
DYLDRendezvous::GetLinkMapAddress
lldb::addr_t GetLinkMapAddress() const
Definition: DYLDRendezvous.h:96
DYLDRendezvous
Definition: DYLDRendezvous.h:34
DYLDRendezvous::GetRendezvousAddress
lldb::addr_t GetRendezvousAddress() const
Definition: DYLDRendezvous.h:89
DYLDRendezvous::loaded_end
iterator loaded_end() const
Definition: DYLDRendezvous.h:176
DYLDRendezvous::GetVersion
uint64_t GetVersion() const
Definition: DYLDRendezvous.h:92
DYLDRendezvous::ResolveRendezvousAddress
lldb::addr_t ResolveRendezvousAddress()
Locates the address of the rendezvous structure.
Definition: DYLDRendezvous.cpp:36
DYLDRendezvous::Rendezvous::Rendezvous
Rendezvous()=default
DYLDRendezvous::SOEntry::SOEntry
SOEntry()
Definition: DYLDRendezvous.h:146
DYLDRendezvous::SOEntryList
std::list< SOEntry > SOEntryList
Definition: DYLDRendezvous.h:164
DYLDRendezvous::ThreadInfo::tls_offset
uint32_t tls_offset
Definition: DYLDRendezvous.h:64
DYLDRendezvous::m_loaded_modules
LoadedModuleInfoList m_loaded_modules
List of currently loaded SO modules.
Definition: DYLDRendezvous.h:200
DYLDRendezvous::m_current
Rendezvous m_current
Current and previous snapshots of the rendezvous structure.
Definition: DYLDRendezvous.h:196
DYLDRendezvous::AddSOEntries
bool AddSOEntries()
Definition: DYLDRendezvous.cpp:386
DYLDRendezvous::GetState
uint64_t GetState() const
Returns the current state of the rendezvous structure.
Definition: DYLDRendezvous.h:108
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
DYLDRendezvous::Resolve
bool Resolve()
Update the internal snapshot of runtime linker rendezvous and recompute the currently loaded modules.
Definition: DYLDRendezvous.cpp:131
DYLDRendezvous::SOEntry::path_addr
lldb::addr_t path_addr
String naming the shared object.
Definition: DYLDRendezvous.h:140
DYLDRendezvous::SOEntry::file_spec
lldb_private::FileSpec file_spec
File spec of shared object.
Definition: DYLDRendezvous.h:144
DYLDRendezvous::SOEntry::link_addr
lldb::addr_t link_addr
Address of this link_map.
Definition: DYLDRendezvous.h:138
DYLDRendezvous::SOEntry::dyn_addr
lldb::addr_t dyn_addr
Dynamic section of shared object.
Definition: DYLDRendezvous.h:141
FileSpec.h
DYLDRendezvous::m_removed_soentries
SOEntryList m_removed_soentries
List of SOEntry's removed from the link map since the last call to Resolve().
Definition: DYLDRendezvous.h:211
DYLDRendezvous::UpdateSOEntries
bool UpdateSOEntries()
Updates the current set of SOEntries, the set of added entries, and the set of removed entries.
Definition: DYLDRendezvous.cpp:261
DYLDRendezvous::eRemoveModules
@ eRemoveModules
Definition: DYLDRendezvous.h:274
DYLDRendezvous::eDelete
@ eDelete
Definition: DYLDRendezvous.h:130
DYLDRendezvous::ReadWord
lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size)
Reads an unsigned integer of size bytes from the inferior's address space starting at addr.
Definition: DYLDRendezvous.cpp:481
lldb_private::Log
Definition: Log.h:49
DYLDRendezvous::m_executable_interpreter
bool m_executable_interpreter
Definition: DYLDRendezvous.h:193
DYLDRendezvous::m_rendezvous_addr
lldb::addr_t m_rendezvous_addr
Location of the r_debug structure in the inferiors address space.
Definition: DYLDRendezvous.h:190
DYLDRendezvous::m_soentries
SOEntryList m_soentries
List of SOEntry objects corresponding to the current link map state.
Definition: DYLDRendezvous.h:203
DYLDRendezvous::SOEntry::clear
void clear()
Definition: DYLDRendezvous.h:152
DYLDRendezvous::SOEntry
Structure representing the shared objects currently loaded into the inferior process.
Definition: DYLDRendezvous.h:137
DYLDRendezvous::GetAction
RendezvousAction GetAction() const
Returns the current action to be taken given the current and previous state.
Definition: DYLDRendezvous.cpp:191