blob: a7ec411cfbda190159816ee6738a442a587a228b [file] [log] [blame]
Greg Clayton944b8282011-08-22 22:30:57 +00001//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- 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
10#include "lldb/Breakpoint/StoppointCallbackContext.h"
11#include "lldb/Core/DataBuffer.h"
12#include "lldb/Core/DataBufferHeap.h"
Greg Clayton07e66e32011-07-20 03:41:06 +000013#include "lldb/Core/Debugger.h"
Greg Clayton7b242382011-07-08 00:48:09 +000014#include "lldb/Core/Log.h"
15#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Core/ModuleSpec.h"
Greg Clayton7b242382011-07-08 00:48:09 +000017#include "lldb/Core/PluginManager.h"
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/Core/Section.h"
Greg Clayton7b242382011-07-08 00:48:09 +000019#include "lldb/Core/State.h"
Jason Molenda68b36072012-10-02 03:49:41 +000020#include "lldb/Host/Symbols.h"
Greg Clayton7b242382011-07-08 00:48:09 +000021#include "lldb/Symbol/ObjectFile.h"
Greg Clayton7b242382011-07-08 00:48:09 +000022#include "lldb/Target/RegisterContext.h"
Jason Molenda68b36072012-10-02 03:49:41 +000023#include "lldb/Target/StackFrame.h"
Greg Clayton7b242382011-07-08 00:48:09 +000024#include "lldb/Target/Target.h"
25#include "lldb/Target/Thread.h"
26#include "lldb/Target/ThreadPlanRunToAddress.h"
Jason Molenda68b36072012-10-02 03:49:41 +000027
Greg Clayton7b242382011-07-08 00:48:09 +000028
Greg Clayton944b8282011-08-22 22:30:57 +000029#include "DynamicLoaderDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000030
31//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
32#ifdef ENABLE_DEBUG_PRINTF
33#include <stdio.h>
34#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
35#else
36#define DEBUG_PRINTF(fmt, ...)
37#endif
38
39using namespace lldb;
40using namespace lldb_private;
41
Greg Clayton7b242382011-07-08 00:48:09 +000042//----------------------------------------------------------------------
43// Create an instance of this class. This function is filled into
44// the plugin info class that gets handed out by the plugin factory and
45// allows the lldb to instantiate an instance of this class.
46//----------------------------------------------------------------------
47DynamicLoader *
Greg Clayton944b8282011-08-22 22:30:57 +000048DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
Greg Clayton7b242382011-07-08 00:48:09 +000049{
50 bool create = force;
51 if (!create)
52 {
Greg Claytonaa149cb2011-08-11 02:48:45 +000053 Module* exe_module = process->GetTarget().GetExecutableModulePointer();
Greg Claytondf0b7d52011-07-08 04:11:42 +000054 if (exe_module)
55 {
56 ObjectFile *object_file = exe_module->GetObjectFile();
57 if (object_file)
58 {
Sean Callanan49bce8e2012-02-10 20:22:35 +000059 create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
Greg Claytondf0b7d52011-07-08 04:11:42 +000060 }
61 }
62
63 if (create)
64 {
65 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
Greg Clayton70512312012-05-08 01:45:38 +000066 switch (triple_ref.getOS())
67 {
68 case llvm::Triple::Darwin:
69 case llvm::Triple::MacOSX:
70 case llvm::Triple::IOS:
71 create = triple_ref.getVendor() == llvm::Triple::Apple;
72 break;
73 default:
74 create = false;
75 break;
76 }
Greg Claytondf0b7d52011-07-08 04:11:42 +000077 }
Greg Clayton7b242382011-07-08 00:48:09 +000078 }
79
80 if (create)
Sean Callanan90539452011-09-20 23:01:51 +000081 {
82 process->SetCanJIT(false);
Greg Clayton944b8282011-08-22 22:30:57 +000083 return new DynamicLoaderDarwinKernel (process);
Sean Callanan90539452011-09-20 23:01:51 +000084 }
Greg Clayton7b242382011-07-08 00:48:09 +000085 return NULL;
86}
87
88//----------------------------------------------------------------------
89// Constructor
90//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +000091DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
Greg Clayton7b242382011-07-08 00:48:09 +000092 DynamicLoader(process),
93 m_kernel(),
Greg Claytond16e1e52011-07-12 17:06:17 +000094 m_kext_summary_header_ptr_addr (),
Greg Clayton0d9fc762011-07-08 03:21:57 +000095 m_kext_summary_header_addr (),
Greg Clayton7b242382011-07-08 00:48:09 +000096 m_kext_summary_header (),
Greg Clayton7b242382011-07-08 00:48:09 +000097 m_kext_summaries(),
Daniel Dunbara08823f2011-10-31 22:50:49 +000098 m_mutex(Mutex::eMutexTypeRecursive),
99 m_break_id (LLDB_INVALID_BREAK_ID)
Greg Clayton7b242382011-07-08 00:48:09 +0000100{
101}
102
103//----------------------------------------------------------------------
104// Destructor
105//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +0000106DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
Greg Clayton7b242382011-07-08 00:48:09 +0000107{
108 Clear(true);
109}
110
Greg Clayton374972e2011-07-09 17:15:55 +0000111void
Greg Clayton944b8282011-08-22 22:30:57 +0000112DynamicLoaderDarwinKernel::UpdateIfNeeded()
Greg Clayton374972e2011-07-09 17:15:55 +0000113{
114 LoadKernelModuleIfNeeded();
115 SetNotificationBreakpointIfNeeded ();
116}
Greg Clayton7b242382011-07-08 00:48:09 +0000117//------------------------------------------------------------------
118/// Called after attaching a process.
119///
120/// Allow DynamicLoader plug-ins to execute some code after
121/// attaching to a process.
122//------------------------------------------------------------------
123void
Greg Clayton944b8282011-08-22 22:30:57 +0000124DynamicLoaderDarwinKernel::DidAttach ()
Greg Clayton7b242382011-07-08 00:48:09 +0000125{
126 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000127 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000128}
129
130//------------------------------------------------------------------
131/// Called after attaching a process.
132///
133/// Allow DynamicLoader plug-ins to execute some code after
134/// attaching to a process.
135//------------------------------------------------------------------
136void
Greg Clayton944b8282011-08-22 22:30:57 +0000137DynamicLoaderDarwinKernel::DidLaunch ()
Greg Clayton7b242382011-07-08 00:48:09 +0000138{
139 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000140 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000141}
142
143
144//----------------------------------------------------------------------
145// Clear out the state of this class.
146//----------------------------------------------------------------------
147void
Greg Clayton944b8282011-08-22 22:30:57 +0000148DynamicLoaderDarwinKernel::Clear (bool clear_process)
Greg Clayton7b242382011-07-08 00:48:09 +0000149{
150 Mutex::Locker locker(m_mutex);
151
152 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
153 m_process->ClearBreakpointSiteByID(m_break_id);
154
155 if (clear_process)
156 m_process = NULL;
157 m_kernel.Clear(false);
Greg Claytond16e1e52011-07-12 17:06:17 +0000158 m_kext_summary_header_ptr_addr.Clear();
Greg Clayton0d9fc762011-07-08 03:21:57 +0000159 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000160 m_kext_summaries.clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000161 m_break_id = LLDB_INVALID_BREAK_ID;
162}
163
Greg Clayton7b242382011-07-08 00:48:09 +0000164
Greg Claytonc859e2d2012-02-13 23:10:39 +0000165bool
Greg Clayton2af282a2012-03-21 04:25:00 +0000166DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process)
167{
168 if (IsLoaded())
169 return true;
170
171 if (module_sp)
172 {
173 bool changed = false;
174 if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
175 load_process_stop_id = process->GetStopID();
176 }
177 return false;
178}
179
180bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000181DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
182{
183 if (IsLoaded())
184 return true;
185
186 bool uuid_is_valid = uuid.IsValid();
Jason Molenda68b36072012-10-02 03:49:41 +0000187 bool memory_module_is_kernel = false;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000188
189 Target &target = process->GetTarget();
190 ModuleSP memory_module_sp;
191 // Use the memory module as the module if we have one...
192 if (address != LLDB_INVALID_ADDRESS)
193 {
194 FileSpec file_spec;
195 if (module_sp)
196 file_spec = module_sp->GetFileSpec();
197 else
198 file_spec.SetFile (name, false);
199
200 memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
201 if (memory_module_sp && !uuid_is_valid)
202 {
203 uuid = memory_module_sp->GetUUID();
204 uuid_is_valid = uuid.IsValid();
205 }
Jason Molenda68b36072012-10-02 03:49:41 +0000206 if (memory_module_sp->GetObjectFile()
207 && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
208 && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
209 {
210 memory_module_is_kernel = true;
Jason Molenda53667f52012-10-06 02:02:26 +0000211 if (memory_module_sp->GetArchitecture().IsValid())
212 {
213 target.SetArchitecture(memory_module_sp->GetArchitecture());
214 }
Jason Molenda68b36072012-10-02 03:49:41 +0000215 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000216 }
217
218 if (!module_sp)
219 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000220 if (uuid_is_valid)
221 {
222 ModuleList &target_images = target.GetImages();
223 module_sp = target_images.FindModule(uuid);
Jason Molenda53667f52012-10-06 02:02:26 +0000224
Greg Claytonc859e2d2012-02-13 23:10:39 +0000225 if (!module_sp)
Greg Claytonb9a01b32012-02-26 05:51:37 +0000226 {
Greg Clayton2af282a2012-03-21 04:25:00 +0000227 ModuleSpec module_spec;
Greg Claytonb9a01b32012-02-26 05:51:37 +0000228 module_spec.GetUUID() = uuid;
Jason Molenda53667f52012-10-06 02:02:26 +0000229 module_spec.GetArchitecture() = target.GetArchitecture();
Jason Molendabb860bd2012-10-09 01:17:11 +0000230
231 // For the kernel, we really do need an on-disk file copy of the
232 // binary.
233 bool force_symbols_search = false;
234 if (memory_module_is_kernel)
235 {
236 force_symbols_search = true;
237 }
238
239 if (Symbols::DownloadObjectAndSymbolFile (module_spec, force_symbols_search))
240 {
241 if (module_spec.GetFileSpec().Exists())
242 {
243 module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
244 if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec))
245 {
246 ModuleList loaded_module_list;
247 loaded_module_list.Append (module_sp);
248 target.ModulesDidLoad (loaded_module_list);
249 }
250 }
251 }
252
253 // Ask the Target to find this file on the local system, if possible.
254 // This will search in the list of currently-loaded files, look in the
255 // standard search paths on the system, and on a Mac it will try calling
256 // the DebugSymbols framework with the UUID to find the binary via its
257 // search methods.
258 if (!module_sp)
259 {
260 module_sp = target.GetSharedModule (module_spec);
261 }
Greg Claytonb9a01b32012-02-26 05:51:37 +0000262 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000263 }
264 }
265
266
Jason Molendabb860bd2012-10-09 01:17:11 +0000267 if (memory_module_sp && module_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000268 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000269 if (module_sp->GetUUID() == memory_module_sp->GetUUID())
Greg Claytonc859e2d2012-02-13 23:10:39 +0000270 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000271 target.GetImages().Append(module_sp);
272 if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get())
Greg Claytonc859e2d2012-02-13 23:10:39 +0000273 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000274 target.SetExecutableModule (module_sp, false);
275 }
Jason Molenda53667f52012-10-06 02:02:26 +0000276
Jason Molendabb860bd2012-10-09 01:17:11 +0000277 ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
278 ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
279 if (memory_object_file && ondisk_object_file)
280 {
281 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
282 SectionList *memory_section_list = memory_object_file->GetSectionList ();
283 if (memory_section_list && ondisk_section_list)
284 {
285 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
286 // There may be CTF sections in the memory image so we can't
287 // always just compare the number of sections (which are actually
288 // segments in mach-o parlance)
289 uint32_t sect_idx = 0;
290
291 // Use the memory_module's addresses for each section to set the
292 // file module's load address as appropriate. We don't want to use
293 // a single slide value for the entire kext - different segments may
294 // be slid different amounts by the kext loader.
295
296 uint32_t num_sections_loaded = 0;
297 for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
298 {
299 SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
300 if (ondisk_section_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000301 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000302 const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
303 if (memory_section)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000304 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000305 target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
306 ++num_sections_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000307 }
308 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000309 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000310 if (num_sections_loaded > 0)
311 load_process_stop_id = process->GetStopID();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000312 else
Jason Molendabb860bd2012-10-09 01:17:11 +0000313 module_sp.reset(); // No sections were loaded
Greg Claytonc859e2d2012-02-13 23:10:39 +0000314 }
315 else
Jason Molendabb860bd2012-10-09 01:17:11 +0000316 module_sp.reset(); // One or both section lists
Greg Claytonc859e2d2012-02-13 23:10:39 +0000317 }
318 else
Jason Molendabb860bd2012-10-09 01:17:11 +0000319 module_sp.reset(); // One or both object files missing
Greg Claytonc859e2d2012-02-13 23:10:39 +0000320 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000321 else
322 module_sp.reset(); // UUID mismatch
Greg Claytonc859e2d2012-02-13 23:10:39 +0000323 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000324
Greg Claytonc859e2d2012-02-13 23:10:39 +0000325 bool is_loaded = IsLoaded();
326
327 if (so_address.IsValid())
328 {
329 if (is_loaded)
330 so_address.SetLoadAddress (address, &target);
331 else
332 target.GetImages().ResolveFileAddress (address, so_address);
333
334 }
Jason Molenda68b36072012-10-02 03:49:41 +0000335
336 if (is_loaded && module_sp && memory_module_is_kernel)
337 {
338 Stream *s = &target.GetDebugger().GetOutputStream();
339 if (s)
340 {
341 char uuidbuf[64];
342 s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf)));
343 s->Printf ("Load Address: 0x%llx\n", address);
Jason Molenda743e43962012-10-02 22:23:42 +0000344 if (module_sp->GetFileSpec().GetDirectory().IsEmpty())
345 {
346 s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString());
347 }
348 else
349 {
350 s->Printf ("Loaded kernel file %s/%s\n",
351 module_sp->GetFileSpec().GetDirectory().AsCString(),
352 module_sp->GetFileSpec().GetFilename().AsCString());
353 }
Jason Molenda68b36072012-10-02 03:49:41 +0000354 s->Flush ();
355 }
356 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000357 return is_loaded;
358}
359
Greg Clayton1f746072012-08-29 21:13:06 +0000360uint32_t
361DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize ()
362{
363 if (module_sp)
364 return module_sp->GetArchitecture().GetAddressByteSize();
365 return 0;
366}
367
368lldb::ByteOrder
369DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder()
370{
371 if (module_sp)
372 return module_sp->GetArchitecture().GetByteOrder();
373 return lldb::endian::InlHostByteOrder();
374}
375
376lldb_private::ArchSpec
377DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const
378{
379 if (module_sp)
380 return module_sp->GetArchitecture();
381 return lldb_private::ArchSpec ();
382}
383
384
Greg Clayton7b242382011-07-08 00:48:09 +0000385//----------------------------------------------------------------------
386// Load the kernel module and initialize the "m_kernel" member. Return
387// true _only_ if the kernel is loaded the first time through (subsequent
388// calls to this function should return false after the kernel has been
389// already loaded).
390//----------------------------------------------------------------------
Greg Clayton374972e2011-07-09 17:15:55 +0000391void
Greg Clayton944b8282011-08-22 22:30:57 +0000392DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
Greg Clayton7b242382011-07-08 00:48:09 +0000393{
Greg Claytond16e1e52011-07-12 17:06:17 +0000394 if (!m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000395 {
396 m_kernel.Clear(false);
397 m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000398
399 ConstString kernel_name("mach_kernel");
400 if (m_kernel.module_sp.get()
401 && m_kernel.module_sp->GetObjectFile()
402 && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
403 {
404 kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename();
405 }
Jason Molenda31a69612012-10-04 02:16:06 +0000406 strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name));
407 m_kernel.name[sizeof (m_kernel.name) - 1] = '\0';
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000408
Greg Claytonc859e2d2012-02-13 23:10:39 +0000409 if (m_kernel.address == LLDB_INVALID_ADDRESS)
Greg Clayton7b242382011-07-08 00:48:09 +0000410 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000411 m_kernel.address = m_process->GetImageInfoAddress ();
412 if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
Greg Clayton7b242382011-07-08 00:48:09 +0000413 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000414 // We didn't get a hint from the process, so we will
415 // try the kernel at the address that it exists at in
416 // the file if we have one
417 ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
418 if (kernel_object_file)
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000419 {
420 addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
421 addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
422 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
423 {
424 m_kernel.address = load_address;
425 if (load_address != file_address)
426 {
427 // Don't accidentally relocate the kernel to the File address --
428 // the Load address has already been set to its actual in-memory address.
429 // Mark it as IsLoaded.
430 m_kernel.load_process_stop_id = m_process->GetStopID();
431 }
432 }
433 else
434 {
435 m_kernel.address = file_address;
436 }
437 }
Greg Clayton7b242382011-07-08 00:48:09 +0000438 }
439 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000440
441 if (m_kernel.address != LLDB_INVALID_ADDRESS)
Greg Clayton2af282a2012-03-21 04:25:00 +0000442 {
443 if (!m_kernel.LoadImageUsingMemoryModule (m_process))
444 {
445 m_kernel.LoadImageAtFileAddress (m_process);
446 }
447 }
Greg Clayton7b242382011-07-08 00:48:09 +0000448
Greg Claytonc859e2d2012-02-13 23:10:39 +0000449 if (m_kernel.IsLoaded())
Greg Clayton7b242382011-07-08 00:48:09 +0000450 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000451 static ConstString kext_summary_symbol ("gLoadedKextSummaries");
452 const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
453 if (symbol)
454 {
Greg Claytone7612132012-03-07 21:03:09 +0000455 m_kext_summary_header_ptr_addr = symbol->GetAddress();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000456 // Update all image infos
457 ReadAllKextSummaries ();
458 }
Greg Clayton7b242382011-07-08 00:48:09 +0000459 }
460 else
Greg Clayton7b242382011-07-08 00:48:09 +0000461 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000462 m_kernel.Clear(false);
Greg Clayton7b242382011-07-08 00:48:09 +0000463 }
464 }
Greg Clayton7b242382011-07-08 00:48:09 +0000465}
466
Greg Clayton7b242382011-07-08 00:48:09 +0000467//----------------------------------------------------------------------
468// Static callback function that gets called when our DYLD notification
469// breakpoint gets hit. We update all of our image infos and then
470// let our super class DynamicLoader class decide if we should stop
471// or not (based on global preference).
472//----------------------------------------------------------------------
473bool
Greg Clayton944b8282011-08-22 22:30:57 +0000474DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
Greg Clayton374972e2011-07-09 17:15:55 +0000475 StoppointCallbackContext *context,
476 user_id_t break_id,
477 user_id_t break_loc_id)
Greg Clayton0d9fc762011-07-08 03:21:57 +0000478{
Greg Clayton944b8282011-08-22 22:30:57 +0000479 return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000480}
481
482bool
Greg Clayton944b8282011-08-22 22:30:57 +0000483DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
Greg Clayton374972e2011-07-09 17:15:55 +0000484 user_id_t break_id,
485 user_id_t break_loc_id)
486{
Greg Claytond16e1e52011-07-12 17:06:17 +0000487 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
488 if (log)
Greg Clayton944b8282011-08-22 22:30:57 +0000489 log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +0000490
Greg Clayton374972e2011-07-09 17:15:55 +0000491 ReadAllKextSummaries ();
Greg Claytond16e1e52011-07-12 17:06:17 +0000492
493 if (log)
494 PutToLog(log.get());
495
Greg Clayton374972e2011-07-09 17:15:55 +0000496 return GetStopWhenImagesChange();
497}
498
499
500bool
Greg Clayton944b8282011-08-22 22:30:57 +0000501DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
Greg Clayton7b242382011-07-08 00:48:09 +0000502{
503 Mutex::Locker locker(m_mutex);
504
505 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +0000506
507 m_kext_summaries.clear();
Greg Claytond16e1e52011-07-12 17:06:17 +0000508 if (m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000509 {
510 const uint32_t addr_size = m_kernel.GetAddressByteSize ();
511 const ByteOrder byte_order = m_kernel.GetByteOrder();
512 Error error;
513 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
514 // which is currenty 4 uint32_t and a pointer.
515 uint8_t buf[24];
516 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
517 const size_t count = 4 * sizeof(uint32_t) + addr_size;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000518 const bool prefer_file_cache = false;
Greg Claytond16e1e52011-07-12 17:06:17 +0000519 if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
520 prefer_file_cache,
521 error,
522 m_kext_summary_header_addr))
Greg Clayton7b242382011-07-08 00:48:09 +0000523 {
Greg Claytond16e1e52011-07-12 17:06:17 +0000524 // We got a valid address for our kext summary header and make sure it isn't NULL
525 if (m_kext_summary_header_addr.IsValid() &&
526 m_kext_summary_header_addr.GetFileAddress() != 0)
527 {
528 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
529 if (bytes_read == count)
530 {
531 uint32_t offset = 0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000532 m_kext_summary_header.version = data.GetU32(&offset);
533 if (m_kext_summary_header.version >= 2)
534 {
535 m_kext_summary_header.entry_size = data.GetU32(&offset);
536 }
537 else
538 {
539 // Versions less than 2 didn't have an entry size, it was hard coded
540 m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
541 }
542 m_kext_summary_header.entry_count = data.GetU32(&offset);
Greg Claytond16e1e52011-07-12 17:06:17 +0000543 return true;
544 }
545 }
Greg Clayton7b242382011-07-08 00:48:09 +0000546 }
547 }
Greg Claytond16e1e52011-07-12 17:06:17 +0000548 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000549 return false;
550}
551
552
553bool
Greg Clayton944b8282011-08-22 22:30:57 +0000554DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
Greg Clayton0d9fc762011-07-08 03:21:57 +0000555 uint32_t count)
Greg Clayton7b242382011-07-08 00:48:09 +0000556{
557 OSKextLoadedKextSummary::collection kext_summaries;
Greg Clayton374972e2011-07-09 17:15:55 +0000558 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000559 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000560 log->Printf ("Adding %d modules.\n", count);
Greg Clayton7b242382011-07-08 00:48:09 +0000561
562 Mutex::Locker locker(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000563
564 if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
565 return false;
566
Greg Clayton07e66e32011-07-20 03:41:06 +0000567 Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
Jason Molenda68b36072012-10-02 03:49:41 +0000568 if (s)
569 s->Printf ("Loading %d kext modules ", count);
Greg Clayton7b242382011-07-08 00:48:09 +0000570 for (uint32_t i = 0; i < count; i++)
571 {
Greg Clayton2af282a2012-03-21 04:25:00 +0000572 if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
573 kext_summaries[i].LoadImageAtFileAddress (m_process);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000574
Greg Clayton5b882162011-07-21 01:12:01 +0000575 if (s)
Jason Molenda68b36072012-10-02 03:49:41 +0000576 s->Printf (".");
577
Greg Claytona63d08c2011-07-19 03:57:15 +0000578 if (log)
579 kext_summaries[i].PutToLog (log.get());
Greg Clayton7b242382011-07-08 00:48:09 +0000580 }
Jason Molenda68b36072012-10-02 03:49:41 +0000581 if (s)
582 {
583 s->Printf (" done.\n");
584 s->Flush ();
585 }
586
Greg Clayton7b242382011-07-08 00:48:09 +0000587 bool return_value = AddModulesUsingImageInfos (kext_summaries);
Greg Clayton7b242382011-07-08 00:48:09 +0000588 return return_value;
589}
590
591// Adds the modules in image_infos to m_kext_summaries.
592// NB don't call this passing in m_kext_summaries.
593
594bool
Greg Clayton944b8282011-08-22 22:30:57 +0000595DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
Greg Clayton7b242382011-07-08 00:48:09 +0000596{
597 // Now add these images to the main list.
598 ModuleList loaded_module_list;
Greg Clayton7b242382011-07-08 00:48:09 +0000599
600 for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
601 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000602 OSKextLoadedKextSummary &image_info = image_infos[idx];
603 m_kext_summaries.push_back(image_info);
Greg Clayton7b242382011-07-08 00:48:09 +0000604
Greg Claytonc859e2d2012-02-13 23:10:39 +0000605 if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
606 loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
Greg Clayton7b242382011-07-08 00:48:09 +0000607 }
608
609 if (loaded_module_list.GetSize() > 0)
610 {
Greg Clayton7b242382011-07-08 00:48:09 +0000611 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
612 }
613 return true;
614}
615
Greg Clayton7b242382011-07-08 00:48:09 +0000616
617uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000618DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000619 uint32_t image_infos_count,
620 OSKextLoadedKextSummary::collection &image_infos)
621{
622 const ByteOrder endian = m_kernel.GetByteOrder();
623 const uint32_t addr_size = m_kernel.GetAddressByteSize();
624
625 image_infos.resize(image_infos_count);
626 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
627 DataBufferHeap data(count, 0);
628 Error error;
Greg Clayton5b882162011-07-21 01:12:01 +0000629
Greg Clayton0d9fc762011-07-08 03:21:57 +0000630 const bool prefer_file_cache = false;
631 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
632 prefer_file_cache,
633 data.GetBytes(),
634 data.GetByteSize(),
635 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000636 if (bytes_read == count)
637 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000638
Greg Clayton7b242382011-07-08 00:48:09 +0000639 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
640 uint32_t i=0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000641 for (uint32_t kext_summary_offset = 0;
642 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
643 ++i, kext_summary_offset += m_kext_summary_header.entry_size)
Greg Clayton7b242382011-07-08 00:48:09 +0000644 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000645 uint32_t offset = kext_summary_offset;
Greg Clayton7b242382011-07-08 00:48:09 +0000646 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
647 if (name_data == NULL)
648 break;
649 memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
650 image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
651 image_infos[i].address = extractor.GetU64(&offset);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000652 if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
653 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
Greg Clayton7b242382011-07-08 00:48:09 +0000654 image_infos[i].size = extractor.GetU64(&offset);
655 image_infos[i].version = extractor.GetU64(&offset);
656 image_infos[i].load_tag = extractor.GetU32(&offset);
657 image_infos[i].flags = extractor.GetU32(&offset);
Greg Claytona63d08c2011-07-19 03:57:15 +0000658 if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
659 {
660 image_infos[i].reference_list = extractor.GetU64(&offset);
661 }
662 else
663 {
664 image_infos[i].reference_list = 0;
665 }
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000666// printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n",
667// i,
668// KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data,
669// image_infos[i].address,
670// image_infos[i].size,
671// image_infos[i].version,
672// image_infos[i].load_tag,
673// image_infos[i].flags);
Greg Clayton7b242382011-07-08 00:48:09 +0000674 }
675 if (i < image_infos.size())
676 image_infos.resize(i);
677 }
678 else
679 {
680 image_infos.clear();
681 }
682 return image_infos.size();
683}
684
685bool
Greg Clayton944b8282011-08-22 22:30:57 +0000686DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
Greg Clayton7b242382011-07-08 00:48:09 +0000687{
Greg Clayton374972e2011-07-09 17:15:55 +0000688 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000689
690 Mutex::Locker locker(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +0000691
Greg Clayton7b242382011-07-08 00:48:09 +0000692 if (ReadKextSummaryHeader ())
693 {
Greg Clayton374972e2011-07-09 17:15:55 +0000694 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000695 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000696 Address summary_addr (m_kext_summary_header_addr);
Greg Claytona63d08c2011-07-19 03:57:15 +0000697 summary_addr.Slide(m_kext_summary_header.GetSize());
Greg Clayton0d9fc762011-07-08 03:21:57 +0000698 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
Greg Clayton7b242382011-07-08 00:48:09 +0000699 {
Greg Clayton7b242382011-07-08 00:48:09 +0000700 m_kext_summaries.clear();
701 }
702 return true;
703 }
704 }
705 return false;
706}
707
708//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000709// Dump an image info structure to the file handle provided.
710//----------------------------------------------------------------------
711void
Greg Clayton944b8282011-08-22 22:30:57 +0000712DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000713{
714 if (log == NULL)
715 return;
Greg Clayton07e66e32011-07-20 03:41:06 +0000716 const uint8_t *u = (uint8_t *)uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +0000717
718 if (address == LLDB_INVALID_ADDRESS)
719 {
720 if (u)
721 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000722 log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)",
Greg Clayton7b242382011-07-08 00:48:09 +0000723 u[ 0], u[ 1], u[ 2], u[ 3],
724 u[ 4], u[ 5], u[ 6], u[ 7],
725 u[ 8], u[ 9], u[10], u[11],
726 u[12], u[13], u[14], u[15],
727 name);
728 }
729 else
Greg Claytona63d08c2011-07-19 03:57:15 +0000730 log->Printf("\tname=\"%s\" (UNLOADED)", name);
Greg Clayton7b242382011-07-08 00:48:09 +0000731 }
732 else
733 {
734 if (u)
735 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000736 log->Printf("\taddr=0x%16.16llx size=0x%16.16llx version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
737 address, size, version, load_tag, flags, reference_list,
738 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
739 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
Greg Clayton7b242382011-07-08 00:48:09 +0000740 name);
741 }
742 else
743 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000744 log->Printf("\t[0x%16.16llx - 0x%16.16llx) version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx name=\"%s\"",
745 address, address+size, version, load_tag, flags, reference_list,
746 name);
Greg Clayton7b242382011-07-08 00:48:09 +0000747 }
Greg Clayton7b242382011-07-08 00:48:09 +0000748 }
749}
750
751//----------------------------------------------------------------------
752// Dump the _dyld_all_image_infos members and all current image infos
753// that we have parsed to the file handle provided.
754//----------------------------------------------------------------------
755void
Greg Clayton944b8282011-08-22 22:30:57 +0000756DynamicLoaderDarwinKernel::PutToLog(Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000757{
758 if (log == NULL)
759 return;
760
761 Mutex::Locker locker(m_mutex);
Greg Claytona63d08c2011-07-19 03:57:15 +0000762 log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
Greg Clayton0d9fc762011-07-08 03:21:57 +0000763 m_kext_summary_header_addr.GetFileAddress(),
Greg Clayton7b242382011-07-08 00:48:09 +0000764 m_kext_summary_header.version,
765 m_kext_summary_header.entry_size,
Greg Claytona63d08c2011-07-19 03:57:15 +0000766 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +0000767
768 size_t i;
769 const size_t count = m_kext_summaries.size();
770 if (count > 0)
771 {
772 log->PutCString("Loaded:");
773 for (i = 0; i<count; i++)
774 m_kext_summaries[i].PutToLog(log);
775 }
776}
777
778void
Greg Clayton944b8282011-08-22 22:30:57 +0000779DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
Greg Clayton7b242382011-07-08 00:48:09 +0000780{
Greg Clayton944b8282011-08-22 22:30:57 +0000781 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton7b242382011-07-08 00:48:09 +0000782 Clear(true);
783 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +0000784}
785
Greg Clayton374972e2011-07-09 17:15:55 +0000786void
Greg Clayton944b8282011-08-22 22:30:57 +0000787DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
Greg Clayton7b242382011-07-08 00:48:09 +0000788{
Greg Claytonc859e2d2012-02-13 23:10:39 +0000789 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
Greg Clayton374972e2011-07-09 17:15:55 +0000790 {
Greg Clayton944b8282011-08-22 22:30:57 +0000791 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +0000792
Greg Claytond16e1e52011-07-12 17:06:17 +0000793
Jim Inghama8558b62012-05-22 00:12:20 +0000794 const bool internal_bp = true;
Greg Claytond16e1e52011-07-12 17:06:17 +0000795 const LazyBool skip_prologue = eLazyBoolNo;
Jim Ingham969795f2011-09-21 01:17:13 +0000796 FileSpecList module_spec_list;
797 module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
798 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
Jim Ingham87df91b2011-09-23 00:54:11 +0000799 NULL,
Greg Clayton374972e2011-07-09 17:15:55 +0000800 "OSKextLoadedKextSummariesUpdated",
801 eFunctionNameTypeFull,
Jim Inghama8558b62012-05-22 00:12:20 +0000802 skip_prologue,
803 internal_bp).get();
Greg Clayton374972e2011-07-09 17:15:55 +0000804
Greg Clayton944b8282011-08-22 22:30:57 +0000805 bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
Greg Clayton374972e2011-07-09 17:15:55 +0000806 m_break_id = bp->GetID();
807 }
Greg Clayton7b242382011-07-08 00:48:09 +0000808}
809
810//----------------------------------------------------------------------
811// Member function that gets called when the process state changes.
812//----------------------------------------------------------------------
813void
Greg Clayton944b8282011-08-22 22:30:57 +0000814DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
Greg Clayton7b242382011-07-08 00:48:09 +0000815{
Greg Clayton944b8282011-08-22 22:30:57 +0000816 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
Greg Clayton7b242382011-07-08 00:48:09 +0000817 switch (state)
818 {
819 case eStateConnected:
820 case eStateAttaching:
821 case eStateLaunching:
822 case eStateInvalid:
823 case eStateUnloaded:
824 case eStateExited:
825 case eStateDetached:
826 Clear(false);
827 break;
828
829 case eStateStopped:
Greg Clayton374972e2011-07-09 17:15:55 +0000830 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000831 break;
832
833 case eStateRunning:
834 case eStateStepping:
835 case eStateCrashed:
836 case eStateSuspended:
837 break;
838
839 default:
840 break;
841 }
842}
843
844ThreadPlanSP
Greg Clayton944b8282011-08-22 22:30:57 +0000845DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
Greg Clayton7b242382011-07-08 00:48:09 +0000846{
847 ThreadPlanSP thread_plan_sp;
Greg Clayton374972e2011-07-09 17:15:55 +0000848 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
849 if (log)
850 log->Printf ("Could not find symbol for step through.");
Greg Clayton7b242382011-07-08 00:48:09 +0000851 return thread_plan_sp;
852}
853
854Error
Greg Clayton944b8282011-08-22 22:30:57 +0000855DynamicLoaderDarwinKernel::CanLoadImage ()
Greg Clayton7b242382011-07-08 00:48:09 +0000856{
857 Error error;
858 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
859 return error;
860}
861
862void
Greg Clayton944b8282011-08-22 22:30:57 +0000863DynamicLoaderDarwinKernel::Initialize()
Greg Clayton7b242382011-07-08 00:48:09 +0000864{
865 PluginManager::RegisterPlugin (GetPluginNameStatic(),
866 GetPluginDescriptionStatic(),
867 CreateInstance);
868}
869
870void
Greg Clayton944b8282011-08-22 22:30:57 +0000871DynamicLoaderDarwinKernel::Terminate()
Greg Clayton7b242382011-07-08 00:48:09 +0000872{
873 PluginManager::UnregisterPlugin (CreateInstance);
874}
875
876
877const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000878DynamicLoaderDarwinKernel::GetPluginNameStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000879{
880 return "dynamic-loader.macosx-kernel";
881}
882
883const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000884DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000885{
886 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
887}
888
889
890//------------------------------------------------------------------
891// PluginInterface protocol
892//------------------------------------------------------------------
893const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000894DynamicLoaderDarwinKernel::GetPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000895{
Greg Clayton944b8282011-08-22 22:30:57 +0000896 return "DynamicLoaderDarwinKernel";
Greg Clayton7b242382011-07-08 00:48:09 +0000897}
898
899const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000900DynamicLoaderDarwinKernel::GetShortPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000901{
902 return GetPluginNameStatic();
903}
904
905uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000906DynamicLoaderDarwinKernel::GetPluginVersion()
Greg Clayton7b242382011-07-08 00:48:09 +0000907{
908 return 1;
909}
910
Greg Clayton1f746072012-08-29 21:13:06 +0000911lldb::ByteOrder
912DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
913{
914 switch (magic)
915 {
916 case llvm::MachO::HeaderMagic32:
917 case llvm::MachO::HeaderMagic64:
918 return lldb::endian::InlHostByteOrder();
919
920 case llvm::MachO::HeaderMagic32Swapped:
921 case llvm::MachO::HeaderMagic64Swapped:
922 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
923 return lldb::eByteOrderLittle;
924 else
925 return lldb::eByteOrderBig;
926
927 default:
928 break;
929 }
930 return lldb::eByteOrderInvalid;
931}
932