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