1 //===-- DynamicLoaderDarwinKernel.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_DynamicLoaderDarwinKernel_h_
11 #define liblldb_DynamicLoaderDarwinKernel_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <vector>
16 #include <string>
17 
18 // Other libraries and framework includes
19 // Project includes
20 #include "lldb/Target/DynamicLoader.h"
21 #include "lldb/Host/FileSpec.h"
22 #include "lldb/Host/TimeValue.h"
23 #include "lldb/Core/UUID.h"
24 #include "lldb/Host/Mutex.h"
25 #include "lldb/Target/Process.h"
26 
27 class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
28 {
29 public:
30     DynamicLoaderDarwinKernel(lldb_private::Process *process, lldb::addr_t kernel_addr);
31 
32     ~DynamicLoaderDarwinKernel() override;
33 
34     //------------------------------------------------------------------
35     // Static Functions
36     //------------------------------------------------------------------
37     static void
38     Initialize();
39 
40     static void
41     Terminate();
42 
43     static lldb_private::ConstString
44     GetPluginNameStatic();
45 
46     static const char *
47     GetPluginDescriptionStatic();
48 
49     static lldb_private::DynamicLoader *
50     CreateInstance (lldb_private::Process *process, bool force);
51 
52     static void
53     DebuggerInitialize (lldb_private::Debugger &debugger);
54 
55     //------------------------------------------------------------------
56     /// Called after attaching a process.
57     ///
58     /// Allow DynamicLoader plug-ins to execute some code after
59     /// attaching to a process.
60     //------------------------------------------------------------------
61     void
62     DidAttach() override;
63 
64     void
65     DidLaunch() override;
66 
67     lldb::ThreadPlanSP
68     GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
69                                  bool stop_others) override;
70 
71     lldb_private::Error
72     CanLoadImage() override;
73 
74     //------------------------------------------------------------------
75     // PluginInterface protocol
76     //------------------------------------------------------------------
77     lldb_private::ConstString
78     GetPluginName() override;
79 
80     uint32_t
81     GetPluginVersion() override;
82 
83 protected:
84     void
85     PrivateInitialize (lldb_private::Process *process);
86 
87     void
88     PrivateProcessStateChanged (lldb_private::Process *process,
89                                 lldb::StateType state);
90 
91     void
92     UpdateIfNeeded();
93 
94     void
95     LoadKernelModuleIfNeeded ();
96 
97     void
98     Clear (bool clear_process);
99 
100     void
101     PutToLog (lldb_private::Log *log) const;
102 
103     static bool
104     BreakpointHitCallback (void *baton,
105                            lldb_private::StoppointCallbackContext *context,
106                            lldb::user_id_t break_id,
107                            lldb::user_id_t break_loc_id);
108 
109     bool
110     BreakpointHit (lldb_private::StoppointCallbackContext *context,
111                    lldb::user_id_t break_id,
112                    lldb::user_id_t break_loc_id);
113     uint32_t
114     GetAddrByteSize()
115     {
116         return m_kernel.GetAddressByteSize();
117     }
118 
119     static lldb::ByteOrder
120     GetByteOrderFromMagic (uint32_t magic);
121 
122     enum
123     {
124         KERNEL_MODULE_MAX_NAME = 64u,
125         // Versions less than 2 didn't have an entry size,
126         // they had a 64 bit name, 16 byte UUID, 8 byte addr,
127         // 8 byte size, 8 byte version, 4 byte load tag, and
128         // 4 byte flags
129         KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
130     };
131 
132     // class KextImageInfo represents a single kext or kernel binary image.
133     // The class was designed to hold the information from the OSKextLoadedKextSummary
134     // structure (in libkern/libkern/OSKextLibPrivate.h from xnu).  The kernel maintains
135     // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure,
136     // which points to an array of OSKextLoadedKextSummary's).
137     //
138     // A KextImageInfos may have -
139     //
140     // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
141     //    (read straight out of the kernel's list-of-kexts loaded)
142     // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
143     //    (very unlikely to have any symbolic information)
144     // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
145     //    or a dSYM
146     //
147     // For performance reasons, the developer may prefer that lldb not load the kexts out
148     // of memory at the start of a kernel session.  But we should build up / maintain a
149     // list of kexts that the kernel has told us about so we can relocate a kext module
150     // later if the user explicitly adds it to the target.
151 
152     class KextImageInfo
153     {
154     public:
155         KextImageInfo () :
156             m_name (),
157             m_module_sp (),
158             m_memory_module_sp (),
159             m_load_process_stop_id (UINT32_MAX),
160             m_uuid (),
161             m_load_address (LLDB_INVALID_ADDRESS),
162             m_size (0),
163             m_kernel_image (false)
164         { }
165 
166         void
167         Clear ()
168         {
169             m_load_address = LLDB_INVALID_ADDRESS;
170             m_size = 0;
171             m_name.clear ();
172             m_uuid.Clear();
173             m_module_sp.reset();
174             m_memory_module_sp.reset();
175             m_load_process_stop_id = UINT32_MAX;
176         }
177 
178         bool
179         LoadImageAtFileAddress (lldb_private::Process *process);
180 
181         bool
182         LoadImageUsingMemoryModule (lldb_private::Process *process);
183 
184         bool
185         IsLoaded ()
186         {
187             return m_load_process_stop_id != UINT32_MAX;
188         }
189 
190         void
191         SetLoadAddress (lldb::addr_t load_addr);     // Address of the Mach-O header for this binary
192 
193         lldb::addr_t
194         GetLoadAddress () const;                     // Address of the Mach-O header for this binary
195 
196         lldb_private::UUID
197         GetUUID () const;
198 
199         void
200         SetUUID (const lldb_private::UUID &uuid);
201 
202         void
203         SetName (const char *);
204 
205         std::string
206         GetName () const;
207 
208         void
209         SetModule (lldb::ModuleSP module);
210 
211         lldb::ModuleSP
212         GetModule ();
213 
214         // try to fill in m_memory_module_sp from memory based on the m_load_address
215         bool
216         ReadMemoryModule (lldb_private::Process *process);
217 
218         bool
219         IsKernel () const;            // true if this is the mach_kernel; false if this is a kext
220 
221         void
222         SetIsKernel (bool is_kernel);
223 
224         uint64_t
225         GetSize () const;
226 
227         void
228         SetSize (uint64_t size);
229 
230         uint32_t
231         GetProcessStopId () const;    // the stop-id when this binary was first noticed
232 
233         void
234         SetProcessStopId (uint32_t stop_id);
235 
236         bool
237         operator== (const KextImageInfo &rhs);
238 
239         uint32_t
240         GetAddressByteSize ();        // as determined by Mach-O header
241 
242         lldb::ByteOrder
243         GetByteOrder();               // as determined by Mach-O header
244 
245         lldb_private::ArchSpec
246         GetArchitecture () const;     // as determined by Mach-O header
247 
248         void
249         PutToLog (lldb_private::Log *log) const;
250 
251         typedef std::vector<KextImageInfo> collection;
252         typedef collection::iterator iterator;
253         typedef collection::const_iterator const_iterator;
254 
255     private:
256         std::string              m_name;
257         lldb::ModuleSP           m_module_sp;
258         lldb::ModuleSP           m_memory_module_sp;
259         uint32_t                 m_load_process_stop_id; // the stop-id when this module was added to the Target
260         lldb_private::UUID       m_uuid;                 // UUID for this dylib if it has one, else all zeros
261         lldb::addr_t             m_load_address;
262         uint64_t                 m_size;
263         bool                     m_kernel_image;         // true if this is the kernel, false if this is a kext
264     };
265 
266     struct OSKextLoadedKextSummaryHeader
267     {
268         uint32_t version;
269         uint32_t entry_size;
270         uint32_t entry_count;
271         lldb::addr_t image_infos_addr;
272 
273         OSKextLoadedKextSummaryHeader() :
274             version (0),
275             entry_size (0),
276             entry_count (0),
277             image_infos_addr (LLDB_INVALID_ADDRESS)
278         {
279         }
280 
281         uint32_t
282         GetSize()
283         {
284             switch (version)
285             {
286                 case 0: return 0;   // Can't know the size without a valid version
287                 case 1: return 8;   // Version 1 only had a version + entry_count
288                 default: break;
289             }
290             // Version 2 and above has version, entry_size, entry_count, and reserved
291             return 16;
292         }
293 
294         void
295         Clear()
296         {
297             version = 0;
298             entry_size = 0;
299             entry_count = 0;
300             image_infos_addr = LLDB_INVALID_ADDRESS;
301         }
302 
303         bool
304         IsValid() const
305         {
306             return version >= 1 || version <= 2;
307         }
308     };
309 
310     void
311     RegisterNotificationCallbacks();
312 
313     void
314     UnregisterNotificationCallbacks();
315 
316     void
317     SetNotificationBreakpointIfNeeded ();
318 
319     bool
320     ReadAllKextSummaries ();
321 
322     bool
323     ReadKextSummaryHeader ();
324 
325     bool
326     ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
327                         uint32_t count);
328 
329     void
330     UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
331                                           uint32_t infos_count,
332                                           bool update_executable);
333 
334     uint32_t
335     ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
336                        uint32_t image_infos_count,
337                        KextImageInfo::collection &image_infos);
338 
339     static lldb::addr_t
340     SearchForDarwinKernel (lldb_private::Process *process);
341 
342     static lldb::addr_t
343     SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
344 
345     static lldb::addr_t
346     SearchForKernelWithDebugHints (lldb_private::Process *process);
347 
348     static lldb::addr_t
349     SearchForKernelNearPC (lldb_private::Process *process);
350 
351     static lldb::addr_t
352     SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
353 
354     static lldb_private::UUID
355     CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
356 
357     lldb::addr_t  m_kernel_load_address;
358     KextImageInfo m_kernel;                 // Info about the current kernel image being used
359 
360     lldb_private::Address          m_kext_summary_header_ptr_addr;
361     lldb_private::Address          m_kext_summary_header_addr;
362     OSKextLoadedKextSummaryHeader  m_kext_summary_header;
363     KextImageInfo::collection      m_known_kexts;
364     mutable lldb_private::Mutex    m_mutex;
365     lldb::user_id_t                m_break_id;
366 
367 private:
368     DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
369 };
370 
371 #endif // liblldb_DynamicLoaderDarwinKernel_h_
372