blob: 194f21e0067e8c22be309e9ef38d7beb9d1bc79f [file] [log] [blame]
Greg Clayton944b8282011-08-22 22:30:57 +00001//===-- DynamicLoaderDarwinKernel.cpp -----------------------------*- C++ -*-===//
Greg Clayton7b242382011-07-08 00:48:09 +00002//
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"
Greg Clayton07e66e32011-07-20 03:41:06 +000013#include "lldb/Core/Debugger.h"
Greg Clayton7b242382011-07-08 00:48:09 +000014#include "lldb/Core/Log.h"
15#include "lldb/Core/Module.h"
Greg Clayton1f746072012-08-29 21:13:06 +000016#include "lldb/Core/ModuleSpec.h"
Greg Clayton7b242382011-07-08 00:48:09 +000017#include "lldb/Core/PluginManager.h"
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/Core/Section.h"
Greg Clayton7b242382011-07-08 00:48:09 +000019#include "lldb/Core/State.h"
Jason Molenda68b36072012-10-02 03:49:41 +000020#include "lldb/Host/Symbols.h"
Greg Clayton7b242382011-07-08 00:48:09 +000021#include "lldb/Symbol/ObjectFile.h"
Greg Clayton7b242382011-07-08 00:48:09 +000022#include "lldb/Target/RegisterContext.h"
Jason Molenda68b36072012-10-02 03:49:41 +000023#include "lldb/Target/StackFrame.h"
Greg Clayton7b242382011-07-08 00:48:09 +000024#include "lldb/Target/Target.h"
25#include "lldb/Target/Thread.h"
26#include "lldb/Target/ThreadPlanRunToAddress.h"
Jason Molenda68b36072012-10-02 03:49:41 +000027
Greg Clayton7b242382011-07-08 00:48:09 +000028
Greg Clayton944b8282011-08-22 22:30:57 +000029#include "DynamicLoaderDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000030
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
39using namespace lldb;
40using namespace lldb_private;
41
Greg Claytone8cd0c92012-10-19 18:02:49 +000042static PropertyDefinition
43g_properties[] =
44{
Greg Clayton66763ee2012-10-19 20:53:18 +000045 { "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 }
Greg Claytone8cd0c92012-10-19 18:02:49 +000047};
48
49enum {
Greg Clayton66763ee2012-10-19 20:53:18 +000050 ePropertyLoadKexts
Greg Claytone8cd0c92012-10-19 18:02:49 +000051};
52
53class DynamicLoaderDarwinKernelProperties : public Properties
54{
55public:
56
57 static ConstString &
58 GetSettingName ()
59 {
Greg Clayton468ea4e2012-10-19 18:14:47 +000060 static ConstString g_setting_name("darwin-kernel");
Greg Claytone8cd0c92012-10-19 18:02:49 +000061 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
Greg Clayton66763ee2012-10-19 20:53:18 +000077 GetLoadKexts() const
Greg Claytone8cd0c92012-10-19 18:02:49 +000078 {
Greg Clayton66763ee2012-10-19 20:53:18 +000079 const uint32_t idx = ePropertyLoadKexts;
Greg Claytone8cd0c92012-10-19 18:02:49 +000080 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
81 }
82
83};
84
85typedef STD_SHARED_PTR(DynamicLoaderDarwinKernelProperties) DynamicLoaderDarwinKernelPropertiesSP;
86
87static const DynamicLoaderDarwinKernelPropertiesSP &
88GetGlobalProperties()
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
Greg Clayton7b242382011-07-08 00:48:09 +000096//----------------------------------------------------------------------
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//----------------------------------------------------------------------
101DynamicLoader *
Greg Clayton944b8282011-08-22 22:30:57 +0000102DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
Greg Clayton7b242382011-07-08 00:48:09 +0000103{
104 bool create = force;
105 if (!create)
106 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000107 Module* exe_module = process->GetTarget().GetExecutableModulePointer();
Greg Claytondf0b7d52011-07-08 04:11:42 +0000108 if (exe_module)
109 {
110 ObjectFile *object_file = exe_module->GetObjectFile();
111 if (object_file)
112 {
Sean Callanan49bce8e2012-02-10 20:22:35 +0000113 create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
Greg Claytondf0b7d52011-07-08 04:11:42 +0000114 }
115 }
116
117 if (create)
118 {
119 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
Greg Clayton70512312012-05-08 01:45:38 +0000120 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 }
Greg Claytondf0b7d52011-07-08 04:11:42 +0000131 }
Greg Clayton7b242382011-07-08 00:48:09 +0000132 }
133
134 if (create)
Sean Callanan90539452011-09-20 23:01:51 +0000135 {
136 process->SetCanJIT(false);
Greg Clayton944b8282011-08-22 22:30:57 +0000137 return new DynamicLoaderDarwinKernel (process);
Sean Callanan90539452011-09-20 23:01:51 +0000138 }
Greg Clayton7b242382011-07-08 00:48:09 +0000139 return NULL;
140}
141
142//----------------------------------------------------------------------
143// Constructor
144//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +0000145DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
Greg Clayton7b242382011-07-08 00:48:09 +0000146 DynamicLoader(process),
147 m_kernel(),
Greg Claytond16e1e52011-07-12 17:06:17 +0000148 m_kext_summary_header_ptr_addr (),
Greg Clayton0d9fc762011-07-08 03:21:57 +0000149 m_kext_summary_header_addr (),
Greg Clayton7b242382011-07-08 00:48:09 +0000150 m_kext_summary_header (),
Greg Clayton7b242382011-07-08 00:48:09 +0000151 m_kext_summaries(),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000152 m_mutex(Mutex::eMutexTypeRecursive),
153 m_break_id (LLDB_INVALID_BREAK_ID)
Greg Clayton7b242382011-07-08 00:48:09 +0000154{
155}
156
157//----------------------------------------------------------------------
158// Destructor
159//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +0000160DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
Greg Clayton7b242382011-07-08 00:48:09 +0000161{
162 Clear(true);
163}
164
Greg Clayton374972e2011-07-09 17:15:55 +0000165void
Greg Clayton944b8282011-08-22 22:30:57 +0000166DynamicLoaderDarwinKernel::UpdateIfNeeded()
Greg Clayton374972e2011-07-09 17:15:55 +0000167{
168 LoadKernelModuleIfNeeded();
169 SetNotificationBreakpointIfNeeded ();
170}
Greg Clayton7b242382011-07-08 00:48:09 +0000171//------------------------------------------------------------------
172/// Called after attaching a process.
173///
174/// Allow DynamicLoader plug-ins to execute some code after
175/// attaching to a process.
176//------------------------------------------------------------------
177void
Greg Clayton944b8282011-08-22 22:30:57 +0000178DynamicLoaderDarwinKernel::DidAttach ()
Greg Clayton7b242382011-07-08 00:48:09 +0000179{
180 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000181 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000182}
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//------------------------------------------------------------------
190void
Greg Clayton944b8282011-08-22 22:30:57 +0000191DynamicLoaderDarwinKernel::DidLaunch ()
Greg Clayton7b242382011-07-08 00:48:09 +0000192{
193 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000194 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000195}
196
197
198//----------------------------------------------------------------------
199// Clear out the state of this class.
200//----------------------------------------------------------------------
201void
Greg Clayton944b8282011-08-22 22:30:57 +0000202DynamicLoaderDarwinKernel::Clear (bool clear_process)
Greg Clayton7b242382011-07-08 00:48:09 +0000203{
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);
Greg Claytond16e1e52011-07-12 17:06:17 +0000212 m_kext_summary_header_ptr_addr.Clear();
Greg Clayton0d9fc762011-07-08 03:21:57 +0000213 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000214 m_kext_summaries.clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000215 m_break_id = LLDB_INVALID_BREAK_ID;
216}
217
Greg Clayton7b242382011-07-08 00:48:09 +0000218
Greg Claytonc859e2d2012-02-13 23:10:39 +0000219bool
Greg Clayton2af282a2012-03-21 04:25:00 +0000220DynamicLoaderDarwinKernel::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
234bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000235DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
236{
237 if (IsLoaded())
238 return true;
239
240 bool uuid_is_valid = uuid.IsValid();
Jason Molenda68b36072012-10-02 03:49:41 +0000241 bool memory_module_is_kernel = false;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000242
243 Target &target = process->GetTarget();
244 ModuleSP memory_module_sp;
Jason Molenda87a04b22012-10-19 03:40:45 +0000245
246 // If this is a kext and the user asked us to ignore kexts, don't try to load it.
Greg Clayton66763ee2012-10-19 20:53:18 +0000247 if (kernel_image == false && GetGlobalProperties()->GetLoadKexts() == false)
Jason Molenda87a04b22012-10-19 03:40:45 +0000248 {
249 return false;
250 }
251
252 // Use the memory module as the module if we have one
Greg Claytonc859e2d2012-02-13 23:10:39 +0000253 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 }
Jason Molendac56bd082012-11-08 00:19:28 +0000267 if (memory_module_sp
268 && memory_module_sp->GetObjectFile()
Jason Molenda68b36072012-10-02 03:49:41 +0000269 && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
270 && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
271 {
272 memory_module_is_kernel = true;
Jason Molenda53667f52012-10-06 02:02:26 +0000273 if (memory_module_sp->GetArchitecture().IsValid())
274 {
275 target.SetArchitecture(memory_module_sp->GetArchitecture());
276 }
Jason Molenda68b36072012-10-02 03:49:41 +0000277 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000278 }
279
280 if (!module_sp)
281 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000282 if (uuid_is_valid)
283 {
Enrico Granata17598482012-11-08 02:22:02 +0000284 const ModuleList &target_images = target.GetImages();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000285 module_sp = target_images.FindModule(uuid);
Jason Molenda53667f52012-10-06 02:02:26 +0000286
Greg Claytonc859e2d2012-02-13 23:10:39 +0000287 if (!module_sp)
Greg Claytonb9a01b32012-02-26 05:51:37 +0000288 {
Greg Clayton2af282a2012-03-21 04:25:00 +0000289 ModuleSpec module_spec;
Greg Claytonb9a01b32012-02-26 05:51:37 +0000290 module_spec.GetUUID() = uuid;
Jason Molenda53667f52012-10-06 02:02:26 +0000291 module_spec.GetArchitecture() = target.GetArchitecture();
Jason Molendabb860bd2012-10-09 01:17:11 +0000292
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 }
Greg Claytonb9a01b32012-02-26 05:51:37 +0000324 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000325 }
326 }
327
328
Jason Molendabb860bd2012-10-09 01:17:11 +0000329 if (memory_module_sp && module_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000330 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000331 if (module_sp->GetUUID() == memory_module_sp->GetUUID())
Greg Claytonc859e2d2012-02-13 23:10:39 +0000332 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000333 target.GetImages().Append(module_sp);
334 if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get())
Greg Claytonc859e2d2012-02-13 23:10:39 +0000335 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000336 target.SetExecutableModule (module_sp, false);
337 }
Jason Molenda53667f52012-10-06 02:02:26 +0000338
Jason Molendabb860bd2012-10-09 01:17:11 +0000339 ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
340 ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
341 if (memory_object_file && ondisk_object_file)
342 {
343 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
344 SectionList *memory_section_list = memory_object_file->GetSectionList ();
345 if (memory_section_list && ondisk_section_list)
346 {
347 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
348 // There may be CTF sections in the memory image so we can't
349 // always just compare the number of sections (which are actually
350 // segments in mach-o parlance)
351 uint32_t sect_idx = 0;
352
353 // Use the memory_module's addresses for each section to set the
354 // file module's load address as appropriate. We don't want to use
355 // a single slide value for the entire kext - different segments may
356 // be slid different amounts by the kext loader.
357
358 uint32_t num_sections_loaded = 0;
359 for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
360 {
361 SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
362 if (ondisk_section_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000363 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000364 const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
365 if (memory_section)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000366 {
Jason Molendabb860bd2012-10-09 01:17:11 +0000367 target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
368 ++num_sections_loaded;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000369 }
370 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000371 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000372 if (num_sections_loaded > 0)
373 load_process_stop_id = process->GetStopID();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000374 else
Jason Molendabb860bd2012-10-09 01:17:11 +0000375 module_sp.reset(); // No sections were loaded
Greg Claytonc859e2d2012-02-13 23:10:39 +0000376 }
377 else
Jason Molendabb860bd2012-10-09 01:17:11 +0000378 module_sp.reset(); // One or both section lists
Greg Claytonc859e2d2012-02-13 23:10:39 +0000379 }
380 else
Jason Molendabb860bd2012-10-09 01:17:11 +0000381 module_sp.reset(); // One or both object files missing
Greg Claytonc859e2d2012-02-13 23:10:39 +0000382 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000383 else
384 module_sp.reset(); // UUID mismatch
Greg Claytonc859e2d2012-02-13 23:10:39 +0000385 }
Jason Molendabb860bd2012-10-09 01:17:11 +0000386
Greg Claytonc859e2d2012-02-13 23:10:39 +0000387 bool is_loaded = IsLoaded();
388
389 if (so_address.IsValid())
390 {
391 if (is_loaded)
392 so_address.SetLoadAddress (address, &target);
393 else
394 target.GetImages().ResolveFileAddress (address, so_address);
395
396 }
Jason Molenda68b36072012-10-02 03:49:41 +0000397
398 if (is_loaded && module_sp && memory_module_is_kernel)
399 {
400 Stream *s = &target.GetDebugger().GetOutputStream();
401 if (s)
402 {
403 char uuidbuf[64];
404 s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf)));
405 s->Printf ("Load Address: 0x%llx\n", address);
Jason Molenda743e43962012-10-02 22:23:42 +0000406 if (module_sp->GetFileSpec().GetDirectory().IsEmpty())
407 {
408 s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString());
409 }
410 else
411 {
412 s->Printf ("Loaded kernel file %s/%s\n",
413 module_sp->GetFileSpec().GetDirectory().AsCString(),
414 module_sp->GetFileSpec().GetFilename().AsCString());
415 }
Jason Molenda68b36072012-10-02 03:49:41 +0000416 s->Flush ();
417 }
418 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000419 return is_loaded;
420}
421
Greg Clayton1f746072012-08-29 21:13:06 +0000422uint32_t
423DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize ()
424{
425 if (module_sp)
426 return module_sp->GetArchitecture().GetAddressByteSize();
427 return 0;
428}
429
430lldb::ByteOrder
431DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder()
432{
433 if (module_sp)
434 return module_sp->GetArchitecture().GetByteOrder();
435 return lldb::endian::InlHostByteOrder();
436}
437
438lldb_private::ArchSpec
439DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const
440{
441 if (module_sp)
442 return module_sp->GetArchitecture();
443 return lldb_private::ArchSpec ();
444}
445
446
Greg Clayton7b242382011-07-08 00:48:09 +0000447//----------------------------------------------------------------------
448// Load the kernel module and initialize the "m_kernel" member. Return
449// true _only_ if the kernel is loaded the first time through (subsequent
450// calls to this function should return false after the kernel has been
451// already loaded).
452//----------------------------------------------------------------------
Greg Clayton374972e2011-07-09 17:15:55 +0000453void
Greg Clayton944b8282011-08-22 22:30:57 +0000454DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
Greg Clayton7b242382011-07-08 00:48:09 +0000455{
Greg Claytond16e1e52011-07-12 17:06:17 +0000456 if (!m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000457 {
458 m_kernel.Clear(false);
459 m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
Jason Molenda87a04b22012-10-19 03:40:45 +0000460 m_kernel.kernel_image = true;
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000461
462 ConstString kernel_name("mach_kernel");
463 if (m_kernel.module_sp.get()
464 && m_kernel.module_sp->GetObjectFile()
465 && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
466 {
467 kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename();
468 }
Jason Molenda31a69612012-10-04 02:16:06 +0000469 strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name));
470 m_kernel.name[sizeof (m_kernel.name) - 1] = '\0';
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000471
Greg Claytonc859e2d2012-02-13 23:10:39 +0000472 if (m_kernel.address == LLDB_INVALID_ADDRESS)
Greg Clayton7b242382011-07-08 00:48:09 +0000473 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000474 m_kernel.address = m_process->GetImageInfoAddress ();
475 if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
Greg Clayton7b242382011-07-08 00:48:09 +0000476 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000477 // We didn't get a hint from the process, so we will
478 // try the kernel at the address that it exists at in
479 // the file if we have one
480 ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
481 if (kernel_object_file)
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000482 {
483 addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
484 addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
485 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
486 {
487 m_kernel.address = load_address;
488 if (load_address != file_address)
489 {
490 // Don't accidentally relocate the kernel to the File address --
491 // the Load address has already been set to its actual in-memory address.
492 // Mark it as IsLoaded.
493 m_kernel.load_process_stop_id = m_process->GetStopID();
494 }
495 }
496 else
497 {
498 m_kernel.address = file_address;
499 }
500 }
Greg Clayton7b242382011-07-08 00:48:09 +0000501 }
502 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000503
504 if (m_kernel.address != LLDB_INVALID_ADDRESS)
Greg Clayton2af282a2012-03-21 04:25:00 +0000505 {
506 if (!m_kernel.LoadImageUsingMemoryModule (m_process))
507 {
508 m_kernel.LoadImageAtFileAddress (m_process);
509 }
510 }
Greg Clayton7b242382011-07-08 00:48:09 +0000511
Jim Ingham28eb5712012-10-12 17:34:26 +0000512 if (m_kernel.IsLoaded() && m_kernel.module_sp)
Greg Clayton7b242382011-07-08 00:48:09 +0000513 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000514 static ConstString kext_summary_symbol ("gLoadedKextSummaries");
515 const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
516 if (symbol)
517 {
Greg Claytone7612132012-03-07 21:03:09 +0000518 m_kext_summary_header_ptr_addr = symbol->GetAddress();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000519 // Update all image infos
520 ReadAllKextSummaries ();
521 }
Greg Clayton7b242382011-07-08 00:48:09 +0000522 }
523 else
Greg Clayton7b242382011-07-08 00:48:09 +0000524 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000525 m_kernel.Clear(false);
Greg Clayton7b242382011-07-08 00:48:09 +0000526 }
527 }
Greg Clayton7b242382011-07-08 00:48:09 +0000528}
529
Greg Clayton7b242382011-07-08 00:48:09 +0000530//----------------------------------------------------------------------
531// Static callback function that gets called when our DYLD notification
532// breakpoint gets hit. We update all of our image infos and then
533// let our super class DynamicLoader class decide if we should stop
534// or not (based on global preference).
535//----------------------------------------------------------------------
536bool
Greg Clayton944b8282011-08-22 22:30:57 +0000537DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
Greg Clayton374972e2011-07-09 17:15:55 +0000538 StoppointCallbackContext *context,
539 user_id_t break_id,
540 user_id_t break_loc_id)
Greg Clayton0d9fc762011-07-08 03:21:57 +0000541{
Greg Clayton944b8282011-08-22 22:30:57 +0000542 return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000543}
544
545bool
Greg Clayton944b8282011-08-22 22:30:57 +0000546DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
Greg Clayton374972e2011-07-09 17:15:55 +0000547 user_id_t break_id,
548 user_id_t break_loc_id)
549{
Greg Claytond16e1e52011-07-12 17:06:17 +0000550 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
551 if (log)
Greg Clayton944b8282011-08-22 22:30:57 +0000552 log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +0000553
Greg Clayton374972e2011-07-09 17:15:55 +0000554 ReadAllKextSummaries ();
Greg Claytond16e1e52011-07-12 17:06:17 +0000555
556 if (log)
557 PutToLog(log.get());
558
Greg Clayton374972e2011-07-09 17:15:55 +0000559 return GetStopWhenImagesChange();
560}
561
562
563bool
Greg Clayton944b8282011-08-22 22:30:57 +0000564DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
Greg Clayton7b242382011-07-08 00:48:09 +0000565{
566 Mutex::Locker locker(m_mutex);
567
568 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +0000569
570 m_kext_summaries.clear();
Greg Claytond16e1e52011-07-12 17:06:17 +0000571 if (m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000572 {
573 const uint32_t addr_size = m_kernel.GetAddressByteSize ();
574 const ByteOrder byte_order = m_kernel.GetByteOrder();
575 Error error;
576 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
577 // which is currenty 4 uint32_t and a pointer.
578 uint8_t buf[24];
579 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
580 const size_t count = 4 * sizeof(uint32_t) + addr_size;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000581 const bool prefer_file_cache = false;
Greg Claytond16e1e52011-07-12 17:06:17 +0000582 if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
583 prefer_file_cache,
584 error,
585 m_kext_summary_header_addr))
Greg Clayton7b242382011-07-08 00:48:09 +0000586 {
Greg Claytond16e1e52011-07-12 17:06:17 +0000587 // We got a valid address for our kext summary header and make sure it isn't NULL
588 if (m_kext_summary_header_addr.IsValid() &&
589 m_kext_summary_header_addr.GetFileAddress() != 0)
590 {
591 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
592 if (bytes_read == count)
593 {
594 uint32_t offset = 0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000595 m_kext_summary_header.version = data.GetU32(&offset);
596 if (m_kext_summary_header.version >= 2)
597 {
598 m_kext_summary_header.entry_size = data.GetU32(&offset);
599 }
600 else
601 {
602 // Versions less than 2 didn't have an entry size, it was hard coded
603 m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
604 }
605 m_kext_summary_header.entry_count = data.GetU32(&offset);
Greg Claytond16e1e52011-07-12 17:06:17 +0000606 return true;
607 }
608 }
Greg Clayton7b242382011-07-08 00:48:09 +0000609 }
610 }
Greg Claytond16e1e52011-07-12 17:06:17 +0000611 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000612 return false;
613}
614
615
616bool
Greg Clayton944b8282011-08-22 22:30:57 +0000617DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
Greg Clayton0d9fc762011-07-08 03:21:57 +0000618 uint32_t count)
Greg Clayton7b242382011-07-08 00:48:09 +0000619{
620 OSKextLoadedKextSummary::collection kext_summaries;
Greg Clayton374972e2011-07-09 17:15:55 +0000621 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000622 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000623 log->Printf ("Adding %d modules.\n", count);
Greg Clayton7b242382011-07-08 00:48:09 +0000624
625 Mutex::Locker locker(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000626
627 if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
628 return false;
629
Greg Clayton07e66e32011-07-20 03:41:06 +0000630 Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
Jason Molenda68b36072012-10-02 03:49:41 +0000631 if (s)
632 s->Printf ("Loading %d kext modules ", count);
Greg Clayton7b242382011-07-08 00:48:09 +0000633 for (uint32_t i = 0; i < count; i++)
634 {
Greg Clayton2af282a2012-03-21 04:25:00 +0000635 if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
636 kext_summaries[i].LoadImageAtFileAddress (m_process);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000637
Greg Clayton5b882162011-07-21 01:12:01 +0000638 if (s)
Jason Molenda68b36072012-10-02 03:49:41 +0000639 s->Printf (".");
640
Greg Claytona63d08c2011-07-19 03:57:15 +0000641 if (log)
642 kext_summaries[i].PutToLog (log.get());
Greg Clayton7b242382011-07-08 00:48:09 +0000643 }
Jason Molenda68b36072012-10-02 03:49:41 +0000644 if (s)
645 {
646 s->Printf (" done.\n");
647 s->Flush ();
648 }
649
Greg Clayton7b242382011-07-08 00:48:09 +0000650 bool return_value = AddModulesUsingImageInfos (kext_summaries);
Greg Clayton7b242382011-07-08 00:48:09 +0000651 return return_value;
652}
653
654// Adds the modules in image_infos to m_kext_summaries.
655// NB don't call this passing in m_kext_summaries.
656
657bool
Greg Clayton944b8282011-08-22 22:30:57 +0000658DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
Greg Clayton7b242382011-07-08 00:48:09 +0000659{
660 // Now add these images to the main list.
661 ModuleList loaded_module_list;
Greg Clayton7b242382011-07-08 00:48:09 +0000662
663 for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
664 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000665 OSKextLoadedKextSummary &image_info = image_infos[idx];
666 m_kext_summaries.push_back(image_info);
Greg Clayton7b242382011-07-08 00:48:09 +0000667
Greg Claytonc859e2d2012-02-13 23:10:39 +0000668 if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
669 loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
Greg Clayton7b242382011-07-08 00:48:09 +0000670 }
671
Enrico Granata17598482012-11-08 02:22:02 +0000672 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
Greg Clayton7b242382011-07-08 00:48:09 +0000673 return true;
674}
675
Greg Clayton7b242382011-07-08 00:48:09 +0000676
677uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000678DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000679 uint32_t image_infos_count,
680 OSKextLoadedKextSummary::collection &image_infos)
681{
682 const ByteOrder endian = m_kernel.GetByteOrder();
683 const uint32_t addr_size = m_kernel.GetAddressByteSize();
684
685 image_infos.resize(image_infos_count);
686 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
687 DataBufferHeap data(count, 0);
688 Error error;
Greg Clayton5b882162011-07-21 01:12:01 +0000689
Greg Clayton0d9fc762011-07-08 03:21:57 +0000690 const bool prefer_file_cache = false;
691 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
692 prefer_file_cache,
693 data.GetBytes(),
694 data.GetByteSize(),
695 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000696 if (bytes_read == count)
697 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000698
Greg Clayton7b242382011-07-08 00:48:09 +0000699 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
700 uint32_t i=0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000701 for (uint32_t kext_summary_offset = 0;
702 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
703 ++i, kext_summary_offset += m_kext_summary_header.entry_size)
Greg Clayton7b242382011-07-08 00:48:09 +0000704 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000705 uint32_t offset = kext_summary_offset;
Greg Clayton7b242382011-07-08 00:48:09 +0000706 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
707 if (name_data == NULL)
708 break;
709 memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
710 image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
711 image_infos[i].address = extractor.GetU64(&offset);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000712 if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
713 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
Greg Clayton7b242382011-07-08 00:48:09 +0000714 image_infos[i].size = extractor.GetU64(&offset);
715 image_infos[i].version = extractor.GetU64(&offset);
716 image_infos[i].load_tag = extractor.GetU32(&offset);
717 image_infos[i].flags = extractor.GetU32(&offset);
Greg Claytona63d08c2011-07-19 03:57:15 +0000718 if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
719 {
720 image_infos[i].reference_list = extractor.GetU64(&offset);
721 }
722 else
723 {
724 image_infos[i].reference_list = 0;
725 }
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000726// printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n",
727// i,
728// KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data,
729// image_infos[i].address,
730// image_infos[i].size,
731// image_infos[i].version,
732// image_infos[i].load_tag,
733// image_infos[i].flags);
Greg Clayton7b242382011-07-08 00:48:09 +0000734 }
735 if (i < image_infos.size())
736 image_infos.resize(i);
737 }
738 else
739 {
740 image_infos.clear();
741 }
742 return image_infos.size();
743}
744
745bool
Greg Clayton944b8282011-08-22 22:30:57 +0000746DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
Greg Clayton7b242382011-07-08 00:48:09 +0000747{
Greg Clayton374972e2011-07-09 17:15:55 +0000748 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000749
750 Mutex::Locker locker(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +0000751
Greg Clayton7b242382011-07-08 00:48:09 +0000752 if (ReadKextSummaryHeader ())
753 {
Greg Clayton374972e2011-07-09 17:15:55 +0000754 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000755 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000756 Address summary_addr (m_kext_summary_header_addr);
Greg Claytona63d08c2011-07-19 03:57:15 +0000757 summary_addr.Slide(m_kext_summary_header.GetSize());
Greg Clayton0d9fc762011-07-08 03:21:57 +0000758 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
Greg Clayton7b242382011-07-08 00:48:09 +0000759 {
Greg Clayton7b242382011-07-08 00:48:09 +0000760 m_kext_summaries.clear();
761 }
762 return true;
763 }
764 }
765 return false;
766}
767
768//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000769// Dump an image info structure to the file handle provided.
770//----------------------------------------------------------------------
771void
Greg Clayton944b8282011-08-22 22:30:57 +0000772DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000773{
774 if (log == NULL)
775 return;
Greg Clayton07e66e32011-07-20 03:41:06 +0000776 const uint8_t *u = (uint8_t *)uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +0000777
778 if (address == LLDB_INVALID_ADDRESS)
779 {
780 if (u)
781 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000782 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)",
Greg Clayton7b242382011-07-08 00:48:09 +0000783 u[ 0], u[ 1], u[ 2], u[ 3],
784 u[ 4], u[ 5], u[ 6], u[ 7],
785 u[ 8], u[ 9], u[10], u[11],
786 u[12], u[13], u[14], u[15],
787 name);
788 }
789 else
Greg Claytona63d08c2011-07-19 03:57:15 +0000790 log->Printf("\tname=\"%s\" (UNLOADED)", name);
Greg Clayton7b242382011-07-08 00:48:09 +0000791 }
792 else
793 {
794 if (u)
795 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000796 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\"",
797 address, size, version, load_tag, flags, reference_list,
798 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
799 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
Greg Clayton7b242382011-07-08 00:48:09 +0000800 name);
801 }
802 else
803 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000804 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\"",
805 address, address+size, version, load_tag, flags, reference_list,
806 name);
Greg Clayton7b242382011-07-08 00:48:09 +0000807 }
Greg Clayton7b242382011-07-08 00:48:09 +0000808 }
809}
810
811//----------------------------------------------------------------------
812// Dump the _dyld_all_image_infos members and all current image infos
813// that we have parsed to the file handle provided.
814//----------------------------------------------------------------------
815void
Greg Clayton944b8282011-08-22 22:30:57 +0000816DynamicLoaderDarwinKernel::PutToLog(Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000817{
818 if (log == NULL)
819 return;
820
821 Mutex::Locker locker(m_mutex);
Greg Claytona63d08c2011-07-19 03:57:15 +0000822 log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
Greg Clayton0d9fc762011-07-08 03:21:57 +0000823 m_kext_summary_header_addr.GetFileAddress(),
Greg Clayton7b242382011-07-08 00:48:09 +0000824 m_kext_summary_header.version,
825 m_kext_summary_header.entry_size,
Greg Claytona63d08c2011-07-19 03:57:15 +0000826 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +0000827
828 size_t i;
829 const size_t count = m_kext_summaries.size();
830 if (count > 0)
831 {
832 log->PutCString("Loaded:");
833 for (i = 0; i<count; i++)
834 m_kext_summaries[i].PutToLog(log);
835 }
836}
837
838void
Greg Clayton944b8282011-08-22 22:30:57 +0000839DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
Greg Clayton7b242382011-07-08 00:48:09 +0000840{
Greg Clayton944b8282011-08-22 22:30:57 +0000841 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton7b242382011-07-08 00:48:09 +0000842 Clear(true);
843 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +0000844}
845
Greg Clayton374972e2011-07-09 17:15:55 +0000846void
Greg Clayton944b8282011-08-22 22:30:57 +0000847DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
Greg Clayton7b242382011-07-08 00:48:09 +0000848{
Greg Claytonc859e2d2012-02-13 23:10:39 +0000849 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
Greg Clayton374972e2011-07-09 17:15:55 +0000850 {
Greg Clayton944b8282011-08-22 22:30:57 +0000851 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +0000852
Greg Claytond16e1e52011-07-12 17:06:17 +0000853
Jim Inghama8558b62012-05-22 00:12:20 +0000854 const bool internal_bp = true;
Greg Claytond16e1e52011-07-12 17:06:17 +0000855 const LazyBool skip_prologue = eLazyBoolNo;
Jim Ingham969795f2011-09-21 01:17:13 +0000856 FileSpecList module_spec_list;
857 module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
858 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
Jim Ingham87df91b2011-09-23 00:54:11 +0000859 NULL,
Greg Clayton374972e2011-07-09 17:15:55 +0000860 "OSKextLoadedKextSummariesUpdated",
861 eFunctionNameTypeFull,
Jim Inghama8558b62012-05-22 00:12:20 +0000862 skip_prologue,
863 internal_bp).get();
Greg Clayton374972e2011-07-09 17:15:55 +0000864
Greg Clayton944b8282011-08-22 22:30:57 +0000865 bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
Greg Clayton374972e2011-07-09 17:15:55 +0000866 m_break_id = bp->GetID();
867 }
Greg Clayton7b242382011-07-08 00:48:09 +0000868}
869
870//----------------------------------------------------------------------
871// Member function that gets called when the process state changes.
872//----------------------------------------------------------------------
873void
Greg Clayton944b8282011-08-22 22:30:57 +0000874DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
Greg Clayton7b242382011-07-08 00:48:09 +0000875{
Greg Clayton944b8282011-08-22 22:30:57 +0000876 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
Greg Clayton7b242382011-07-08 00:48:09 +0000877 switch (state)
878 {
879 case eStateConnected:
880 case eStateAttaching:
881 case eStateLaunching:
882 case eStateInvalid:
883 case eStateUnloaded:
884 case eStateExited:
885 case eStateDetached:
886 Clear(false);
887 break;
888
889 case eStateStopped:
Greg Clayton374972e2011-07-09 17:15:55 +0000890 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000891 break;
892
893 case eStateRunning:
894 case eStateStepping:
895 case eStateCrashed:
896 case eStateSuspended:
897 break;
898
899 default:
900 break;
901 }
902}
903
904ThreadPlanSP
Greg Clayton944b8282011-08-22 22:30:57 +0000905DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
Greg Clayton7b242382011-07-08 00:48:09 +0000906{
907 ThreadPlanSP thread_plan_sp;
Greg Clayton374972e2011-07-09 17:15:55 +0000908 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
909 if (log)
910 log->Printf ("Could not find symbol for step through.");
Greg Clayton7b242382011-07-08 00:48:09 +0000911 return thread_plan_sp;
912}
913
914Error
Greg Clayton944b8282011-08-22 22:30:57 +0000915DynamicLoaderDarwinKernel::CanLoadImage ()
Greg Clayton7b242382011-07-08 00:48:09 +0000916{
917 Error error;
918 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
919 return error;
920}
921
922void
Greg Clayton944b8282011-08-22 22:30:57 +0000923DynamicLoaderDarwinKernel::Initialize()
Greg Clayton7b242382011-07-08 00:48:09 +0000924{
925 PluginManager::RegisterPlugin (GetPluginNameStatic(),
926 GetPluginDescriptionStatic(),
Greg Claytone8cd0c92012-10-19 18:02:49 +0000927 CreateInstance,
928 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +0000929}
930
931void
Greg Clayton944b8282011-08-22 22:30:57 +0000932DynamicLoaderDarwinKernel::Terminate()
Greg Clayton7b242382011-07-08 00:48:09 +0000933{
934 PluginManager::UnregisterPlugin (CreateInstance);
935}
936
Greg Claytone8cd0c92012-10-19 18:02:49 +0000937void
938DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
939{
940 if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
941 {
942 const bool is_global_setting = true;
943 PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
944 GetGlobalProperties()->GetValueProperties(),
945 ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
946 is_global_setting);
947 }
948}
Greg Clayton7b242382011-07-08 00:48:09 +0000949
950const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000951DynamicLoaderDarwinKernel::GetPluginNameStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000952{
Greg Clayton468ea4e2012-10-19 18:14:47 +0000953 return "dynamic-loader.darwin-kernel";
Greg Clayton7b242382011-07-08 00:48:09 +0000954}
955
956const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000957DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000958{
959 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
960}
961
962
963//------------------------------------------------------------------
964// PluginInterface protocol
965//------------------------------------------------------------------
966const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000967DynamicLoaderDarwinKernel::GetPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000968{
Greg Clayton944b8282011-08-22 22:30:57 +0000969 return "DynamicLoaderDarwinKernel";
Greg Clayton7b242382011-07-08 00:48:09 +0000970}
971
972const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000973DynamicLoaderDarwinKernel::GetShortPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000974{
975 return GetPluginNameStatic();
976}
977
978uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000979DynamicLoaderDarwinKernel::GetPluginVersion()
Greg Clayton7b242382011-07-08 00:48:09 +0000980{
981 return 1;
982}
983
Greg Clayton1f746072012-08-29 21:13:06 +0000984lldb::ByteOrder
985DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
986{
987 switch (magic)
988 {
989 case llvm::MachO::HeaderMagic32:
990 case llvm::MachO::HeaderMagic64:
991 return lldb::endian::InlHostByteOrder();
992
993 case llvm::MachO::HeaderMagic32Swapped:
994 case llvm::MachO::HeaderMagic64Swapped:
995 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
996 return lldb::eByteOrderLittle;
997 else
998 return lldb::eByteOrderBig;
999
1000 default:
1001 break;
1002 }
1003 return lldb::eByteOrderInvalid;
1004}
1005