blob: a73c5885ea241c38de0767f310b0bf0f5b619944 [file] [log] [blame]
Greg Clayton944b8282011-08-22 22:30:57 +00001//===-- DynamicLoaderDarwinKernel.h -----------------------------*- C++ -*-===//
Greg Clayton7b242382011-07-08 00:48:09 +00002//
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
Greg Clayton944b8282011-08-22 22:30:57 +000010#ifndef liblldb_DynamicLoaderDarwinKernel_h_
11#define liblldb_DynamicLoaderDarwinKernel_h_
Greg Clayton7b242382011-07-08 00:48:09 +000012
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
Greg Clayton944b8282011-08-22 22:30:57 +000029class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
Greg Clayton7b242382011-07-08 00:48:09 +000030{
31public:
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
Greg Claytone8cd0c92012-10-19 18:02:49 +000050 static void
51 DebuggerInitialize (lldb_private::Debugger &debugger);
52
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000053 DynamicLoaderDarwinKernel (lldb_private::Process *process, lldb::addr_t kernel_addr);
Greg Clayton7b242382011-07-08 00:48:09 +000054
55 virtual
Greg Clayton944b8282011-08-22 22:30:57 +000056 ~DynamicLoaderDarwinKernel ();
Greg Clayton7b242382011-07-08 00:48:09 +000057 //------------------------------------------------------------------
58 /// Called after attaching a process.
59 ///
60 /// Allow DynamicLoader plug-ins to execute some code after
61 /// attaching to a process.
62 //------------------------------------------------------------------
63 virtual void
64 DidAttach ();
65
66 virtual void
67 DidLaunch ();
68
69 virtual lldb::ThreadPlanSP
70 GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
71 bool stop_others);
72
73 virtual lldb_private::Error
74 CanLoadImage ();
75
76 //------------------------------------------------------------------
77 // PluginInterface protocol
78 //------------------------------------------------------------------
79 virtual const char *
80 GetPluginName();
81
82 virtual const char *
83 GetShortPluginName();
84
85 virtual uint32_t
86 GetPluginVersion();
87
88protected:
89 void
90 PrivateInitialize (lldb_private::Process *process);
91
92 void
93 PrivateProcessStateChanged (lldb_private::Process *process,
94 lldb::StateType state);
Greg Clayton374972e2011-07-09 17:15:55 +000095
96 void
97 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +000098
Greg Clayton374972e2011-07-09 17:15:55 +000099 void
100 LoadKernelModuleIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000101
102 void
103 Clear (bool clear_process);
104
105 void
106 PutToLog (lldb_private::Log *log) const;
107
108 static bool
Greg Clayton374972e2011-07-09 17:15:55 +0000109 BreakpointHitCallback (void *baton,
110 lldb_private::StoppointCallbackContext *context,
111 lldb::user_id_t break_id,
112 lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000113
Greg Clayton374972e2011-07-09 17:15:55 +0000114 bool
115 BreakpointHit (lldb_private::StoppointCallbackContext *context,
116 lldb::user_id_t break_id,
117 lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000118 uint32_t
Greg Claytonc859e2d2012-02-13 23:10:39 +0000119 GetAddrByteSize()
Greg Clayton7b242382011-07-08 00:48:09 +0000120 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000121 return m_kernel.GetAddressByteSize();
Greg Clayton7b242382011-07-08 00:48:09 +0000122 }
123
124 static lldb::ByteOrder
Greg Clayton1f746072012-08-29 21:13:06 +0000125 GetByteOrderFromMagic (uint32_t magic);
Greg Clayton7b242382011-07-08 00:48:09 +0000126
Greg Claytona63d08c2011-07-19 03:57:15 +0000127 enum
128 {
129 KERNEL_MODULE_MAX_NAME = 64u,
130 // Versions less than 2 didn't have an entry size,
131 // they had a 64 bit name, 16 byte UUID, 8 byte addr,
132 // 8 byte size, 8 byte version, 4 byte load tag, and
133 // 4 byte flags
134 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
135 };
Greg Clayton7b242382011-07-08 00:48:09 +0000136
137 struct OSKextLoadedKextSummary
138 {
139 char name[KERNEL_MODULE_MAX_NAME];
140 lldb::ModuleSP module_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000141 uint32_t load_process_stop_id;
Jason Molenda87a04b22012-10-19 03:40:45 +0000142 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
Greg Clayton0d9fc762011-07-08 03:21:57 +0000143 lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files
Greg Clayton7b242382011-07-08 00:48:09 +0000144 uint64_t address;
145 uint64_t size;
146 uint64_t version;
147 uint32_t load_tag;
148 uint32_t flags;
149 uint64_t reference_list;
Jason Molenda87a04b22012-10-19 03:40:45 +0000150 bool kernel_image; // true if this is the kernel, false if this is a kext
Greg Clayton7b242382011-07-08 00:48:09 +0000151
152 OSKextLoadedKextSummary() :
153 module_sp (),
Greg Claytonc859e2d2012-02-13 23:10:39 +0000154 load_process_stop_id (UINT32_MAX),
Greg Clayton7b242382011-07-08 00:48:09 +0000155 uuid (),
Greg Clayton0d9fc762011-07-08 03:21:57 +0000156 so_address (),
Greg Clayton7b242382011-07-08 00:48:09 +0000157 address (LLDB_INVALID_ADDRESS),
158 size (0),
159 version (0),
160 load_tag (0),
161 flags (0),
Jason Molenda87a04b22012-10-19 03:40:45 +0000162 reference_list (0),
163 kernel_image (false)
Greg Clayton7b242382011-07-08 00:48:09 +0000164 {
165 name[0] = '\0';
166 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000167
168 bool
169 IsLoaded ()
170 {
171 return load_process_stop_id != UINT32_MAX;
172 }
Greg Clayton7b242382011-07-08 00:48:09 +0000173
174 void
175 Clear (bool load_cmd_data_only)
176 {
177 if (!load_cmd_data_only)
178 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000179 so_address.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000180 address = LLDB_INVALID_ADDRESS;
181 size = 0;
182 version = 0;
183 load_tag = 0;
184 flags = 0;
185 reference_list = 0;
186 name[0] = '\0';
Greg Clayton7b242382011-07-08 00:48:09 +0000187 }
188 module_sp.reset();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000189 load_process_stop_id = UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000190 }
191
192 bool
Greg Clayton02c322c2012-03-21 22:50:54 +0000193 LoadImageAtFileAddress (lldb_private::Process *process);
194
195 bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000196 LoadImageUsingMemoryModule (lldb_private::Process *process);
197
198// bool
199// operator == (const OSKextLoadedKextSummary& rhs) const
200// {
201// return address == rhs.address
202// && size == rhs.size
203// //&& module_sp.get() == rhs.module_sp.get()
204// && uuid == rhs.uuid
205// && version == rhs.version
206// && load_tag == rhs.load_tag
207// && flags == rhs.flags
208// && reference_list == rhs.reference_list
209// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
210// }
211//
Greg Clayton7b242382011-07-08 00:48:09 +0000212 bool
213 UUIDValid() const
214 {
215 return uuid.IsValid();
216 }
217
218 uint32_t
Greg Clayton1f746072012-08-29 21:13:06 +0000219 GetAddressByteSize ();
Greg Clayton7b242382011-07-08 00:48:09 +0000220
221 lldb::ByteOrder
Greg Clayton1f746072012-08-29 21:13:06 +0000222 GetByteOrder();
Greg Clayton7b242382011-07-08 00:48:09 +0000223
224 lldb_private::ArchSpec
Greg Clayton1f746072012-08-29 21:13:06 +0000225 GetArchitecture () const;
Greg Clayton7b242382011-07-08 00:48:09 +0000226
Greg Clayton7b242382011-07-08 00:48:09 +0000227 void
228 PutToLog (lldb_private::Log *log) const;
229
230 typedef std::vector<OSKextLoadedKextSummary> collection;
231 typedef collection::iterator iterator;
232 typedef collection::const_iterator const_iterator;
233 };
234
235 struct OSKextLoadedKextSummaryHeader
236 {
237 uint32_t version;
238 uint32_t entry_size;
239 uint32_t entry_count;
Greg Clayton7b242382011-07-08 00:48:09 +0000240 lldb::addr_t image_infos_addr;
241
242 OSKextLoadedKextSummaryHeader() :
243 version (0),
244 entry_size (0),
245 entry_count (0),
Greg Clayton7b242382011-07-08 00:48:09 +0000246 image_infos_addr (LLDB_INVALID_ADDRESS)
247 {
248 }
249
Greg Claytona63d08c2011-07-19 03:57:15 +0000250 uint32_t
251 GetSize()
252 {
253 switch (version)
254 {
255 case 0: return 0; // Can't know the size without a valid version
256 case 1: return 8; // Version 1 only had a version + entry_count
257 default: break;
258 }
259 // Version 2 and above has version, entry_size, entry_count, and reserved
260 return 16;
261 }
262
Greg Clayton7b242382011-07-08 00:48:09 +0000263 void
264 Clear()
265 {
266 version = 0;
267 entry_size = 0;
268 entry_count = 0;
Greg Clayton7b242382011-07-08 00:48:09 +0000269 image_infos_addr = LLDB_INVALID_ADDRESS;
270 }
271
272 bool
273 IsValid() const
274 {
275 return version >= 1 || version <= 2;
276 }
277 };
278
279 void
280 RegisterNotificationCallbacks();
281
282 void
283 UnregisterNotificationCallbacks();
284
Greg Clayton374972e2011-07-09 17:15:55 +0000285 void
286 SetNotificationBreakpointIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000287
288 bool
Greg Clayton374972e2011-07-09 17:15:55 +0000289 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000290
291 bool
292 ReadKextSummaryHeader ();
293
294 bool
Greg Clayton0d9fc762011-07-08 03:21:57 +0000295 ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
296 uint32_t count);
Greg Clayton7b242382011-07-08 00:48:09 +0000297
298 bool
299 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
300
Greg Clayton7b242382011-07-08 00:48:09 +0000301 void
302 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
303 uint32_t infos_count,
304 bool update_executable);
305
Greg Clayton7b242382011-07-08 00:48:09 +0000306 uint32_t
Greg Clayton0d9fc762011-07-08 03:21:57 +0000307 ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000308 uint32_t image_infos_count,
309 OSKextLoadedKextSummary::collection &image_infos);
310
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000311 static lldb::addr_t
312 SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
313
314 static lldb::addr_t
315 SearchForKernelWithDebugHints (lldb_private::Process *process);
316
317 static lldb::addr_t
318 SearchForKernelNearPC (lldb_private::Process *process);
319
320 static lldb::addr_t
321 SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
322
323 static lldb_private::UUID
324 CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
325
326 lldb::addr_t m_kernel_load_address;
Greg Clayton7b242382011-07-08 00:48:09 +0000327 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
Greg Claytond16e1e52011-07-12 17:06:17 +0000328 lldb_private::Address m_kext_summary_header_ptr_addr;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000329 lldb_private::Address m_kext_summary_header_addr;
Greg Clayton7b242382011-07-08 00:48:09 +0000330 OSKextLoadedKextSummaryHeader m_kext_summary_header;
Greg Clayton7b242382011-07-08 00:48:09 +0000331 OSKextLoadedKextSummary::collection m_kext_summaries;
Greg Clayton7b242382011-07-08 00:48:09 +0000332 mutable lldb_private::Mutex m_mutex;
Greg Clayton374972e2011-07-09 17:15:55 +0000333 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000334
335private:
Greg Clayton944b8282011-08-22 22:30:57 +0000336 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000337};
338
Greg Clayton944b8282011-08-22 22:30:57 +0000339#endif // liblldb_DynamicLoaderDarwinKernel_h_