1 //===-- HexagonDYLDRendezvous.h ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_HexagonDYLDRendezvous_H_
11 #define liblldb_HexagonDYLDRendezvous_H_
14 #include <limits.h> // for PATH_MAX
20 // Other libraries and framework includes
21 #include "lldb/lldb-defines.h"
22 #include "lldb/lldb-types.h"
24 namespace lldb_private {
28 /// @class HexagonDYLDRendezvous
29 /// Interface to the runtime linker.
31 /// A structure is present in a processes memory space which is updated by the
32 /// runtime liker each time a module is loaded or unloaded. This class
33 /// provides an interface to this structure and maintains a consistent
34 /// snapshot of the currently loaded modules.
35 class HexagonDYLDRendezvous {
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.
43 lldb::addr_t map_addr;
49 : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
50 state(0), ldbase(0) {}
54 // Various metadata supplied by the inferior's threading library to describe
55 // the per-thread state.
57 bool valid; // whether we read valid metadata
58 uint32_t dtv_offset; // offset of DTV pointer within pthread
59 uint32_t dtv_slot_size; // size of one DTV slot
60 uint32_t modid_offset; // offset of module ID within link_map
61 uint32_t tls_offset; // offset of TLS pointer within DTV slot
64 HexagonDYLDRendezvous(lldb_private::Process *process);
66 /// Update the internal snapshot of runtime linker rendezvous and recompute
67 /// the currently loaded modules.
69 /// This method should be called once one start up, then once each time the
70 /// runtime linker enters the function given by GetBreakAddress().
72 /// @returns true on success and false on failure.
74 /// @see GetBreakAddress().
77 /// @returns true if this rendezvous has been located in the inferiors
78 /// address space and false otherwise.
81 /// @returns the address of the rendezvous structure in the inferiors
83 lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
85 /// Provide the dyld structure address
86 void SetRendezvousAddress(lldb::addr_t);
88 /// @returns the version of the rendezvous protocol being used.
89 uint64_t GetVersion() const { return m_current.version; }
91 /// @returns address in the inferiors address space containing the linked
92 /// list of shared object descriptors.
93 lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
95 /// A breakpoint should be set at this address and Resolve called on each
98 /// @returns the address of a function called by the runtime linker each
99 /// time a module is loaded/unloaded, or about to be loaded/unloaded.
102 lldb::addr_t GetBreakAddress() const { return m_current.brk; }
104 /// In hexagon it is possible that we can know the dyld breakpoint without
105 /// having to find it from the rendezvous structure
107 void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
109 /// Returns the current state of the rendezvous structure.
110 uint64_t GetState() const { return m_current.state; }
112 /// @returns the base address of the runtime linker in the inferiors address
114 lldb::addr_t GetLDBase() const { return m_current.ldbase; }
116 /// @returns the thread layout metadata from the inferiors thread library.
117 const ThreadInfo &GetThreadInfo();
119 /// @returns true if modules have been loaded into the inferior since the
120 /// last call to Resolve().
121 bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
123 /// @returns true if modules have been unloaded from the inferior since the
124 /// last call to Resolve().
125 bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
127 void DumpToLog(lldb_private::Log *log) const;
129 /// Constants describing the state of the rendezvous.
132 enum RendezvousState {
138 /// Structure representing the shared objects currently loaded into the
139 /// inferior process.
141 /// This object is a rough analogue to the struct link_map object which
142 /// actually lives in the inferiors memory.
144 lldb::addr_t link_addr; ///< Address of this link_map.
145 lldb::addr_t base_addr; ///< Base address of the loaded object.
146 lldb::addr_t path_addr; ///< String naming the shared object.
147 lldb::addr_t dyn_addr; ///< Dynamic section of shared object.
148 lldb::addr_t next; ///< Address of next so_entry.
149 lldb::addr_t prev; ///< Address of previous so_entry.
150 std::string path; ///< File name of shared object.
152 SOEntry() { clear(); }
154 bool operator==(const SOEntry &entry) { return this->path == entry.path; }
168 typedef std::list<SOEntry> SOEntryList;
171 typedef SOEntryList::const_iterator iterator;
173 /// Iterators over all currently loaded modules.
174 iterator begin() const { return m_soentries.begin(); }
175 iterator end() const { return m_soentries.end(); }
177 /// Iterators over all modules loaded into the inferior since the last call
179 iterator loaded_begin() const { return m_added_soentries.begin(); }
180 iterator loaded_end() const { return m_added_soentries.end(); }
182 /// Iterators over all modules unloaded from the inferior since the last
183 /// call to Resolve().
184 iterator unloaded_begin() const { return m_removed_soentries.begin(); }
185 iterator unloaded_end() const { return m_removed_soentries.end(); }
188 lldb_private::Process *m_process;
190 // Cached copy of executable pathname
191 char m_exe_path[PATH_MAX];
193 /// Location of the r_debug structure in the inferiors address space.
194 lldb::addr_t m_rendezvous_addr;
196 /// Current and previous snapshots of the rendezvous structure.
197 Rendezvous m_current;
198 Rendezvous m_previous;
200 /// List of SOEntry objects corresponding to the current link map state.
201 SOEntryList m_soentries;
203 /// List of SOEntry's added to the link map since the last call to
205 SOEntryList m_added_soentries;
207 /// List of SOEntry's removed from the link map since the last call to
209 SOEntryList m_removed_soentries;
211 /// Threading metadata read from the inferior.
212 ThreadInfo m_thread_info;
214 /// Reads an unsigned integer of @p size bytes from the inferior's address
215 /// space starting at @p addr.
217 /// @returns addr + size if the read was successful and false otherwise.
218 lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
220 /// Reads an address from the inferior's address space starting at @p addr.
222 /// @returns addr + target address size if the read was successful and
224 lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
226 /// Reads a null-terminated C string from the memory location starting at @p
228 std::string ReadStringFromMemory(lldb::addr_t addr);
230 /// Reads an SOEntry starting at @p addr.
231 bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
233 /// Updates the current set of SOEntries, the set of added entries, and the
234 /// set of removed entries.
235 bool UpdateSOEntries();
237 bool UpdateSOEntriesForAddition();
239 bool UpdateSOEntriesForDeletion();
241 /// Reads the current list of shared objects according to the link map
242 /// supplied by the runtime linker.
243 bool TakeSnapshot(SOEntryList &entry_list);
245 enum PThreadField { eSize, eNElem, eOffset };
247 bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
250 #endif // liblldb_HexagonDYLDRendezvous_H_