]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / DynamicLoader / Hexagon-DYLD / HexagonDYLDRendezvous.h
1 //===-- HexagonDYLDRendezvous.h ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef liblldb_HexagonDYLDRendezvous_H_
10 #define liblldb_HexagonDYLDRendezvous_H_
11
12 #include <limits.h>
13 #include <list>
14 #include <map>
15 #include <string>
16
17 #include "lldb/lldb-defines.h"
18 #include "lldb/lldb-types.h"
19
20 namespace lldb_private {
21 class Process;
22 }
23
24 /// \class HexagonDYLDRendezvous
25 /// Interface to the runtime linker.
26 ///
27 /// A structure is present in a processes memory space which is updated by the
28 /// runtime liker each time a module is loaded or unloaded.  This class
29 /// provides an interface to this structure and maintains a consistent
30 /// snapshot of the currently loaded modules.
31 class HexagonDYLDRendezvous {
32
33   // This structure is used to hold the contents of the debug rendezvous
34   // information (struct r_debug) as found in the inferiors memory.  Note that
35   // the layout of this struct is not binary compatible, it is simply large
36   // enough to hold the information on both 32 and 64 bit platforms.
37   struct Rendezvous {
38     uint64_t version;
39     lldb::addr_t map_addr;
40     lldb::addr_t brk;
41     uint64_t state;
42     lldb::addr_t ldbase;
43
44     Rendezvous()
45         : version(0), map_addr(LLDB_INVALID_ADDRESS), brk(LLDB_INVALID_ADDRESS),
46           state(0), ldbase(0) {}
47   };
48
49 public:
50   // Various metadata supplied by the inferior's threading library to describe
51   // the per-thread state.
52   struct ThreadInfo {
53     bool valid;             // whether we read valid metadata
54     uint32_t dtv_offset;    // offset of DTV pointer within pthread
55     uint32_t dtv_slot_size; // size of one DTV slot
56     uint32_t modid_offset;  // offset of module ID within link_map
57     uint32_t tls_offset;    // offset of TLS pointer within DTV slot
58   };
59
60   HexagonDYLDRendezvous(lldb_private::Process *process);
61
62   /// Update the internal snapshot of runtime linker rendezvous and recompute
63   /// the currently loaded modules.
64   ///
65   /// This method should be called once one start up, then once each time the
66   /// runtime linker enters the function given by GetBreakAddress().
67   ///
68   /// \returns true on success and false on failure.
69   ///
70   /// \see GetBreakAddress().
71   bool Resolve();
72
73   /// \returns true if this rendezvous has been located in the inferiors
74   /// address space and false otherwise.
75   bool IsValid();
76
77   /// \returns the address of the rendezvous structure in the inferiors
78   /// address space.
79   lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
80
81   /// Provide the dyld structure address
82   void SetRendezvousAddress(lldb::addr_t);
83
84   /// \returns the version of the rendezvous protocol being used.
85   uint64_t GetVersion() const { return m_current.version; }
86
87   /// \returns address in the inferiors address space containing the linked
88   /// list of shared object descriptors.
89   lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }
90
91   /// A breakpoint should be set at this address and Resolve called on each
92   /// hit.
93   ///
94   /// \returns the address of a function called by the runtime linker each
95   /// time a module is loaded/unloaded, or about to be loaded/unloaded.
96   ///
97   /// \see Resolve()
98   lldb::addr_t GetBreakAddress() const { return m_current.brk; }
99
100   /// In hexagon it is possible that we can know the dyld breakpoint without
101   /// having to find it from the rendezvous structure
102   ///
103   void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }
104
105   /// Returns the current state of the rendezvous structure.
106   uint64_t GetState() const { return m_current.state; }
107
108   /// \returns the base address of the runtime linker in the inferiors address
109   /// space.
110   lldb::addr_t GetLDBase() const { return m_current.ldbase; }
111
112   /// \returns the thread layout metadata from the inferiors thread library.
113   const ThreadInfo &GetThreadInfo();
114
115   /// \returns true if modules have been loaded into the inferior since the
116   /// last call to Resolve().
117   bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
118
119   /// \returns true if modules have been unloaded from the inferior since the
120   /// last call to Resolve().
121   bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
122
123   void DumpToLog(lldb_private::Log *log) const;
124
125   /// Constants describing the state of the rendezvous.
126   ///
127   /// \see GetState().
128   enum RendezvousState {
129     eConsistent = 0,
130     eAdd,
131     eDelete,
132   };
133
134   /// Structure representing the shared objects currently loaded into the
135   /// inferior process.
136   ///
137   /// This object is a rough analogue to the struct link_map object which
138   /// actually lives in the inferiors memory.
139   struct SOEntry {
140     lldb::addr_t link_addr; ///< Address of this link_map.
141     lldb::addr_t base_addr; ///< Base address of the loaded object.
142     lldb::addr_t path_addr; ///< String naming the shared object.
143     lldb::addr_t dyn_addr;  ///< Dynamic section of shared object.
144     lldb::addr_t next;      ///< Address of next so_entry.
145     lldb::addr_t prev;      ///< Address of previous so_entry.
146     std::string path;       ///< File name of shared object.
147
148     SOEntry() { clear(); }
149
150     bool operator==(const SOEntry &entry) { return this->path == entry.path; }
151
152     void clear() {
153       link_addr = 0;
154       base_addr = 0;
155       path_addr = 0;
156       dyn_addr = 0;
157       next = 0;
158       prev = 0;
159       path.clear();
160     }
161   };
162
163 protected:
164   typedef std::list<SOEntry> SOEntryList;
165
166 public:
167   typedef SOEntryList::const_iterator iterator;
168
169   /// Iterators over all currently loaded modules.
170   iterator begin() const { return m_soentries.begin(); }
171   iterator end() const { return m_soentries.end(); }
172
173   /// Iterators over all modules loaded into the inferior since the last call
174   /// to Resolve().
175   iterator loaded_begin() const { return m_added_soentries.begin(); }
176   iterator loaded_end() const { return m_added_soentries.end(); }
177
178   /// Iterators over all modules unloaded from the inferior since the last
179   /// call to Resolve().
180   iterator unloaded_begin() const { return m_removed_soentries.begin(); }
181   iterator unloaded_end() const { return m_removed_soentries.end(); }
182
183 protected:
184   lldb_private::Process *m_process;
185
186   // Cached copy of executable pathname
187   char m_exe_path[PATH_MAX];
188
189   /// Location of the r_debug structure in the inferiors address space.
190   lldb::addr_t m_rendezvous_addr;
191
192   /// Current and previous snapshots of the rendezvous structure.
193   Rendezvous m_current;
194   Rendezvous m_previous;
195
196   /// List of SOEntry objects corresponding to the current link map state.
197   SOEntryList m_soentries;
198
199   /// List of SOEntry's added to the link map since the last call to
200   /// Resolve().
201   SOEntryList m_added_soentries;
202
203   /// List of SOEntry's removed from the link map since the last call to
204   /// Resolve().
205   SOEntryList m_removed_soentries;
206
207   /// Threading metadata read from the inferior.
208   ThreadInfo m_thread_info;
209
210   /// Reads an unsigned integer of \p size bytes from the inferior's address
211   /// space starting at \p addr.
212   ///
213   /// \returns addr + size if the read was successful and false otherwise.
214   lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
215
216   /// Reads an address from the inferior's address space starting at \p addr.
217   ///
218   /// \returns addr + target address size if the read was successful and
219   /// 0 otherwise.
220   lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
221
222   /// Reads a null-terminated C string from the memory location starting at @p
223   /// addr.
224   std::string ReadStringFromMemory(lldb::addr_t addr);
225
226   /// Reads an SOEntry starting at \p addr.
227   bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
228
229   /// Updates the current set of SOEntries, the set of added entries, and the
230   /// set of removed entries.
231   bool UpdateSOEntries();
232
233   bool UpdateSOEntriesForAddition();
234
235   bool UpdateSOEntriesForDeletion();
236
237   /// Reads the current list of shared objects according to the link map
238   /// supplied by the runtime linker.
239   bool TakeSnapshot(SOEntryList &entry_list);
240
241   enum PThreadField { eSize, eNElem, eOffset };
242
243   bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
244 };
245
246 #endif // liblldb_HexagonDYLDRendezvous_H_