1254721Semaste//===-- DYLDRendezvous.h ----------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#ifndef liblldb_Rendezvous_H_ 11254721Semaste#define liblldb_Rendezvous_H_ 12254721Semaste 13254721Semaste// C Includes 14254721Semaste// C++ Includes 15254721Semaste#include <list> 16254721Semaste#include <string> 17254721Semaste 18254721Semaste// Other libraries and framework includes 19254721Semaste#include "lldb/lldb-defines.h" 20254721Semaste#include "lldb/lldb-types.h" 21254721Semaste 22254721Semastenamespace lldb_private { 23254721Semasteclass Process; 24254721Semaste} 25254721Semaste 26254721Semaste/// @class DYLDRendezvous 27254721Semaste/// @brief Interface to the runtime linker. 28254721Semaste/// 29254721Semaste/// A structure is present in a processes memory space which is updated by the 30254721Semaste/// runtime liker each time a module is loaded or unloaded. This class provides 31254721Semaste/// an interface to this structure and maintains a consistent snapshot of the 32254721Semaste/// currently loaded modules. 33254721Semasteclass DYLDRendezvous { 34254721Semaste 35254721Semaste // This structure is used to hold the contents of the debug rendezvous 36254721Semaste // information (struct r_debug) as found in the inferiors memory. Note that 37254721Semaste // the layout of this struct is not binary compatible, it is simply large 38254721Semaste // enough to hold the information on both 32 and 64 bit platforms. 39254721Semaste struct Rendezvous { 40254721Semaste uint64_t version; 41254721Semaste lldb::addr_t map_addr; 42254721Semaste lldb::addr_t brk; 43254721Semaste uint64_t state; 44254721Semaste lldb::addr_t ldbase; 45254721Semaste 46254721Semaste Rendezvous() 47254721Semaste : version(0), map_addr(0), brk(0), state(0), ldbase(0) { } 48254721Semaste }; 49254721Semaste 50254721Semastepublic: 51254721Semaste DYLDRendezvous(lldb_private::Process *process); 52254721Semaste 53254721Semaste /// Update the internal snapshot of runtime linker rendezvous and recompute 54254721Semaste /// the currently loaded modules. 55254721Semaste /// 56254721Semaste /// This method should be called once one start up, then once each time the 57254721Semaste /// runtime linker enters the function given by GetBreakAddress(). 58254721Semaste /// 59254721Semaste /// @returns true on success and false on failure. 60254721Semaste /// 61254721Semaste /// @see GetBreakAddress(). 62254721Semaste bool 63254721Semaste Resolve(); 64254721Semaste 65254721Semaste /// @returns true if this rendezvous has been located in the inferiors 66254721Semaste /// address space and false otherwise. 67254721Semaste bool 68254721Semaste IsValid(); 69254721Semaste 70254721Semaste /// @returns the address of the rendezvous structure in the inferiors 71254721Semaste /// address space. 72254721Semaste lldb::addr_t 73254721Semaste GetRendezvousAddress() const { return m_rendezvous_addr; } 74254721Semaste 75254721Semaste /// @returns the version of the rendezvous protocol being used. 76254721Semaste uint64_t 77254721Semaste GetVersion() const { return m_current.version; } 78254721Semaste 79254721Semaste /// @returns address in the inferiors address space containing the linked 80254721Semaste /// list of shared object descriptors. 81254721Semaste lldb::addr_t 82254721Semaste GetLinkMapAddress() const { return m_current.map_addr; } 83254721Semaste 84254721Semaste /// A breakpoint should be set at this address and Resolve called on each 85254721Semaste /// hit. 86254721Semaste /// 87254721Semaste /// @returns the address of a function called by the runtime linker each 88254721Semaste /// time a module is loaded/unloaded, or about to be loaded/unloaded. 89254721Semaste /// 90254721Semaste /// @see Resolve() 91254721Semaste lldb::addr_t 92254721Semaste GetBreakAddress() const { return m_current.brk; } 93254721Semaste 94254721Semaste /// Returns the current state of the rendezvous structure. 95254721Semaste uint64_t 96254721Semaste GetState() const { return m_current.state; } 97254721Semaste 98254721Semaste /// @returns the base address of the runtime linker in the inferiors address 99254721Semaste /// space. 100254721Semaste lldb::addr_t 101254721Semaste GetLDBase() const { return m_current.ldbase; } 102254721Semaste 103254721Semaste /// @returns true if modules have been loaded into the inferior since the 104254721Semaste /// last call to Resolve(). 105254721Semaste bool 106254721Semaste ModulesDidLoad() const { return !m_added_soentries.empty(); } 107254721Semaste 108254721Semaste /// @returns true if modules have been unloaded from the inferior since the 109254721Semaste /// last call to Resolve(). 110254721Semaste bool 111254721Semaste ModulesDidUnload() const { return !m_removed_soentries.empty(); } 112254721Semaste 113254721Semaste void 114254721Semaste DumpToLog(lldb_private::Log *log) const; 115254721Semaste 116254721Semaste /// @brief Constants describing the state of the rendezvous. 117254721Semaste /// 118254721Semaste /// @see GetState(). 119254721Semaste enum RendezvousState { 120254721Semaste eConsistent, 121254721Semaste eAdd, 122254721Semaste eDelete 123254721Semaste }; 124254721Semaste 125254721Semaste /// @brief Structure representing the shared objects currently loaded into 126254721Semaste /// the inferior process. 127254721Semaste /// 128254721Semaste /// This object is a rough analogue to the struct link_map object which 129254721Semaste /// actually lives in the inferiors memory. 130254721Semaste struct SOEntry { 131254721Semaste lldb::addr_t base_addr; ///< Base address of the loaded object. 132254721Semaste lldb::addr_t path_addr; ///< String naming the shared object. 133254721Semaste lldb::addr_t dyn_addr; ///< Dynamic section of shared object. 134254721Semaste lldb::addr_t next; ///< Address of next so_entry. 135254721Semaste lldb::addr_t prev; ///< Address of previous so_entry. 136254721Semaste std::string path; ///< File name of shared object. 137254721Semaste 138254721Semaste SOEntry() { clear(); } 139254721Semaste 140254721Semaste bool operator ==(const SOEntry &entry) { 141254721Semaste return this->path == entry.path; 142254721Semaste } 143254721Semaste 144254721Semaste void clear() { 145254721Semaste base_addr = 0; 146254721Semaste path_addr = 0; 147254721Semaste dyn_addr = 0; 148254721Semaste next = 0; 149254721Semaste prev = 0; 150254721Semaste path.clear(); 151254721Semaste } 152254721Semaste }; 153254721Semaste 154254721Semasteprotected: 155254721Semaste typedef std::list<SOEntry> SOEntryList; 156254721Semaste 157254721Semastepublic: 158254721Semaste typedef SOEntryList::const_iterator iterator; 159254721Semaste 160254721Semaste /// Iterators over all currently loaded modules. 161254721Semaste iterator begin() const { return m_soentries.begin(); } 162254721Semaste iterator end() const { return m_soentries.end(); } 163254721Semaste 164254721Semaste /// Iterators over all modules loaded into the inferior since the last call 165254721Semaste /// to Resolve(). 166254721Semaste iterator loaded_begin() const { return m_added_soentries.begin(); } 167254721Semaste iterator loaded_end() const { return m_added_soentries.end(); } 168254721Semaste 169254721Semaste /// Iterators over all modules unloaded from the inferior since the last 170254721Semaste /// call to Resolve(). 171254721Semaste iterator unloaded_begin() const { return m_removed_soentries.begin(); } 172254721Semaste iterator unloaded_end() const { return m_removed_soentries.end(); } 173254721Semaste 174254721Semasteprotected: 175254721Semaste lldb_private::Process *m_process; 176254721Semaste 177254721Semaste // Cached copy of executable pathname 178254721Semaste char m_exe_path[PATH_MAX]; 179254721Semaste 180254721Semaste /// Location of the r_debug structure in the inferiors address space. 181254721Semaste lldb::addr_t m_rendezvous_addr; 182254721Semaste 183254721Semaste /// Current and previous snapshots of the rendezvous structure. 184254721Semaste Rendezvous m_current; 185254721Semaste Rendezvous m_previous; 186254721Semaste 187254721Semaste /// List of SOEntry objects corresponding to the current link map state. 188254721Semaste SOEntryList m_soentries; 189254721Semaste 190254721Semaste /// List of SOEntry's added to the link map since the last call to Resolve(). 191254721Semaste SOEntryList m_added_soentries; 192254721Semaste 193254721Semaste /// List of SOEntry's removed from the link map since the last call to 194254721Semaste /// Resolve(). 195254721Semaste SOEntryList m_removed_soentries; 196254721Semaste 197254721Semaste /// Reads @p size bytes from the inferiors address space starting at @p 198254721Semaste /// addr. 199254721Semaste /// 200254721Semaste /// @returns addr + size if the read was successful and false otherwise. 201254721Semaste lldb::addr_t 202254721Semaste ReadMemory(lldb::addr_t addr, void *dst, size_t size); 203254721Semaste 204254721Semaste /// Reads a null-terminated C string from the memory location starting at @p 205254721Semaste /// addr. 206254721Semaste std::string 207254721Semaste ReadStringFromMemory(lldb::addr_t addr); 208254721Semaste 209254721Semaste /// Reads an SOEntry starting at @p addr. 210254721Semaste bool 211254721Semaste ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry); 212254721Semaste 213254721Semaste /// Updates the current set of SOEntries, the set of added entries, and the 214254721Semaste /// set of removed entries. 215254721Semaste bool 216254721Semaste UpdateSOEntries(); 217254721Semaste 218254721Semaste bool 219254721Semaste UpdateSOEntriesForAddition(); 220254721Semaste 221254721Semaste bool 222254721Semaste UpdateSOEntriesForDeletion(); 223254721Semaste 224254721Semaste /// Reads the current list of shared objects according to the link map 225254721Semaste /// supplied by the runtime linker. 226254721Semaste bool 227254721Semaste TakeSnapshot(SOEntryList &entry_list); 228254721Semaste}; 229254721Semaste 230254721Semaste#endif 231