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