xref: /llvm-project/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h (revision c859e2d52488ef1852e6489716ddf6147402ea64)
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 <map>
16 #include <vector>
17 #include <string>
18 
19 // Other libraries and framework includes
20 #include "llvm/Support/MachO.h"
21 
22 #include "lldb/Target/DynamicLoader.h"
23 #include "lldb/Host/FileSpec.h"
24 #include "lldb/Host/TimeValue.h"
25 #include "lldb/Core/UUID.h"
26 #include "lldb/Host/Mutex.h"
27 #include "lldb/Target/Process.h"
28 
29 class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
30 {
31 public:
32     //------------------------------------------------------------------
33     // Static Functions
34     //------------------------------------------------------------------
35     static void
36     Initialize();
37 
38     static void
39     Terminate();
40 
41     static const char *
42     GetPluginNameStatic();
43 
44     static const char *
45     GetPluginDescriptionStatic();
46 
47     static lldb_private::DynamicLoader *
48     CreateInstance (lldb_private::Process *process, bool force);
49 
50     DynamicLoaderDarwinKernel (lldb_private::Process *process);
51 
52     virtual
53     ~DynamicLoaderDarwinKernel ();
54     //------------------------------------------------------------------
55     /// Called after attaching a process.
56     ///
57     /// Allow DynamicLoader plug-ins to execute some code after
58     /// attaching to a process.
59     //------------------------------------------------------------------
60     virtual void
61     DidAttach ();
62 
63     virtual void
64     DidLaunch ();
65 
66     virtual lldb::ThreadPlanSP
67     GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
68                                   bool stop_others);
69 
70     virtual lldb_private::Error
71     CanLoadImage ();
72 
73     //------------------------------------------------------------------
74     // PluginInterface protocol
75     //------------------------------------------------------------------
76     virtual const char *
77     GetPluginName();
78 
79     virtual const char *
80     GetShortPluginName();
81 
82     virtual uint32_t
83     GetPluginVersion();
84 
85 protected:
86     void
87     PrivateInitialize (lldb_private::Process *process);
88 
89     void
90     PrivateProcessStateChanged (lldb_private::Process *process,
91                                 lldb::StateType state);
92 
93     void
94     UpdateIfNeeded();
95 
96     void
97     LoadKernelModuleIfNeeded ();
98 
99     void
100     Clear (bool clear_process);
101 
102     void
103     PutToLog (lldb_private::Log *log) const;
104 
105     static bool
106     BreakpointHitCallback (void *baton,
107                            lldb_private::StoppointCallbackContext *context,
108                            lldb::user_id_t break_id,
109                            lldb::user_id_t break_loc_id);
110 
111     bool
112     BreakpointHit (lldb_private::StoppointCallbackContext *context,
113                    lldb::user_id_t break_id,
114                    lldb::user_id_t break_loc_id);
115     uint32_t
116     GetAddrByteSize()
117     {
118         return m_kernel.GetAddressByteSize();
119     }
120 
121     static lldb::ByteOrder
122     GetByteOrderFromMagic (uint32_t magic)
123     {
124         switch (magic)
125         {
126             case llvm::MachO::HeaderMagic32:
127             case llvm::MachO::HeaderMagic64:
128                 return lldb::endian::InlHostByteOrder();
129 
130             case llvm::MachO::HeaderMagic32Swapped:
131             case llvm::MachO::HeaderMagic64Swapped:
132                 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
133                     return lldb::eByteOrderLittle;
134                 else
135                     return lldb::eByteOrderBig;
136 
137             default:
138                 break;
139         }
140         return lldb::eByteOrderInvalid;
141     }
142     enum
143     {
144         KERNEL_MODULE_MAX_NAME = 64u,
145         // Versions less than 2 didn't have an entry size,
146         // they had a 64 bit name, 16 byte UUID, 8 byte addr,
147         // 8 byte size, 8 byte version, 4 byte load tag, and
148         // 4 byte flags
149         KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
150     };
151 
152     struct OSKextLoadedKextSummary
153     {
154         char                     name[KERNEL_MODULE_MAX_NAME];
155         lldb::ModuleSP           module_sp;
156         uint32_t                 load_process_stop_id;
157         lldb_private::UUID       uuid;            // UUID for this dylib if it has one, else all zeros
158         lldb_private::Address    so_address;        // The section offset address for this kext in case it can be read from object files
159         uint64_t                 address;
160         uint64_t                 size;
161         uint64_t                 version;
162         uint32_t                 load_tag;
163         uint32_t                 flags;
164         uint64_t                 reference_list;
165 
166         OSKextLoadedKextSummary() :
167             module_sp (),
168             load_process_stop_id (UINT32_MAX),
169             uuid (),
170             so_address (),
171             address (LLDB_INVALID_ADDRESS),
172             size (0),
173             version (0),
174             load_tag (0),
175             flags (0),
176             reference_list (0)
177         {
178             name[0] = '\0';
179         }
180 
181         bool
182         IsLoaded ()
183         {
184             return load_process_stop_id != UINT32_MAX;
185         }
186 
187         void
188         Clear (bool load_cmd_data_only)
189         {
190             if (!load_cmd_data_only)
191             {
192                 so_address.Clear();
193                 address = LLDB_INVALID_ADDRESS;
194                 size = 0;
195                 version = 0;
196                 load_tag = 0;
197                 flags = 0;
198                 reference_list = 0;
199                 name[0] = '\0';
200             }
201             module_sp.reset();
202             load_process_stop_id = UINT32_MAX;
203         }
204 
205         bool
206         LoadImageUsingMemoryModule (lldb_private::Process *process);
207 
208 //        bool
209 //        operator == (const OSKextLoadedKextSummary& rhs) const
210 //        {
211 //            return  address == rhs.address
212 //                    && size == rhs.size
213 //            //&& module_sp.get() == rhs.module_sp.get()
214 //                    && uuid == rhs.uuid
215 //                    && version == rhs.version
216 //                    && load_tag == rhs.load_tag
217 //                    && flags == rhs.flags
218 //                    && reference_list == rhs.reference_list
219 //                    && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
220 //        }
221 //
222         bool
223         UUIDValid() const
224         {
225             return uuid.IsValid();
226         }
227 
228         uint32_t
229         GetAddressByteSize ()
230         {
231             if (module_sp)
232                 return module_sp->GetArchitecture().GetAddressByteSize();
233             return 0;
234         }
235 
236         lldb::ByteOrder
237         GetByteOrder()
238         {
239             if (module_sp)
240                 return module_sp->GetArchitecture().GetByteOrder();
241             return lldb::endian::InlHostByteOrder();
242         }
243 
244         lldb_private::ArchSpec
245         GetArchitecture () const
246         {
247             if (module_sp)
248                 return module_sp->GetArchitecture();
249             return lldb_private::ArchSpec ();
250         }
251 
252         void
253         PutToLog (lldb_private::Log *log) const;
254 
255         typedef std::vector<OSKextLoadedKextSummary> collection;
256         typedef collection::iterator iterator;
257         typedef collection::const_iterator const_iterator;
258     };
259 
260     struct OSKextLoadedKextSummaryHeader
261     {
262         uint32_t version;
263         uint32_t entry_size;
264         uint32_t entry_count;
265         lldb::addr_t image_infos_addr;
266 
267         OSKextLoadedKextSummaryHeader() :
268             version (0),
269             entry_size (0),
270             entry_count (0),
271             image_infos_addr (LLDB_INVALID_ADDRESS)
272         {
273         }
274 
275         uint32_t
276         GetSize()
277         {
278             switch (version)
279             {
280                 case 0: return 0;   // Can't know the size without a valid version
281                 case 1: return 8;   // Version 1 only had a version + entry_count
282                 default: break;
283             }
284             // Version 2 and above has version, entry_size, entry_count, and reserved
285             return 16;
286         }
287 
288         void
289         Clear()
290         {
291             version = 0;
292             entry_size = 0;
293             entry_count = 0;
294             image_infos_addr = LLDB_INVALID_ADDRESS;
295         }
296 
297         bool
298         IsValid() const
299         {
300             return version >= 1 || version <= 2;
301         }
302     };
303 
304     void
305     RegisterNotificationCallbacks();
306 
307     void
308     UnregisterNotificationCallbacks();
309 
310     void
311     SetNotificationBreakpointIfNeeded ();
312 
313     bool
314     ReadAllKextSummaries ();
315 
316     bool
317     ReadKextSummaryHeader ();
318 
319     bool
320     ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
321                         uint32_t count);
322 
323     bool
324     AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
325 
326     void
327     UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
328                                           uint32_t infos_count,
329                                           bool update_executable);
330 
331     uint32_t
332     ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
333                        uint32_t image_infos_count,
334                        OSKextLoadedKextSummary::collection &image_infos);
335 
336     OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
337     lldb_private::Address m_kext_summary_header_ptr_addr;
338     lldb_private::Address m_kext_summary_header_addr;
339     OSKextLoadedKextSummaryHeader m_kext_summary_header;
340     OSKextLoadedKextSummary::collection m_kext_summaries;
341     mutable lldb_private::Mutex m_mutex;
342     lldb::user_id_t m_break_id;
343 
344 private:
345     DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
346 };
347 
348 #endif  // liblldb_DynamicLoaderDarwinKernel_h_
349