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