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