]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / DynamicLoader / Hexagon-DYLD / HexagonDYLDRendezvous.h
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
21 namespace lldb_private {
22 class 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.
32 class 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
50 public:
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
164 protected:
165   typedef std::list<SOEntry> SOEntryList;
166
167 public:
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
184 protected:
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_