]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
Upgrade to OpenSSH 7.8p1.
[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 // C++ Includes
15 #include <list>
16 #include <string>
17
18 // Other libraries and framework includes
19 #include "lldb/lldb-defines.h"
20 #include "lldb/lldb-types.h"
21
22 namespace lldb_private {
23 class Process;
24 }
25
26 /// @class HexagonDYLDRendezvous
27 /// @brief Interface to the runtime linker.
28 ///
29 /// A structure is present in a processes memory space which is updated by the
30 /// runtime liker each time a module is loaded or unloaded.  This class provides
31 /// an interface to this structure and maintains a consistent snapshot of the
32 /// currently loaded modules.
33 class HexagonDYLDRendezvous {
34
35   // This structure is used to hold the contents of the debug rendezvous
36   // information (struct r_debug) as found in the inferiors memory.  Note that
37   // the layout of this struct is not binary compatible, it is simply large
38   // enough to hold the information on both 32 and 64 bit platforms.
39   struct Rendezvous {
40     uint64_t version;
41     lldb::addr_t map_addr;
42     lldb::addr_t brk;
43     uint64_t state;
44     lldb::addr_t ldbase;
45
46     Rendezvous()
47         : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
48           state(0), ldbase(0) {}
49   };
50
51 public:
52   // Various metadata supplied by the inferior's threading library to describe
53   // the per-thread state.
54   struct ThreadInfo {
55     bool valid;             // whether we read valid metadata
56     uint32_t dtv_offset;    // offset of DTV pointer within pthread
57     uint32_t dtv_slot_size; // size of one DTV slot
58     uint32_t modid_offset;  // offset of module ID within link_map
59     uint32_t tls_offset;    // offset of TLS pointer within DTV slot
60   };
61
62   HexagonDYLDRendezvous(lldb_private::Process *process);
63
64   /// Update the internal snapshot of runtime linker rendezvous and recompute
65   /// the currently loaded modules.
66   ///
67   /// This method should be called once one start up, then once each time the
68   /// runtime linker enters the function given by GetBreakAddress().
69   ///
70   /// @returns true on success and false on failure.
71   ///
72   /// @see GetBreakAddress().
73   bool Resolve();
74
75   /// @returns true if this rendezvous has been located in the inferiors
76   /// address space and false otherwise.
77   bool IsValid();
78
79   /// @returns the address of the rendezvous structure in the inferiors
80   /// address space.
81   lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
82
83   /// Provide the dyld structure address
84   void SetRendezvousAddress(lldb::addr_t);
85
86   /// @returns the version of the rendezvous protocol being used.
87   uint64_t GetVersion() const { return m_current.version; }
88
89   /// @returns address in the inferiors address space containing the linked
90   /// list of shared object descriptors.
91   lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
92
93   /// A breakpoint should be set at this address and Resolve called on each
94   /// hit.
95   ///
96   /// @returns the address of a function called by the runtime linker each
97   /// time a module is loaded/unloaded, or about to be loaded/unloaded.
98   ///
99   /// @see Resolve()
100   lldb::addr_t GetBreakAddress() const { return m_current.brk; }
101
102   /// In hexagon it is possible that we can know the dyld breakpoint without
103   /// having to find it from the rendezvous structure
104   ///
105   void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
106
107   /// Returns the current state of the rendezvous structure.
108   uint64_t GetState() const { return m_current.state; }
109
110   /// @returns the base address of the runtime linker in the inferiors address
111   /// space.
112   lldb::addr_t GetLDBase() const { return m_current.ldbase; }
113
114   /// @returns the thread layout metadata from the inferiors thread library.
115   const ThreadInfo &GetThreadInfo();
116
117   /// @returns true if modules have been loaded into the inferior since the
118   /// last call to Resolve().
119   bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
120
121   /// @returns true if modules have been unloaded from the inferior since the
122   /// last call to Resolve().
123   bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
124
125   void DumpToLog(lldb_private::Log *log) const;
126
127   /// @brief Constants describing the state of the rendezvous.
128   ///
129   /// @see GetState().
130   enum RendezvousState {
131     eConsistent = 0,
132     eAdd,
133     eDelete,
134   };
135
136   /// @brief Structure representing the shared objects currently loaded into
137   /// the inferior process.
138   ///
139   /// This object is a rough analogue to the struct link_map object which
140   /// actually lives in the inferiors memory.
141   struct SOEntry {
142     lldb::addr_t link_addr; ///< Address of this link_map.
143     lldb::addr_t base_addr; ///< Base address of the loaded object.
144     lldb::addr_t path_addr; ///< String naming the shared object.
145     lldb::addr_t dyn_addr;  ///< Dynamic section of shared object.
146     lldb::addr_t next;      ///< Address of next so_entry.
147     lldb::addr_t prev;      ///< Address of previous so_entry.
148     std::string path;       ///< File name of shared object.
149
150     SOEntry() { clear(); }
151
152     bool operator==(const SOEntry &entry) { return this->path == entry.path; }
153
154     void clear() {
155       link_addr = 0;
156       base_addr = 0;
157       path_addr = 0;
158       dyn_addr = 0;
159       next = 0;
160       prev = 0;
161       path.clear();
162     }
163   };
164
165 protected:
166   typedef std::list<SOEntry> SOEntryList;
167
168 public:
169   typedef SOEntryList::const_iterator iterator;
170
171   /// Iterators over all currently loaded modules.
172   iterator begin() const { return m_soentries.begin(); }
173   iterator end() const { return m_soentries.end(); }
174
175   /// Iterators over all modules loaded into the inferior since the last call
176   /// to Resolve().
177   iterator loaded_begin() const { return m_added_soentries.begin(); }
178   iterator loaded_end() const { return m_added_soentries.end(); }
179
180   /// Iterators over all modules unloaded from the inferior since the last
181   /// call to Resolve().
182   iterator unloaded_begin() const { return m_removed_soentries.begin(); }
183   iterator unloaded_end() const { return m_removed_soentries.end(); }
184
185 protected:
186   lldb_private::Process *m_process;
187
188   // Cached copy of executable pathname
189   char m_exe_path[PATH_MAX];
190
191   /// Location of the r_debug structure in the inferiors address space.
192   lldb::addr_t m_rendezvous_addr;
193
194   /// Current and previous snapshots of the rendezvous structure.
195   Rendezvous m_current;
196   Rendezvous m_previous;
197
198   /// List of SOEntry objects corresponding to the current link map state.
199   SOEntryList m_soentries;
200
201   /// List of SOEntry's added to the link map since the last call to 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_