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