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"
22 namespace lldb_private {
26 /// @class DYLDRendezvous
27 /// @brief Interface to the runtime linker.
29 /// A structure is present in a processes memory space which is updated by the
30 /// runtime liker each time a module is loaded or unloaded. This class provides
31 /// an interface to this structure and maintains a consistent snapshot of the
32 /// currently loaded modules.
33 class DYLDRendezvous {
35 // This structure is used to hold the contents of the debug rendezvous
36 // information (struct r_debug) as found in the inferiors memory. Note that
37 // the layout of this struct is not binary compatible, it is simply large
38 // enough to hold the information on both 32 and 64 bit platforms.
41 lldb::addr_t map_addr;
47 : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
51 DYLDRendezvous(lldb_private::Process *process);
53 /// Update the internal snapshot of runtime linker rendezvous and recompute
54 /// the currently loaded modules.
56 /// This method should be called once one start up, then once each time the
57 /// runtime linker enters the function given by GetBreakAddress().
59 /// @returns true on success and false on failure.
61 /// @see GetBreakAddress().
65 /// @returns true if this rendezvous has been located in the inferiors
66 /// address space and false otherwise.
70 /// @returns the address of the rendezvous structure in the inferiors
73 GetRendezvousAddress() const { return m_rendezvous_addr; }
75 /// @returns the version of the rendezvous protocol being used.
77 GetVersion() const { return m_current.version; }
79 /// @returns address in the inferiors address space containing the linked
80 /// list of shared object descriptors.
82 GetLinkMapAddress() const { return m_current.map_addr; }
84 /// A breakpoint should be set at this address and Resolve called on each
87 /// @returns the address of a function called by the runtime linker each
88 /// time a module is loaded/unloaded, or about to be loaded/unloaded.
92 GetBreakAddress() const { return m_current.brk; }
94 /// Returns the current state of the rendezvous structure.
96 GetState() const { return m_current.state; }
98 /// @returns the base address of the runtime linker in the inferiors address
101 GetLDBase() const { return m_current.ldbase; }
103 /// @returns true if modules have been loaded into the inferior since the
104 /// last call to Resolve().
106 ModulesDidLoad() const { return !m_added_soentries.empty(); }
108 /// @returns true if modules have been unloaded from the inferior since the
109 /// last call to Resolve().
111 ModulesDidUnload() const { return !m_removed_soentries.empty(); }
114 DumpToLog(lldb_private::Log *log) const;
116 /// @brief Constants describing the state of the rendezvous.
119 enum RendezvousState {
125 /// @brief Structure representing the shared objects currently loaded into
126 /// the inferior process.
128 /// This object is a rough analogue to the struct link_map object which
129 /// actually lives in the inferiors memory.
131 lldb::addr_t base_addr; ///< Base address of the loaded object.
132 lldb::addr_t path_addr; ///< String naming the shared object.
133 lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
134 lldb::addr_t next; ///< Address of next so_entry.
135 lldb::addr_t prev; ///< Address of previous so_entry.
136 std::string path; ///< File name of shared object.
138 SOEntry() { clear(); }
140 bool operator ==(const SOEntry &entry) {
141 return this->path == entry.path;
155 typedef std::list<SOEntry> SOEntryList;
158 typedef SOEntryList::const_iterator iterator;
160 /// Iterators over all currently loaded modules.
161 iterator begin() const { return m_soentries.begin(); }
162 iterator end() const { return m_soentries.end(); }
164 /// Iterators over all modules loaded into the inferior since the last call
166 iterator loaded_begin() const { return m_added_soentries.begin(); }
167 iterator loaded_end() const { return m_added_soentries.end(); }
169 /// Iterators over all modules unloaded from the inferior since the last
170 /// call to Resolve().
171 iterator unloaded_begin() const { return m_removed_soentries.begin(); }
172 iterator unloaded_end() const { return m_removed_soentries.end(); }
175 lldb_private::Process *m_process;
177 // Cached copy of executable pathname
178 char m_exe_path[PATH_MAX];
180 /// Location of the r_debug structure in the inferiors address space.
181 lldb::addr_t m_rendezvous_addr;
183 /// Current and previous snapshots of the rendezvous structure.
184 Rendezvous m_current;
185 Rendezvous m_previous;
187 /// List of SOEntry objects corresponding to the current link map state.
188 SOEntryList m_soentries;
190 /// List of SOEntry's added to the link map since the last call to Resolve().
191 SOEntryList m_added_soentries;
193 /// List of SOEntry's removed from the link map since the last call to
195 SOEntryList m_removed_soentries;
197 /// Reads @p size bytes from the inferiors address space starting at @p
200 /// @returns addr + size if the read was successful and false otherwise.
202 ReadMemory(lldb::addr_t addr, void *dst, size_t size);
204 /// Reads a null-terminated C string from the memory location starting at @p
207 ReadStringFromMemory(lldb::addr_t addr);
209 /// Reads an SOEntry starting at @p addr.
211 ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
213 /// Updates the current set of SOEntries, the set of added entries, and the
214 /// set of removed entries.
219 UpdateSOEntriesForAddition();
222 UpdateSOEntriesForDeletion();
224 /// Reads the current list of shared objects according to the link map
225 /// supplied by the runtime linker.
227 TakeSnapshot(SOEntryList &entry_list);