blob: 3863762a276c5e81597b839aa2a07dca2925e306 [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 {
284 ModuleList &target_images = target.GetImages();
285 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
672 if (loaded_module_list.GetSize() > 0)
673 {
Greg Clayton7b242382011-07-08 00:48:09 +0000674 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
675 }
676 return true;
677}
678
Greg Clayton7b242382011-07-08 00:48:09 +0000679
680uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000681DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000682 uint32_t image_infos_count,
683 OSKextLoadedKextSummary::collection &image_infos)
684{
685 const ByteOrder endian = m_kernel.GetByteOrder();
686 const uint32_t addr_size = m_kernel.GetAddressByteSize();
687
688 image_infos.resize(image_infos_count);
689 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
690 DataBufferHeap data(count, 0);
691 Error error;
Greg Clayton5b882162011-07-21 01:12:01 +0000692
Greg Clayton0d9fc762011-07-08 03:21:57 +0000693 const bool prefer_file_cache = false;
694 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
695 prefer_file_cache,
696 data.GetBytes(),
697 data.GetByteSize(),
698 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000699 if (bytes_read == count)
700 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000701
Greg Clayton7b242382011-07-08 00:48:09 +0000702 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
703 uint32_t i=0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000704 for (uint32_t kext_summary_offset = 0;
705 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
706 ++i, kext_summary_offset += m_kext_summary_header.entry_size)
Greg Clayton7b242382011-07-08 00:48:09 +0000707 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000708 uint32_t offset = kext_summary_offset;
Greg Clayton7b242382011-07-08 00:48:09 +0000709 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
710 if (name_data == NULL)
711 break;
712 memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
713 image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
714 image_infos[i].address = extractor.GetU64(&offset);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000715 if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
716 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
Greg Clayton7b242382011-07-08 00:48:09 +0000717 image_infos[i].size = extractor.GetU64(&offset);
718 image_infos[i].version = extractor.GetU64(&offset);
719 image_infos[i].load_tag = extractor.GetU32(&offset);
720 image_infos[i].flags = extractor.GetU32(&offset);
Greg Claytona63d08c2011-07-19 03:57:15 +0000721 if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
722 {
723 image_infos[i].reference_list = extractor.GetU64(&offset);
724 }
725 else
726 {
727 image_infos[i].reference_list = 0;
728 }
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000729// 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",
730// i,
731// KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data,
732// image_infos[i].address,
733// image_infos[i].size,
734// image_infos[i].version,
735// image_infos[i].load_tag,
736// image_infos[i].flags);
Greg Clayton7b242382011-07-08 00:48:09 +0000737 }
738 if (i < image_infos.size())
739 image_infos.resize(i);
740 }
741 else
742 {
743 image_infos.clear();
744 }
745 return image_infos.size();
746}
747
748bool
Greg Clayton944b8282011-08-22 22:30:57 +0000749DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
Greg Clayton7b242382011-07-08 00:48:09 +0000750{
Greg Clayton374972e2011-07-09 17:15:55 +0000751 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000752
753 Mutex::Locker locker(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +0000754
Greg Clayton7b242382011-07-08 00:48:09 +0000755 if (ReadKextSummaryHeader ())
756 {
Greg Clayton374972e2011-07-09 17:15:55 +0000757 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000758 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000759 Address summary_addr (m_kext_summary_header_addr);
Greg Claytona63d08c2011-07-19 03:57:15 +0000760 summary_addr.Slide(m_kext_summary_header.GetSize());
Greg Clayton0d9fc762011-07-08 03:21:57 +0000761 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
Greg Clayton7b242382011-07-08 00:48:09 +0000762 {
Greg Clayton7b242382011-07-08 00:48:09 +0000763 m_kext_summaries.clear();
764 }
765 return true;
766 }
767 }
768 return false;
769}
770
771//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000772// Dump an image info structure to the file handle provided.
773//----------------------------------------------------------------------
774void
Greg Clayton944b8282011-08-22 22:30:57 +0000775DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000776{
777 if (log == NULL)
778 return;
Greg Clayton07e66e32011-07-20 03:41:06 +0000779 const uint8_t *u = (uint8_t *)uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +0000780
781 if (address == LLDB_INVALID_ADDRESS)
782 {
783 if (u)
784 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000785 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 +0000786 u[ 0], u[ 1], u[ 2], u[ 3],
787 u[ 4], u[ 5], u[ 6], u[ 7],
788 u[ 8], u[ 9], u[10], u[11],
789 u[12], u[13], u[14], u[15],
790 name);
791 }
792 else
Greg Claytona63d08c2011-07-19 03:57:15 +0000793 log->Printf("\tname=\"%s\" (UNLOADED)", name);
Greg Clayton7b242382011-07-08 00:48:09 +0000794 }
795 else
796 {
797 if (u)
798 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000799 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\"",
800 address, size, version, load_tag, flags, reference_list,
801 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
802 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
Greg Clayton7b242382011-07-08 00:48:09 +0000803 name);
804 }
805 else
806 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000807 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\"",
808 address, address+size, version, load_tag, flags, reference_list,
809 name);
Greg Clayton7b242382011-07-08 00:48:09 +0000810 }
Greg Clayton7b242382011-07-08 00:48:09 +0000811 }
812}
813
814//----------------------------------------------------------------------
815// Dump the _dyld_all_image_infos members and all current image infos
816// that we have parsed to the file handle provided.
817//----------------------------------------------------------------------
818void
Greg Clayton944b8282011-08-22 22:30:57 +0000819DynamicLoaderDarwinKernel::PutToLog(Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000820{
821 if (log == NULL)
822 return;
823
824 Mutex::Locker locker(m_mutex);
Greg Claytona63d08c2011-07-19 03:57:15 +0000825 log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
Greg Clayton0d9fc762011-07-08 03:21:57 +0000826 m_kext_summary_header_addr.GetFileAddress(),
Greg Clayton7b242382011-07-08 00:48:09 +0000827 m_kext_summary_header.version,
828 m_kext_summary_header.entry_size,
Greg Claytona63d08c2011-07-19 03:57:15 +0000829 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +0000830
831 size_t i;
832 const size_t count = m_kext_summaries.size();
833 if (count > 0)
834 {
835 log->PutCString("Loaded:");
836 for (i = 0; i<count; i++)
837 m_kext_summaries[i].PutToLog(log);
838 }
839}
840
841void
Greg Clayton944b8282011-08-22 22:30:57 +0000842DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
Greg Clayton7b242382011-07-08 00:48:09 +0000843{
Greg Clayton944b8282011-08-22 22:30:57 +0000844 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton7b242382011-07-08 00:48:09 +0000845 Clear(true);
846 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +0000847}
848
Greg Clayton374972e2011-07-09 17:15:55 +0000849void
Greg Clayton944b8282011-08-22 22:30:57 +0000850DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
Greg Clayton7b242382011-07-08 00:48:09 +0000851{
Greg Claytonc859e2d2012-02-13 23:10:39 +0000852 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
Greg Clayton374972e2011-07-09 17:15:55 +0000853 {
Greg Clayton944b8282011-08-22 22:30:57 +0000854 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +0000855
Greg Claytond16e1e52011-07-12 17:06:17 +0000856
Jim Inghama8558b62012-05-22 00:12:20 +0000857 const bool internal_bp = true;
Greg Claytond16e1e52011-07-12 17:06:17 +0000858 const LazyBool skip_prologue = eLazyBoolNo;
Jim Ingham969795f2011-09-21 01:17:13 +0000859 FileSpecList module_spec_list;
860 module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
861 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
Jim Ingham87df91b2011-09-23 00:54:11 +0000862 NULL,
Greg Clayton374972e2011-07-09 17:15:55 +0000863 "OSKextLoadedKextSummariesUpdated",
864 eFunctionNameTypeFull,
Jim Inghama8558b62012-05-22 00:12:20 +0000865 skip_prologue,
866 internal_bp).get();
Greg Clayton374972e2011-07-09 17:15:55 +0000867
Greg Clayton944b8282011-08-22 22:30:57 +0000868 bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
Greg Clayton374972e2011-07-09 17:15:55 +0000869 m_break_id = bp->GetID();
870 }
Greg Clayton7b242382011-07-08 00:48:09 +0000871}
872
873//----------------------------------------------------------------------
874// Member function that gets called when the process state changes.
875//----------------------------------------------------------------------
876void
Greg Clayton944b8282011-08-22 22:30:57 +0000877DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
Greg Clayton7b242382011-07-08 00:48:09 +0000878{
Greg Clayton944b8282011-08-22 22:30:57 +0000879 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
Greg Clayton7b242382011-07-08 00:48:09 +0000880 switch (state)
881 {
882 case eStateConnected:
883 case eStateAttaching:
884 case eStateLaunching:
885 case eStateInvalid:
886 case eStateUnloaded:
887 case eStateExited:
888 case eStateDetached:
889 Clear(false);
890 break;
891
892 case eStateStopped:
Greg Clayton374972e2011-07-09 17:15:55 +0000893 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000894 break;
895
896 case eStateRunning:
897 case eStateStepping:
898 case eStateCrashed:
899 case eStateSuspended:
900 break;
901
902 default:
903 break;
904 }
905}
906
907ThreadPlanSP
Greg Clayton944b8282011-08-22 22:30:57 +0000908DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
Greg Clayton7b242382011-07-08 00:48:09 +0000909{
910 ThreadPlanSP thread_plan_sp;
Greg Clayton374972e2011-07-09 17:15:55 +0000911 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
912 if (log)
913 log->Printf ("Could not find symbol for step through.");
Greg Clayton7b242382011-07-08 00:48:09 +0000914 return thread_plan_sp;
915}
916
917Error
Greg Clayton944b8282011-08-22 22:30:57 +0000918DynamicLoaderDarwinKernel::CanLoadImage ()
Greg Clayton7b242382011-07-08 00:48:09 +0000919{
920 Error error;
921 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
922 return error;
923}
924
925void
Greg Clayton944b8282011-08-22 22:30:57 +0000926DynamicLoaderDarwinKernel::Initialize()
Greg Clayton7b242382011-07-08 00:48:09 +0000927{
928 PluginManager::RegisterPlugin (GetPluginNameStatic(),
929 GetPluginDescriptionStatic(),
Greg Claytone8cd0c92012-10-19 18:02:49 +0000930 CreateInstance,
931 DebuggerInitialize);
Greg Clayton7b242382011-07-08 00:48:09 +0000932}
933
934void
Greg Clayton944b8282011-08-22 22:30:57 +0000935DynamicLoaderDarwinKernel::Terminate()
Greg Clayton7b242382011-07-08 00:48:09 +0000936{
937 PluginManager::UnregisterPlugin (CreateInstance);
938}
939
Greg Claytone8cd0c92012-10-19 18:02:49 +0000940void
941DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger)
942{
943 if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName()))
944 {
945 const bool is_global_setting = true;
946 PluginManager::CreateSettingForDynamicLoaderPlugin (debugger,
947 GetGlobalProperties()->GetValueProperties(),
948 ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."),
949 is_global_setting);
950 }
951}
Greg Clayton7b242382011-07-08 00:48:09 +0000952
953const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000954DynamicLoaderDarwinKernel::GetPluginNameStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000955{
Greg Clayton468ea4e2012-10-19 18:14:47 +0000956 return "dynamic-loader.darwin-kernel";
Greg Clayton7b242382011-07-08 00:48:09 +0000957}
958
959const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000960DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000961{
962 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
963}
964
965
966//------------------------------------------------------------------
967// PluginInterface protocol
968//------------------------------------------------------------------
969const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000970DynamicLoaderDarwinKernel::GetPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000971{
Greg Clayton944b8282011-08-22 22:30:57 +0000972 return "DynamicLoaderDarwinKernel";
Greg Clayton7b242382011-07-08 00:48:09 +0000973}
974
975const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000976DynamicLoaderDarwinKernel::GetShortPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000977{
978 return GetPluginNameStatic();
979}
980
981uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000982DynamicLoaderDarwinKernel::GetPluginVersion()
Greg Clayton7b242382011-07-08 00:48:09 +0000983{
984 return 1;
985}
986
Greg Clayton1f746072012-08-29 21:13:06 +0000987lldb::ByteOrder
988DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
989{
990 switch (magic)
991 {
992 case llvm::MachO::HeaderMagic32:
993 case llvm::MachO::HeaderMagic64:
994 return lldb::endian::InlHostByteOrder();
995
996 case llvm::MachO::HeaderMagic32Swapped:
997 case llvm::MachO::HeaderMagic64Swapped:
998 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
999 return lldb::eByteOrderLittle;
1000 else
1001 return lldb::eByteOrderBig;
1002
1003 default:
1004 break;
1005 }
1006 return lldb::eByteOrderInvalid;
1007}
1008