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