]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / DynamicLoader / POSIX-DYLD / DYLDRendezvous.h
1 //===-- DYLDRendezvous.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_Rendezvous_H_
11 #define liblldb_Rendezvous_H_
12
13 // C Includes
14 // C++ Includes
15 #include <list>
16 #include <string>
17
18 // Other libraries and framework includes
19 #include "lldb/Utility/FileSpec.h"
20 #include "lldb/lldb-defines.h"
21 #include "lldb/lldb-types.h"
22
23 #include "lldb/Core/LoadedModuleInfoList.h"
24
25 using lldb_private::LoadedModuleInfoList;
26
27 namespace lldb_private {
28 class Process;
29 }
30
31 /// @class DYLDRendezvous
32 /// Interface to the runtime linker.
33 ///
34 /// A structure is present in a processes memory space which is updated by the
35 /// runtime liker each time a module is loaded or unloaded.  This class
36 /// provides an interface to this structure and maintains a consistent
37 /// snapshot of the currently loaded modules.
38 class DYLDRendezvous {
39
40   // This structure is used to hold the contents of the debug rendezvous
41   // information (struct r_debug) as found in the inferiors memory.  Note that
42   // the layout of this struct is not binary compatible, it is simply large
43   // enough to hold the information on both 32 and 64 bit platforms.
44   struct Rendezvous {
45     uint64_t version;
46     lldb::addr_t map_addr;
47     lldb::addr_t brk;
48     uint64_t state;
49     lldb::addr_t ldbase;
50
51     Rendezvous() : version(0), map_addr(0), brk(0), state(0), ldbase(0) {}
52   };
53
54 public:
55   // Various metadata supplied by the inferior's threading library to describe
56   // the per-thread state.
57   struct ThreadInfo {
58     bool valid;             // whether we read valid metadata
59     uint32_t dtv_offset;    // offset of DTV pointer within pthread
60     uint32_t dtv_slot_size; // size of one DTV slot
61     uint32_t modid_offset;  // offset of module ID within link_map
62     uint32_t tls_offset;    // offset of TLS pointer within DTV slot
63   };
64
65   DYLDRendezvous(lldb_private::Process *process);
66
67   /// Update the internal snapshot of runtime linker rendezvous and recompute
68   /// the currently loaded modules.
69   ///
70   /// This method should be called once one start up, then once each time the
71   /// runtime linker enters the function given by GetBreakAddress().
72   ///
73   /// @returns true on success and false on failure.
74   ///
75   /// @see GetBreakAddress().
76   bool Resolve();
77
78   /// @returns true if this rendezvous has been located in the inferiors
79   /// address space and false otherwise.
80   bool IsValid();
81
82   /// @returns the address of the rendezvous structure in the inferiors
83   /// address space.
84   lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }
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   /// Returns the current state of the rendezvous structure.
103   uint64_t GetState() const { return m_current.state; }
104
105   /// @returns the base address of the runtime linker in the inferiors address
106   /// space.
107   lldb::addr_t GetLDBase() const { return m_current.ldbase; }
108
109   /// @returns the thread layout metadata from the inferiors thread library.
110   const ThreadInfo &GetThreadInfo();
111
112   /// @returns true if modules have been loaded into the inferior since the
113   /// last call to Resolve().
114   bool ModulesDidLoad() const { return !m_added_soentries.empty(); }
115
116   /// @returns true if modules have been unloaded from the inferior since the
117   /// last call to Resolve().
118   bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }
119
120   void DumpToLog(lldb_private::Log *log) const;
121
122   /// Constants describing the state of the rendezvous.
123   ///
124   /// @see GetState().
125   enum RendezvousState { eConsistent, eAdd, eDelete };
126
127   /// Structure representing the shared objects currently loaded into the
128   /// inferior process.
129   ///
130   /// This object is a rough analogue to the struct link_map object which
131   /// actually lives in the inferiors memory.
132   struct SOEntry {
133     lldb::addr_t link_addr;           ///< Address of this link_map.
134     lldb::addr_t base_addr;           ///< Base address of the loaded object.
135     lldb::addr_t path_addr;           ///< String naming the shared object.
136     lldb::addr_t dyn_addr;            ///< Dynamic section of shared object.
137     lldb::addr_t next;                ///< Address of next so_entry.
138     lldb::addr_t prev;                ///< Address of previous so_entry.
139     lldb_private::FileSpec file_spec; ///< File spec of shared object.
140
141     SOEntry() { clear(); }
142
143     bool operator==(const SOEntry &entry) {
144       return file_spec == entry.file_spec;
145     }
146
147     void clear() {
148       link_addr = 0;
149       base_addr = 0;
150       path_addr = 0;
151       dyn_addr = 0;
152       next = 0;
153       prev = 0;
154       file_spec.Clear();
155     }
156   };
157
158 protected:
159   typedef std::list<SOEntry> SOEntryList;
160
161 public:
162   typedef SOEntryList::const_iterator iterator;
163
164   /// Iterators over all currently loaded modules.
165   iterator begin() const { return m_soentries.begin(); }
166   iterator end() const { return m_soentries.end(); }
167
168   /// Iterators over all modules loaded into the inferior since the last call
169   /// to Resolve().
170   iterator loaded_begin() const { return m_added_soentries.begin(); }
171   iterator loaded_end() const { return m_added_soentries.end(); }
172
173   /// Iterators over all modules unloaded from the inferior since the last
174   /// call to Resolve().
175   iterator unloaded_begin() const { return m_removed_soentries.begin(); }
176   iterator unloaded_end() const { return m_removed_soentries.end(); }
177
178 protected:
179   lldb_private::Process *m_process;
180
181   // Cached copy of executable file spec
182   lldb_private::FileSpec m_exe_file_spec;
183
184   /// Location of the r_debug structure in the inferiors address space.
185   lldb::addr_t m_rendezvous_addr;
186
187   /// Current and previous snapshots of the rendezvous structure.
188   Rendezvous m_current;
189   Rendezvous m_previous;
190
191   /// List of currently loaded SO modules
192   LoadedModuleInfoList m_loaded_modules;
193
194   /// List of SOEntry objects corresponding to the current link map state.
195   SOEntryList m_soentries;
196
197   /// List of SOEntry's added to the link map since the last call to
198   /// Resolve().
199   SOEntryList m_added_soentries;
200
201   /// List of SOEntry's removed from the link map since the last call to
202   /// Resolve().
203   SOEntryList m_removed_soentries;
204
205   /// Threading metadata read from the inferior.
206   ThreadInfo m_thread_info;
207
208   /// Reads an unsigned integer of @p size bytes from the inferior's address
209   /// space starting at @p addr.
210   ///
211   /// @returns addr + size if the read was successful and false otherwise.
212   lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
213
214   /// Reads an address from the inferior's address space starting at @p addr.
215   ///
216   /// @returns addr + target address size if the read was successful and
217   /// 0 otherwise.
218   lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
219
220   /// Reads a null-terminated C string from the memory location starting at @p
221   /// addr.
222   std::string ReadStringFromMemory(lldb::addr_t addr);
223
224   /// Reads an SOEntry starting at @p addr.
225   bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
226
227   /// Updates the current set of SOEntries, the set of added entries, and the
228   /// set of removed entries.
229   bool UpdateSOEntries(bool fromRemote = false);
230
231   bool FillSOEntryFromModuleInfo(
232       LoadedModuleInfoList::LoadedModuleInfo const &modInfo, SOEntry &entry);
233
234   bool SaveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
235
236   bool AddSOEntriesFromRemote(LoadedModuleInfoList &module_list);
237
238   bool RemoveSOEntriesFromRemote(LoadedModuleInfoList &module_list);
239
240   bool AddSOEntries();
241
242   bool RemoveSOEntries();
243
244   void UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path);
245
246   bool SOEntryIsMainExecutable(const SOEntry &entry);
247
248   /// Reads the current list of shared objects according to the link map
249   /// supplied by the runtime linker.
250   bool TakeSnapshot(SOEntryList &entry_list);
251
252   enum PThreadField { eSize, eNElem, eOffset };
253
254   bool FindMetadata(const char *name, PThreadField field, uint32_t &value);
255 };
256
257 #endif