blob: 005f5ea3903c63d9de8154062f97ca855482836d [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 Clayton02c322c2012-03-21 22:50:54 +0000206 LoadImageAtFileAddress (lldb_private::Process *process);
207
208 bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000209 LoadImageUsingMemoryModule (lldb_private::Process *process);
210
211// bool
212// operator == (const OSKextLoadedKextSummary& rhs) const
213// {
214// return address == rhs.address
215// && size == rhs.size
216// //&& module_sp.get() == rhs.module_sp.get()
217// && uuid == rhs.uuid
218// && version == rhs.version
219// && load_tag == rhs.load_tag
220// && flags == rhs.flags
221// && reference_list == rhs.reference_list
222// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
223// }
224//
Greg Clayton7b242382011-07-08 00:48:09 +0000225 bool
226 UUIDValid() const
227 {
228 return uuid.IsValid();
229 }
230
231 uint32_t
232 GetAddressByteSize ()
233 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000234 if (module_sp)
235 return module_sp->GetArchitecture().GetAddressByteSize();
Greg Clayton7b242382011-07-08 00:48:09 +0000236 return 0;
237 }
238
239 lldb::ByteOrder
240 GetByteOrder()
241 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000242 if (module_sp)
243 return module_sp->GetArchitecture().GetByteOrder();
Greg Clayton7b242382011-07-08 00:48:09 +0000244 return lldb::endian::InlHostByteOrder();
245 }
246
247 lldb_private::ArchSpec
248 GetArchitecture () const
249 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000250 if (module_sp)
251 return module_sp->GetArchitecture();
252 return lldb_private::ArchSpec ();
Greg Clayton7b242382011-07-08 00:48:09 +0000253 }
254
Greg Clayton7b242382011-07-08 00:48:09 +0000255 void
256 PutToLog (lldb_private::Log *log) const;
257
258 typedef std::vector<OSKextLoadedKextSummary> collection;
259 typedef collection::iterator iterator;
260 typedef collection::const_iterator const_iterator;
261 };
262
263 struct OSKextLoadedKextSummaryHeader
264 {
265 uint32_t version;
266 uint32_t entry_size;
267 uint32_t entry_count;
Greg Clayton7b242382011-07-08 00:48:09 +0000268 lldb::addr_t image_infos_addr;
269
270 OSKextLoadedKextSummaryHeader() :
271 version (0),
272 entry_size (0),
273 entry_count (0),
Greg Clayton7b242382011-07-08 00:48:09 +0000274 image_infos_addr (LLDB_INVALID_ADDRESS)
275 {
276 }
277
Greg Claytona63d08c2011-07-19 03:57:15 +0000278 uint32_t
279 GetSize()
280 {
281 switch (version)
282 {
283 case 0: return 0; // Can't know the size without a valid version
284 case 1: return 8; // Version 1 only had a version + entry_count
285 default: break;
286 }
287 // Version 2 and above has version, entry_size, entry_count, and reserved
288 return 16;
289 }
290
Greg Clayton7b242382011-07-08 00:48:09 +0000291 void
292 Clear()
293 {
294 version = 0;
295 entry_size = 0;
296 entry_count = 0;
Greg Clayton7b242382011-07-08 00:48:09 +0000297 image_infos_addr = LLDB_INVALID_ADDRESS;
298 }
299
300 bool
301 IsValid() const
302 {
303 return version >= 1 || version <= 2;
304 }
305 };
306
307 void
308 RegisterNotificationCallbacks();
309
310 void
311 UnregisterNotificationCallbacks();
312
Greg Clayton374972e2011-07-09 17:15:55 +0000313 void
314 SetNotificationBreakpointIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000315
316 bool
Greg Clayton374972e2011-07-09 17:15:55 +0000317 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000318
319 bool
320 ReadKextSummaryHeader ();
321
322 bool
Greg Clayton0d9fc762011-07-08 03:21:57 +0000323 ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
324 uint32_t count);
Greg Clayton7b242382011-07-08 00:48:09 +0000325
326 bool
327 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
328
Greg Clayton7b242382011-07-08 00:48:09 +0000329 void
330 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
331 uint32_t infos_count,
332 bool update_executable);
333
Greg Clayton7b242382011-07-08 00:48:09 +0000334 uint32_t
Greg Clayton0d9fc762011-07-08 03:21:57 +0000335 ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000336 uint32_t image_infos_count,
337 OSKextLoadedKextSummary::collection &image_infos);
338
Greg Clayton7b242382011-07-08 00:48:09 +0000339 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
Greg Claytond16e1e52011-07-12 17:06:17 +0000340 lldb_private::Address m_kext_summary_header_ptr_addr;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000341 lldb_private::Address m_kext_summary_header_addr;
Greg Clayton7b242382011-07-08 00:48:09 +0000342 OSKextLoadedKextSummaryHeader m_kext_summary_header;
Greg Clayton7b242382011-07-08 00:48:09 +0000343 OSKextLoadedKextSummary::collection m_kext_summaries;
Greg Clayton7b242382011-07-08 00:48:09 +0000344 mutable lldb_private::Mutex m_mutex;
Greg Clayton374972e2011-07-09 17:15:55 +0000345 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000346
347private:
Greg Clayton944b8282011-08-22 22:30:57 +0000348 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000349};
350
Greg Clayton944b8282011-08-22 22:30:57 +0000351#endif // liblldb_DynamicLoaderDarwinKernel_h_