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