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