1 //===-- DYLDRendezvous.h ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_Rendezvous_H_
11 #define liblldb_Rendezvous_H_
18 // Other libraries and framework includes
19 #include "lldb/lldb-defines.h"
20 #include "lldb/lldb-types.h"
21 #include "lldb/Host/FileSpec.h"
23 #include "lldb/Core/LoadedModuleInfoList.h"
25 using lldb_private::LoadedModuleInfoList;
27 namespace lldb_private {
31 /// @class DYLDRendezvous
32 /// @brief Interface to the runtime linker.
34 /// A structure is present in a processes memory space which is updated by the
35 /// runtime liker each time a module is loaded or unloaded. This class provides
36 /// an interface to this structure and maintains a consistent snapshot of the
37 /// currently loaded modules.
38 class DYLDRendezvous {
40 // This structure is used to hold the contents of the debug rendezvous
41 // information (struct r_debug) as found in the inferiors memory. Note that
42 // the layout of this struct is not binary compatible, it is simply large
43 // enough to hold the information on both 32 and 64 bit platforms.
46 lldb::addr_t map_addr;
52 : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
56 // Various metadata supplied by the inferior's threading library to describe
57 // the per-thread state.
59 bool valid; // whether we read valid metadata
60 uint32_t dtv_offset; // offset of DTV pointer within pthread
61 uint32_t dtv_slot_size; // size of one DTV slot
62 uint32_t modid_offset; // offset of module ID within link_map
63 uint32_t tls_offset; // offset of TLS pointer within DTV slot
66 DYLDRendezvous(lldb_private::Process *process);
68 /// Update the internal snapshot of runtime linker rendezvous and recompute
69 /// the currently loaded modules.
71 /// This method should be called once one start up, then once each time the
72 /// runtime linker enters the function given by GetBreakAddress().
74 /// @returns true on success and false on failure.
76 /// @see GetBreakAddress().
80 /// @returns true if this rendezvous has been located in the inferiors
81 /// address space and false otherwise.
85 /// @returns the address of the rendezvous structure in the inferiors
88 GetRendezvousAddress() const { return m_rendezvous_addr; }
90 /// @returns the version of the rendezvous protocol being used.
92 GetVersion() const { return m_current.version; }
94 /// @returns address in the inferiors address space containing the linked
95 /// list of shared object descriptors.
97 GetLinkMapAddress() const { return m_current.map_addr; }
99 /// A breakpoint should be set at this address and Resolve called on each
102 /// @returns the address of a function called by the runtime linker each
103 /// time a module is loaded/unloaded, or about to be loaded/unloaded.
107 GetBreakAddress() const { return m_current.brk; }
109 /// Returns the current state of the rendezvous structure.
111 GetState() const { return m_current.state; }
113 /// @returns the base address of the runtime linker in the inferiors address
116 GetLDBase() const { return m_current.ldbase; }
118 /// @returns the thread layout metadata from the inferiors thread library.
122 /// @returns true if modules have been loaded into the inferior since the
123 /// last call to Resolve().
125 ModulesDidLoad() const { return !m_added_soentries.empty(); }
127 /// @returns true if modules have been unloaded from the inferior since the
128 /// last call to Resolve().
130 ModulesDidUnload() const { return !m_removed_soentries.empty(); }
133 DumpToLog(lldb_private::Log *log) const;
135 /// @brief Constants describing the state of the rendezvous.
138 enum RendezvousState {
144 /// @brief Structure representing the shared objects currently loaded into
145 /// the inferior process.
147 /// This object is a rough analogue to the struct link_map object which
148 /// actually lives in the inferiors memory.
150 lldb::addr_t link_addr; ///< Address of this link_map.
151 lldb::addr_t base_addr; ///< Base address of the loaded object.
152 lldb::addr_t path_addr; ///< String naming the shared object.
153 lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
154 lldb::addr_t next; ///< Address of next so_entry.
155 lldb::addr_t prev; ///< Address of previous so_entry.
156 lldb_private::FileSpec file_spec; ///< File spec of shared object.
158 SOEntry() { clear(); }
160 bool operator ==(const SOEntry &entry) {
161 return file_spec == entry.file_spec;
176 typedef std::list<SOEntry> SOEntryList;
179 typedef SOEntryList::const_iterator iterator;
181 /// Iterators over all currently loaded modules.
182 iterator begin() const { return m_soentries.begin(); }
183 iterator end() const { return m_soentries.end(); }
185 /// Iterators over all modules loaded into the inferior since the last call
187 iterator loaded_begin() const { return m_added_soentries.begin(); }
188 iterator loaded_end() const { return m_added_soentries.end(); }
190 /// Iterators over all modules unloaded from the inferior since the last
191 /// call to Resolve().
192 iterator unloaded_begin() const { return m_removed_soentries.begin(); }
193 iterator unloaded_end() const { return m_removed_soentries.end(); }
196 lldb_private::Process *m_process;
198 // Cached copy of executable file spec
199 lldb_private::FileSpec m_exe_file_spec;
201 /// Location of the r_debug structure in the inferiors address space.
202 lldb::addr_t m_rendezvous_addr;
204 /// Current and previous snapshots of the rendezvous structure.
205 Rendezvous m_current;
206 Rendezvous m_previous;
208 /// List of currently loaded SO modules
209 LoadedModuleInfoList m_loaded_modules;
211 /// List of SOEntry objects corresponding to the current link map state.
212 SOEntryList m_soentries;
214 /// List of SOEntry's added to the link map since the last call to Resolve().
215 SOEntryList m_added_soentries;
217 /// List of SOEntry's removed from the link map since the last call to
219 SOEntryList m_removed_soentries;
221 /// Threading metadata read from the inferior.
222 ThreadInfo m_thread_info;
224 /// Reads an unsigned integer of @p size bytes from the inferior's address
225 /// space starting at @p addr.
227 /// @returns addr + size if the read was successful and false otherwise.
229 ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
231 /// Reads an address from the inferior's address space starting at @p addr.
233 /// @returns addr + target address size if the read was successful and
236 ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
238 /// Reads a null-terminated C string from the memory location starting at @p
241 ReadStringFromMemory(lldb::addr_t addr);
243 /// Reads an SOEntry starting at @p addr.
245 ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
247 /// Updates the current set of SOEntries, the set of added entries, and the
248 /// set of removed entries.
250 UpdateSOEntries(bool fromRemote = false);
253 FillSOEntryFromModuleInfo (LoadedModuleInfoList::LoadedModuleInfo const & modInfo,
257 SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
260 AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
263 RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
272 UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
275 SOEntryIsMainExecutable(const SOEntry &entry);
277 /// Reads the current list of shared objects according to the link map
278 /// supplied by the runtime linker.
280 TakeSnapshot(SOEntryList &entry_list);
282 enum PThreadField { eSize, eNElem, eOffset };
284 bool FindMetadata(const char *name, PThreadField field, uint32_t& value);