]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
Copy googletest 1.8.1 from ^/vendor/google/googletest/1.8.1 to .../contrib/googletest
[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 // C Includes
14 #include <limits.h> // for PATH_MAX
15 // C++ Includes
16 #include <list>
17 #include <map>
18 #include <string>
19
20 // Other libraries and framework includes
21 #include "lldb/lldb-defines.h"
22 #include "lldb/lldb-types.h"
23
24 namespace lldb_private {
25 class Process;
26 }
27
28 /// @class HexagonDYLDRendezvous
29 /// Interface to the runtime linker.
30 ///
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 {
36
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.
41   struct Rendezvous {
42     uint64_t version;
43     lldb::addr_t map_addr;
44     lldb::addr_t brk;
45     uint64_t state;
46     lldb::addr_t ldbase;
47
48     Rendezvous()
49         : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
50           state(0), ldbase(0) {}
51   };
52
53 public:
54   // Various metadata supplied by the inferior's threading library to describe
55   // the per-thread state.
56   struct ThreadInfo {
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
62   };
63
64   HexagonDYLDRendezvous(lldb_private::Process *process);
65
66   /// Update the internal snapshot of runtime linker rendezvous and recompute
67   /// the currently loaded modules.
68   ///
69   /// This method should be called once one start up, then once each time the
70   /// runtime linker enters the function given by GetBreakAddress().
71   ///
72   /// @returns true on success and false on failure.
73   ///
74   /// @see GetBreakAddress().
75   bool Resolve();
76
77   /// @returns true if this rendezvous has been located in the inferiors
78   /// address space and false otherwise.
79   bool IsValid();
80
81   /// @returns the address of the rendezvous structure in the inferiors
82   /// address space.
83   lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
84
85   /// Provide the dyld structure address
86   void SetRendezvousAddress(lldb::addr_t);
87
88   /// @returns the version of the rendezvous protocol being used.
89   uint64_t GetVersion() const { return m_current.version; }
90
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; }
94
95   /// A breakpoint should be set at this address and Resolve called on each
96   /// hit.
97   ///
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.
100   ///
101   /// @see Resolve()
102   lldb::addr_t GetBreakAddress() const { return m_current.brk; }
103
104   /// In hexagon it is possible that we can know the dyld breakpoint without
105   /// having to find it from the rendezvous structure
106   ///
107   void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
108
109   /// Returns the current state of the rendezvous structure.
110   uint64_t GetState() const { return m_current.state; }
111
112   /// @returns the base address of the runtime linker in the inferiors address
113   /// space.
114   lldb::addr_t GetLDBase() const { return m_current.ldbase; }
115
116   /// @returns the thread layout metadata from the inferiors thread library.
117   const ThreadInfo &GetThreadInfo();
118
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(); }
122
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(); }
126
127   void DumpToLog(lldb_private::Log *log) const;
128
129   /// Constants describing the state of the rendezvous.
130   ///
131   /// @see GetState().
132   enum RendezvousState {
133     eConsistent = 0,
134     eAdd,
135     eDelete,
136   };
137
138   /// Structure representing the shared objects currently loaded into the
139   /// inferior process.
140   ///
141   /// This object is a rough analogue to the struct link_map object which
142   /// actually lives in the inferiors memory.
143   struct SOEntry {
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.
151
152     SOEntry() { clear(); }
153
154     bool operator==(const SOEntry &entry) { return this->path == entry.path; }
155
156     void clear() {
157       link_addr = 0;
158       base_addr = 0;
159       path_addr = 0;
160       dyn_addr = 0;
161       next = 0;
162       prev = 0;
163       path.clear();
164     }
165   };
166
167 protected:
168   typedef std::list<SOEntry> SOEntryList;
169
170 public:
171   typedef SOEntryList::const_iterator iterator;
172
173   /// Iterators over all currently loaded modules.
174   iterator begin() const { return m_soentries.begin(); }
175   iterator end() const { return m_soentries.end(); }
176
177   /// Iterators over all modules loaded into the inferior since the last call
178   /// to Resolve().
179   iterator loaded_begin() const { return m_added_soentries.begin(); }
180   iterator loaded_end() const { return m_added_soentries.end(); }
181
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(); }
186
187 protected:
188   lldb_private::Process *m_process;
189
190   // Cached copy of executable pathname
191   char m_exe_path[PATH_MAX];
192
193   /// Location of the r_debug structure in the inferiors address space.
194   lldb::addr_t m_rendezvous_addr;
195
196   /// Current and previous snapshots of the rendezvous structure.
197   Rendezvous m_current;
198   Rendezvous m_previous;
199
200   /// List of SOEntry objects corresponding to the current link map state.
201   SOEntryList m_soentries;
202
203   /// List of SOEntry's added to the link map since the last call to
204   /// Resolve().
205   SOEntryList m_added_soentries;
206
207   /// List of SOEntry's removed from the link map since the last call to
208   /// Resolve().
209   SOEntryList m_removed_soentries;
210
211   /// Threading metadata read from the inferior.
212   ThreadInfo m_thread_info;
213
214   /// Reads an unsigned integer of @p size bytes from the inferior's address
215   /// space starting at @p addr.
216   ///
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);
219
220   /// Reads an address from the inferior's address space starting at @p addr.
221   ///
222   /// @returns addr + target address size if the read was successful and
223   /// 0 otherwise.
224   lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
225
226   /// Reads a null-terminated C string from the memory location starting at @p
227   /// addr.
228   std::string ReadStringFromMemory(lldb::addr_t addr);
229
230   /// Reads an SOEntry starting at @p addr.
231   bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
232
233   /// Updates the current set of SOEntries, the set of added entries, and the
234   /// set of removed entries.
235   bool UpdateSOEntries();
236
237   bool UpdateSOEntriesForAddition();
238
239   bool UpdateSOEntriesForDeletion();
240
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);
244
245   enum PThreadField { eSize, eNElem, eOffset };
246
247   bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
248 };
249
250 #endif // liblldb_HexagonDYLDRendezvous_H_