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