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