blob: 4d9b42207cd31b3131445311082638827e73a8ff [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 Clayton944b8282011-08-22 22:30:57 +000050 DynamicLoaderDarwinKernel (lldb_private::Process *process);
Greg Clayton7b242382011-07-08 00:48:09 +000051
52 virtual
Greg Clayton944b8282011-08-22 22:30:57 +000053 ~DynamicLoaderDarwinKernel ();
Greg Clayton7b242382011-07-08 00:48:09 +000054 //------------------------------------------------------------------
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
85protected:
86 void
87 PrivateInitialize (lldb_private::Process *process);
88
89 void
90 PrivateProcessStateChanged (lldb_private::Process *process,
91 lldb::StateType state);
Greg Clayton374972e2011-07-09 17:15:55 +000092
93 void
94 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +000095
Greg Clayton374972e2011-07-09 17:15:55 +000096 void
97 LoadKernelModuleIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +000098
99 void
100 Clear (bool clear_process);
101
102 void
103 PutToLog (lldb_private::Log *log) const;
104
105 static bool
Greg Clayton374972e2011-07-09 17:15:55 +0000106 BreakpointHitCallback (void *baton,
107 lldb_private::StoppointCallbackContext *context,
108 lldb::user_id_t break_id,
109 lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000110
Greg Clayton374972e2011-07-09 17:15:55 +0000111 bool
112 BreakpointHit (lldb_private::StoppointCallbackContext *context,
113 lldb::user_id_t break_id,
114 lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000115 uint32_t
Greg Claytonc859e2d2012-02-13 23:10:39 +0000116 GetAddrByteSize()
Greg Clayton7b242382011-07-08 00:48:09 +0000117 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000118 return m_kernel.GetAddressByteSize();
Greg Clayton7b242382011-07-08 00:48:09 +0000119 }
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 }
Greg Claytona63d08c2011-07-19 03:57:15 +0000142 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 };
Greg Clayton7b242382011-07-08 00:48:09 +0000151
152 struct OSKextLoadedKextSummary
153 {
154 char name[KERNEL_MODULE_MAX_NAME];
155 lldb::ModuleSP module_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000156 uint32_t load_process_stop_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000157 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
Greg Clayton0d9fc762011-07-08 03:21:57 +0000158 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 +0000159 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;
Greg Clayton7b242382011-07-08 00:48:09 +0000165
166 OSKextLoadedKextSummary() :
167 module_sp (),
Greg Claytonc859e2d2012-02-13 23:10:39 +0000168 load_process_stop_id (UINT32_MAX),
Greg Clayton7b242382011-07-08 00:48:09 +0000169 uuid (),
Greg Clayton0d9fc762011-07-08 03:21:57 +0000170 so_address (),
Greg Clayton7b242382011-07-08 00:48:09 +0000171 address (LLDB_INVALID_ADDRESS),
172 size (0),
173 version (0),
174 load_tag (0),
175 flags (0),
Greg Claytonc859e2d2012-02-13 23:10:39 +0000176 reference_list (0)
Greg Clayton7b242382011-07-08 00:48:09 +0000177 {
178 name[0] = '\0';
179 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000180
181 bool
182 IsLoaded ()
183 {
184 return load_process_stop_id != UINT32_MAX;
185 }
Greg Clayton7b242382011-07-08 00:48:09 +0000186
187 void
188 Clear (bool load_cmd_data_only)
189 {
190 if (!load_cmd_data_only)
191 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000192 so_address.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000193 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';
Greg Clayton7b242382011-07-08 00:48:09 +0000200 }
201 module_sp.reset();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000202 load_process_stop_id = UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000203 }
204
205 bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000206 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//
Greg Clayton7b242382011-07-08 00:48:09 +0000222 bool
223 UUIDValid() const
224 {
225 return uuid.IsValid();
226 }
227
228 uint32_t
229 GetAddressByteSize ()
230 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000231 if (module_sp)
232 return module_sp->GetArchitecture().GetAddressByteSize();
Greg Clayton7b242382011-07-08 00:48:09 +0000233 return 0;
234 }
235
236 lldb::ByteOrder
237 GetByteOrder()
238 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000239 if (module_sp)
240 return module_sp->GetArchitecture().GetByteOrder();
Greg Clayton7b242382011-07-08 00:48:09 +0000241 return lldb::endian::InlHostByteOrder();
242 }
243
244 lldb_private::ArchSpec
245 GetArchitecture () const
246 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000247 if (module_sp)
248 return module_sp->GetArchitecture();
249 return lldb_private::ArchSpec ();
Greg Clayton7b242382011-07-08 00:48:09 +0000250 }
251
Greg Clayton7b242382011-07-08 00:48:09 +0000252 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;
Greg Clayton7b242382011-07-08 00:48:09 +0000265 lldb::addr_t image_infos_addr;
266
267 OSKextLoadedKextSummaryHeader() :
268 version (0),
269 entry_size (0),
270 entry_count (0),
Greg Clayton7b242382011-07-08 00:48:09 +0000271 image_infos_addr (LLDB_INVALID_ADDRESS)
272 {
273 }
274
Greg Claytona63d08c2011-07-19 03:57:15 +0000275 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
Greg Clayton7b242382011-07-08 00:48:09 +0000288 void
289 Clear()
290 {
291 version = 0;
292 entry_size = 0;
293 entry_count = 0;
Greg Clayton7b242382011-07-08 00:48:09 +0000294 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
Greg Clayton374972e2011-07-09 17:15:55 +0000310 void
311 SetNotificationBreakpointIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000312
313 bool
Greg Clayton374972e2011-07-09 17:15:55 +0000314 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000315
316 bool
317 ReadKextSummaryHeader ();
318
319 bool
Greg Clayton0d9fc762011-07-08 03:21:57 +0000320 ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
321 uint32_t count);
Greg Clayton7b242382011-07-08 00:48:09 +0000322
323 bool
324 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
325
Greg Clayton7b242382011-07-08 00:48:09 +0000326 void
327 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
328 uint32_t infos_count,
329 bool update_executable);
330
Greg Clayton7b242382011-07-08 00:48:09 +0000331 uint32_t
Greg Clayton0d9fc762011-07-08 03:21:57 +0000332 ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000333 uint32_t image_infos_count,
334 OSKextLoadedKextSummary::collection &image_infos);
335
Greg Clayton7b242382011-07-08 00:48:09 +0000336 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
Greg Claytond16e1e52011-07-12 17:06:17 +0000337 lldb_private::Address m_kext_summary_header_ptr_addr;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000338 lldb_private::Address m_kext_summary_header_addr;
Greg Clayton7b242382011-07-08 00:48:09 +0000339 OSKextLoadedKextSummaryHeader m_kext_summary_header;
Greg Clayton7b242382011-07-08 00:48:09 +0000340 OSKextLoadedKextSummary::collection m_kext_summaries;
Greg Clayton7b242382011-07-08 00:48:09 +0000341 mutable lldb_private::Mutex m_mutex;
Greg Clayton374972e2011-07-09 17:15:55 +0000342 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000343
344private:
Greg Clayton944b8282011-08-22 22:30:57 +0000345 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000346};
347
Greg Clayton944b8282011-08-22 22:30:57 +0000348#endif // liblldb_DynamicLoaderDarwinKernel_h_