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