DYLDRendezvous.h revision 263363
1//===-- DYLDRendezvous.h ----------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef liblldb_Rendezvous_H_ 11#define liblldb_Rendezvous_H_ 12 13// C Includes 14// C++ Includes 15#include <list> 16#include <string> 17 18// Other libraries and framework includes 19#include "lldb/lldb-defines.h" 20#include "lldb/lldb-types.h" 21 22namespace lldb_private { 23class Process; 24} 25 26/// @class DYLDRendezvous 27/// @brief Interface to the runtime linker. 28/// 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. 33class DYLDRendezvous { 34 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. 39 struct Rendezvous { 40 uint64_t version; 41 lldb::addr_t map_addr; 42 lldb::addr_t brk; 43 uint64_t state; 44 lldb::addr_t ldbase; 45 46 Rendezvous() 47 : version(0), map_addr(0), brk(0), state(0), ldbase(0) { } 48 }; 49 50public: 51 // Various metadata supplied by the inferior's threading library to describe 52 // the per-thread state. 53 struct ThreadInfo { 54 bool valid; // whether we read valid metadata 55 uint32_t dtv_offset; // offset of DTV pointer within pthread 56 uint32_t dtv_slot_size; // size of one DTV slot 57 uint32_t modid_offset; // offset of module ID within link_map 58 uint32_t tls_offset; // offset of TLS pointer within DTV slot 59 }; 60 61 DYLDRendezvous(lldb_private::Process *process); 62 63 /// Update the internal snapshot of runtime linker rendezvous and recompute 64 /// the currently loaded modules. 65 /// 66 /// This method should be called once one start up, then once each time the 67 /// runtime linker enters the function given by GetBreakAddress(). 68 /// 69 /// @returns true on success and false on failure. 70 /// 71 /// @see GetBreakAddress(). 72 bool 73 Resolve(); 74 75 /// @returns true if this rendezvous has been located in the inferiors 76 /// address space and false otherwise. 77 bool 78 IsValid(); 79 80 /// @returns the address of the rendezvous structure in the inferiors 81 /// address space. 82 lldb::addr_t 83 GetRendezvousAddress() const { return m_rendezvous_addr; } 84 85 /// @returns the version of the rendezvous protocol being used. 86 uint64_t 87 GetVersion() const { return m_current.version; } 88 89 /// @returns address in the inferiors address space containing the linked 90 /// list of shared object descriptors. 91 lldb::addr_t 92 GetLinkMapAddress() const { return m_current.map_addr; } 93 94 /// A breakpoint should be set at this address and Resolve called on each 95 /// hit. 96 /// 97 /// @returns the address of a function called by the runtime linker each 98 /// time a module is loaded/unloaded, or about to be loaded/unloaded. 99 /// 100 /// @see Resolve() 101 lldb::addr_t 102 GetBreakAddress() const { return m_current.brk; } 103 104 /// Returns the current state of the rendezvous structure. 105 uint64_t 106 GetState() const { return m_current.state; } 107 108 /// @returns the base address of the runtime linker in the inferiors address 109 /// space. 110 lldb::addr_t 111 GetLDBase() const { return m_current.ldbase; } 112 113 /// @returns the thread layout metadata from the inferiors thread library. 114 const ThreadInfo& 115 GetThreadInfo(); 116 117 /// @returns true if modules have been loaded into the inferior since the 118 /// last call to Resolve(). 119 bool 120 ModulesDidLoad() const { return !m_added_soentries.empty(); } 121 122 /// @returns true if modules have been unloaded from the inferior since the 123 /// last call to Resolve(). 124 bool 125 ModulesDidUnload() const { return !m_removed_soentries.empty(); } 126 127 void 128 DumpToLog(lldb_private::Log *log) const; 129 130 /// @brief Constants describing the state of the rendezvous. 131 /// 132 /// @see GetState(). 133 enum RendezvousState { 134 eConsistent, 135 eAdd, 136 eDelete 137 }; 138 139 /// @brief Structure representing the shared objects currently loaded into 140 /// the inferior process. 141 /// 142 /// This object is a rough analogue to the struct link_map object which 143 /// actually lives in the inferiors memory. 144 struct SOEntry { 145 lldb::addr_t link_addr; ///< Address of this link_map. 146 lldb::addr_t base_addr; ///< Base address of the loaded object. 147 lldb::addr_t path_addr; ///< String naming the shared object. 148 lldb::addr_t dyn_addr; ///< Dynamic section of shared object. 149 lldb::addr_t next; ///< Address of next so_entry. 150 lldb::addr_t prev; ///< Address of previous so_entry. 151 std::string path; ///< File name of shared object. 152 153 SOEntry() { clear(); } 154 155 bool operator ==(const SOEntry &entry) { 156 return this->path == entry.path; 157 } 158 159 void clear() { 160 link_addr = 0; 161 base_addr = 0; 162 path_addr = 0; 163 dyn_addr = 0; 164 next = 0; 165 prev = 0; 166 path.clear(); 167 } 168 }; 169 170protected: 171 typedef std::list<SOEntry> SOEntryList; 172 173public: 174 typedef SOEntryList::const_iterator iterator; 175 176 /// Iterators over all currently loaded modules. 177 iterator begin() const { return m_soentries.begin(); } 178 iterator end() const { return m_soentries.end(); } 179 180 /// Iterators over all modules loaded into the inferior since the last call 181 /// to Resolve(). 182 iterator loaded_begin() const { return m_added_soentries.begin(); } 183 iterator loaded_end() const { return m_added_soentries.end(); } 184 185 /// Iterators over all modules unloaded from the inferior since the last 186 /// call to Resolve(). 187 iterator unloaded_begin() const { return m_removed_soentries.begin(); } 188 iterator unloaded_end() const { return m_removed_soentries.end(); } 189 190protected: 191 lldb_private::Process *m_process; 192 193 // Cached copy of executable pathname 194 char m_exe_path[PATH_MAX]; 195 196 /// Location of the r_debug structure in the inferiors address space. 197 lldb::addr_t m_rendezvous_addr; 198 199 /// Current and previous snapshots of the rendezvous structure. 200 Rendezvous m_current; 201 Rendezvous m_previous; 202 203 /// List of SOEntry objects corresponding to the current link map state. 204 SOEntryList m_soentries; 205 206 /// List of SOEntry's added to the link map since the last call to Resolve(). 207 SOEntryList m_added_soentries; 208 209 /// List of SOEntry's removed from the link map since the last call to 210 /// Resolve(). 211 SOEntryList m_removed_soentries; 212 213 /// Threading metadata read from the inferior. 214 ThreadInfo m_thread_info; 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 221 ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size); 222 223 /// Reads an address from the inferior's address space starting at @p addr. 224 /// 225 /// @returns addr + target address size if the read was successful and 226 /// 0 otherwise. 227 lldb::addr_t 228 ReadPointer(lldb::addr_t addr, lldb::addr_t *dst); 229 230 /// Reads a null-terminated C string from the memory location starting at @p 231 /// addr. 232 std::string 233 ReadStringFromMemory(lldb::addr_t addr); 234 235 /// Reads an SOEntry starting at @p addr. 236 bool 237 ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry); 238 239 /// Updates the current set of SOEntries, the set of added entries, and the 240 /// set of removed entries. 241 bool 242 UpdateSOEntries(); 243 244 bool 245 UpdateSOEntriesForAddition(); 246 247 bool 248 UpdateSOEntriesForDeletion(); 249 250 /// Reads the current list of shared objects according to the link map 251 /// supplied by the runtime linker. 252 bool 253 TakeSnapshot(SOEntryList &entry_list); 254 255 enum PThreadField { eSize, eNElem, eOffset }; 256 257 bool FindMetadata(const char *name, PThreadField field, uint32_t& value); 258}; 259 260#endif 261