blob: abaf1b4e8627b7f103ed89707182f13fbfc642e4 [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"
20#include "lldb/Symbol/ObjectFile.h"
21#include "lldb/Target/ObjCLanguageRuntime.h"
22#include "lldb/Target/RegisterContext.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/Thread.h"
25#include "lldb/Target/ThreadPlanRunToAddress.h"
26#include "lldb/Target/StackFrame.h"
27
Greg Clayton944b8282011-08-22 22:30:57 +000028#include "DynamicLoaderDarwinKernel.h"
Greg Clayton7b242382011-07-08 00:48:09 +000029
30//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
31#ifdef ENABLE_DEBUG_PRINTF
32#include <stdio.h>
33#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
34#else
35#define DEBUG_PRINTF(fmt, ...)
36#endif
37
38using namespace lldb;
39using namespace lldb_private;
40
41/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
42/// I am putting it here so I can invoke it in the Trampoline code here, but
43/// it should be moved to the ObjC Runtime support when it is set up.
44
45
46//----------------------------------------------------------------------
47// Create an instance of this class. This function is filled into
48// the plugin info class that gets handed out by the plugin factory and
49// allows the lldb to instantiate an instance of this class.
50//----------------------------------------------------------------------
51DynamicLoader *
Greg Clayton944b8282011-08-22 22:30:57 +000052DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
Greg Clayton7b242382011-07-08 00:48:09 +000053{
54 bool create = force;
55 if (!create)
56 {
Greg Claytonaa149cb2011-08-11 02:48:45 +000057 Module* exe_module = process->GetTarget().GetExecutableModulePointer();
Greg Claytondf0b7d52011-07-08 04:11:42 +000058 if (exe_module)
59 {
60 ObjectFile *object_file = exe_module->GetObjectFile();
61 if (object_file)
62 {
Sean Callanan49bce8e2012-02-10 20:22:35 +000063 create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
Greg Claytondf0b7d52011-07-08 04:11:42 +000064 }
65 }
66
67 if (create)
68 {
69 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
Greg Clayton70512312012-05-08 01:45:38 +000070 switch (triple_ref.getOS())
71 {
72 case llvm::Triple::Darwin:
73 case llvm::Triple::MacOSX:
74 case llvm::Triple::IOS:
75 create = triple_ref.getVendor() == llvm::Triple::Apple;
76 break;
77 default:
78 create = false;
79 break;
80 }
Greg Claytondf0b7d52011-07-08 04:11:42 +000081 }
Greg Clayton7b242382011-07-08 00:48:09 +000082 }
83
84 if (create)
Sean Callanan90539452011-09-20 23:01:51 +000085 {
86 process->SetCanJIT(false);
Greg Clayton944b8282011-08-22 22:30:57 +000087 return new DynamicLoaderDarwinKernel (process);
Sean Callanan90539452011-09-20 23:01:51 +000088 }
Greg Clayton7b242382011-07-08 00:48:09 +000089 return NULL;
90}
91
92//----------------------------------------------------------------------
93// Constructor
94//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +000095DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
Greg Clayton7b242382011-07-08 00:48:09 +000096 DynamicLoader(process),
97 m_kernel(),
Greg Claytond16e1e52011-07-12 17:06:17 +000098 m_kext_summary_header_ptr_addr (),
Greg Clayton0d9fc762011-07-08 03:21:57 +000099 m_kext_summary_header_addr (),
Greg Clayton7b242382011-07-08 00:48:09 +0000100 m_kext_summary_header (),
Greg Clayton7b242382011-07-08 00:48:09 +0000101 m_kext_summaries(),
Daniel Dunbara08823f2011-10-31 22:50:49 +0000102 m_mutex(Mutex::eMutexTypeRecursive),
103 m_break_id (LLDB_INVALID_BREAK_ID)
Greg Clayton7b242382011-07-08 00:48:09 +0000104{
105}
106
107//----------------------------------------------------------------------
108// Destructor
109//----------------------------------------------------------------------
Greg Clayton944b8282011-08-22 22:30:57 +0000110DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel()
Greg Clayton7b242382011-07-08 00:48:09 +0000111{
112 Clear(true);
113}
114
Greg Clayton374972e2011-07-09 17:15:55 +0000115void
Greg Clayton944b8282011-08-22 22:30:57 +0000116DynamicLoaderDarwinKernel::UpdateIfNeeded()
Greg Clayton374972e2011-07-09 17:15:55 +0000117{
118 LoadKernelModuleIfNeeded();
119 SetNotificationBreakpointIfNeeded ();
120}
Greg Clayton7b242382011-07-08 00:48:09 +0000121//------------------------------------------------------------------
122/// Called after attaching a process.
123///
124/// Allow DynamicLoader plug-ins to execute some code after
125/// attaching to a process.
126//------------------------------------------------------------------
127void
Greg Clayton944b8282011-08-22 22:30:57 +0000128DynamicLoaderDarwinKernel::DidAttach ()
Greg Clayton7b242382011-07-08 00:48:09 +0000129{
130 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000131 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000132}
133
134//------------------------------------------------------------------
135/// Called after attaching a process.
136///
137/// Allow DynamicLoader plug-ins to execute some code after
138/// attaching to a process.
139//------------------------------------------------------------------
140void
Greg Clayton944b8282011-08-22 22:30:57 +0000141DynamicLoaderDarwinKernel::DidLaunch ()
Greg Clayton7b242382011-07-08 00:48:09 +0000142{
143 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000144 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000145}
146
147
148//----------------------------------------------------------------------
149// Clear out the state of this class.
150//----------------------------------------------------------------------
151void
Greg Clayton944b8282011-08-22 22:30:57 +0000152DynamicLoaderDarwinKernel::Clear (bool clear_process)
Greg Clayton7b242382011-07-08 00:48:09 +0000153{
154 Mutex::Locker locker(m_mutex);
155
156 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
157 m_process->ClearBreakpointSiteByID(m_break_id);
158
159 if (clear_process)
160 m_process = NULL;
161 m_kernel.Clear(false);
Greg Claytond16e1e52011-07-12 17:06:17 +0000162 m_kext_summary_header_ptr_addr.Clear();
Greg Clayton0d9fc762011-07-08 03:21:57 +0000163 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000164 m_kext_summaries.clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000165 m_break_id = LLDB_INVALID_BREAK_ID;
166}
167
Greg Clayton7b242382011-07-08 00:48:09 +0000168
Greg Claytonc859e2d2012-02-13 23:10:39 +0000169bool
Greg Clayton2af282a2012-03-21 04:25:00 +0000170DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process)
171{
172 if (IsLoaded())
173 return true;
174
175 if (module_sp)
176 {
177 bool changed = false;
178 if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
179 load_process_stop_id = process->GetStopID();
180 }
181 return false;
182}
183
184bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000185DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
186{
187 if (IsLoaded())
188 return true;
189
190 bool uuid_is_valid = uuid.IsValid();
191
192 Target &target = process->GetTarget();
193 ModuleSP memory_module_sp;
194 // Use the memory module as the module if we have one...
195 if (address != LLDB_INVALID_ADDRESS)
196 {
197 FileSpec file_spec;
198 if (module_sp)
199 file_spec = module_sp->GetFileSpec();
200 else
201 file_spec.SetFile (name, false);
202
203 memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
204 if (memory_module_sp && !uuid_is_valid)
205 {
206 uuid = memory_module_sp->GetUUID();
207 uuid_is_valid = uuid.IsValid();
208 }
209 }
210
211 if (!module_sp)
212 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000213 if (uuid_is_valid)
214 {
215 ModuleList &target_images = target.GetImages();
216 module_sp = target_images.FindModule(uuid);
217
218 if (!module_sp)
Greg Claytonb9a01b32012-02-26 05:51:37 +0000219 {
Greg Clayton2af282a2012-03-21 04:25:00 +0000220 ModuleSpec module_spec;
Greg Claytonb9a01b32012-02-26 05:51:37 +0000221 module_spec.GetUUID() = uuid;
222 module_sp = target.GetSharedModule (module_spec);
223 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000224 }
225 }
226
227
228 if (memory_module_sp)
229 {
230 // Someone already supplied a file, make sure it is the right one.
231 if (module_sp)
232 {
233 if (module_sp->GetUUID() == memory_module_sp->GetUUID())
234 {
235 ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
236 ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
237 if (memory_object_file && ondisk_object_file)
238 {
239 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
240 SectionList *memory_section_list = memory_object_file->GetSectionList ();
241 if (memory_section_list && ondisk_section_list)
242 {
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000243 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000244 // There may be CTF sections in the memory image so we can't
245 // always just compare the number of sections (which are actually
246 // segments in mach-o parlance)
247 uint32_t sect_idx = 0;
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000248
249
250 // We now iterate through all sections in the file module
251 // and look to see if the memory module has a load address
252 // for that section.
253 uint32_t num_sections_loaded = 0;
254 for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000255 {
Greg Clayton7820bd12012-07-07 01:24:12 +0000256 SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
257 if (ondisk_section_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000258 {
Greg Clayton7820bd12012-07-07 01:24:12 +0000259 const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000260 if (memory_section)
261 {
Greg Clayton7820bd12012-07-07 01:24:12 +0000262 target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress());
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000263 ++num_sections_loaded;
264 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000265 }
266 }
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000267 if (num_sections_loaded > 0)
268 load_process_stop_id = process->GetStopID();
269 else
270 module_sp.reset(); // No sections were loaded
Greg Claytonc859e2d2012-02-13 23:10:39 +0000271 }
272 else
273 module_sp.reset(); // One or both section lists
274 }
275 else
276 module_sp.reset(); // One or both object files missing
277 }
278 else
279 module_sp.reset(); // UUID mismatch
280 }
281
282 // Use the memory module as the module if we didn't like the file
283 // module we either found or were supplied with
284 if (!module_sp)
285 {
286 module_sp = memory_module_sp;
287 // Load the memory image in the target as all adresses are already correct
288 bool changed = false;
289 target.GetImages().Append (memory_module_sp);
290 if (module_sp->SetLoadAddress (target, 0, changed))
291 load_process_stop_id = process->GetStopID();
292 }
293 }
294 bool is_loaded = IsLoaded();
295
296 if (so_address.IsValid())
297 {
298 if (is_loaded)
299 so_address.SetLoadAddress (address, &target);
300 else
301 target.GetImages().ResolveFileAddress (address, so_address);
302
303 }
304 return is_loaded;
305}
306
Greg Clayton1f746072012-08-29 21:13:06 +0000307uint32_t
308DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize ()
309{
310 if (module_sp)
311 return module_sp->GetArchitecture().GetAddressByteSize();
312 return 0;
313}
314
315lldb::ByteOrder
316DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder()
317{
318 if (module_sp)
319 return module_sp->GetArchitecture().GetByteOrder();
320 return lldb::endian::InlHostByteOrder();
321}
322
323lldb_private::ArchSpec
324DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const
325{
326 if (module_sp)
327 return module_sp->GetArchitecture();
328 return lldb_private::ArchSpec ();
329}
330
331
Greg Clayton7b242382011-07-08 00:48:09 +0000332//----------------------------------------------------------------------
333// Load the kernel module and initialize the "m_kernel" member. Return
334// true _only_ if the kernel is loaded the first time through (subsequent
335// calls to this function should return false after the kernel has been
336// already loaded).
337//----------------------------------------------------------------------
Greg Clayton374972e2011-07-09 17:15:55 +0000338void
Greg Clayton944b8282011-08-22 22:30:57 +0000339DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
Greg Clayton7b242382011-07-08 00:48:09 +0000340{
Greg Claytond16e1e52011-07-12 17:06:17 +0000341 if (!m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000342 {
343 m_kernel.Clear(false);
344 m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000345
346 ConstString kernel_name("mach_kernel");
347 if (m_kernel.module_sp.get()
348 && m_kernel.module_sp->GetObjectFile()
349 && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
350 {
351 kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename();
352 }
353 strlcpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name));
354
Greg Claytonc859e2d2012-02-13 23:10:39 +0000355 if (m_kernel.address == LLDB_INVALID_ADDRESS)
Greg Clayton7b242382011-07-08 00:48:09 +0000356 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000357 m_kernel.address = m_process->GetImageInfoAddress ();
358 if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
Greg Clayton7b242382011-07-08 00:48:09 +0000359 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000360 // We didn't get a hint from the process, so we will
361 // try the kernel at the address that it exists at in
362 // the file if we have one
363 ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
364 if (kernel_object_file)
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000365 {
366 addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
367 addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
368 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
369 {
370 m_kernel.address = load_address;
371 if (load_address != file_address)
372 {
373 // Don't accidentally relocate the kernel to the File address --
374 // the Load address has already been set to its actual in-memory address.
375 // Mark it as IsLoaded.
376 m_kernel.load_process_stop_id = m_process->GetStopID();
377 }
378 }
379 else
380 {
381 m_kernel.address = file_address;
382 }
383 }
Greg Clayton7b242382011-07-08 00:48:09 +0000384 }
385 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000386
387 if (m_kernel.address != LLDB_INVALID_ADDRESS)
Greg Clayton2af282a2012-03-21 04:25:00 +0000388 {
389 if (!m_kernel.LoadImageUsingMemoryModule (m_process))
390 {
391 m_kernel.LoadImageAtFileAddress (m_process);
392 }
393 }
Greg Clayton7b242382011-07-08 00:48:09 +0000394
Greg Claytonc859e2d2012-02-13 23:10:39 +0000395 if (m_kernel.IsLoaded())
Greg Clayton7b242382011-07-08 00:48:09 +0000396 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000397 static ConstString kext_summary_symbol ("gLoadedKextSummaries");
398 const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
399 if (symbol)
400 {
Greg Claytone7612132012-03-07 21:03:09 +0000401 m_kext_summary_header_ptr_addr = symbol->GetAddress();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000402 // Update all image infos
403 ReadAllKextSummaries ();
404 }
Greg Clayton7b242382011-07-08 00:48:09 +0000405 }
406 else
Greg Clayton7b242382011-07-08 00:48:09 +0000407 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000408 m_kernel.Clear(false);
Greg Clayton7b242382011-07-08 00:48:09 +0000409 }
410 }
Greg Clayton7b242382011-07-08 00:48:09 +0000411}
412
Greg Clayton7b242382011-07-08 00:48:09 +0000413//----------------------------------------------------------------------
414// Static callback function that gets called when our DYLD notification
415// breakpoint gets hit. We update all of our image infos and then
416// let our super class DynamicLoader class decide if we should stop
417// or not (based on global preference).
418//----------------------------------------------------------------------
419bool
Greg Clayton944b8282011-08-22 22:30:57 +0000420DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton,
Greg Clayton374972e2011-07-09 17:15:55 +0000421 StoppointCallbackContext *context,
422 user_id_t break_id,
423 user_id_t break_loc_id)
Greg Clayton0d9fc762011-07-08 03:21:57 +0000424{
Greg Clayton944b8282011-08-22 22:30:57 +0000425 return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000426}
427
428bool
Greg Clayton944b8282011-08-22 22:30:57 +0000429DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context,
Greg Clayton374972e2011-07-09 17:15:55 +0000430 user_id_t break_id,
431 user_id_t break_loc_id)
432{
Greg Claytond16e1e52011-07-12 17:06:17 +0000433 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
434 if (log)
Greg Clayton944b8282011-08-22 22:30:57 +0000435 log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
Greg Claytond16e1e52011-07-12 17:06:17 +0000436
Greg Clayton374972e2011-07-09 17:15:55 +0000437 ReadAllKextSummaries ();
Greg Claytond16e1e52011-07-12 17:06:17 +0000438
439 if (log)
440 PutToLog(log.get());
441
Greg Clayton374972e2011-07-09 17:15:55 +0000442 return GetStopWhenImagesChange();
443}
444
445
446bool
Greg Clayton944b8282011-08-22 22:30:57 +0000447DynamicLoaderDarwinKernel::ReadKextSummaryHeader ()
Greg Clayton7b242382011-07-08 00:48:09 +0000448{
449 Mutex::Locker locker(m_mutex);
450
451 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +0000452
453 m_kext_summaries.clear();
Greg Claytond16e1e52011-07-12 17:06:17 +0000454 if (m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000455 {
456 const uint32_t addr_size = m_kernel.GetAddressByteSize ();
457 const ByteOrder byte_order = m_kernel.GetByteOrder();
458 Error error;
459 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
460 // which is currenty 4 uint32_t and a pointer.
461 uint8_t buf[24];
462 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
463 const size_t count = 4 * sizeof(uint32_t) + addr_size;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000464 const bool prefer_file_cache = false;
Greg Claytond16e1e52011-07-12 17:06:17 +0000465 if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
466 prefer_file_cache,
467 error,
468 m_kext_summary_header_addr))
Greg Clayton7b242382011-07-08 00:48:09 +0000469 {
Greg Claytond16e1e52011-07-12 17:06:17 +0000470 // We got a valid address for our kext summary header and make sure it isn't NULL
471 if (m_kext_summary_header_addr.IsValid() &&
472 m_kext_summary_header_addr.GetFileAddress() != 0)
473 {
474 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
475 if (bytes_read == count)
476 {
477 uint32_t offset = 0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000478 m_kext_summary_header.version = data.GetU32(&offset);
479 if (m_kext_summary_header.version >= 2)
480 {
481 m_kext_summary_header.entry_size = data.GetU32(&offset);
482 }
483 else
484 {
485 // Versions less than 2 didn't have an entry size, it was hard coded
486 m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
487 }
488 m_kext_summary_header.entry_count = data.GetU32(&offset);
Greg Claytond16e1e52011-07-12 17:06:17 +0000489 return true;
490 }
491 }
Greg Clayton7b242382011-07-08 00:48:09 +0000492 }
493 }
Greg Claytond16e1e52011-07-12 17:06:17 +0000494 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000495 return false;
496}
497
498
499bool
Greg Clayton944b8282011-08-22 22:30:57 +0000500DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
Greg Clayton0d9fc762011-07-08 03:21:57 +0000501 uint32_t count)
Greg Clayton7b242382011-07-08 00:48:09 +0000502{
503 OSKextLoadedKextSummary::collection kext_summaries;
Greg Clayton374972e2011-07-09 17:15:55 +0000504 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000505 if (log)
Jason Molendafd54b362011-09-20 21:44:10 +0000506 log->Printf ("Adding %d modules.\n", count);
Greg Clayton7b242382011-07-08 00:48:09 +0000507
508 Mutex::Locker locker(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000509
510 if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
511 return false;
512
Greg Clayton07e66e32011-07-20 03:41:06 +0000513 Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
Greg Clayton7b242382011-07-08 00:48:09 +0000514 for (uint32_t i = 0; i < count; i++)
515 {
Greg Clayton07e66e32011-07-20 03:41:06 +0000516 if (s)
517 {
518 const uint8_t *u = (const uint8_t *)kext_summaries[i].uuid.GetBytes();
519 if (u)
520 {
Jason Molenda0ca4f8b2011-09-24 02:47:39 +0000521 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\"...",
Greg Clayton07e66e32011-07-20 03:41:06 +0000522 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
523 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
524 kext_summaries[i].address, kext_summaries[i].name);
525 }
526 else
527 {
Jason Molenda0ca4f8b2011-09-24 02:47:39 +0000528 s->Printf("0x%16.16llx \"%s\"...", kext_summaries[i].address, kext_summaries[i].name);
Greg Clayton07e66e32011-07-20 03:41:06 +0000529 }
530 }
531
Greg Clayton2af282a2012-03-21 04:25:00 +0000532 if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
533 kext_summaries[i].LoadImageAtFileAddress (m_process);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000534
Greg Clayton5b882162011-07-21 01:12:01 +0000535 if (s)
536 {
537 if (kext_summaries[i].module_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000538 {
539 if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory())
540 s->Printf("\n found kext: %s/%s\n",
541 kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(),
542 kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
543 else
544 s->Printf("\n found kext: %s\n",
545 kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
546 }
Jason Molenda0ca4f8b2011-09-24 02:47:39 +0000547 else
548 s->Printf (" failed to locate/load.\n");
Greg Clayton5b882162011-07-21 01:12:01 +0000549 }
550
Greg Claytona63d08c2011-07-19 03:57:15 +0000551 if (log)
552 kext_summaries[i].PutToLog (log.get());
Greg Clayton7b242382011-07-08 00:48:09 +0000553 }
554 bool return_value = AddModulesUsingImageInfos (kext_summaries);
Greg Clayton7b242382011-07-08 00:48:09 +0000555 return return_value;
556}
557
558// Adds the modules in image_infos to m_kext_summaries.
559// NB don't call this passing in m_kext_summaries.
560
561bool
Greg Clayton944b8282011-08-22 22:30:57 +0000562DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
Greg Clayton7b242382011-07-08 00:48:09 +0000563{
564 // Now add these images to the main list.
565 ModuleList loaded_module_list;
Greg Clayton7b242382011-07-08 00:48:09 +0000566
567 for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
568 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000569 OSKextLoadedKextSummary &image_info = image_infos[idx];
570 m_kext_summaries.push_back(image_info);
Greg Clayton7b242382011-07-08 00:48:09 +0000571
Greg Claytonc859e2d2012-02-13 23:10:39 +0000572 if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
573 loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
Greg Clayton7b242382011-07-08 00:48:09 +0000574 }
575
576 if (loaded_module_list.GetSize() > 0)
577 {
Greg Clayton7b242382011-07-08 00:48:09 +0000578 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
579 }
580 return true;
581}
582
Greg Clayton7b242382011-07-08 00:48:09 +0000583
584uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000585DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000586 uint32_t image_infos_count,
587 OSKextLoadedKextSummary::collection &image_infos)
588{
589 const ByteOrder endian = m_kernel.GetByteOrder();
590 const uint32_t addr_size = m_kernel.GetAddressByteSize();
591
592 image_infos.resize(image_infos_count);
593 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
594 DataBufferHeap data(count, 0);
595 Error error;
Greg Clayton5b882162011-07-21 01:12:01 +0000596
597 Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
598
599 if (s)
600 s->Printf ("Reading %u kext summaries...\n", image_infos_count);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000601 const bool prefer_file_cache = false;
602 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
603 prefer_file_cache,
604 data.GetBytes(),
605 data.GetByteSize(),
606 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000607 if (bytes_read == count)
608 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000609
Greg Clayton7b242382011-07-08 00:48:09 +0000610 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
611 uint32_t i=0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000612 for (uint32_t kext_summary_offset = 0;
613 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
614 ++i, kext_summary_offset += m_kext_summary_header.entry_size)
Greg Clayton7b242382011-07-08 00:48:09 +0000615 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000616 uint32_t offset = kext_summary_offset;
Greg Clayton7b242382011-07-08 00:48:09 +0000617 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
618 if (name_data == NULL)
619 break;
620 memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
621 image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
622 image_infos[i].address = extractor.GetU64(&offset);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000623 if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
624 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
Greg Clayton7b242382011-07-08 00:48:09 +0000625 image_infos[i].size = extractor.GetU64(&offset);
626 image_infos[i].version = extractor.GetU64(&offset);
627 image_infos[i].load_tag = extractor.GetU32(&offset);
628 image_infos[i].flags = extractor.GetU32(&offset);
Greg Claytona63d08c2011-07-19 03:57:15 +0000629 if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
630 {
631 image_infos[i].reference_list = extractor.GetU64(&offset);
632 }
633 else
634 {
635 image_infos[i].reference_list = 0;
636 }
Greg Claytonbae2f2f2012-02-14 00:14:24 +0000637// 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",
638// i,
639// KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data,
640// image_infos[i].address,
641// image_infos[i].size,
642// image_infos[i].version,
643// image_infos[i].load_tag,
644// image_infos[i].flags);
Greg Clayton7b242382011-07-08 00:48:09 +0000645 }
646 if (i < image_infos.size())
647 image_infos.resize(i);
648 }
649 else
650 {
651 image_infos.clear();
652 }
653 return image_infos.size();
654}
655
656bool
Greg Clayton944b8282011-08-22 22:30:57 +0000657DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
Greg Clayton7b242382011-07-08 00:48:09 +0000658{
Greg Clayton374972e2011-07-09 17:15:55 +0000659 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000660
661 Mutex::Locker locker(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +0000662
Greg Clayton7b242382011-07-08 00:48:09 +0000663 if (ReadKextSummaryHeader ())
664 {
Greg Clayton374972e2011-07-09 17:15:55 +0000665 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000666 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000667 Address summary_addr (m_kext_summary_header_addr);
Greg Claytona63d08c2011-07-19 03:57:15 +0000668 summary_addr.Slide(m_kext_summary_header.GetSize());
Greg Clayton0d9fc762011-07-08 03:21:57 +0000669 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
Greg Clayton7b242382011-07-08 00:48:09 +0000670 {
Greg Clayton7b242382011-07-08 00:48:09 +0000671 m_kext_summaries.clear();
672 }
673 return true;
674 }
675 }
676 return false;
677}
678
679//----------------------------------------------------------------------
Greg Clayton7b242382011-07-08 00:48:09 +0000680// Dump an image info structure to the file handle provided.
681//----------------------------------------------------------------------
682void
Greg Clayton944b8282011-08-22 22:30:57 +0000683DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000684{
685 if (log == NULL)
686 return;
Greg Clayton07e66e32011-07-20 03:41:06 +0000687 const uint8_t *u = (uint8_t *)uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +0000688
689 if (address == LLDB_INVALID_ADDRESS)
690 {
691 if (u)
692 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000693 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 +0000694 u[ 0], u[ 1], u[ 2], u[ 3],
695 u[ 4], u[ 5], u[ 6], u[ 7],
696 u[ 8], u[ 9], u[10], u[11],
697 u[12], u[13], u[14], u[15],
698 name);
699 }
700 else
Greg Claytona63d08c2011-07-19 03:57:15 +0000701 log->Printf("\tname=\"%s\" (UNLOADED)", name);
Greg Clayton7b242382011-07-08 00:48:09 +0000702 }
703 else
704 {
705 if (u)
706 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000707 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\"",
708 address, size, version, load_tag, flags, reference_list,
709 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
710 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
Greg Clayton7b242382011-07-08 00:48:09 +0000711 name);
712 }
713 else
714 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000715 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\"",
716 address, address+size, version, load_tag, flags, reference_list,
717 name);
Greg Clayton7b242382011-07-08 00:48:09 +0000718 }
Greg Clayton7b242382011-07-08 00:48:09 +0000719 }
720}
721
722//----------------------------------------------------------------------
723// Dump the _dyld_all_image_infos members and all current image infos
724// that we have parsed to the file handle provided.
725//----------------------------------------------------------------------
726void
Greg Clayton944b8282011-08-22 22:30:57 +0000727DynamicLoaderDarwinKernel::PutToLog(Log *log) const
Greg Clayton7b242382011-07-08 00:48:09 +0000728{
729 if (log == NULL)
730 return;
731
732 Mutex::Locker locker(m_mutex);
Greg Claytona63d08c2011-07-19 03:57:15 +0000733 log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
Greg Clayton0d9fc762011-07-08 03:21:57 +0000734 m_kext_summary_header_addr.GetFileAddress(),
Greg Clayton7b242382011-07-08 00:48:09 +0000735 m_kext_summary_header.version,
736 m_kext_summary_header.entry_size,
Greg Claytona63d08c2011-07-19 03:57:15 +0000737 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +0000738
739 size_t i;
740 const size_t count = m_kext_summaries.size();
741 if (count > 0)
742 {
743 log->PutCString("Loaded:");
744 for (i = 0; i<count; i++)
745 m_kext_summaries[i].PutToLog(log);
746 }
747}
748
749void
Greg Clayton944b8282011-08-22 22:30:57 +0000750DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
Greg Clayton7b242382011-07-08 00:48:09 +0000751{
Greg Clayton944b8282011-08-22 22:30:57 +0000752 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton7b242382011-07-08 00:48:09 +0000753 Clear(true);
754 m_process = process;
Greg Clayton7b242382011-07-08 00:48:09 +0000755}
756
Greg Clayton374972e2011-07-09 17:15:55 +0000757void
Greg Clayton944b8282011-08-22 22:30:57 +0000758DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
Greg Clayton7b242382011-07-08 00:48:09 +0000759{
Greg Claytonc859e2d2012-02-13 23:10:39 +0000760 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
Greg Clayton374972e2011-07-09 17:15:55 +0000761 {
Greg Clayton944b8282011-08-22 22:30:57 +0000762 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
Greg Clayton374972e2011-07-09 17:15:55 +0000763
Greg Claytond16e1e52011-07-12 17:06:17 +0000764
Jim Inghama8558b62012-05-22 00:12:20 +0000765 const bool internal_bp = true;
Greg Claytond16e1e52011-07-12 17:06:17 +0000766 const LazyBool skip_prologue = eLazyBoolNo;
Jim Ingham969795f2011-09-21 01:17:13 +0000767 FileSpecList module_spec_list;
768 module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
769 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
Jim Ingham87df91b2011-09-23 00:54:11 +0000770 NULL,
Greg Clayton374972e2011-07-09 17:15:55 +0000771 "OSKextLoadedKextSummariesUpdated",
772 eFunctionNameTypeFull,
Jim Inghama8558b62012-05-22 00:12:20 +0000773 skip_prologue,
774 internal_bp).get();
Greg Clayton374972e2011-07-09 17:15:55 +0000775
Greg Clayton944b8282011-08-22 22:30:57 +0000776 bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true);
Greg Clayton374972e2011-07-09 17:15:55 +0000777 m_break_id = bp->GetID();
778 }
Greg Clayton7b242382011-07-08 00:48:09 +0000779}
780
781//----------------------------------------------------------------------
782// Member function that gets called when the process state changes.
783//----------------------------------------------------------------------
784void
Greg Clayton944b8282011-08-22 22:30:57 +0000785DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state)
Greg Clayton7b242382011-07-08 00:48:09 +0000786{
Greg Clayton944b8282011-08-22 22:30:57 +0000787 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
Greg Clayton7b242382011-07-08 00:48:09 +0000788 switch (state)
789 {
790 case eStateConnected:
791 case eStateAttaching:
792 case eStateLaunching:
793 case eStateInvalid:
794 case eStateUnloaded:
795 case eStateExited:
796 case eStateDetached:
797 Clear(false);
798 break;
799
800 case eStateStopped:
Greg Clayton374972e2011-07-09 17:15:55 +0000801 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000802 break;
803
804 case eStateRunning:
805 case eStateStepping:
806 case eStateCrashed:
807 case eStateSuspended:
808 break;
809
810 default:
811 break;
812 }
813}
814
815ThreadPlanSP
Greg Clayton944b8282011-08-22 22:30:57 +0000816DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
Greg Clayton7b242382011-07-08 00:48:09 +0000817{
818 ThreadPlanSP thread_plan_sp;
Greg Clayton374972e2011-07-09 17:15:55 +0000819 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
820 if (log)
821 log->Printf ("Could not find symbol for step through.");
Greg Clayton7b242382011-07-08 00:48:09 +0000822 return thread_plan_sp;
823}
824
825Error
Greg Clayton944b8282011-08-22 22:30:57 +0000826DynamicLoaderDarwinKernel::CanLoadImage ()
Greg Clayton7b242382011-07-08 00:48:09 +0000827{
828 Error error;
829 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
830 return error;
831}
832
833void
Greg Clayton944b8282011-08-22 22:30:57 +0000834DynamicLoaderDarwinKernel::Initialize()
Greg Clayton7b242382011-07-08 00:48:09 +0000835{
836 PluginManager::RegisterPlugin (GetPluginNameStatic(),
837 GetPluginDescriptionStatic(),
838 CreateInstance);
839}
840
841void
Greg Clayton944b8282011-08-22 22:30:57 +0000842DynamicLoaderDarwinKernel::Terminate()
Greg Clayton7b242382011-07-08 00:48:09 +0000843{
844 PluginManager::UnregisterPlugin (CreateInstance);
845}
846
847
848const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000849DynamicLoaderDarwinKernel::GetPluginNameStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000850{
851 return "dynamic-loader.macosx-kernel";
852}
853
854const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000855DynamicLoaderDarwinKernel::GetPluginDescriptionStatic()
Greg Clayton7b242382011-07-08 00:48:09 +0000856{
857 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
858}
859
860
861//------------------------------------------------------------------
862// PluginInterface protocol
863//------------------------------------------------------------------
864const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000865DynamicLoaderDarwinKernel::GetPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000866{
Greg Clayton944b8282011-08-22 22:30:57 +0000867 return "DynamicLoaderDarwinKernel";
Greg Clayton7b242382011-07-08 00:48:09 +0000868}
869
870const char *
Greg Clayton944b8282011-08-22 22:30:57 +0000871DynamicLoaderDarwinKernel::GetShortPluginName()
Greg Clayton7b242382011-07-08 00:48:09 +0000872{
873 return GetPluginNameStatic();
874}
875
876uint32_t
Greg Clayton944b8282011-08-22 22:30:57 +0000877DynamicLoaderDarwinKernel::GetPluginVersion()
Greg Clayton7b242382011-07-08 00:48:09 +0000878{
879 return 1;
880}
881
Greg Clayton1f746072012-08-29 21:13:06 +0000882lldb::ByteOrder
883DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic)
884{
885 switch (magic)
886 {
887 case llvm::MachO::HeaderMagic32:
888 case llvm::MachO::HeaderMagic64:
889 return lldb::endian::InlHostByteOrder();
890
891 case llvm::MachO::HeaderMagic32Swapped:
892 case llvm::MachO::HeaderMagic64Swapped:
893 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig)
894 return lldb::eByteOrderLittle;
895 else
896 return lldb::eByteOrderBig;
897
898 default:
899 break;
900 }
901 return lldb::eByteOrderInvalid;
902}
903