1 //===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- 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 #include "lldb/Breakpoint/StoppointCallbackContext.h"
11 #include "lldb/Core/DataBuffer.h"
12 #include "lldb/Core/DataBufferHeap.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/Log.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/State.h"
18 #include "lldb/Symbol/ObjectFile.h"
19 #include "lldb/Target/ObjCLanguageRuntime.h"
20 #include "lldb/Target/RegisterContext.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Target/Thread.h"
23 #include "lldb/Target/ThreadPlanRunToAddress.h"
24 #include "lldb/Target/StackFrame.h"
25 
26 #include "DynamicLoaderDarwinKernel.h"
27 
28 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
29 #ifdef ENABLE_DEBUG_PRINTF
30 #include <stdio.h>
31 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
32 #else
33 #define DEBUG_PRINTF(fmt, ...)
34 #endif
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 
39 /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
40 /// I am putting it here so I can invoke it in the Trampoline code here, but
41 /// it should be moved to the ObjC Runtime support when it is set up.
42 
43 
44 //----------------------------------------------------------------------
45 // Create an instance of this class. This function is filled into
46 // the plugin info class that gets handed out by the plugin factory and
47 // allows the lldb to instantiate an instance of this class.
48 //----------------------------------------------------------------------
49 DynamicLoader *
50 DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
51 {
52     bool create = force;
53     if (!create)
54     {
55         Module* exe_module = process->GetTarget().GetExecutableModulePointer();
56         if (exe_module)
57         {
58             ObjectFile *object_file = exe_module->GetObjectFile();
59             if (object_file)
60             {
61                 create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
62             }
63         }
64 
65         if (create)
66         {
67             const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
68             switch (triple_ref.getOS())
69             {
70                 case llvm::Triple::Darwin:
71                 case llvm::Triple::MacOSX:
72                 case llvm::Triple::IOS:
73                     create = triple_ref.getVendor() == llvm::Triple::Apple;
74                     break;
75                 default:
76                     create = false;
77                     break;
78             }
79         }
80     }
81 
82     if (create)
83     {
84         process->SetCanJIT(false);
85         return new DynamicLoaderDarwinKernel (process);
86     }
87     return NULL;
88 }
89 
90 //----------------------------------------------------------------------
91 // Constructor
92 //----------------------------------------------------------------------
93 DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
94     DynamicLoader(process),
95     m_kernel(),
96     m_kext_summary_header_ptr_addr (),
97     m_kext_summary_header_addr (),
98     m_kext_summary_header (),
99     m_kext_summaries(),
100     m_mutex(Mutex::eMutexTypeRecursive),
101     m_break_id (LLDB_INVALID_BREAK_ID)
102 {
103 }
104 
105 //----------------------------------------------------------------------
106 // Destructor
107 //----------------------------------------------------------------------
108 DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
109 {
110     Clear(true);
111 }
112 
113 void
114 DynamicLoaderDarwinKernel::UpdateIfNeeded()
115 {
116     LoadKernelModuleIfNeeded();
117     SetNotificationBreakpointIfNeeded ();
118 }
119 //------------------------------------------------------------------
120 /// Called after attaching a process.
121 ///
122 /// Allow DynamicLoader plug-ins to execute some code after
123 /// attaching to a process.
124 //------------------------------------------------------------------
125 void
126 DynamicLoaderDarwinKernel::DidAttach ()
127 {
128     PrivateInitialize(m_process);
129     UpdateIfNeeded();
130 }
131 
132 //------------------------------------------------------------------
133 /// Called after attaching a process.
134 ///
135 /// Allow DynamicLoader plug-ins to execute some code after
136 /// attaching to a process.
137 //------------------------------------------------------------------
138 void
139 DynamicLoaderDarwinKernel::DidLaunch ()
140 {
141     PrivateInitialize(m_process);
142     UpdateIfNeeded();
143 }
144 
145 
146 //----------------------------------------------------------------------
147 // Clear out the state of this class.
148 //----------------------------------------------------------------------
149 void
150 DynamicLoaderDarwinKernel::Clear (bool clear_process)
151 {
152     Mutex::Locker locker(m_mutex);
153 
154     if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
155         m_process->ClearBreakpointSiteByID(m_break_id);
156 
157     if (clear_process)
158         m_process = NULL;
159     m_kernel.Clear(false);
160     m_kext_summary_header_ptr_addr.Clear();
161     m_kext_summary_header_addr.Clear();
162     m_kext_summaries.clear();
163     m_break_id = LLDB_INVALID_BREAK_ID;
164 }
165 
166 
167 bool
168 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process)
169 {
170     if (IsLoaded())
171         return true;
172 
173     if (module_sp)
174     {
175         bool changed = false;
176         if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
177             load_process_stop_id = process->GetStopID();
178     }
179     return false;
180 }
181 
182 bool
183 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
184 {
185     if (IsLoaded())
186         return true;
187 
188     bool uuid_is_valid = uuid.IsValid();
189 
190     Target &target = process->GetTarget();
191     ModuleSP memory_module_sp;
192     // Use the memory module as the module if we have one...
193     if (address != LLDB_INVALID_ADDRESS)
194     {
195         FileSpec file_spec;
196         if (module_sp)
197             file_spec = module_sp->GetFileSpec();
198         else
199             file_spec.SetFile (name, false);
200 
201         memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
202         if (memory_module_sp && !uuid_is_valid)
203         {
204             uuid = memory_module_sp->GetUUID();
205             uuid_is_valid = uuid.IsValid();
206         }
207     }
208 
209     if (!module_sp)
210     {
211         if (uuid_is_valid)
212         {
213             ModuleList &target_images = target.GetImages();
214             module_sp = target_images.FindModule(uuid);
215 
216             if (!module_sp)
217             {
218                 ModuleSpec module_spec;
219                 module_spec.GetUUID() = uuid;
220                 module_sp = target.GetSharedModule (module_spec);
221             }
222         }
223     }
224 
225 
226     if (memory_module_sp)
227     {
228         // Someone already supplied a file, make sure it is the right one.
229         if (module_sp)
230         {
231             if (module_sp->GetUUID() == memory_module_sp->GetUUID())
232             {
233                 ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
234                 ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
235                 if (memory_object_file && ondisk_object_file)
236                 {
237                     SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
238                     SectionList *memory_section_list = memory_object_file->GetSectionList ();
239                     if (memory_section_list && ondisk_section_list)
240                     {
241                         const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
242                         // There may be CTF sections in the memory image so we can't
243                         // always just compare the number of sections (which are actually
244                         // segments in mach-o parlance)
245                         uint32_t sect_idx = 0;
246 
247 
248                         // We now iterate through all sections in the file module
249                         // and look to see if the memory module has a load address
250                         // for that section.
251                         uint32_t num_sections_loaded = 0;
252                         for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
253                         {
254                             SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
255                             if (ondisk_section_sp)
256                             {
257                                 const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
258                                 if (memory_section)
259                                 {
260                                     target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
261                                     ++num_sections_loaded;
262                                 }
263                             }
264                         }
265                         if (num_sections_loaded > 0)
266                             load_process_stop_id = process->GetStopID();
267                         else
268                             module_sp.reset(); // No sections were loaded
269                     }
270                     else
271                         module_sp.reset(); // One or both section lists
272                 }
273                 else
274                     module_sp.reset(); // One or both object files missing
275             }
276             else
277                 module_sp.reset(); // UUID mismatch
278         }
279 
280         // Use the memory module as the module if we didn't like the file
281         // module we either found or were supplied with
282         if (!module_sp)
283         {
284             module_sp = memory_module_sp;
285             // Load the memory image in the target as all adresses are already correct
286             bool changed = false;
287             target.GetImages().Append (memory_module_sp);
288             if (module_sp->SetLoadAddress (target, 0, changed))
289                 load_process_stop_id = process->GetStopID();
290         }
291     }
292     bool is_loaded = IsLoaded();
293 
294     if (so_address.IsValid())
295     {
296         if (is_loaded)
297             so_address.SetLoadAddress (address, &target);
298         else
299             target.GetImages().ResolveFileAddress (address, so_address);
300 
301     }
302     return is_loaded;
303 }
304 
305 //----------------------------------------------------------------------
306 // Load the kernel module and initialize the "m_kernel" member. Return
307 // true _only_ if the kernel is loaded the first time through (subsequent
308 // calls to this function should return false after the kernel has been
309 // already loaded).
310 //----------------------------------------------------------------------
311 void
312 DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
313 {
314     if (!m_kext_summary_header_ptr_addr.IsValid())
315     {
316         m_kernel.Clear(false);
317         m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
318         strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name));
319         if (m_kernel.address == LLDB_INVALID_ADDRESS)
320         {
321             m_kernel.address = m_process->GetImageInfoAddress ();
322             if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
323             {
324                 // We didn't get a hint from the process, so we will
325                 // try the kernel at the address that it exists at in
326                 // the file if we have one
327                 ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
328                 if (kernel_object_file)
329                     m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress();
330             }
331         }
332 
333         if (m_kernel.address != LLDB_INVALID_ADDRESS)
334         {
335             if (!m_kernel.LoadImageUsingMemoryModule (m_process))
336             {
337                 m_kernel.LoadImageAtFileAddress (m_process);
338             }
339         }
340 
341         if (m_kernel.IsLoaded())
342         {
343             static ConstString kext_summary_symbol ("gLoadedKextSummaries");
344             const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
345             if (symbol)
346             {
347                 m_kext_summary_header_ptr_addr = symbol->GetAddress();
348                 // Update all image infos
349                 ReadAllKextSummaries ();
350             }
351         }
352         else
353         {
354             m_kernel.Clear(false);
355         }
356     }
357 }
358 
359 //----------------------------------------------------------------------
360 // Static callback function that gets called when our DYLD notification
361 // breakpoint gets hit. We update all of our image infos and then
362 // let our super class DynamicLoader class decide if we should stop
363 // or not (based on global preference).
364 //----------------------------------------------------------------------
365 bool
366 DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
367                                                   StoppointCallbackContext *context,
368                                                   user_id_t break_id,
369                                                   user_id_t break_loc_id)
370 {
371     return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
372 }
373 
374 bool
375 DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
376                                           user_id_t break_id,
377                                           user_id_t break_loc_id)
378 {
379     LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
380     if (log)
381         log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
382 
383     ReadAllKextSummaries ();
384 
385     if (log)
386         PutToLog(log.get());
387 
388     return GetStopWhenImagesChange();
389 }
390 
391 
392 bool
393 DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
394 {
395     Mutex::Locker locker(m_mutex);
396 
397     // the all image infos is already valid for this process stop ID
398 
399     m_kext_summaries.clear();
400     if (m_kext_summary_header_ptr_addr.IsValid())
401     {
402         const uint32_t addr_size = m_kernel.GetAddressByteSize ();
403         const ByteOrder byte_order = m_kernel.GetByteOrder();
404         Error error;
405         // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
406         // which is currenty 4 uint32_t and a pointer.
407         uint8_t buf[24];
408         DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
409         const size_t count = 4 * sizeof(uint32_t) + addr_size;
410         const bool prefer_file_cache = false;
411         if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
412                                                           prefer_file_cache,
413                                                           error,
414                                                           m_kext_summary_header_addr))
415         {
416             // We got a valid address for our kext summary header and make sure it isn't NULL
417             if (m_kext_summary_header_addr.IsValid() &&
418                 m_kext_summary_header_addr.GetFileAddress() != 0)
419             {
420                 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
421                 if (bytes_read == count)
422                 {
423                     uint32_t offset = 0;
424                     m_kext_summary_header.version = data.GetU32(&offset);
425                     if (m_kext_summary_header.version >= 2)
426                     {
427                         m_kext_summary_header.entry_size = data.GetU32(&offset);
428                     }
429                     else
430                     {
431                         // Versions less than 2 didn't have an entry size, it was hard coded
432                         m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
433                     }
434                     m_kext_summary_header.entry_count = data.GetU32(&offset);
435                     return true;
436                 }
437             }
438         }
439     }
440     m_kext_summary_header_addr.Clear();
441     return false;
442 }
443 
444 
445 bool
446 DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
447                                                uint32_t count)
448 {
449     OSKextLoadedKextSummary::collection kext_summaries;
450     LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
451     if (log)
452         log->Printf ("Adding %d modules.\n", count);
453 
454     Mutex::Locker locker(m_mutex);
455 
456     if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
457         return false;
458 
459     Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
460     for (uint32_t i = 0; i < count; i++)
461     {
462         if (s)
463         {
464             const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes();
465             if (u)
466             {
467                 s->Printf("Loading kext: %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 0x%16.16llx \"%s\"...",
468                           u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
469                           u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
470                           kext_summaries[i].address, kext_summaries[i].name);
471             }
472             else
473             {
474                 s->Printf("0x%16.16llx \"%s\"...", kext_summaries[i].address, kext_summaries[i].name);
475             }
476         }
477 
478         if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
479             kext_summaries[i].LoadImageAtFileAddress (m_process);
480 
481         if (s)
482         {
483             if (kext_summaries[i].module_sp)
484             {
485                 if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory())
486                     s->Printf("\n  found kext: %s/%s\n",
487                               kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(),
488                               kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
489                 else
490                     s->Printf("\n  found kext: %s\n",
491                               kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
492             }
493             else
494                 s->Printf (" failed to locate/load.\n");
495         }
496 
497         if (log)
498             kext_summaries[i].PutToLog (log.get());
499     }
500     bool return_value = AddModulesUsingImageInfos (kext_summaries);
501     return return_value;
502 }
503 
504 // Adds the modules in image_infos to m_kext_summaries.
505 // NB don't call this passing in m_kext_summaries.
506 
507 bool
508 DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
509 {
510     // Now add these images to the main list.
511     ModuleList loaded_module_list;
512 
513     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
514     {
515         OSKextLoadedKextSummary &image_info = image_infos[idx];
516         m_kext_summaries.push_back(image_info);
517 
518         if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
519             loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
520     }
521 
522     if (loaded_module_list.GetSize() > 0)
523     {
524         m_process->GetTarget().ModulesDidLoad (loaded_module_list);
525     }
526     return true;
527 }
528 
529 
530 uint32_t
531 DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
532                                               uint32_t image_infos_count,
533                                               OSKextLoadedKextSummary::collection &image_infos)
534 {
535     const ByteOrder endian = m_kernel.GetByteOrder();
536     const uint32_t addr_size = m_kernel.GetAddressByteSize();
537 
538     image_infos.resize(image_infos_count);
539     const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
540     DataBufferHeap data(count, 0);
541     Error error;
542 
543     Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
544 
545     if (s)
546         s->Printf ("Reading %u kext summaries...\n", image_infos_count);
547     const bool prefer_file_cache = false;
548     const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
549                                                                  prefer_file_cache,
550                                                                  data.GetBytes(),
551                                                                  data.GetByteSize(),
552                                                                  error);
553     if (bytes_read == count)
554     {
555 
556         DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
557         uint32_t i=0;
558         for (uint32_t kext_summary_offset = 0;
559              i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
560              ++i, kext_summary_offset += m_kext_summary_header.entry_size)
561         {
562             uint32_t offset = kext_summary_offset;
563             const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
564             if (name_data == NULL)
565                 break;
566             memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
567             image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
568             image_infos[i].address          = extractor.GetU64(&offset);
569             if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
570                 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
571             image_infos[i].size             = extractor.GetU64(&offset);
572             image_infos[i].version          = extractor.GetU64(&offset);
573             image_infos[i].load_tag         = extractor.GetU32(&offset);
574             image_infos[i].flags            = extractor.GetU32(&offset);
575             if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
576             {
577                 image_infos[i].reference_list = extractor.GetU64(&offset);
578             }
579             else
580             {
581                 image_infos[i].reference_list = 0;
582             }
583 //            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",
584 //                    i,
585 //                    KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME,  (char *)name_data,
586 //                    image_infos[i].address,
587 //                    image_infos[i].size,
588 //                    image_infos[i].version,
589 //                    image_infos[i].load_tag,
590 //                    image_infos[i].flags);
591         }
592         if (i < image_infos.size())
593             image_infos.resize(i);
594     }
595     else
596     {
597         image_infos.clear();
598     }
599     return image_infos.size();
600 }
601 
602 bool
603 DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
604 {
605     LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
606 
607     Mutex::Locker locker(m_mutex);
608 
609     if (ReadKextSummaryHeader ())
610     {
611         if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
612         {
613             Address summary_addr (m_kext_summary_header_addr);
614             summary_addr.Slide(m_kext_summary_header.GetSize());
615             if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
616             {
617                 m_kext_summaries.clear();
618             }
619             return true;
620         }
621     }
622     return false;
623 }
624 
625 //----------------------------------------------------------------------
626 // Dump an image info structure to the file handle provided.
627 //----------------------------------------------------------------------
628 void
629 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
630 {
631     if (log == NULL)
632         return;
633     const uint8_t *u = (uint8_t *)uuid.GetBytes();
634 
635     if (address == LLDB_INVALID_ADDRESS)
636     {
637         if (u)
638         {
639             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)",
640                         u[ 0], u[ 1], u[ 2], u[ 3],
641                         u[ 4], u[ 5], u[ 6], u[ 7],
642                         u[ 8], u[ 9], u[10], u[11],
643                         u[12], u[13], u[14], u[15],
644                         name);
645         }
646         else
647             log->Printf("\tname=\"%s\" (UNLOADED)", name);
648     }
649     else
650     {
651         if (u)
652         {
653             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\"",
654                         address, size, version, load_tag, flags, reference_list,
655                         u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
656                         u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
657                         name);
658         }
659         else
660         {
661             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\"",
662                         address, address+size, version, load_tag, flags, reference_list,
663                         name);
664         }
665     }
666 }
667 
668 //----------------------------------------------------------------------
669 // Dump the _dyld_all_image_infos members and all current image infos
670 // that we have parsed to the file handle provided.
671 //----------------------------------------------------------------------
672 void
673 DynamicLoaderDarwinKernel::PutToLog(Log *log) const
674 {
675     if (log == NULL)
676         return;
677 
678     Mutex::Locker locker(m_mutex);
679     log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
680                 m_kext_summary_header_addr.GetFileAddress(),
681                 m_kext_summary_header.version,
682                 m_kext_summary_header.entry_size,
683                 m_kext_summary_header.entry_count);
684 
685     size_t i;
686     const size_t count = m_kext_summaries.size();
687     if (count > 0)
688     {
689         log->PutCString("Loaded:");
690         for (i = 0; i<count; i++)
691             m_kext_summaries[i].PutToLog(log);
692     }
693 }
694 
695 void
696 DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
697 {
698     DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
699     Clear(true);
700     m_process = process;
701     m_process->GetTarget().GetSectionLoadList().Clear();
702 }
703 
704 void
705 DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
706 {
707     if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
708     {
709         DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
710 
711 
712         const bool internal_bp = true;
713         const LazyBool skip_prologue = eLazyBoolNo;
714         FileSpecList module_spec_list;
715         module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
716         Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
717                                                                   NULL,
718                                                                   "OSKextLoadedKextSummariesUpdated",
719                                                                   eFunctionNameTypeFull,
720                                                                   skip_prologue,
721                                                                   internal_bp).get();
722 
723         bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
724         m_break_id = bp->GetID();
725     }
726 }
727 
728 //----------------------------------------------------------------------
729 // Member function that gets called when the process state changes.
730 //----------------------------------------------------------------------
731 void
732 DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
733 {
734     DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
735     switch (state)
736     {
737     case eStateConnected:
738     case eStateAttaching:
739     case eStateLaunching:
740     case eStateInvalid:
741     case eStateUnloaded:
742     case eStateExited:
743     case eStateDetached:
744         Clear(false);
745         break;
746 
747     case eStateStopped:
748         UpdateIfNeeded();
749         break;
750 
751     case eStateRunning:
752     case eStateStepping:
753     case eStateCrashed:
754     case eStateSuspended:
755         break;
756 
757     default:
758         break;
759     }
760 }
761 
762 ThreadPlanSP
763 DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
764 {
765     ThreadPlanSP thread_plan_sp;
766     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
767     if (log)
768         log->Printf ("Could not find symbol for step through.");
769     return thread_plan_sp;
770 }
771 
772 Error
773 DynamicLoaderDarwinKernel::CanLoadImage ()
774 {
775     Error error;
776     error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
777     return error;
778 }
779 
780 void
781 DynamicLoaderDarwinKernel::Initialize()
782 {
783     PluginManager::RegisterPlugin (GetPluginNameStatic(),
784                                    GetPluginDescriptionStatic(),
785                                    CreateInstance);
786 }
787 
788 void
789 DynamicLoaderDarwinKernel::Terminate()
790 {
791     PluginManager::UnregisterPlugin (CreateInstance);
792 }
793 
794 
795 const char *
796 DynamicLoaderDarwinKernel::GetPluginNameStatic()
797 {
798     return "dynamic-loader.macosx-kernel";
799 }
800 
801 const char *
802 DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
803 {
804     return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
805 }
806 
807 
808 //------------------------------------------------------------------
809 // PluginInterface protocol
810 //------------------------------------------------------------------
811 const char *
812 DynamicLoaderDarwinKernel::GetPluginName()
813 {
814     return "DynamicLoaderDarwinKernel";
815 }
816 
817 const char *
818 DynamicLoaderDarwinKernel::GetShortPluginName()
819 {
820     return GetPluginNameStatic();
821 }
822 
823 uint32_t
824 DynamicLoaderDarwinKernel::GetPluginVersion()
825 {
826     return 1;
827 }
828 
829