1*d4bfbc9aSGreg Clayton //===-- DynamicLoaderMacOSXKernel.cpp -----------------------------*- C++ -*-===//
2*d4bfbc9aSGreg Clayton //
3*d4bfbc9aSGreg Clayton //                     The LLVM Compiler Infrastructure
4*d4bfbc9aSGreg Clayton //
5*d4bfbc9aSGreg Clayton // This file is distributed under the University of Illinois Open Source
6*d4bfbc9aSGreg Clayton // License. See LICENSE.TXT for details.
7*d4bfbc9aSGreg Clayton //
8*d4bfbc9aSGreg Clayton //===----------------------------------------------------------------------===//
9*d4bfbc9aSGreg Clayton 
10*d4bfbc9aSGreg Clayton #include "lldb/Breakpoint/StoppointCallbackContext.h"
11*d4bfbc9aSGreg Clayton #include "lldb/Core/DataBuffer.h"
12*d4bfbc9aSGreg Clayton #include "lldb/Core/DataBufferHeap.h"
13*d4bfbc9aSGreg Clayton #include "lldb/Core/Debugger.h"
14*d4bfbc9aSGreg Clayton #include "lldb/Core/Log.h"
15*d4bfbc9aSGreg Clayton #include "lldb/Core/Module.h"
16*d4bfbc9aSGreg Clayton #include "lldb/Core/PluginManager.h"
17*d4bfbc9aSGreg Clayton #include "lldb/Core/State.h"
18*d4bfbc9aSGreg Clayton #include "lldb/Symbol/ObjectFile.h"
19*d4bfbc9aSGreg Clayton #include "lldb/Target/ObjCLanguageRuntime.h"
20*d4bfbc9aSGreg Clayton #include "lldb/Target/RegisterContext.h"
21*d4bfbc9aSGreg Clayton #include "lldb/Target/Target.h"
22*d4bfbc9aSGreg Clayton #include "lldb/Target/Thread.h"
23*d4bfbc9aSGreg Clayton #include "lldb/Target/ThreadPlanRunToAddress.h"
24*d4bfbc9aSGreg Clayton #include "lldb/Target/StackFrame.h"
25*d4bfbc9aSGreg Clayton 
26*d4bfbc9aSGreg Clayton #include "DynamicLoaderMacOSXKernel.h"
27*d4bfbc9aSGreg Clayton 
28*d4bfbc9aSGreg Clayton //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
29*d4bfbc9aSGreg Clayton #ifdef ENABLE_DEBUG_PRINTF
30*d4bfbc9aSGreg Clayton #include <stdio.h>
31*d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
32*d4bfbc9aSGreg Clayton #else
33*d4bfbc9aSGreg Clayton #define DEBUG_PRINTF(fmt, ...)
34*d4bfbc9aSGreg Clayton #endif
35*d4bfbc9aSGreg Clayton 
36*d4bfbc9aSGreg Clayton using namespace lldb;
37*d4bfbc9aSGreg Clayton using namespace lldb_private;
38*d4bfbc9aSGreg Clayton 
39*d4bfbc9aSGreg Clayton /// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
40*d4bfbc9aSGreg Clayton /// I am putting it here so I can invoke it in the Trampoline code here, but
41*d4bfbc9aSGreg Clayton /// it should be moved to the ObjC Runtime support when it is set up.
42*d4bfbc9aSGreg Clayton 
43*d4bfbc9aSGreg Clayton 
44*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
45*d4bfbc9aSGreg Clayton // Create an instance of this class. This function is filled into
46*d4bfbc9aSGreg Clayton // the plugin info class that gets handed out by the plugin factory and
47*d4bfbc9aSGreg Clayton // allows the lldb to instantiate an instance of this class.
48*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
49*d4bfbc9aSGreg Clayton DynamicLoader *
50*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::CreateInstance (Process* process, bool force)
51*d4bfbc9aSGreg Clayton {
52*d4bfbc9aSGreg Clayton     bool create = force;
53*d4bfbc9aSGreg Clayton     if (!create)
54*d4bfbc9aSGreg Clayton     {
55*d4bfbc9aSGreg Clayton         Module* exe_module = process->GetTarget().GetExecutableModulePointer();
56*d4bfbc9aSGreg Clayton         if (exe_module)
57*d4bfbc9aSGreg Clayton         {
58*d4bfbc9aSGreg Clayton             ObjectFile *object_file = exe_module->GetObjectFile();
59*d4bfbc9aSGreg Clayton             if (object_file)
60*d4bfbc9aSGreg Clayton             {
61*d4bfbc9aSGreg Clayton                 SectionList *section_list = object_file->GetSectionList();
62*d4bfbc9aSGreg Clayton                 if (section_list)
63*d4bfbc9aSGreg Clayton                 {
64*d4bfbc9aSGreg Clayton                     static ConstString g_kld_section_name ("__KLD");
65*d4bfbc9aSGreg Clayton                     if (section_list->FindSectionByName (g_kld_section_name))
66*d4bfbc9aSGreg Clayton                     {
67*d4bfbc9aSGreg Clayton                         create = true;
68*d4bfbc9aSGreg Clayton                     }
69*d4bfbc9aSGreg Clayton                 }
70*d4bfbc9aSGreg Clayton             }
71*d4bfbc9aSGreg Clayton         }
72*d4bfbc9aSGreg Clayton 
73*d4bfbc9aSGreg Clayton         if (create)
74*d4bfbc9aSGreg Clayton         {
75*d4bfbc9aSGreg Clayton             const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
76*d4bfbc9aSGreg Clayton             create = triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple;
77*d4bfbc9aSGreg Clayton         }
78*d4bfbc9aSGreg Clayton     }
79*d4bfbc9aSGreg Clayton 
80*d4bfbc9aSGreg Clayton     if (create)
81*d4bfbc9aSGreg Clayton         return new DynamicLoaderMacOSXKernel (process);
82*d4bfbc9aSGreg Clayton     return NULL;
83*d4bfbc9aSGreg Clayton }
84*d4bfbc9aSGreg Clayton 
85*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
86*d4bfbc9aSGreg Clayton // Constructor
87*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
88*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::DynamicLoaderMacOSXKernel (Process* process) :
89*d4bfbc9aSGreg Clayton     DynamicLoader(process),
90*d4bfbc9aSGreg Clayton     m_kernel(),
91*d4bfbc9aSGreg Clayton     m_kext_summary_header_ptr_addr (),
92*d4bfbc9aSGreg Clayton     m_kext_summary_header_addr (),
93*d4bfbc9aSGreg Clayton     m_kext_summary_header (),
94*d4bfbc9aSGreg Clayton     m_break_id (LLDB_INVALID_BREAK_ID),
95*d4bfbc9aSGreg Clayton     m_kext_summaries(),
96*d4bfbc9aSGreg Clayton     m_mutex(Mutex::eMutexTypeRecursive)
97*d4bfbc9aSGreg Clayton {
98*d4bfbc9aSGreg Clayton }
99*d4bfbc9aSGreg Clayton 
100*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
101*d4bfbc9aSGreg Clayton // Destructor
102*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
103*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::~DynamicLoaderMacOSXKernel()
104*d4bfbc9aSGreg Clayton {
105*d4bfbc9aSGreg Clayton     Clear(true);
106*d4bfbc9aSGreg Clayton }
107*d4bfbc9aSGreg Clayton 
108*d4bfbc9aSGreg Clayton void
109*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UpdateIfNeeded()
110*d4bfbc9aSGreg Clayton {
111*d4bfbc9aSGreg Clayton     LoadKernelModuleIfNeeded();
112*d4bfbc9aSGreg Clayton     SetNotificationBreakpointIfNeeded ();
113*d4bfbc9aSGreg Clayton }
114*d4bfbc9aSGreg Clayton //------------------------------------------------------------------
115*d4bfbc9aSGreg Clayton /// Called after attaching a process.
116*d4bfbc9aSGreg Clayton ///
117*d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after
118*d4bfbc9aSGreg Clayton /// attaching to a process.
119*d4bfbc9aSGreg Clayton //------------------------------------------------------------------
120*d4bfbc9aSGreg Clayton void
121*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::DidAttach ()
122*d4bfbc9aSGreg Clayton {
123*d4bfbc9aSGreg Clayton     PrivateInitialize(m_process);
124*d4bfbc9aSGreg Clayton     UpdateIfNeeded();
125*d4bfbc9aSGreg Clayton }
126*d4bfbc9aSGreg Clayton 
127*d4bfbc9aSGreg Clayton //------------------------------------------------------------------
128*d4bfbc9aSGreg Clayton /// Called after attaching a process.
129*d4bfbc9aSGreg Clayton ///
130*d4bfbc9aSGreg Clayton /// Allow DynamicLoader plug-ins to execute some code after
131*d4bfbc9aSGreg Clayton /// attaching to a process.
132*d4bfbc9aSGreg Clayton //------------------------------------------------------------------
133*d4bfbc9aSGreg Clayton void
134*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::DidLaunch ()
135*d4bfbc9aSGreg Clayton {
136*d4bfbc9aSGreg Clayton     PrivateInitialize(m_process);
137*d4bfbc9aSGreg Clayton     UpdateIfNeeded();
138*d4bfbc9aSGreg Clayton }
139*d4bfbc9aSGreg Clayton 
140*d4bfbc9aSGreg Clayton 
141*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
142*d4bfbc9aSGreg Clayton // Clear out the state of this class.
143*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
144*d4bfbc9aSGreg Clayton void
145*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Clear (bool clear_process)
146*d4bfbc9aSGreg Clayton {
147*d4bfbc9aSGreg Clayton     Mutex::Locker locker(m_mutex);
148*d4bfbc9aSGreg Clayton 
149*d4bfbc9aSGreg Clayton     if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
150*d4bfbc9aSGreg Clayton         m_process->ClearBreakpointSiteByID(m_break_id);
151*d4bfbc9aSGreg Clayton 
152*d4bfbc9aSGreg Clayton     if (clear_process)
153*d4bfbc9aSGreg Clayton         m_process = NULL;
154*d4bfbc9aSGreg Clayton     m_kernel.Clear(false);
155*d4bfbc9aSGreg Clayton     m_kext_summary_header_ptr_addr.Clear();
156*d4bfbc9aSGreg Clayton     m_kext_summary_header_addr.Clear();
157*d4bfbc9aSGreg Clayton     m_kext_summaries.clear();
158*d4bfbc9aSGreg Clayton     m_break_id = LLDB_INVALID_BREAK_ID;
159*d4bfbc9aSGreg Clayton }
160*d4bfbc9aSGreg Clayton 
161*d4bfbc9aSGreg Clayton 
162*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
163*d4bfbc9aSGreg Clayton // Load the kernel module and initialize the "m_kernel" member. Return
164*d4bfbc9aSGreg Clayton // true _only_ if the kernel is loaded the first time through (subsequent
165*d4bfbc9aSGreg Clayton // calls to this function should return false after the kernel has been
166*d4bfbc9aSGreg Clayton // already loaded).
167*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
168*d4bfbc9aSGreg Clayton void
169*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::LoadKernelModuleIfNeeded()
170*d4bfbc9aSGreg Clayton {
171*d4bfbc9aSGreg Clayton     if (!m_kext_summary_header_ptr_addr.IsValid())
172*d4bfbc9aSGreg Clayton     {
173*d4bfbc9aSGreg Clayton         m_kernel.Clear(false);
174*d4bfbc9aSGreg Clayton         m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
175*d4bfbc9aSGreg Clayton         if (m_kernel.module_sp)
176*d4bfbc9aSGreg Clayton         {
177*d4bfbc9aSGreg Clayton             static ConstString mach_header_name ("_mh_execute_header");
178*d4bfbc9aSGreg Clayton             static ConstString kext_summary_symbol ("gLoadedKextSummaries");
179*d4bfbc9aSGreg Clayton             const Symbol *symbol = NULL;
180*d4bfbc9aSGreg Clayton             symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
181*d4bfbc9aSGreg Clayton             if (symbol)
182*d4bfbc9aSGreg Clayton                 m_kext_summary_header_ptr_addr = symbol->GetValue();
183*d4bfbc9aSGreg Clayton 
184*d4bfbc9aSGreg Clayton             symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (mach_header_name, eSymbolTypeAbsolute);
185*d4bfbc9aSGreg Clayton             if (symbol)
186*d4bfbc9aSGreg Clayton             {
187*d4bfbc9aSGreg Clayton                 // The "_mh_execute_header" symbol is absolute and not a section based
188*d4bfbc9aSGreg Clayton                 // symbol that will have a valid address, so we need to resolve it...
189*d4bfbc9aSGreg Clayton                 m_process->GetTarget().GetImages().ResolveFileAddress (symbol->GetValue().GetFileAddress(), m_kernel.so_address);
190*d4bfbc9aSGreg Clayton                 DataExtractor data; // Load command data
191*d4bfbc9aSGreg Clayton                 if (ReadMachHeader (m_kernel, &data))
192*d4bfbc9aSGreg Clayton                 {
193*d4bfbc9aSGreg Clayton                     if (m_kernel.header.filetype == llvm::MachO::HeaderFileTypeExecutable)
194*d4bfbc9aSGreg Clayton                     {
195*d4bfbc9aSGreg Clayton                         if (ParseLoadCommands (data, m_kernel))
196*d4bfbc9aSGreg Clayton                             UpdateImageLoadAddress (m_kernel);
197*d4bfbc9aSGreg Clayton 
198*d4bfbc9aSGreg Clayton                         // Update all image infos
199*d4bfbc9aSGreg Clayton                         ReadAllKextSummaries ();
200*d4bfbc9aSGreg Clayton                     }
201*d4bfbc9aSGreg Clayton                 }
202*d4bfbc9aSGreg Clayton                 else
203*d4bfbc9aSGreg Clayton                 {
204*d4bfbc9aSGreg Clayton                     m_kernel.Clear(false);
205*d4bfbc9aSGreg Clayton                 }
206*d4bfbc9aSGreg Clayton             }
207*d4bfbc9aSGreg Clayton         }
208*d4bfbc9aSGreg Clayton     }
209*d4bfbc9aSGreg Clayton }
210*d4bfbc9aSGreg Clayton 
211*d4bfbc9aSGreg Clayton bool
212*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::FindTargetModule (OSKextLoadedKextSummary &image_info, bool can_create, bool *did_create_ptr)
213*d4bfbc9aSGreg Clayton {
214*d4bfbc9aSGreg Clayton     if (did_create_ptr)
215*d4bfbc9aSGreg Clayton         *did_create_ptr = false;
216*d4bfbc9aSGreg Clayton 
217*d4bfbc9aSGreg Clayton     const bool image_info_uuid_is_valid = image_info.uuid.IsValid();
218*d4bfbc9aSGreg Clayton 
219*d4bfbc9aSGreg Clayton     if (image_info.module_sp)
220*d4bfbc9aSGreg Clayton     {
221*d4bfbc9aSGreg Clayton         if (image_info_uuid_is_valid)
222*d4bfbc9aSGreg Clayton         {
223*d4bfbc9aSGreg Clayton             if (image_info.module_sp->GetUUID() == image_info.uuid)
224*d4bfbc9aSGreg Clayton                 return true;
225*d4bfbc9aSGreg Clayton             else
226*d4bfbc9aSGreg Clayton                 image_info.module_sp.reset();
227*d4bfbc9aSGreg Clayton         }
228*d4bfbc9aSGreg Clayton         else
229*d4bfbc9aSGreg Clayton             return true;
230*d4bfbc9aSGreg Clayton     }
231*d4bfbc9aSGreg Clayton 
232*d4bfbc9aSGreg Clayton     ModuleList &target_images = m_process->GetTarget().GetImages();
233*d4bfbc9aSGreg Clayton     if (image_info_uuid_is_valid)
234*d4bfbc9aSGreg Clayton         image_info.module_sp = target_images.FindModule(image_info.uuid);
235*d4bfbc9aSGreg Clayton 
236*d4bfbc9aSGreg Clayton     if (image_info.module_sp)
237*d4bfbc9aSGreg Clayton         return true;
238*d4bfbc9aSGreg Clayton 
239*d4bfbc9aSGreg Clayton     ArchSpec arch (image_info.GetArchitecture ());
240*d4bfbc9aSGreg Clayton     if (can_create)
241*d4bfbc9aSGreg Clayton     {
242*d4bfbc9aSGreg Clayton         if (image_info_uuid_is_valid)
243*d4bfbc9aSGreg Clayton         {
244*d4bfbc9aSGreg Clayton             image_info.module_sp = m_process->GetTarget().GetSharedModule (FileSpec(),
245*d4bfbc9aSGreg Clayton                                                                            arch,
246*d4bfbc9aSGreg Clayton                                                                            &image_info.uuid);
247*d4bfbc9aSGreg Clayton             if (did_create_ptr)
248*d4bfbc9aSGreg Clayton                 *did_create_ptr = image_info.module_sp;
249*d4bfbc9aSGreg Clayton         }
250*d4bfbc9aSGreg Clayton     }
251*d4bfbc9aSGreg Clayton     return image_info.module_sp;
252*d4bfbc9aSGreg Clayton }
253*d4bfbc9aSGreg Clayton 
254*d4bfbc9aSGreg Clayton bool
255*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UpdateCommPageLoadAddress(Module *module)
256*d4bfbc9aSGreg Clayton {
257*d4bfbc9aSGreg Clayton     bool changed = false;
258*d4bfbc9aSGreg Clayton     if (module)
259*d4bfbc9aSGreg Clayton     {
260*d4bfbc9aSGreg Clayton         ObjectFile *image_object_file = module->GetObjectFile();
261*d4bfbc9aSGreg Clayton         if (image_object_file)
262*d4bfbc9aSGreg Clayton         {
263*d4bfbc9aSGreg Clayton             SectionList *section_list = image_object_file->GetSectionList ();
264*d4bfbc9aSGreg Clayton             if (section_list)
265*d4bfbc9aSGreg Clayton             {
266*d4bfbc9aSGreg Clayton                 uint32_t num_sections = section_list->GetSize();
267*d4bfbc9aSGreg Clayton                 for (uint32_t i=0; i<num_sections; ++i)
268*d4bfbc9aSGreg Clayton                 {
269*d4bfbc9aSGreg Clayton                     Section* section = section_list->GetSectionAtIndex (i).get();
270*d4bfbc9aSGreg Clayton                     if (section)
271*d4bfbc9aSGreg Clayton                     {
272*d4bfbc9aSGreg Clayton                         const addr_t new_section_load_addr = section->GetFileAddress ();
273*d4bfbc9aSGreg Clayton                         const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
274*d4bfbc9aSGreg Clayton                         if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
275*d4bfbc9aSGreg Clayton                             old_section_load_addr != new_section_load_addr)
276*d4bfbc9aSGreg Clayton                         {
277*d4bfbc9aSGreg Clayton                             if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
278*d4bfbc9aSGreg Clayton                                 changed = true;
279*d4bfbc9aSGreg Clayton                         }
280*d4bfbc9aSGreg Clayton                     }
281*d4bfbc9aSGreg Clayton                 }
282*d4bfbc9aSGreg Clayton             }
283*d4bfbc9aSGreg Clayton         }
284*d4bfbc9aSGreg Clayton     }
285*d4bfbc9aSGreg Clayton     return changed;
286*d4bfbc9aSGreg Clayton }
287*d4bfbc9aSGreg Clayton 
288*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
289*d4bfbc9aSGreg Clayton // Update the load addresses for all segments in MODULE using the
290*d4bfbc9aSGreg Clayton // updated INFO that is passed in.
291*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
292*d4bfbc9aSGreg Clayton bool
293*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UpdateImageLoadAddress (OSKextLoadedKextSummary& info)
294*d4bfbc9aSGreg Clayton {
295*d4bfbc9aSGreg Clayton     Module *module = info.module_sp.get();
296*d4bfbc9aSGreg Clayton     bool changed = false;
297*d4bfbc9aSGreg Clayton     if (module)
298*d4bfbc9aSGreg Clayton     {
299*d4bfbc9aSGreg Clayton         ObjectFile *image_object_file = module->GetObjectFile();
300*d4bfbc9aSGreg Clayton         if (image_object_file)
301*d4bfbc9aSGreg Clayton         {
302*d4bfbc9aSGreg Clayton             SectionList *section_list = image_object_file->GetSectionList ();
303*d4bfbc9aSGreg Clayton             if (section_list)
304*d4bfbc9aSGreg Clayton             {
305*d4bfbc9aSGreg Clayton                 // We now know the slide amount, so go through all sections
306*d4bfbc9aSGreg Clayton                 // and update the load addresses with the correct values.
307*d4bfbc9aSGreg Clayton                 uint32_t num_segments = info.segments.size();
308*d4bfbc9aSGreg Clayton                 for (uint32_t i=0; i<num_segments; ++i)
309*d4bfbc9aSGreg Clayton                 {
310*d4bfbc9aSGreg Clayton                     const addr_t new_section_load_addr = info.segments[i].vmaddr;
311*d4bfbc9aSGreg Clayton                     if (section_list->FindSectionByName(info.segments[i].name))
312*d4bfbc9aSGreg Clayton                     {
313*d4bfbc9aSGreg Clayton                         SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
314*d4bfbc9aSGreg Clayton                         if (section_sp)
315*d4bfbc9aSGreg Clayton                         {
316*d4bfbc9aSGreg Clayton                             const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
317*d4bfbc9aSGreg Clayton                             if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
318*d4bfbc9aSGreg Clayton                                 old_section_load_addr != new_section_load_addr)
319*d4bfbc9aSGreg Clayton                             {
320*d4bfbc9aSGreg Clayton                                 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
321*d4bfbc9aSGreg Clayton                                     changed = true;
322*d4bfbc9aSGreg Clayton                             }
323*d4bfbc9aSGreg Clayton                         }
324*d4bfbc9aSGreg Clayton                         else
325*d4bfbc9aSGreg Clayton                         {
326*d4bfbc9aSGreg Clayton                             fprintf (stderr,
327*d4bfbc9aSGreg Clayton                                      "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
328*d4bfbc9aSGreg Clayton                                      info.segments[i].name.AsCString("<invalid>"),
329*d4bfbc9aSGreg Clayton                                      (uint64_t)new_section_load_addr,
330*d4bfbc9aSGreg Clayton                                      image_object_file->GetFileSpec().GetDirectory().AsCString(),
331*d4bfbc9aSGreg Clayton                                      image_object_file->GetFileSpec().GetFilename().AsCString());
332*d4bfbc9aSGreg Clayton                         }
333*d4bfbc9aSGreg Clayton                     }
334*d4bfbc9aSGreg Clayton                     else
335*d4bfbc9aSGreg Clayton                     {
336*d4bfbc9aSGreg Clayton                         // The segment name is empty which means this is a .o file.
337*d4bfbc9aSGreg Clayton                         // Object files in LLDB end up getting reorganized so that
338*d4bfbc9aSGreg Clayton                         // the segment name that is in the section is promoted into
339*d4bfbc9aSGreg Clayton                         // an actual segment, so we just need to go through all sections
340*d4bfbc9aSGreg Clayton                         // and slide them by a single amount.
341*d4bfbc9aSGreg Clayton 
342*d4bfbc9aSGreg Clayton                         uint32_t num_sections = section_list->GetSize();
343*d4bfbc9aSGreg Clayton                         for (uint32_t i=0; i<num_sections; ++i)
344*d4bfbc9aSGreg Clayton                         {
345*d4bfbc9aSGreg Clayton                             Section* section = section_list->GetSectionAtIndex (i).get();
346*d4bfbc9aSGreg Clayton                             if (section)
347*d4bfbc9aSGreg Clayton                             {
348*d4bfbc9aSGreg Clayton                                 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + new_section_load_addr))
349*d4bfbc9aSGreg Clayton                                     changed = true;
350*d4bfbc9aSGreg Clayton                             }
351*d4bfbc9aSGreg Clayton                         }
352*d4bfbc9aSGreg Clayton                     }
353*d4bfbc9aSGreg Clayton                 }
354*d4bfbc9aSGreg Clayton             }
355*d4bfbc9aSGreg Clayton         }
356*d4bfbc9aSGreg Clayton     }
357*d4bfbc9aSGreg Clayton     return changed;
358*d4bfbc9aSGreg Clayton }
359*d4bfbc9aSGreg Clayton 
360*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
361*d4bfbc9aSGreg Clayton // Update the load addresses for all segments in MODULE using the
362*d4bfbc9aSGreg Clayton // updated INFO that is passed in.
363*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
364*d4bfbc9aSGreg Clayton bool
365*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::UnloadImageLoadAddress (OSKextLoadedKextSummary& info)
366*d4bfbc9aSGreg Clayton {
367*d4bfbc9aSGreg Clayton     Module *module = info.module_sp.get();
368*d4bfbc9aSGreg Clayton     bool changed = false;
369*d4bfbc9aSGreg Clayton     if (module)
370*d4bfbc9aSGreg Clayton     {
371*d4bfbc9aSGreg Clayton         ObjectFile *image_object_file = module->GetObjectFile();
372*d4bfbc9aSGreg Clayton         if (image_object_file)
373*d4bfbc9aSGreg Clayton         {
374*d4bfbc9aSGreg Clayton             SectionList *section_list = image_object_file->GetSectionList ();
375*d4bfbc9aSGreg Clayton             if (section_list)
376*d4bfbc9aSGreg Clayton             {
377*d4bfbc9aSGreg Clayton                 uint32_t num_segments = info.segments.size();
378*d4bfbc9aSGreg Clayton                 for (uint32_t i=0; i<num_segments; ++i)
379*d4bfbc9aSGreg Clayton                 {
380*d4bfbc9aSGreg Clayton                     SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
381*d4bfbc9aSGreg Clayton                     if (section_sp)
382*d4bfbc9aSGreg Clayton                     {
383*d4bfbc9aSGreg Clayton                         const addr_t old_section_load_addr = info.segments[i].vmaddr;
384*d4bfbc9aSGreg Clayton                         if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
385*d4bfbc9aSGreg Clayton                             changed = true;
386*d4bfbc9aSGreg Clayton                     }
387*d4bfbc9aSGreg Clayton                     else
388*d4bfbc9aSGreg Clayton                     {
389*d4bfbc9aSGreg Clayton                         fprintf (stderr,
390*d4bfbc9aSGreg Clayton                                  "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n",
391*d4bfbc9aSGreg Clayton                                  info.segments[i].name.AsCString("<invalid>"),
392*d4bfbc9aSGreg Clayton                                  image_object_file->GetFileSpec().GetDirectory().AsCString(),
393*d4bfbc9aSGreg Clayton                                  image_object_file->GetFileSpec().GetFilename().AsCString());
394*d4bfbc9aSGreg Clayton                     }
395*d4bfbc9aSGreg Clayton                 }
396*d4bfbc9aSGreg Clayton             }
397*d4bfbc9aSGreg Clayton         }
398*d4bfbc9aSGreg Clayton     }
399*d4bfbc9aSGreg Clayton     return changed;
400*d4bfbc9aSGreg Clayton }
401*d4bfbc9aSGreg Clayton 
402*d4bfbc9aSGreg Clayton 
403*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
404*d4bfbc9aSGreg Clayton // Static callback function that gets called when our DYLD notification
405*d4bfbc9aSGreg Clayton // breakpoint gets hit. We update all of our image infos and then
406*d4bfbc9aSGreg Clayton // let our super class DynamicLoader class decide if we should stop
407*d4bfbc9aSGreg Clayton // or not (based on global preference).
408*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
409*d4bfbc9aSGreg Clayton bool
410*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::BreakpointHitCallback (void *baton,
411*d4bfbc9aSGreg Clayton                                                   StoppointCallbackContext *context,
412*d4bfbc9aSGreg Clayton                                                   user_id_t break_id,
413*d4bfbc9aSGreg Clayton                                                   user_id_t break_loc_id)
414*d4bfbc9aSGreg Clayton {
415*d4bfbc9aSGreg Clayton     return static_cast<DynamicLoaderMacOSXKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
416*d4bfbc9aSGreg Clayton }
417*d4bfbc9aSGreg Clayton 
418*d4bfbc9aSGreg Clayton bool
419*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::BreakpointHit (StoppointCallbackContext *context,
420*d4bfbc9aSGreg Clayton                                           user_id_t break_id,
421*d4bfbc9aSGreg Clayton                                           user_id_t break_loc_id)
422*d4bfbc9aSGreg Clayton {
423*d4bfbc9aSGreg Clayton     LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
424*d4bfbc9aSGreg Clayton     if (log)
425*d4bfbc9aSGreg Clayton         log->Printf ("DynamicLoaderMacOSXKernel::BreakpointHit (...)\n");
426*d4bfbc9aSGreg Clayton 
427*d4bfbc9aSGreg Clayton     ReadAllKextSummaries ();
428*d4bfbc9aSGreg Clayton 
429*d4bfbc9aSGreg Clayton     if (log)
430*d4bfbc9aSGreg Clayton         PutToLog(log.get());
431*d4bfbc9aSGreg Clayton 
432*d4bfbc9aSGreg Clayton     return GetStopWhenImagesChange();
433*d4bfbc9aSGreg Clayton }
434*d4bfbc9aSGreg Clayton 
435*d4bfbc9aSGreg Clayton 
436*d4bfbc9aSGreg Clayton bool
437*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadKextSummaryHeader ()
438*d4bfbc9aSGreg Clayton {
439*d4bfbc9aSGreg Clayton     Mutex::Locker locker(m_mutex);
440*d4bfbc9aSGreg Clayton 
441*d4bfbc9aSGreg Clayton     // the all image infos is already valid for this process stop ID
442*d4bfbc9aSGreg Clayton 
443*d4bfbc9aSGreg Clayton     m_kext_summaries.clear();
444*d4bfbc9aSGreg Clayton     if (m_kext_summary_header_ptr_addr.IsValid())
445*d4bfbc9aSGreg Clayton     {
446*d4bfbc9aSGreg Clayton         const uint32_t addr_size = m_kernel.GetAddressByteSize ();
447*d4bfbc9aSGreg Clayton         const ByteOrder byte_order = m_kernel.GetByteOrder();
448*d4bfbc9aSGreg Clayton         Error error;
449*d4bfbc9aSGreg Clayton         // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
450*d4bfbc9aSGreg Clayton         // which is currenty 4 uint32_t and a pointer.
451*d4bfbc9aSGreg Clayton         uint8_t buf[24];
452*d4bfbc9aSGreg Clayton         DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
453*d4bfbc9aSGreg Clayton         const size_t count = 4 * sizeof(uint32_t) + addr_size;
454*d4bfbc9aSGreg Clayton         const bool prefer_file_cache = false;
455*d4bfbc9aSGreg Clayton         if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
456*d4bfbc9aSGreg Clayton                                                           prefer_file_cache,
457*d4bfbc9aSGreg Clayton                                                           error,
458*d4bfbc9aSGreg Clayton                                                           m_kext_summary_header_addr))
459*d4bfbc9aSGreg Clayton         {
460*d4bfbc9aSGreg Clayton             // We got a valid address for our kext summary header and make sure it isn't NULL
461*d4bfbc9aSGreg Clayton             if (m_kext_summary_header_addr.IsValid() &&
462*d4bfbc9aSGreg Clayton                 m_kext_summary_header_addr.GetFileAddress() != 0)
463*d4bfbc9aSGreg Clayton             {
464*d4bfbc9aSGreg Clayton                 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
465*d4bfbc9aSGreg Clayton                 if (bytes_read == count)
466*d4bfbc9aSGreg Clayton                 {
467*d4bfbc9aSGreg Clayton                     uint32_t offset = 0;
468*d4bfbc9aSGreg Clayton                     m_kext_summary_header.version = data.GetU32(&offset);
469*d4bfbc9aSGreg Clayton                     if (m_kext_summary_header.version >= 2)
470*d4bfbc9aSGreg Clayton                     {
471*d4bfbc9aSGreg Clayton                         m_kext_summary_header.entry_size = data.GetU32(&offset);
472*d4bfbc9aSGreg Clayton                     }
473*d4bfbc9aSGreg Clayton                     else
474*d4bfbc9aSGreg Clayton                     {
475*d4bfbc9aSGreg Clayton                         // Versions less than 2 didn't have an entry size, it was hard coded
476*d4bfbc9aSGreg Clayton                         m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
477*d4bfbc9aSGreg Clayton                     }
478*d4bfbc9aSGreg Clayton                     m_kext_summary_header.entry_count = data.GetU32(&offset);
479*d4bfbc9aSGreg Clayton                     return true;
480*d4bfbc9aSGreg Clayton                 }
481*d4bfbc9aSGreg Clayton             }
482*d4bfbc9aSGreg Clayton         }
483*d4bfbc9aSGreg Clayton     }
484*d4bfbc9aSGreg Clayton     m_kext_summary_header_addr.Clear();
485*d4bfbc9aSGreg Clayton     return false;
486*d4bfbc9aSGreg Clayton }
487*d4bfbc9aSGreg Clayton 
488*d4bfbc9aSGreg Clayton 
489*d4bfbc9aSGreg Clayton bool
490*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ParseKextSummaries (const Address &kext_summary_addr,
491*d4bfbc9aSGreg Clayton                                                uint32_t count)
492*d4bfbc9aSGreg Clayton {
493*d4bfbc9aSGreg Clayton     OSKextLoadedKextSummary::collection kext_summaries;
494*d4bfbc9aSGreg Clayton     LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
495*d4bfbc9aSGreg Clayton     if (log)
496*d4bfbc9aSGreg Clayton         log->Printf ("Adding %d modules.\n");
497*d4bfbc9aSGreg Clayton 
498*d4bfbc9aSGreg Clayton     Mutex::Locker locker(m_mutex);
499*d4bfbc9aSGreg Clayton 
500*d4bfbc9aSGreg Clayton     if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
501*d4bfbc9aSGreg Clayton         return false;
502*d4bfbc9aSGreg Clayton 
503*d4bfbc9aSGreg Clayton     Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
504*d4bfbc9aSGreg Clayton     for (uint32_t i = 0; i < count; i++)
505*d4bfbc9aSGreg Clayton     {
506*d4bfbc9aSGreg Clayton         if (s)
507*d4bfbc9aSGreg Clayton         {
508*d4bfbc9aSGreg Clayton             const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes();
509*d4bfbc9aSGreg Clayton             if (u)
510*d4bfbc9aSGreg Clayton             {
511*d4bfbc9aSGreg Clayton                 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\"...\n",
512*d4bfbc9aSGreg Clayton                           u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
513*d4bfbc9aSGreg Clayton                           u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
514*d4bfbc9aSGreg Clayton                           kext_summaries[i].address, kext_summaries[i].name);
515*d4bfbc9aSGreg Clayton             }
516*d4bfbc9aSGreg Clayton             else
517*d4bfbc9aSGreg Clayton             {
518*d4bfbc9aSGreg Clayton                 s->Printf("0x%16.16llx \"%s\"...\n", kext_summaries[i].address, kext_summaries[i].name);
519*d4bfbc9aSGreg Clayton             }
520*d4bfbc9aSGreg Clayton         }
521*d4bfbc9aSGreg Clayton 
522*d4bfbc9aSGreg Clayton         DataExtractor data; // Load command data
523*d4bfbc9aSGreg Clayton         if (ReadMachHeader (kext_summaries[i], &data))
524*d4bfbc9aSGreg Clayton         {
525*d4bfbc9aSGreg Clayton             ParseLoadCommands (data, kext_summaries[i]);
526*d4bfbc9aSGreg Clayton         }
527*d4bfbc9aSGreg Clayton 
528*d4bfbc9aSGreg Clayton         if (s)
529*d4bfbc9aSGreg Clayton         {
530*d4bfbc9aSGreg Clayton             if (kext_summaries[i].module_sp)
531*d4bfbc9aSGreg Clayton                 s->Printf("  found kext: %s/%s\n",
532*d4bfbc9aSGreg Clayton                           kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(),
533*d4bfbc9aSGreg Clayton                           kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
534*d4bfbc9aSGreg Clayton         }
535*d4bfbc9aSGreg Clayton 
536*d4bfbc9aSGreg Clayton         if (log)
537*d4bfbc9aSGreg Clayton             kext_summaries[i].PutToLog (log.get());
538*d4bfbc9aSGreg Clayton     }
539*d4bfbc9aSGreg Clayton     bool return_value = AddModulesUsingImageInfos (kext_summaries);
540*d4bfbc9aSGreg Clayton     return return_value;
541*d4bfbc9aSGreg Clayton }
542*d4bfbc9aSGreg Clayton 
543*d4bfbc9aSGreg Clayton // Adds the modules in image_infos to m_kext_summaries.
544*d4bfbc9aSGreg Clayton // NB don't call this passing in m_kext_summaries.
545*d4bfbc9aSGreg Clayton 
546*d4bfbc9aSGreg Clayton bool
547*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
548*d4bfbc9aSGreg Clayton {
549*d4bfbc9aSGreg Clayton     // Now add these images to the main list.
550*d4bfbc9aSGreg Clayton     ModuleList loaded_module_list;
551*d4bfbc9aSGreg Clayton 
552*d4bfbc9aSGreg Clayton     for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
553*d4bfbc9aSGreg Clayton     {
554*d4bfbc9aSGreg Clayton         m_kext_summaries.push_back(image_infos[idx]);
555*d4bfbc9aSGreg Clayton 
556*d4bfbc9aSGreg Clayton         if (FindTargetModule (image_infos[idx], true, NULL))
557*d4bfbc9aSGreg Clayton         {
558*d4bfbc9aSGreg Clayton             // UpdateImageLoadAddress will return true if any segments
559*d4bfbc9aSGreg Clayton             // change load address. We need to check this so we don't
560*d4bfbc9aSGreg Clayton             // mention that all loaded shared libraries are newly loaded
561*d4bfbc9aSGreg Clayton             // each time we hit out dyld breakpoint since dyld will list all
562*d4bfbc9aSGreg Clayton             // shared libraries each time.
563*d4bfbc9aSGreg Clayton             if (UpdateImageLoadAddress (image_infos[idx]))
564*d4bfbc9aSGreg Clayton             {
565*d4bfbc9aSGreg Clayton                 loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
566*d4bfbc9aSGreg Clayton             }
567*d4bfbc9aSGreg Clayton         }
568*d4bfbc9aSGreg Clayton     }
569*d4bfbc9aSGreg Clayton 
570*d4bfbc9aSGreg Clayton     if (loaded_module_list.GetSize() > 0)
571*d4bfbc9aSGreg Clayton     {
572*d4bfbc9aSGreg Clayton         // FIXME: This should really be in the Runtime handlers class, which should get
573*d4bfbc9aSGreg Clayton         // called by the target's ModulesDidLoad, but we're doing it all locally for now
574*d4bfbc9aSGreg Clayton         // to save time.
575*d4bfbc9aSGreg Clayton         // Also, I'm assuming there can be only one libobjc dylib loaded...
576*d4bfbc9aSGreg Clayton 
577*d4bfbc9aSGreg Clayton         ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
578*d4bfbc9aSGreg Clayton         if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
579*d4bfbc9aSGreg Clayton         {
580*d4bfbc9aSGreg Clayton             size_t num_modules = loaded_module_list.GetSize();
581*d4bfbc9aSGreg Clayton             for (int i = 0; i < num_modules; i++)
582*d4bfbc9aSGreg Clayton             {
583*d4bfbc9aSGreg Clayton                 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
584*d4bfbc9aSGreg Clayton                 {
585*d4bfbc9aSGreg Clayton                     objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
586*d4bfbc9aSGreg Clayton                     break;
587*d4bfbc9aSGreg Clayton                 }
588*d4bfbc9aSGreg Clayton             }
589*d4bfbc9aSGreg Clayton         }
590*d4bfbc9aSGreg Clayton //        if (log)
591*d4bfbc9aSGreg Clayton //            loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXKernel::ModulesDidLoad");
592*d4bfbc9aSGreg Clayton         m_process->GetTarget().ModulesDidLoad (loaded_module_list);
593*d4bfbc9aSGreg Clayton     }
594*d4bfbc9aSGreg Clayton     return true;
595*d4bfbc9aSGreg Clayton }
596*d4bfbc9aSGreg Clayton 
597*d4bfbc9aSGreg Clayton 
598*d4bfbc9aSGreg Clayton uint32_t
599*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadKextSummaries (const Address &kext_summary_addr,
600*d4bfbc9aSGreg Clayton                                               uint32_t image_infos_count,
601*d4bfbc9aSGreg Clayton                                               OSKextLoadedKextSummary::collection &image_infos)
602*d4bfbc9aSGreg Clayton {
603*d4bfbc9aSGreg Clayton     const ByteOrder endian = m_kernel.GetByteOrder();
604*d4bfbc9aSGreg Clayton     const uint32_t addr_size = m_kernel.GetAddressByteSize();
605*d4bfbc9aSGreg Clayton 
606*d4bfbc9aSGreg Clayton     image_infos.resize(image_infos_count);
607*d4bfbc9aSGreg Clayton     const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
608*d4bfbc9aSGreg Clayton     DataBufferHeap data(count, 0);
609*d4bfbc9aSGreg Clayton     Error error;
610*d4bfbc9aSGreg Clayton 
611*d4bfbc9aSGreg Clayton     Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
612*d4bfbc9aSGreg Clayton 
613*d4bfbc9aSGreg Clayton     if (s)
614*d4bfbc9aSGreg Clayton         s->Printf ("Reading %u kext summaries...\n", image_infos_count);
615*d4bfbc9aSGreg Clayton     const bool prefer_file_cache = false;
616*d4bfbc9aSGreg Clayton     const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
617*d4bfbc9aSGreg Clayton                                                                  prefer_file_cache,
618*d4bfbc9aSGreg Clayton                                                                  data.GetBytes(),
619*d4bfbc9aSGreg Clayton                                                                  data.GetByteSize(),
620*d4bfbc9aSGreg Clayton                                                                  error);
621*d4bfbc9aSGreg Clayton     if (bytes_read == count)
622*d4bfbc9aSGreg Clayton     {
623*d4bfbc9aSGreg Clayton 
624*d4bfbc9aSGreg Clayton         DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
625*d4bfbc9aSGreg Clayton         uint32_t i=0;
626*d4bfbc9aSGreg Clayton         for (uint32_t kext_summary_offset = 0;
627*d4bfbc9aSGreg Clayton              i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
628*d4bfbc9aSGreg Clayton              ++i, kext_summary_offset += m_kext_summary_header.entry_size)
629*d4bfbc9aSGreg Clayton         {
630*d4bfbc9aSGreg Clayton             uint32_t offset = kext_summary_offset;
631*d4bfbc9aSGreg Clayton             const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
632*d4bfbc9aSGreg Clayton             if (name_data == NULL)
633*d4bfbc9aSGreg Clayton                 break;
634*d4bfbc9aSGreg Clayton             memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
635*d4bfbc9aSGreg Clayton             image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
636*d4bfbc9aSGreg Clayton             image_infos[i].address          = extractor.GetU64(&offset);
637*d4bfbc9aSGreg Clayton             if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
638*d4bfbc9aSGreg Clayton                 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
639*d4bfbc9aSGreg Clayton             image_infos[i].size             = extractor.GetU64(&offset);
640*d4bfbc9aSGreg Clayton             image_infos[i].version          = extractor.GetU64(&offset);
641*d4bfbc9aSGreg Clayton             image_infos[i].load_tag         = extractor.GetU32(&offset);
642*d4bfbc9aSGreg Clayton             image_infos[i].flags            = extractor.GetU32(&offset);
643*d4bfbc9aSGreg Clayton             if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
644*d4bfbc9aSGreg Clayton             {
645*d4bfbc9aSGreg Clayton                 image_infos[i].reference_list = extractor.GetU64(&offset);
646*d4bfbc9aSGreg Clayton             }
647*d4bfbc9aSGreg Clayton             else
648*d4bfbc9aSGreg Clayton             {
649*d4bfbc9aSGreg Clayton                 image_infos[i].reference_list = 0;
650*d4bfbc9aSGreg Clayton             }
651*d4bfbc9aSGreg Clayton         }
652*d4bfbc9aSGreg Clayton         if (i < image_infos.size())
653*d4bfbc9aSGreg Clayton             image_infos.resize(i);
654*d4bfbc9aSGreg Clayton     }
655*d4bfbc9aSGreg Clayton     else
656*d4bfbc9aSGreg Clayton     {
657*d4bfbc9aSGreg Clayton         image_infos.clear();
658*d4bfbc9aSGreg Clayton     }
659*d4bfbc9aSGreg Clayton     return image_infos.size();
660*d4bfbc9aSGreg Clayton }
661*d4bfbc9aSGreg Clayton 
662*d4bfbc9aSGreg Clayton bool
663*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadAllKextSummaries ()
664*d4bfbc9aSGreg Clayton {
665*d4bfbc9aSGreg Clayton     LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
666*d4bfbc9aSGreg Clayton 
667*d4bfbc9aSGreg Clayton     Mutex::Locker locker(m_mutex);
668*d4bfbc9aSGreg Clayton 
669*d4bfbc9aSGreg Clayton     if (ReadKextSummaryHeader ())
670*d4bfbc9aSGreg Clayton     {
671*d4bfbc9aSGreg Clayton         if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
672*d4bfbc9aSGreg Clayton         {
673*d4bfbc9aSGreg Clayton             Address summary_addr (m_kext_summary_header_addr);
674*d4bfbc9aSGreg Clayton             summary_addr.Slide(m_kext_summary_header.GetSize());
675*d4bfbc9aSGreg Clayton             if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
676*d4bfbc9aSGreg Clayton             {
677*d4bfbc9aSGreg Clayton                 m_kext_summaries.clear();
678*d4bfbc9aSGreg Clayton             }
679*d4bfbc9aSGreg Clayton             return true;
680*d4bfbc9aSGreg Clayton         }
681*d4bfbc9aSGreg Clayton     }
682*d4bfbc9aSGreg Clayton     return false;
683*d4bfbc9aSGreg Clayton }
684*d4bfbc9aSGreg Clayton 
685*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
686*d4bfbc9aSGreg Clayton // Read a mach_header at ADDR into HEADER, and also fill in the load
687*d4bfbc9aSGreg Clayton // command data into LOAD_COMMAND_DATA if it is non-NULL.
688*d4bfbc9aSGreg Clayton //
689*d4bfbc9aSGreg Clayton // Returns true if we succeed, false if we fail for any reason.
690*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
691*d4bfbc9aSGreg Clayton bool
692*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ReadMachHeader (OSKextLoadedKextSummary& kext_summary, DataExtractor *load_command_data)
693*d4bfbc9aSGreg Clayton {
694*d4bfbc9aSGreg Clayton     DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
695*d4bfbc9aSGreg Clayton     Error error;
696*d4bfbc9aSGreg Clayton     const bool prefer_file_cache = false;
697*d4bfbc9aSGreg Clayton     size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary.so_address,
698*d4bfbc9aSGreg Clayton                                                            prefer_file_cache,
699*d4bfbc9aSGreg Clayton                                                            header_bytes.GetBytes(),
700*d4bfbc9aSGreg Clayton                                                            header_bytes.GetByteSize(),
701*d4bfbc9aSGreg Clayton                                                            error);
702*d4bfbc9aSGreg Clayton     if (bytes_read == sizeof(llvm::MachO::mach_header))
703*d4bfbc9aSGreg Clayton     {
704*d4bfbc9aSGreg Clayton         uint32_t offset = 0;
705*d4bfbc9aSGreg Clayton         ::memset (&kext_summary.header, 0, sizeof(kext_summary.header));
706*d4bfbc9aSGreg Clayton 
707*d4bfbc9aSGreg Clayton         // Get the magic byte unswapped so we can figure out what we are dealing with
708*d4bfbc9aSGreg Clayton         DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4);
709*d4bfbc9aSGreg Clayton         kext_summary.header.magic = data.GetU32(&offset);
710*d4bfbc9aSGreg Clayton         Address load_cmd_addr = kext_summary.so_address;
711*d4bfbc9aSGreg Clayton         data.SetByteOrder(DynamicLoaderMacOSXKernel::GetByteOrderFromMagic(kext_summary.header.magic));
712*d4bfbc9aSGreg Clayton         switch (kext_summary.header.magic)
713*d4bfbc9aSGreg Clayton         {
714*d4bfbc9aSGreg Clayton         case llvm::MachO::HeaderMagic32:
715*d4bfbc9aSGreg Clayton         case llvm::MachO::HeaderMagic32Swapped:
716*d4bfbc9aSGreg Clayton             data.SetAddressByteSize(4);
717*d4bfbc9aSGreg Clayton             load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header));
718*d4bfbc9aSGreg Clayton             break;
719*d4bfbc9aSGreg Clayton 
720*d4bfbc9aSGreg Clayton         case llvm::MachO::HeaderMagic64:
721*d4bfbc9aSGreg Clayton         case llvm::MachO::HeaderMagic64Swapped:
722*d4bfbc9aSGreg Clayton             data.SetAddressByteSize(8);
723*d4bfbc9aSGreg Clayton             load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header_64));
724*d4bfbc9aSGreg Clayton             break;
725*d4bfbc9aSGreg Clayton 
726*d4bfbc9aSGreg Clayton         default:
727*d4bfbc9aSGreg Clayton             return false;
728*d4bfbc9aSGreg Clayton         }
729*d4bfbc9aSGreg Clayton 
730*d4bfbc9aSGreg Clayton         // Read the rest of dyld's mach header
731*d4bfbc9aSGreg Clayton         if (data.GetU32(&offset, &kext_summary.header.cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
732*d4bfbc9aSGreg Clayton         {
733*d4bfbc9aSGreg Clayton             if (load_command_data == NULL)
734*d4bfbc9aSGreg Clayton                 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
735*d4bfbc9aSGreg Clayton 
736*d4bfbc9aSGreg Clayton             DataBufferSP load_cmd_data_sp(new DataBufferHeap(kext_summary.header.sizeofcmds, 0));
737*d4bfbc9aSGreg Clayton 
738*d4bfbc9aSGreg Clayton             size_t load_cmd_bytes_read = m_process->GetTarget().ReadMemory (load_cmd_addr,
739*d4bfbc9aSGreg Clayton                                                                             prefer_file_cache,
740*d4bfbc9aSGreg Clayton                                                                             load_cmd_data_sp->GetBytes(),
741*d4bfbc9aSGreg Clayton                                                                             load_cmd_data_sp->GetByteSize(),
742*d4bfbc9aSGreg Clayton                                                                             error);
743*d4bfbc9aSGreg Clayton 
744*d4bfbc9aSGreg Clayton             if (load_cmd_bytes_read == kext_summary.header.sizeofcmds)
745*d4bfbc9aSGreg Clayton             {
746*d4bfbc9aSGreg Clayton                 // Set the load command data and also set the correct endian
747*d4bfbc9aSGreg Clayton                 // swap settings and the correct address size
748*d4bfbc9aSGreg Clayton                 load_command_data->SetData(load_cmd_data_sp, 0, kext_summary.header.sizeofcmds);
749*d4bfbc9aSGreg Clayton                 load_command_data->SetByteOrder(data.GetByteOrder());
750*d4bfbc9aSGreg Clayton                 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
751*d4bfbc9aSGreg Clayton                 return true; // We successfully read the mach_header and the load command data
752*d4bfbc9aSGreg Clayton             }
753*d4bfbc9aSGreg Clayton 
754*d4bfbc9aSGreg Clayton             return false; // We weren't able to read the load command data
755*d4bfbc9aSGreg Clayton         }
756*d4bfbc9aSGreg Clayton     }
757*d4bfbc9aSGreg Clayton     return false; // We failed the read the mach_header
758*d4bfbc9aSGreg Clayton }
759*d4bfbc9aSGreg Clayton 
760*d4bfbc9aSGreg Clayton 
761*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
762*d4bfbc9aSGreg Clayton // Parse the load commands for an image
763*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
764*d4bfbc9aSGreg Clayton uint32_t
765*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::ParseLoadCommands (const DataExtractor& data, OSKextLoadedKextSummary& image_info)
766*d4bfbc9aSGreg Clayton {
767*d4bfbc9aSGreg Clayton     uint32_t offset = 0;
768*d4bfbc9aSGreg Clayton     uint32_t cmd_idx;
769*d4bfbc9aSGreg Clayton     Segment segment;
770*d4bfbc9aSGreg Clayton     image_info.Clear (true);
771*d4bfbc9aSGreg Clayton 
772*d4bfbc9aSGreg Clayton     for (cmd_idx = 0; cmd_idx < image_info.header.ncmds; cmd_idx++)
773*d4bfbc9aSGreg Clayton     {
774*d4bfbc9aSGreg Clayton         // Clear out any load command specific data from image_info since
775*d4bfbc9aSGreg Clayton         // we are about to read it.
776*d4bfbc9aSGreg Clayton 
777*d4bfbc9aSGreg Clayton         if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
778*d4bfbc9aSGreg Clayton         {
779*d4bfbc9aSGreg Clayton             llvm::MachO::load_command load_cmd;
780*d4bfbc9aSGreg Clayton             uint32_t load_cmd_offset = offset;
781*d4bfbc9aSGreg Clayton             load_cmd.cmd = data.GetU32 (&offset);
782*d4bfbc9aSGreg Clayton             load_cmd.cmdsize = data.GetU32 (&offset);
783*d4bfbc9aSGreg Clayton             switch (load_cmd.cmd)
784*d4bfbc9aSGreg Clayton             {
785*d4bfbc9aSGreg Clayton             case llvm::MachO::LoadCommandSegment32:
786*d4bfbc9aSGreg Clayton                 {
787*d4bfbc9aSGreg Clayton                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
788*d4bfbc9aSGreg Clayton                     // We are putting 4 uint32_t values 4 uint64_t values so
789*d4bfbc9aSGreg Clayton                     // we have to use multiple 32 bit gets below.
790*d4bfbc9aSGreg Clayton                     segment.vmaddr = data.GetU32 (&offset);
791*d4bfbc9aSGreg Clayton                     segment.vmsize = data.GetU32 (&offset);
792*d4bfbc9aSGreg Clayton                     segment.fileoff = data.GetU32 (&offset);
793*d4bfbc9aSGreg Clayton                     segment.filesize = data.GetU32 (&offset);
794*d4bfbc9aSGreg Clayton                     // Extract maxprot, initprot, nsects and flags all at once
795*d4bfbc9aSGreg Clayton                     data.GetU32(&offset, &segment.maxprot, 4);
796*d4bfbc9aSGreg Clayton                     image_info.segments.push_back (segment);
797*d4bfbc9aSGreg Clayton                 }
798*d4bfbc9aSGreg Clayton                 break;
799*d4bfbc9aSGreg Clayton 
800*d4bfbc9aSGreg Clayton             case llvm::MachO::LoadCommandSegment64:
801*d4bfbc9aSGreg Clayton                 {
802*d4bfbc9aSGreg Clayton                     segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
803*d4bfbc9aSGreg Clayton                     // Extract vmaddr, vmsize, fileoff, and filesize all at once
804*d4bfbc9aSGreg Clayton                     data.GetU64(&offset, &segment.vmaddr, 4);
805*d4bfbc9aSGreg Clayton                     // Extract maxprot, initprot, nsects and flags all at once
806*d4bfbc9aSGreg Clayton                     data.GetU32(&offset, &segment.maxprot, 4);
807*d4bfbc9aSGreg Clayton                     image_info.segments.push_back (segment);
808*d4bfbc9aSGreg Clayton                 }
809*d4bfbc9aSGreg Clayton                 break;
810*d4bfbc9aSGreg Clayton 
811*d4bfbc9aSGreg Clayton             case llvm::MachO::LoadCommandUUID:
812*d4bfbc9aSGreg Clayton                 image_info.uuid.SetBytes(data.GetData (&offset, 16));
813*d4bfbc9aSGreg Clayton                 break;
814*d4bfbc9aSGreg Clayton 
815*d4bfbc9aSGreg Clayton             default:
816*d4bfbc9aSGreg Clayton                 break;
817*d4bfbc9aSGreg Clayton             }
818*d4bfbc9aSGreg Clayton             // Set offset to be the beginning of the next load command.
819*d4bfbc9aSGreg Clayton             offset = load_cmd_offset + load_cmd.cmdsize;
820*d4bfbc9aSGreg Clayton         }
821*d4bfbc9aSGreg Clayton     }
822*d4bfbc9aSGreg Clayton #if 0
823*d4bfbc9aSGreg Clayton     // No slide in the kernel...
824*d4bfbc9aSGreg Clayton 
825*d4bfbc9aSGreg Clayton     // All sections listed in the dyld image info structure will all
826*d4bfbc9aSGreg Clayton     // either be fixed up already, or they will all be off by a single
827*d4bfbc9aSGreg Clayton     // slide amount that is determined by finding the first segment
828*d4bfbc9aSGreg Clayton     // that is at file offset zero which also has bytes (a file size
829*d4bfbc9aSGreg Clayton     // that is greater than zero) in the object file.
830*d4bfbc9aSGreg Clayton 
831*d4bfbc9aSGreg Clayton     // Determine the slide amount (if any)
832*d4bfbc9aSGreg Clayton     const size_t num_sections = image_info.segments.size();
833*d4bfbc9aSGreg Clayton     for (size_t i = 0; i < num_sections; ++i)
834*d4bfbc9aSGreg Clayton     {
835*d4bfbc9aSGreg Clayton         // Iterate through the object file sections to find the
836*d4bfbc9aSGreg Clayton         // first section that starts of file offset zero and that
837*d4bfbc9aSGreg Clayton         // has bytes in the file...
838*d4bfbc9aSGreg Clayton         if (image_info.segments[i].fileoff == 0 && image_info.segments[i].filesize > 0)
839*d4bfbc9aSGreg Clayton         {
840*d4bfbc9aSGreg Clayton             image_info.slide = image_info.address - image_info.segments[i].vmaddr;
841*d4bfbc9aSGreg Clayton             // We have found the slide amount, so we can exit
842*d4bfbc9aSGreg Clayton             // this for loop.
843*d4bfbc9aSGreg Clayton             break;
844*d4bfbc9aSGreg Clayton         }
845*d4bfbc9aSGreg Clayton     }
846*d4bfbc9aSGreg Clayton #endif
847*d4bfbc9aSGreg Clayton     if (image_info.uuid.IsValid())
848*d4bfbc9aSGreg Clayton     {
849*d4bfbc9aSGreg Clayton         bool did_create = false;
850*d4bfbc9aSGreg Clayton         if (FindTargetModule(image_info, true, &did_create))
851*d4bfbc9aSGreg Clayton         {
852*d4bfbc9aSGreg Clayton             if (did_create)
853*d4bfbc9aSGreg Clayton                 image_info.module_create_stop_id = m_process->GetStopID();
854*d4bfbc9aSGreg Clayton         }
855*d4bfbc9aSGreg Clayton     }
856*d4bfbc9aSGreg Clayton     return cmd_idx;
857*d4bfbc9aSGreg Clayton }
858*d4bfbc9aSGreg Clayton 
859*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
860*d4bfbc9aSGreg Clayton // Dump a Segment to the file handle provided.
861*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
862*d4bfbc9aSGreg Clayton void
863*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Segment::PutToLog (Log *log, addr_t slide) const
864*d4bfbc9aSGreg Clayton {
865*d4bfbc9aSGreg Clayton     if (log)
866*d4bfbc9aSGreg Clayton     {
867*d4bfbc9aSGreg Clayton         if (slide == 0)
868*d4bfbc9aSGreg Clayton             log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)",
869*d4bfbc9aSGreg Clayton                          name.AsCString(""),
870*d4bfbc9aSGreg Clayton                          vmaddr + slide,
871*d4bfbc9aSGreg Clayton                          vmaddr + slide + vmsize);
872*d4bfbc9aSGreg Clayton         else
873*d4bfbc9aSGreg Clayton             log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx",
874*d4bfbc9aSGreg Clayton                          name.AsCString(""),
875*d4bfbc9aSGreg Clayton                          vmaddr + slide,
876*d4bfbc9aSGreg Clayton                          vmaddr + slide + vmsize,
877*d4bfbc9aSGreg Clayton                          slide);
878*d4bfbc9aSGreg Clayton     }
879*d4bfbc9aSGreg Clayton }
880*d4bfbc9aSGreg Clayton 
881*d4bfbc9aSGreg Clayton const DynamicLoaderMacOSXKernel::Segment *
882*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::FindSegment (const ConstString &name) const
883*d4bfbc9aSGreg Clayton {
884*d4bfbc9aSGreg Clayton     const size_t num_segments = segments.size();
885*d4bfbc9aSGreg Clayton     for (size_t i=0; i<num_segments; ++i)
886*d4bfbc9aSGreg Clayton     {
887*d4bfbc9aSGreg Clayton         if (segments[i].name == name)
888*d4bfbc9aSGreg Clayton             return &segments[i];
889*d4bfbc9aSGreg Clayton     }
890*d4bfbc9aSGreg Clayton     return NULL;
891*d4bfbc9aSGreg Clayton }
892*d4bfbc9aSGreg Clayton 
893*d4bfbc9aSGreg Clayton 
894*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
895*d4bfbc9aSGreg Clayton // Dump an image info structure to the file handle provided.
896*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
897*d4bfbc9aSGreg Clayton void
898*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
899*d4bfbc9aSGreg Clayton {
900*d4bfbc9aSGreg Clayton     if (log == NULL)
901*d4bfbc9aSGreg Clayton         return;
902*d4bfbc9aSGreg Clayton     const uint8_t *u = (uint8_t *)uuid.GetBytes();
903*d4bfbc9aSGreg Clayton 
904*d4bfbc9aSGreg Clayton     if (address == LLDB_INVALID_ADDRESS)
905*d4bfbc9aSGreg Clayton     {
906*d4bfbc9aSGreg Clayton         if (u)
907*d4bfbc9aSGreg Clayton         {
908*d4bfbc9aSGreg Clayton             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)",
909*d4bfbc9aSGreg Clayton                         u[ 0], u[ 1], u[ 2], u[ 3],
910*d4bfbc9aSGreg Clayton                         u[ 4], u[ 5], u[ 6], u[ 7],
911*d4bfbc9aSGreg Clayton                         u[ 8], u[ 9], u[10], u[11],
912*d4bfbc9aSGreg Clayton                         u[12], u[13], u[14], u[15],
913*d4bfbc9aSGreg Clayton                         name);
914*d4bfbc9aSGreg Clayton         }
915*d4bfbc9aSGreg Clayton         else
916*d4bfbc9aSGreg Clayton             log->Printf("\tname=\"%s\" (UNLOADED)", name);
917*d4bfbc9aSGreg Clayton     }
918*d4bfbc9aSGreg Clayton     else
919*d4bfbc9aSGreg Clayton     {
920*d4bfbc9aSGreg Clayton         if (u)
921*d4bfbc9aSGreg Clayton         {
922*d4bfbc9aSGreg Clayton             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\"",
923*d4bfbc9aSGreg Clayton                         address, size, version, load_tag, flags, reference_list,
924*d4bfbc9aSGreg Clayton                         u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
925*d4bfbc9aSGreg Clayton                         u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
926*d4bfbc9aSGreg Clayton                         name);
927*d4bfbc9aSGreg Clayton         }
928*d4bfbc9aSGreg Clayton         else
929*d4bfbc9aSGreg Clayton         {
930*d4bfbc9aSGreg Clayton             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\"",
931*d4bfbc9aSGreg Clayton                         address, address+size, version, load_tag, flags, reference_list,
932*d4bfbc9aSGreg Clayton                         name);
933*d4bfbc9aSGreg Clayton         }
934*d4bfbc9aSGreg Clayton         for (uint32_t i=0; i<segments.size(); ++i)
935*d4bfbc9aSGreg Clayton             segments[i].PutToLog(log, 0);
936*d4bfbc9aSGreg Clayton     }
937*d4bfbc9aSGreg Clayton }
938*d4bfbc9aSGreg Clayton 
939*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
940*d4bfbc9aSGreg Clayton // Dump the _dyld_all_image_infos members and all current image infos
941*d4bfbc9aSGreg Clayton // that we have parsed to the file handle provided.
942*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
943*d4bfbc9aSGreg Clayton void
944*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::PutToLog(Log *log) const
945*d4bfbc9aSGreg Clayton {
946*d4bfbc9aSGreg Clayton     if (log == NULL)
947*d4bfbc9aSGreg Clayton         return;
948*d4bfbc9aSGreg Clayton 
949*d4bfbc9aSGreg Clayton     Mutex::Locker locker(m_mutex);
950*d4bfbc9aSGreg Clayton     log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
951*d4bfbc9aSGreg Clayton                 m_kext_summary_header_addr.GetFileAddress(),
952*d4bfbc9aSGreg Clayton                 m_kext_summary_header.version,
953*d4bfbc9aSGreg Clayton                 m_kext_summary_header.entry_size,
954*d4bfbc9aSGreg Clayton                 m_kext_summary_header.entry_count);
955*d4bfbc9aSGreg Clayton 
956*d4bfbc9aSGreg Clayton     size_t i;
957*d4bfbc9aSGreg Clayton     const size_t count = m_kext_summaries.size();
958*d4bfbc9aSGreg Clayton     if (count > 0)
959*d4bfbc9aSGreg Clayton     {
960*d4bfbc9aSGreg Clayton         log->PutCString("Loaded:");
961*d4bfbc9aSGreg Clayton         for (i = 0; i<count; i++)
962*d4bfbc9aSGreg Clayton             m_kext_summaries[i].PutToLog(log);
963*d4bfbc9aSGreg Clayton     }
964*d4bfbc9aSGreg Clayton }
965*d4bfbc9aSGreg Clayton 
966*d4bfbc9aSGreg Clayton void
967*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::PrivateInitialize(Process *process)
968*d4bfbc9aSGreg Clayton {
969*d4bfbc9aSGreg Clayton     DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
970*d4bfbc9aSGreg Clayton     Clear(true);
971*d4bfbc9aSGreg Clayton     m_process = process;
972*d4bfbc9aSGreg Clayton     m_process->GetTarget().GetSectionLoadList().Clear();
973*d4bfbc9aSGreg Clayton }
974*d4bfbc9aSGreg Clayton 
975*d4bfbc9aSGreg Clayton void
976*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::SetNotificationBreakpointIfNeeded ()
977*d4bfbc9aSGreg Clayton {
978*d4bfbc9aSGreg Clayton     if (m_break_id == LLDB_INVALID_BREAK_ID)
979*d4bfbc9aSGreg Clayton     {
980*d4bfbc9aSGreg Clayton         DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
981*d4bfbc9aSGreg Clayton 
982*d4bfbc9aSGreg Clayton 
983*d4bfbc9aSGreg Clayton         const bool internal_bp = false;
984*d4bfbc9aSGreg Clayton         const LazyBool skip_prologue = eLazyBoolNo;
985*d4bfbc9aSGreg Clayton         Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&m_kernel.module_sp->GetFileSpec(),
986*d4bfbc9aSGreg Clayton                                                                   "OSKextLoadedKextSummariesUpdated",
987*d4bfbc9aSGreg Clayton                                                                   eFunctionNameTypeFull,
988*d4bfbc9aSGreg Clayton                                                                   internal_bp,
989*d4bfbc9aSGreg Clayton                                                                   skip_prologue).get();
990*d4bfbc9aSGreg Clayton 
991*d4bfbc9aSGreg Clayton         bp->SetCallback (DynamicLoaderMacOSXKernel::BreakpointHitCallback, this, true);
992*d4bfbc9aSGreg Clayton         m_break_id = bp->GetID();
993*d4bfbc9aSGreg Clayton     }
994*d4bfbc9aSGreg Clayton }
995*d4bfbc9aSGreg Clayton 
996*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
997*d4bfbc9aSGreg Clayton // Member function that gets called when the process state changes.
998*d4bfbc9aSGreg Clayton //----------------------------------------------------------------------
999*d4bfbc9aSGreg Clayton void
1000*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::PrivateProcessStateChanged (Process *process, StateType state)
1001*d4bfbc9aSGreg Clayton {
1002*d4bfbc9aSGreg Clayton     DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1003*d4bfbc9aSGreg Clayton     switch (state)
1004*d4bfbc9aSGreg Clayton     {
1005*d4bfbc9aSGreg Clayton     case eStateConnected:
1006*d4bfbc9aSGreg Clayton     case eStateAttaching:
1007*d4bfbc9aSGreg Clayton     case eStateLaunching:
1008*d4bfbc9aSGreg Clayton     case eStateInvalid:
1009*d4bfbc9aSGreg Clayton     case eStateUnloaded:
1010*d4bfbc9aSGreg Clayton     case eStateExited:
1011*d4bfbc9aSGreg Clayton     case eStateDetached:
1012*d4bfbc9aSGreg Clayton         Clear(false);
1013*d4bfbc9aSGreg Clayton         break;
1014*d4bfbc9aSGreg Clayton 
1015*d4bfbc9aSGreg Clayton     case eStateStopped:
1016*d4bfbc9aSGreg Clayton         UpdateIfNeeded();
1017*d4bfbc9aSGreg Clayton         break;
1018*d4bfbc9aSGreg Clayton 
1019*d4bfbc9aSGreg Clayton     case eStateRunning:
1020*d4bfbc9aSGreg Clayton     case eStateStepping:
1021*d4bfbc9aSGreg Clayton     case eStateCrashed:
1022*d4bfbc9aSGreg Clayton     case eStateSuspended:
1023*d4bfbc9aSGreg Clayton         break;
1024*d4bfbc9aSGreg Clayton 
1025*d4bfbc9aSGreg Clayton     default:
1026*d4bfbc9aSGreg Clayton         break;
1027*d4bfbc9aSGreg Clayton     }
1028*d4bfbc9aSGreg Clayton }
1029*d4bfbc9aSGreg Clayton 
1030*d4bfbc9aSGreg Clayton ThreadPlanSP
1031*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1032*d4bfbc9aSGreg Clayton {
1033*d4bfbc9aSGreg Clayton     ThreadPlanSP thread_plan_sp;
1034*d4bfbc9aSGreg Clayton     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1035*d4bfbc9aSGreg Clayton     if (log)
1036*d4bfbc9aSGreg Clayton         log->Printf ("Could not find symbol for step through.");
1037*d4bfbc9aSGreg Clayton     return thread_plan_sp;
1038*d4bfbc9aSGreg Clayton }
1039*d4bfbc9aSGreg Clayton 
1040*d4bfbc9aSGreg Clayton Error
1041*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::CanLoadImage ()
1042*d4bfbc9aSGreg Clayton {
1043*d4bfbc9aSGreg Clayton     Error error;
1044*d4bfbc9aSGreg Clayton     error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
1045*d4bfbc9aSGreg Clayton     return error;
1046*d4bfbc9aSGreg Clayton }
1047*d4bfbc9aSGreg Clayton 
1048*d4bfbc9aSGreg Clayton void
1049*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Initialize()
1050*d4bfbc9aSGreg Clayton {
1051*d4bfbc9aSGreg Clayton     PluginManager::RegisterPlugin (GetPluginNameStatic(),
1052*d4bfbc9aSGreg Clayton                                    GetPluginDescriptionStatic(),
1053*d4bfbc9aSGreg Clayton                                    CreateInstance);
1054*d4bfbc9aSGreg Clayton }
1055*d4bfbc9aSGreg Clayton 
1056*d4bfbc9aSGreg Clayton void
1057*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::Terminate()
1058*d4bfbc9aSGreg Clayton {
1059*d4bfbc9aSGreg Clayton     PluginManager::UnregisterPlugin (CreateInstance);
1060*d4bfbc9aSGreg Clayton }
1061*d4bfbc9aSGreg Clayton 
1062*d4bfbc9aSGreg Clayton 
1063*d4bfbc9aSGreg Clayton const char *
1064*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginNameStatic()
1065*d4bfbc9aSGreg Clayton {
1066*d4bfbc9aSGreg Clayton     return "dynamic-loader.macosx-kernel";
1067*d4bfbc9aSGreg Clayton }
1068*d4bfbc9aSGreg Clayton 
1069*d4bfbc9aSGreg Clayton const char *
1070*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginDescriptionStatic()
1071*d4bfbc9aSGreg Clayton {
1072*d4bfbc9aSGreg Clayton     return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
1073*d4bfbc9aSGreg Clayton }
1074*d4bfbc9aSGreg Clayton 
1075*d4bfbc9aSGreg Clayton 
1076*d4bfbc9aSGreg Clayton //------------------------------------------------------------------
1077*d4bfbc9aSGreg Clayton // PluginInterface protocol
1078*d4bfbc9aSGreg Clayton //------------------------------------------------------------------
1079*d4bfbc9aSGreg Clayton const char *
1080*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginName()
1081*d4bfbc9aSGreg Clayton {
1082*d4bfbc9aSGreg Clayton     return "DynamicLoaderMacOSXKernel";
1083*d4bfbc9aSGreg Clayton }
1084*d4bfbc9aSGreg Clayton 
1085*d4bfbc9aSGreg Clayton const char *
1086*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetShortPluginName()
1087*d4bfbc9aSGreg Clayton {
1088*d4bfbc9aSGreg Clayton     return GetPluginNameStatic();
1089*d4bfbc9aSGreg Clayton }
1090*d4bfbc9aSGreg Clayton 
1091*d4bfbc9aSGreg Clayton uint32_t
1092*d4bfbc9aSGreg Clayton DynamicLoaderMacOSXKernel::GetPluginVersion()
1093*d4bfbc9aSGreg Clayton {
1094*d4bfbc9aSGreg Clayton     return 1;
1095*d4bfbc9aSGreg Clayton }
1096*d4bfbc9aSGreg Clayton 
1097