HexagonDYLDRendezvous.h revision 276479
128257Smsmith//===-- HexagonDYLDRendezvous.h ---------------------------------*- C++ -*-===// 255939Snsouch// 328257Smsmith// The LLVM Compiler Infrastructure 428257Smsmith// 528257Smsmith// This file is distributed under the University of Illinois Open Source 628257Smsmith// License. See LICENSE.TXT for details. 728257Smsmith// 828257Smsmith//===----------------------------------------------------------------------===// 928257Smsmith 1028257Smsmith#ifndef liblldb_HexagonDYLDRendezvous_H_ 1128257Smsmith#define liblldb_HexagonDYLDRendezvous_H_ 1228257Smsmith 1328257Smsmith// C Includes 1428257Smsmith// C++ Includes 1528257Smsmith#include <list> 1628257Smsmith#include <string> 1728257Smsmith 1828257Smsmith// Other libraries and framework includes 1928257Smsmith#include "lldb/lldb-defines.h" 2028257Smsmith#include "lldb/lldb-types.h" 2128257Smsmith 2228257Smsmithnamespace lldb_private 2328257Smsmith{ 2428257Smsmith class Process; 2528257Smsmith} 26119418Sobrien 27119418Sobrien/// @class HexagonDYLDRendezvous 28119418Sobrien/// @brief Interface to the runtime linker. 29119418Sobrien/// 3028257Smsmith/// A structure is present in a processes memory space which is updated by the 31187576Sjhb/// runtime liker each time a module is loaded or unloaded. This class provides 3228257Smsmith/// an interface to this structure and maintains a consistent snapshot of the 3355939Snsouch/// currently loaded modules. 34187576Sjhbclass HexagonDYLDRendezvous 35187576Sjhb{ 3655939Snsouch 3755939Snsouch // This structure is used to hold the contents of the debug rendezvous 3828257Smsmith // information (struct r_debug) as found in the inferiors memory. Note that 39185003Sjhb // the layout of this struct is not binary compatible, it is simply large 4055939Snsouch // enough to hold the information on both 32 and 64 bit platforms. 4128257Smsmith struct Rendezvous { 4255939Snsouch uint64_t version; 43185003Sjhb lldb::addr_t map_addr; 44119284Simp lldb::addr_t brk; 45119284Simp uint64_t state; 4655939Snsouch lldb::addr_t ldbase; 47185003Sjhb 4828257Smsmith Rendezvous() 4955939Snsouch : version (0) 5028257Smsmith , map_addr(LLDB_INVALID_ADDRESS) 5155939Snsouch , brk (LLDB_INVALID_ADDRESS) 5228257Smsmith , state (0) 5328257Smsmith , ldbase (0) 5428257Smsmith { } 5528257Smsmith 5655939Snsouch }; 5755939Snsouch 5828257Smsmithpublic: 59187576Sjhb // Various metadata supplied by the inferior's threading library to describe 6042475Snsouch // the per-thread state. 6142475Snsouch struct ThreadInfo { 6228257Smsmith bool valid; // whether we read valid metadata 63187576Sjhb uint32_t dtv_offset; // offset of DTV pointer within pthread 64187576Sjhb uint32_t dtv_slot_size; // size of one DTV slot 6542475Snsouch uint32_t modid_offset; // offset of module ID within link_map 6642475Snsouch uint32_t tls_offset; // offset of TLS pointer within DTV slot 6742475Snsouch }; 6855939Snsouch 6942475Snsouch HexagonDYLDRendezvous(lldb_private::Process *process); 7042475Snsouch 7142475Snsouch /// Update the internal snapshot of runtime linker rendezvous and recompute 7242475Snsouch /// the currently loaded modules. 7342475Snsouch /// 7442475Snsouch /// This method should be called once one start up, then once each time the 7542475Snsouch /// runtime linker enters the function given by GetBreakAddress(). 7642475Snsouch /// 7755939Snsouch /// @returns true on success and false on failure. 7828257Smsmith /// 7928257Smsmith /// @see GetBreakAddress(). 80187576Sjhb bool 81187576Sjhb Resolve(); 82187576Sjhb 83187576Sjhb /// @returns true if this rendezvous has been located in the inferiors 84187576Sjhb /// address space and false otherwise. 8542475Snsouch bool 8628257Smsmith IsValid(); 8728257Smsmith 8828257Smsmith /// @returns the address of the rendezvous structure in the inferiors 8928257Smsmith /// address space. 9028257Smsmith lldb::addr_t 9128257Smsmith GetRendezvousAddress() const { return m_rendezvous_addr; } 9255939Snsouch 9338061Smsmith /// Provide the dyld structure address 9455939Snsouch void 9538061Smsmith SetRendezvousAddress( lldb::addr_t ); 9638061Smsmith 9755939Snsouch /// @returns the version of the rendezvous protocol being used. 9838061Smsmith uint64_t 99187576Sjhb GetVersion() const { return m_current.version; } 100187576Sjhb 101187576Sjhb /// @returns address in the inferiors address space containing the linked 10255939Snsouch /// list of shared object descriptors. 10338061Smsmith lldb::addr_t 104187576Sjhb GetLinkMapAddress() const { return m_current.map_addr; } 10555939Snsouch 10638061Smsmith /// A breakpoint should be set at this address and Resolve called on each 10755939Snsouch /// hit. 10855939Snsouch /// 10955939Snsouch /// @returns the address of a function called by the runtime linker each 11055939Snsouch /// time a module is loaded/unloaded, or about to be loaded/unloaded. 11155939Snsouch /// 11255939Snsouch /// @see Resolve() 11355939Snsouch lldb::addr_t 11455939Snsouch GetBreakAddress() const { return m_current.brk; } 11555939Snsouch 11655939Snsouch /// In hexagon it is possible that we can know the dyld breakpoint without 11755939Snsouch /// having to find it from the rendezvous structure 11855939Snsouch /// 11938061Smsmith void 120187576Sjhb SetBreakAddress( lldb::addr_t addr ) { m_current.brk = addr; } 12155939Snsouch 12255939Snsouch /// Returns the current state of the rendezvous structure. 12338061Smsmith uint64_t 12455939Snsouch GetState() const { return m_current.state; } 12555939Snsouch 12655939Snsouch /// @returns the base address of the runtime linker in the inferiors address 12755939Snsouch /// space. 12855939Snsouch lldb::addr_t 12955939Snsouch GetLDBase() const { return m_current.ldbase; } 13055939Snsouch 13155939Snsouch /// @returns the thread layout metadata from the inferiors thread library. 13255939Snsouch const ThreadInfo& 13355939Snsouch GetThreadInfo(); 13455939Snsouch 135187576Sjhb /// @returns true if modules have been loaded into the inferior since the 13663458Sn_hibma /// last call to Resolve(). 137185003Sjhb bool 13855939Snsouch ModulesDidLoad() const { return !m_added_soentries.empty(); } 13963458Sn_hibma 14063458Sn_hibma /// @returns true if modules have been unloaded from the inferior since the 14163458Sn_hibma /// last call to Resolve(). 14238061Smsmith bool 14338061Smsmith ModulesDidUnload() const { return !m_removed_soentries.empty(); } 14438061Smsmith 14538061Smsmith void 14642475Snsouch DumpToLog(lldb_private::Log *log) const; 14742475Snsouch 14842475Snsouch /// @brief Constants describing the state of the rendezvous. 14942475Snsouch /// 15042475Snsouch /// @see GetState(). 15155939Snsouch enum RendezvousState 15242475Snsouch { 153187576Sjhb eConsistent = 0, 154187576Sjhb eAdd , 155187576Sjhb eDelete , 156187576Sjhb }; 157187576Sjhb 15855939Snsouch /// @brief Structure representing the shared objects currently loaded into 15942475Snsouch /// the inferior process. 16042475Snsouch /// 16142475Snsouch /// This object is a rough analogue to the struct link_map object which 16228257Smsmith /// actually lives in the inferiors memory. 16328257Smsmith struct SOEntry { 16438061Smsmith lldb::addr_t link_addr; ///< Address of this link_map. 16528257Smsmith lldb::addr_t base_addr; ///< Base address of the loaded object. 16628257Smsmith lldb::addr_t path_addr; ///< String naming the shared object. 16755939Snsouch lldb::addr_t dyn_addr; ///< Dynamic section of shared object. 16828257Smsmith lldb::addr_t next; ///< Address of next so_entry. 169187576Sjhb lldb::addr_t prev; ///< Address of previous so_entry. 170187576Sjhb std::string path; ///< File name of shared object. 171187576Sjhb 172187576Sjhb SOEntry() { clear(); } 173187576Sjhb 17455939Snsouch bool operator ==(const SOEntry &entry) { 17528257Smsmith return this->path == entry.path; 17628257Smsmith } 17728257Smsmith 17828257Smsmith void clear() { 17928257Smsmith link_addr = 0; 18038061Smsmith base_addr = 0; 18128257Smsmith path_addr = 0; 18228257Smsmith dyn_addr = 0; 18355939Snsouch next = 0; 18428257Smsmith prev = 0; 185187576Sjhb path.clear(); 186187576Sjhb } 187187576Sjhb }; 188187576Sjhb 189187576Sjhbprotected: 19055939Snsouch typedef std::list<SOEntry> SOEntryList; 19128257Smsmith 19228257Smsmithpublic: 19328257Smsmith typedef SOEntryList::const_iterator iterator; 19428257Smsmith 19528257Smsmith /// Iterators over all currently loaded modules. 19638061Smsmith iterator begin() const { return m_soentries.begin(); } 19728257Smsmith iterator end() const { return m_soentries.end(); } 19828257Smsmith 19955939Snsouch /// Iterators over all modules loaded into the inferior since the last call 20028257Smsmith /// to Resolve(). 201187576Sjhb iterator loaded_begin() const { return m_added_soentries.begin(); } 202187576Sjhb iterator loaded_end() const { return m_added_soentries.end(); } 203187576Sjhb 20428257Smsmith /// Iterators over all modules unloaded from the inferior since the last 20528257Smsmith /// call to Resolve(). 206187576Sjhb iterator unloaded_begin() const { return m_removed_soentries.begin(); } 207187576Sjhb iterator unloaded_end() const { return m_removed_soentries.end(); } 20855939Snsouch 20928257Smsmithprotected: 21028257Smsmith lldb_private::Process *m_process; 21128257Smsmith 21228257Smsmith // Cached copy of executable pathname 21339134Snsouch char m_exe_path[PATH_MAX]; 21428257Smsmith 21528257Smsmith /// Location of the r_debug structure in the inferiors address space. 21628257Smsmith lldb::addr_t m_rendezvous_addr; 21728257Smsmith 21828257Smsmith /// Current and previous snapshots of the rendezvous structure. 219187576Sjhb Rendezvous m_current; 220187576Sjhb Rendezvous m_previous; 221187576Sjhb 222187576Sjhb /// List of SOEntry objects corresponding to the current link map state. 223187576Sjhb SOEntryList m_soentries; 224187576Sjhb 225187576Sjhb /// List of SOEntry's added to the link map since the last call to Resolve(). 226187576Sjhb SOEntryList m_added_soentries; 227187576Sjhb 228187576Sjhb /// List of SOEntry's removed from the link map since the last call to 229187576Sjhb /// Resolve(). 230187576Sjhb SOEntryList m_removed_soentries; 231187576Sjhb 232187576Sjhb /// Threading metadata read from the inferior. 233187576Sjhb ThreadInfo m_thread_info; 234187576Sjhb 235187576Sjhb /// Reads an unsigned integer of @p size bytes from the inferior's address 236187576Sjhb /// space starting at @p addr. 237187576Sjhb /// 238187576Sjhb /// @returns addr + size if the read was successful and false otherwise. 239187576Sjhb lldb::addr_t 240230799Sattilio ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size); 241187576Sjhb 242187576Sjhb /// Reads an address from the inferior's address space starting at @p addr. 243187576Sjhb /// 244187576Sjhb /// @returns addr + target address size if the read was successful and 245187576Sjhb /// 0 otherwise. 246187576Sjhb lldb::addr_t 247187576Sjhb ReadPointer(lldb::addr_t addr, lldb::addr_t *dst); 248187576Sjhb 249187576Sjhb /// Reads a null-terminated C string from the memory location starting at @p 250187576Sjhb /// addr. 251187576Sjhb std::string 252187576Sjhb ReadStringFromMemory(lldb::addr_t addr); 253187576Sjhb 254187576Sjhb /// Reads an SOEntry starting at @p addr. 255187576Sjhb bool 256187576Sjhb ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry); 257187576Sjhb 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