]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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/lldb-defines.h"
20 #include "lldb/lldb-types.h"
21
22 namespace lldb_private {
23 class Process;
24 }
25
26 /// @class DYLDRendezvous
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 DYLDRendezvous {
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(0), brk(0), 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     DYLDRendezvous(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 
73     Resolve();
74
75     /// @returns true if this rendezvous has been located in the inferiors
76     /// address space and false otherwise.
77     bool 
78     IsValid();
79
80     /// @returns the address of the rendezvous structure in the inferiors
81     /// address space.
82     lldb::addr_t
83     GetRendezvousAddress() const { return m_rendezvous_addr; }
84
85     /// @returns the version of the rendezvous protocol being used.
86     uint64_t
87     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 
92     GetLinkMapAddress() const { return m_current.map_addr; }
93
94     /// A breakpoint should be set at this address and Resolve called on each
95     /// hit.
96     ///
97     /// @returns the address of a function called by the runtime linker each
98     /// time a module is loaded/unloaded, or about to be loaded/unloaded.
99     ///
100     /// @see Resolve()
101     lldb::addr_t
102     GetBreakAddress() const { return m_current.brk; }
103
104     /// Returns the current state of the rendezvous structure.
105     uint64_t
106     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
111     GetLDBase() const { return m_current.ldbase; }
112
113     /// @returns the thread layout metadata from the inferiors thread library.
114     const ThreadInfo&
115     GetThreadInfo();
116
117     /// @returns true if modules have been loaded into the inferior since the
118     /// last call to Resolve().
119     bool
120     ModulesDidLoad() const { return !m_added_soentries.empty(); }
121
122     /// @returns true if modules have been unloaded from the inferior since the
123     /// last call to Resolve().
124     bool
125     ModulesDidUnload() const { return !m_removed_soentries.empty(); }
126
127     void
128     DumpToLog(lldb_private::Log *log) const;
129
130     /// @brief Constants describing the state of the rendezvous.
131     ///
132     /// @see GetState().
133     enum RendezvousState {
134         eConsistent,
135         eAdd,
136         eDelete
137     };
138
139     /// @brief Structure representing the shared objects currently loaded into
140     /// the inferior process.
141     ///
142     /// This object is a rough analogue to the struct link_map object which
143     /// actually lives in the inferiors memory.
144     struct SOEntry {
145         lldb::addr_t link_addr; ///< Address of this link_map.
146         lldb::addr_t base_addr; ///< Base address of the loaded object.
147         lldb::addr_t path_addr; ///< String naming the shared object.
148         lldb::addr_t dyn_addr;  ///< Dynamic section of shared object.
149         lldb::addr_t next;      ///< Address of next so_entry.
150         lldb::addr_t prev;      ///< Address of previous so_entry.
151         std::string  path;      ///< File name of shared object.
152
153         SOEntry() { clear(); }
154
155         bool operator ==(const SOEntry &entry) {
156             return this->path == entry.path;
157         }
158
159         void clear() {
160             link_addr = 0;
161             base_addr = 0;
162             path_addr = 0;
163             dyn_addr  = 0;
164             next = 0;
165             prev = 0;
166             path.clear();
167         }
168     };
169
170 protected:
171     typedef std::list<SOEntry> SOEntryList;
172
173 public:
174     typedef SOEntryList::const_iterator iterator;
175
176     /// Iterators over all currently loaded modules.
177     iterator begin() const { return m_soentries.begin(); }
178     iterator end() const { return m_soentries.end(); }
179
180     /// Iterators over all modules loaded into the inferior since the last call
181     /// to Resolve().
182     iterator loaded_begin() const { return m_added_soentries.begin(); }
183     iterator loaded_end() const { return m_added_soentries.end(); }
184
185     /// Iterators over all modules unloaded from the inferior since the last
186     /// call to Resolve().
187     iterator unloaded_begin() const { return m_removed_soentries.begin(); }
188     iterator unloaded_end() const { return m_removed_soentries.end(); }
189     
190 protected:
191     lldb_private::Process *m_process;
192
193     // Cached copy of executable pathname
194     char m_exe_path[PATH_MAX];
195
196     /// Location of the r_debug structure in the inferiors address space.
197     lldb::addr_t m_rendezvous_addr;
198
199     /// Current and previous snapshots of the rendezvous structure.
200     Rendezvous m_current;
201     Rendezvous m_previous;
202
203     /// List of SOEntry objects corresponding to the current link map state.
204     SOEntryList m_soentries;
205
206     /// List of SOEntry's added to the link map since the last call to Resolve().
207     SOEntryList m_added_soentries;
208
209     /// List of SOEntry's removed from the link map since the last call to
210     /// Resolve().
211     SOEntryList m_removed_soentries;
212
213     /// Threading metadata read from the inferior.
214     ThreadInfo  m_thread_info;
215
216     /// Reads an unsigned integer of @p size bytes from the inferior's address
217     /// space starting at @p addr.
218     ///
219     /// @returns addr + size if the read was successful and false otherwise.
220     lldb::addr_t
221     ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);
222
223     /// Reads an address from the inferior's address space starting at @p addr.
224     ///
225     /// @returns addr + target address size if the read was successful and
226     /// 0 otherwise.
227     lldb::addr_t
228     ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);
229
230     /// Reads a null-terminated C string from the memory location starting at @p
231     /// addr.
232     std::string
233     ReadStringFromMemory(lldb::addr_t addr);
234
235     /// Reads an SOEntry starting at @p addr.
236     bool
237     ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
238
239     /// Updates the current set of SOEntries, the set of added entries, and the
240     /// set of removed entries.
241     bool
242     UpdateSOEntries();
243
244     bool
245     UpdateSOEntriesForAddition();
246
247     bool
248     UpdateSOEntriesForDeletion();
249
250     /// Reads the current list of shared objects according to the link map
251     /// supplied by the runtime linker.
252     bool
253     TakeSnapshot(SOEntryList &entry_list);
254
255     enum PThreadField { eSize, eNElem, eOffset };
256
257     bool FindMetadata(const char *name, PThreadField field, uint32_t& value);
258 };
259
260 #endif