blob: d59600ce17388e0375ba73fd1cfe028b38ec6084 [file] [log] [blame]
Greg Clayton7b242382011-07-08 00:48:09 +00001//===-- DynamicLoaderMacOSXKernel.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Breakpoint/StoppointCallbackContext.h"
11#include "lldb/Core/DataBuffer.h"
12#include "lldb/Core/DataBufferHeap.h"
13#include "lldb/Core/Log.h"
14#include "lldb/Core/Module.h"
15#include "lldb/Core/PluginManager.h"
16#include "lldb/Core/State.h"
17#include "lldb/Symbol/ObjectFile.h"
18#include "lldb/Target/ObjCLanguageRuntime.h"
19#include "lldb/Target/RegisterContext.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Target/Thread.h"
22#include "lldb/Target/ThreadPlanRunToAddress.h"
23#include "lldb/Target/StackFrame.h"
24
25#include "DynamicLoaderMacOSXKernel.h"
26
27//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
28#ifdef ENABLE_DEBUG_PRINTF
29#include <stdio.h>
30#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
31#else
32#define DEBUG_PRINTF(fmt, ...)
33#endif
34
35using namespace lldb;
36using namespace lldb_private;
37
38/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
39/// I am putting it here so I can invoke it in the Trampoline code here, but
40/// it should be moved to the ObjC Runtime support when it is set up.
41
42
43//----------------------------------------------------------------------
44// Create an instance of this class. This function is filled into
45// the plugin info class that gets handed out by the plugin factory and
46// allows the lldb to instantiate an instance of this class.
47//----------------------------------------------------------------------
48DynamicLoader *
49DynamicLoaderMacOSXKernel::CreateInstance (Process* process, bool force)
50{
51 bool create = force;
52 if (!create)
53 {
Greg Claytondf0b7d52011-07-08 04:11:42 +000054 Module* exe_module = process->GetTarget().GetExecutableModule().get();
55 if (exe_module)
56 {
57 ObjectFile *object_file = exe_module->GetObjectFile();
58 if (object_file)
59 {
60 SectionList *section_list = object_file->GetSectionList();
61 if (section_list)
62 {
63 static ConstString g_kld_section_name ("__KLD");
64 if (section_list->FindSectionByName (g_kld_section_name))
65 {
66 create = true;
67 }
68 }
69 }
70 }
71
72 if (create)
73 {
74 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
75 create = triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple;
76 }
Greg Clayton7b242382011-07-08 00:48:09 +000077 }
78
79 if (create)
80 return new DynamicLoaderMacOSXKernel (process);
81 return NULL;
82}
83
84//----------------------------------------------------------------------
85// Constructor
86//----------------------------------------------------------------------
87DynamicLoaderMacOSXKernel::DynamicLoaderMacOSXKernel (Process* process) :
88 DynamicLoader(process),
89 m_kernel(),
Greg Claytond16e1e52011-07-12 17:06:17 +000090 m_kext_summary_header_ptr_addr (),
Greg Clayton0d9fc762011-07-08 03:21:57 +000091 m_kext_summary_header_addr (),
Greg Clayton7b242382011-07-08 00:48:09 +000092 m_kext_summary_header (),
Greg Clayton7b242382011-07-08 00:48:09 +000093 m_break_id (LLDB_INVALID_BREAK_ID),
94 m_kext_summaries(),
Greg Clayton374972e2011-07-09 17:15:55 +000095 m_mutex(Mutex::eMutexTypeRecursive)
Greg Clayton7b242382011-07-08 00:48:09 +000096{
97}
98
99//----------------------------------------------------------------------
100// Destructor
101//----------------------------------------------------------------------
102DynamicLoaderMacOSXKernel::~DynamicLoaderMacOSXKernel()
103{
104 Clear(true);
105}
106
Greg Clayton374972e2011-07-09 17:15:55 +0000107void
108DynamicLoaderMacOSXKernel::UpdateIfNeeded()
109{
110 LoadKernelModuleIfNeeded();
111 SetNotificationBreakpointIfNeeded ();
112}
Greg Clayton7b242382011-07-08 00:48:09 +0000113//------------------------------------------------------------------
114/// Called after attaching a process.
115///
116/// Allow DynamicLoader plug-ins to execute some code after
117/// attaching to a process.
118//------------------------------------------------------------------
119void
120DynamicLoaderMacOSXKernel::DidAttach ()
121{
122 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000123 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000124}
125
126//------------------------------------------------------------------
127/// Called after attaching a process.
128///
129/// Allow DynamicLoader plug-ins to execute some code after
130/// attaching to a process.
131//------------------------------------------------------------------
132void
133DynamicLoaderMacOSXKernel::DidLaunch ()
134{
135 PrivateInitialize(m_process);
Greg Clayton374972e2011-07-09 17:15:55 +0000136 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000137}
138
139
140//----------------------------------------------------------------------
141// Clear out the state of this class.
142//----------------------------------------------------------------------
143void
144DynamicLoaderMacOSXKernel::Clear (bool clear_process)
145{
146 Mutex::Locker locker(m_mutex);
147
148 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
149 m_process->ClearBreakpointSiteByID(m_break_id);
150
151 if (clear_process)
152 m_process = NULL;
153 m_kernel.Clear(false);
Greg Claytond16e1e52011-07-12 17:06:17 +0000154 m_kext_summary_header_ptr_addr.Clear();
Greg Clayton0d9fc762011-07-08 03:21:57 +0000155 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000156 m_kext_summaries.clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000157 m_break_id = LLDB_INVALID_BREAK_ID;
158}
159
Greg Clayton7b242382011-07-08 00:48:09 +0000160
161//----------------------------------------------------------------------
162// Load the kernel module and initialize the "m_kernel" member. Return
163// true _only_ if the kernel is loaded the first time through (subsequent
164// calls to this function should return false after the kernel has been
165// already loaded).
166//----------------------------------------------------------------------
Greg Clayton374972e2011-07-09 17:15:55 +0000167void
168DynamicLoaderMacOSXKernel::LoadKernelModuleIfNeeded()
Greg Clayton7b242382011-07-08 00:48:09 +0000169{
Greg Claytond16e1e52011-07-12 17:06:17 +0000170 if (!m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000171 {
172 m_kernel.Clear(false);
173 m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
174 if (m_kernel.module_sp)
175 {
176 static ConstString mach_header_name ("_mh_execute_header");
Greg Claytondf0b7d52011-07-08 04:11:42 +0000177 static ConstString kext_summary_symbol ("gLoadedKextSummaries");
178 const Symbol *symbol = NULL;
179 symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
180 if (symbol)
Greg Claytond16e1e52011-07-12 17:06:17 +0000181 m_kext_summary_header_ptr_addr = symbol->GetValue();
Greg Claytondf0b7d52011-07-08 04:11:42 +0000182
183 symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (mach_header_name, eSymbolTypeAbsolute);
Greg Clayton7b242382011-07-08 00:48:09 +0000184 if (symbol)
185 {
Greg Claytondf0b7d52011-07-08 04:11:42 +0000186 // The "_mh_execute_header" symbol is absolute and not a section based
187 // symbol that will have a valid address, so we need to resolve it...
188 m_process->GetTarget().GetImages().ResolveFileAddress (symbol->GetValue().GetFileAddress(), m_kernel.so_address);
Greg Clayton7b242382011-07-08 00:48:09 +0000189 DataExtractor data; // Load command data
Greg Clayton0d9fc762011-07-08 03:21:57 +0000190 if (ReadMachHeader (m_kernel, &data))
Greg Clayton7b242382011-07-08 00:48:09 +0000191 {
Greg Claytondf0b7d52011-07-08 04:11:42 +0000192 if (m_kernel.header.filetype == llvm::MachO::HeaderFileTypeExecutable)
Greg Clayton7b242382011-07-08 00:48:09 +0000193 {
194 if (ParseLoadCommands (data, m_kernel))
195 UpdateImageLoadAddress (m_kernel);
196
197 // Update all image infos
Greg Clayton374972e2011-07-09 17:15:55 +0000198 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000199 }
200 }
201 else
202 {
203 m_kernel.Clear(false);
204 }
Greg Clayton7b242382011-07-08 00:48:09 +0000205 }
206 }
207 }
Greg Clayton7b242382011-07-08 00:48:09 +0000208}
209
210bool
211DynamicLoaderMacOSXKernel::FindTargetModule (OSKextLoadedKextSummary &image_info, bool can_create, bool *did_create_ptr)
212{
213 if (did_create_ptr)
214 *did_create_ptr = false;
215
216 const bool image_info_uuid_is_valid = image_info.uuid.IsValid();
217
218 if (image_info.module_sp)
219 {
220 if (image_info_uuid_is_valid)
221 {
222 if (image_info.module_sp->GetUUID() == image_info.uuid)
223 return true;
224 else
225 image_info.module_sp.reset();
226 }
227 else
228 return true;
229 }
230
231 ModuleList &target_images = m_process->GetTarget().GetImages();
232 if (image_info_uuid_is_valid)
233 image_info.module_sp = target_images.FindModule(image_info.uuid);
234
235 if (image_info.module_sp)
236 return true;
237
238 ArchSpec arch (image_info.GetArchitecture ());
239 if (can_create)
240 {
241 if (image_info_uuid_is_valid)
242 {
243 image_info.module_sp = m_process->GetTarget().GetSharedModule (FileSpec(),
Greg Claytona63d08c2011-07-19 03:57:15 +0000244 arch,
245 &image_info.uuid);
Greg Clayton7b242382011-07-08 00:48:09 +0000246 if (did_create_ptr)
247 *did_create_ptr = image_info.module_sp;
248 }
249 }
250 return image_info.module_sp;
251}
252
253bool
254DynamicLoaderMacOSXKernel::UpdateCommPageLoadAddress(Module *module)
255{
256 bool changed = false;
257 if (module)
258 {
259 ObjectFile *image_object_file = module->GetObjectFile();
260 if (image_object_file)
261 {
262 SectionList *section_list = image_object_file->GetSectionList ();
263 if (section_list)
264 {
265 uint32_t num_sections = section_list->GetSize();
266 for (uint32_t i=0; i<num_sections; ++i)
267 {
268 Section* section = section_list->GetSectionAtIndex (i).get();
269 if (section)
270 {
271 const addr_t new_section_load_addr = section->GetFileAddress ();
272 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
273 if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
274 old_section_load_addr != new_section_load_addr)
275 {
276 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
277 changed = true;
278 }
279 }
280 }
281 }
282 }
283 }
284 return changed;
285}
286
287//----------------------------------------------------------------------
288// Update the load addresses for all segments in MODULE using the
289// updated INFO that is passed in.
290//----------------------------------------------------------------------
291bool
292DynamicLoaderMacOSXKernel::UpdateImageLoadAddress (OSKextLoadedKextSummary& info)
293{
294 Module *module = info.module_sp.get();
295 bool changed = false;
296 if (module)
297 {
298 ObjectFile *image_object_file = module->GetObjectFile();
299 if (image_object_file)
300 {
301 SectionList *section_list = image_object_file->GetSectionList ();
302 if (section_list)
303 {
304 // We now know the slide amount, so go through all sections
305 // and update the load addresses with the correct values.
306 uint32_t num_segments = info.segments.size();
307 for (uint32_t i=0; i<num_segments; ++i)
308 {
Greg Clayton7b242382011-07-08 00:48:09 +0000309 const addr_t new_section_load_addr = info.segments[i].vmaddr;
Greg Claytona63d08c2011-07-19 03:57:15 +0000310 if (section_list->FindSectionByName(info.segments[i].name))
Greg Clayton7b242382011-07-08 00:48:09 +0000311 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000312 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
313 if (section_sp)
Greg Clayton7b242382011-07-08 00:48:09 +0000314 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000315 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
316 if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
317 old_section_load_addr != new_section_load_addr)
318 {
319 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
320 changed = true;
321 }
322 }
323 else
324 {
325 fprintf (stderr,
326 "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
327 info.segments[i].name.AsCString("<invalid>"),
328 (uint64_t)new_section_load_addr,
329 image_object_file->GetFileSpec().GetDirectory().AsCString(),
330 image_object_file->GetFileSpec().GetFilename().AsCString());
Greg Clayton7b242382011-07-08 00:48:09 +0000331 }
332 }
333 else
334 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000335 // The segment name is empty which means this is a .o file.
336 // Object files in LLDB end up getting reorganized so that
337 // the segment name that is in the section is promoted into
338 // an actual segment, so we just need to go through all sections
339 // and slide them by a single amount.
340
341 uint32_t num_sections = section_list->GetSize();
342 for (uint32_t i=0; i<num_sections; ++i)
343 {
344 Section* section = section_list->GetSectionAtIndex (i).get();
345 if (section)
346 {
347 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + new_section_load_addr))
348 changed = true;
349 }
350 }
Greg Clayton7b242382011-07-08 00:48:09 +0000351 }
352 }
353 }
354 }
355 }
356 return changed;
357}
358
359//----------------------------------------------------------------------
360// Update the load addresses for all segments in MODULE using the
361// updated INFO that is passed in.
362//----------------------------------------------------------------------
363bool
364DynamicLoaderMacOSXKernel::UnloadImageLoadAddress (OSKextLoadedKextSummary& info)
365{
366 Module *module = info.module_sp.get();
367 bool changed = false;
368 if (module)
369 {
370 ObjectFile *image_object_file = module->GetObjectFile();
371 if (image_object_file)
372 {
373 SectionList *section_list = image_object_file->GetSectionList ();
374 if (section_list)
375 {
376 uint32_t num_segments = info.segments.size();
377 for (uint32_t i=0; i<num_segments; ++i)
378 {
379 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
380 if (section_sp)
381 {
382 const addr_t old_section_load_addr = info.segments[i].vmaddr;
383 if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
384 changed = true;
385 }
386 else
387 {
388 fprintf (stderr,
389 "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n",
390 info.segments[i].name.AsCString("<invalid>"),
391 image_object_file->GetFileSpec().GetDirectory().AsCString(),
392 image_object_file->GetFileSpec().GetFilename().AsCString());
393 }
394 }
395 }
396 }
397 }
398 return changed;
399}
400
401
402//----------------------------------------------------------------------
403// Static callback function that gets called when our DYLD notification
404// breakpoint gets hit. We update all of our image infos and then
405// let our super class DynamicLoader class decide if we should stop
406// or not (based on global preference).
407//----------------------------------------------------------------------
408bool
Greg Clayton374972e2011-07-09 17:15:55 +0000409DynamicLoaderMacOSXKernel::BreakpointHitCallback (void *baton,
410 StoppointCallbackContext *context,
411 user_id_t break_id,
412 user_id_t break_loc_id)
Greg Clayton0d9fc762011-07-08 03:21:57 +0000413{
Greg Clayton374972e2011-07-09 17:15:55 +0000414 return static_cast<DynamicLoaderMacOSXKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000415}
416
417bool
Greg Clayton374972e2011-07-09 17:15:55 +0000418DynamicLoaderMacOSXKernel::BreakpointHit (StoppointCallbackContext *context,
419 user_id_t break_id,
420 user_id_t break_loc_id)
421{
Greg Claytond16e1e52011-07-12 17:06:17 +0000422 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
423 if (log)
424 log->Printf ("DynamicLoaderMacOSXKernel::BreakpointHit (...)\n");
425
Greg Clayton374972e2011-07-09 17:15:55 +0000426 ReadAllKextSummaries ();
Greg Claytond16e1e52011-07-12 17:06:17 +0000427
428 if (log)
429 PutToLog(log.get());
430
Greg Clayton374972e2011-07-09 17:15:55 +0000431 return GetStopWhenImagesChange();
432}
433
434
435bool
Greg Clayton7b242382011-07-08 00:48:09 +0000436DynamicLoaderMacOSXKernel::ReadKextSummaryHeader ()
437{
438 Mutex::Locker locker(m_mutex);
439
440 // the all image infos is already valid for this process stop ID
Greg Clayton7b242382011-07-08 00:48:09 +0000441
442 m_kext_summaries.clear();
Greg Claytond16e1e52011-07-12 17:06:17 +0000443 if (m_kext_summary_header_ptr_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000444 {
445 const uint32_t addr_size = m_kernel.GetAddressByteSize ();
446 const ByteOrder byte_order = m_kernel.GetByteOrder();
447 Error error;
448 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure
449 // which is currenty 4 uint32_t and a pointer.
450 uint8_t buf[24];
451 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
452 const size_t count = 4 * sizeof(uint32_t) + addr_size;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000453 const bool prefer_file_cache = false;
Greg Claytond16e1e52011-07-12 17:06:17 +0000454 if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr,
455 prefer_file_cache,
456 error,
457 m_kext_summary_header_addr))
Greg Clayton7b242382011-07-08 00:48:09 +0000458 {
Greg Claytond16e1e52011-07-12 17:06:17 +0000459 // We got a valid address for our kext summary header and make sure it isn't NULL
460 if (m_kext_summary_header_addr.IsValid() &&
461 m_kext_summary_header_addr.GetFileAddress() != 0)
462 {
463 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
464 if (bytes_read == count)
465 {
466 uint32_t offset = 0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000467 m_kext_summary_header.version = data.GetU32(&offset);
468 if (m_kext_summary_header.version >= 2)
469 {
470 m_kext_summary_header.entry_size = data.GetU32(&offset);
471 }
472 else
473 {
474 // Versions less than 2 didn't have an entry size, it was hard coded
475 m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1;
476 }
477 m_kext_summary_header.entry_count = data.GetU32(&offset);
Greg Claytond16e1e52011-07-12 17:06:17 +0000478 return true;
479 }
480 }
Greg Clayton7b242382011-07-08 00:48:09 +0000481 }
482 }
Greg Claytond16e1e52011-07-12 17:06:17 +0000483 m_kext_summary_header_addr.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000484 return false;
485}
486
487
488bool
Greg Clayton374972e2011-07-09 17:15:55 +0000489DynamicLoaderMacOSXKernel::ParseKextSummaries (const Address &kext_summary_addr,
Greg Clayton0d9fc762011-07-08 03:21:57 +0000490 uint32_t count)
Greg Clayton7b242382011-07-08 00:48:09 +0000491{
492 OSKextLoadedKextSummary::collection kext_summaries;
Greg Clayton374972e2011-07-09 17:15:55 +0000493 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000494 if (log)
495 log->Printf ("Adding %d modules.\n");
496
497 Mutex::Locker locker(m_mutex);
Greg Clayton7b242382011-07-08 00:48:09 +0000498
499 if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
500 return false;
501
502 for (uint32_t i = 0; i < count; i++)
503 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000504 DataExtractor data; // Load command data
505 if (ReadMachHeader (kext_summaries[i], &data))
Greg Clayton7b242382011-07-08 00:48:09 +0000506 {
Greg Clayton7b242382011-07-08 00:48:09 +0000507 ParseLoadCommands (data, kext_summaries[i]);
508 }
Greg Claytona63d08c2011-07-19 03:57:15 +0000509
510 if (log)
511 kext_summaries[i].PutToLog (log.get());
Greg Clayton7b242382011-07-08 00:48:09 +0000512 }
513 bool return_value = AddModulesUsingImageInfos (kext_summaries);
Greg Clayton7b242382011-07-08 00:48:09 +0000514 return return_value;
515}
516
517// Adds the modules in image_infos to m_kext_summaries.
518// NB don't call this passing in m_kext_summaries.
519
520bool
521DynamicLoaderMacOSXKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
522{
523 // Now add these images to the main list.
524 ModuleList loaded_module_list;
Greg Clayton7b242382011-07-08 00:48:09 +0000525
526 for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
527 {
Greg Clayton7b242382011-07-08 00:48:09 +0000528 m_kext_summaries.push_back(image_infos[idx]);
529
530 if (FindTargetModule (image_infos[idx], true, NULL))
531 {
532 // UpdateImageLoadAddress will return true if any segments
533 // change load address. We need to check this so we don't
534 // mention that all loaded shared libraries are newly loaded
535 // each time we hit out dyld breakpoint since dyld will list all
536 // shared libraries each time.
537 if (UpdateImageLoadAddress (image_infos[idx]))
538 {
539 loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
540 }
541 }
542 }
543
544 if (loaded_module_list.GetSize() > 0)
545 {
546 // FIXME: This should really be in the Runtime handlers class, which should get
547 // called by the target's ModulesDidLoad, but we're doing it all locally for now
548 // to save time.
549 // Also, I'm assuming there can be only one libobjc dylib loaded...
550
551 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
552 if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
553 {
554 size_t num_modules = loaded_module_list.GetSize();
555 for (int i = 0; i < num_modules; i++)
556 {
557 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
558 {
559 objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
560 break;
561 }
562 }
563 }
Greg Claytond16e1e52011-07-12 17:06:17 +0000564// if (log)
565// loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXKernel::ModulesDidLoad");
Greg Clayton7b242382011-07-08 00:48:09 +0000566 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
567 }
568 return true;
569}
570
Greg Clayton7b242382011-07-08 00:48:09 +0000571
572uint32_t
Greg Clayton374972e2011-07-09 17:15:55 +0000573DynamicLoaderMacOSXKernel::ReadKextSummaries (const Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000574 uint32_t image_infos_count,
575 OSKextLoadedKextSummary::collection &image_infos)
576{
577 const ByteOrder endian = m_kernel.GetByteOrder();
578 const uint32_t addr_size = m_kernel.GetAddressByteSize();
579
580 image_infos.resize(image_infos_count);
581 const size_t count = image_infos.size() * m_kext_summary_header.entry_size;
582 DataBufferHeap data(count, 0);
583 Error error;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000584 const bool prefer_file_cache = false;
585 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr,
586 prefer_file_cache,
587 data.GetBytes(),
588 data.GetByteSize(),
589 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000590 if (bytes_read == count)
591 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000592
Greg Clayton7b242382011-07-08 00:48:09 +0000593 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
594 uint32_t i=0;
Greg Claytona63d08c2011-07-19 03:57:15 +0000595 for (uint32_t kext_summary_offset = 0;
596 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
597 ++i, kext_summary_offset += m_kext_summary_header.entry_size)
Greg Clayton7b242382011-07-08 00:48:09 +0000598 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000599 uint32_t offset = kext_summary_offset;
Greg Clayton7b242382011-07-08 00:48:09 +0000600 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
601 if (name_data == NULL)
602 break;
603 memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
604 image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
605 image_infos[i].address = extractor.GetU64(&offset);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000606 if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
607 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
Greg Clayton7b242382011-07-08 00:48:09 +0000608 image_infos[i].size = extractor.GetU64(&offset);
609 image_infos[i].version = extractor.GetU64(&offset);
610 image_infos[i].load_tag = extractor.GetU32(&offset);
611 image_infos[i].flags = extractor.GetU32(&offset);
Greg Claytona63d08c2011-07-19 03:57:15 +0000612 if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
613 {
614 image_infos[i].reference_list = extractor.GetU64(&offset);
615 }
616 else
617 {
618 image_infos[i].reference_list = 0;
619 }
Greg Clayton7b242382011-07-08 00:48:09 +0000620 }
621 if (i < image_infos.size())
622 image_infos.resize(i);
623 }
624 else
625 {
626 image_infos.clear();
627 }
628 return image_infos.size();
629}
630
631bool
Greg Clayton374972e2011-07-09 17:15:55 +0000632DynamicLoaderMacOSXKernel::ReadAllKextSummaries ()
Greg Clayton7b242382011-07-08 00:48:09 +0000633{
Greg Clayton374972e2011-07-09 17:15:55 +0000634 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton7b242382011-07-08 00:48:09 +0000635
636 Mutex::Locker locker(m_mutex);
Greg Clayton374972e2011-07-09 17:15:55 +0000637
Greg Clayton7b242382011-07-08 00:48:09 +0000638 if (ReadKextSummaryHeader ())
639 {
Greg Clayton374972e2011-07-09 17:15:55 +0000640 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid())
Greg Clayton7b242382011-07-08 00:48:09 +0000641 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000642 Address summary_addr (m_kext_summary_header_addr);
Greg Claytona63d08c2011-07-19 03:57:15 +0000643 summary_addr.Slide(m_kext_summary_header.GetSize());
Greg Clayton0d9fc762011-07-08 03:21:57 +0000644 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
Greg Clayton7b242382011-07-08 00:48:09 +0000645 {
Greg Clayton7b242382011-07-08 00:48:09 +0000646 m_kext_summaries.clear();
647 }
648 return true;
649 }
650 }
651 return false;
652}
653
654//----------------------------------------------------------------------
655// Read a mach_header at ADDR into HEADER, and also fill in the load
656// command data into LOAD_COMMAND_DATA if it is non-NULL.
657//
658// Returns true if we succeed, false if we fail for any reason.
659//----------------------------------------------------------------------
660bool
Greg Clayton0d9fc762011-07-08 03:21:57 +0000661DynamicLoaderMacOSXKernel::ReadMachHeader (OSKextLoadedKextSummary& kext_summary, DataExtractor *load_command_data)
Greg Clayton7b242382011-07-08 00:48:09 +0000662{
663 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
664 Error error;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000665 const bool prefer_file_cache = false;
666 size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary.so_address,
667 prefer_file_cache,
668 header_bytes.GetBytes(),
669 header_bytes.GetByteSize(),
670 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000671 if (bytes_read == sizeof(llvm::MachO::mach_header))
672 {
673 uint32_t offset = 0;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000674 ::memset (&kext_summary.header, 0, sizeof(kext_summary.header));
Greg Clayton7b242382011-07-08 00:48:09 +0000675
676 // Get the magic byte unswapped so we can figure out what we are dealing with
Greg Clayton374972e2011-07-09 17:15:55 +0000677 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000678 kext_summary.header.magic = data.GetU32(&offset);
679 Address load_cmd_addr = kext_summary.so_address;
680 data.SetByteOrder(DynamicLoaderMacOSXKernel::GetByteOrderFromMagic(kext_summary.header.magic));
681 switch (kext_summary.header.magic)
Greg Clayton7b242382011-07-08 00:48:09 +0000682 {
683 case llvm::MachO::HeaderMagic32:
684 case llvm::MachO::HeaderMagic32Swapped:
685 data.SetAddressByteSize(4);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000686 load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header));
Greg Clayton7b242382011-07-08 00:48:09 +0000687 break;
688
689 case llvm::MachO::HeaderMagic64:
690 case llvm::MachO::HeaderMagic64Swapped:
691 data.SetAddressByteSize(8);
Greg Clayton0d9fc762011-07-08 03:21:57 +0000692 load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header_64));
Greg Clayton7b242382011-07-08 00:48:09 +0000693 break;
694
695 default:
696 return false;
697 }
698
699 // Read the rest of dyld's mach header
Greg Clayton0d9fc762011-07-08 03:21:57 +0000700 if (data.GetU32(&offset, &kext_summary.header.cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
Greg Clayton7b242382011-07-08 00:48:09 +0000701 {
702 if (load_command_data == NULL)
703 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
704
Greg Clayton0d9fc762011-07-08 03:21:57 +0000705 DataBufferSP load_cmd_data_sp(new DataBufferHeap(kext_summary.header.sizeofcmds, 0));
Greg Clayton7b242382011-07-08 00:48:09 +0000706
Greg Clayton0d9fc762011-07-08 03:21:57 +0000707 size_t load_cmd_bytes_read = m_process->GetTarget().ReadMemory (load_cmd_addr,
708 prefer_file_cache,
709 load_cmd_data_sp->GetBytes(),
710 load_cmd_data_sp->GetByteSize(),
711 error);
Greg Clayton7b242382011-07-08 00:48:09 +0000712
Greg Clayton0d9fc762011-07-08 03:21:57 +0000713 if (load_cmd_bytes_read == kext_summary.header.sizeofcmds)
Greg Clayton7b242382011-07-08 00:48:09 +0000714 {
715 // Set the load command data and also set the correct endian
716 // swap settings and the correct address size
Greg Clayton0d9fc762011-07-08 03:21:57 +0000717 load_command_data->SetData(load_cmd_data_sp, 0, kext_summary.header.sizeofcmds);
Greg Clayton7b242382011-07-08 00:48:09 +0000718 load_command_data->SetByteOrder(data.GetByteOrder());
719 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
720 return true; // We successfully read the mach_header and the load command data
721 }
722
723 return false; // We weren't able to read the load command data
724 }
725 }
726 return false; // We failed the read the mach_header
727}
728
729
730//----------------------------------------------------------------------
731// Parse the load commands for an image
732//----------------------------------------------------------------------
733uint32_t
Greg Claytondf0b7d52011-07-08 04:11:42 +0000734DynamicLoaderMacOSXKernel::ParseLoadCommands (const DataExtractor& data, OSKextLoadedKextSummary& image_info)
Greg Clayton7b242382011-07-08 00:48:09 +0000735{
736 uint32_t offset = 0;
737 uint32_t cmd_idx;
738 Segment segment;
Greg Claytondf0b7d52011-07-08 04:11:42 +0000739 image_info.Clear (true);
Greg Clayton7b242382011-07-08 00:48:09 +0000740
Greg Claytondf0b7d52011-07-08 04:11:42 +0000741 for (cmd_idx = 0; cmd_idx < image_info.header.ncmds; cmd_idx++)
Greg Clayton7b242382011-07-08 00:48:09 +0000742 {
Greg Claytondf0b7d52011-07-08 04:11:42 +0000743 // Clear out any load command specific data from image_info since
Greg Clayton7b242382011-07-08 00:48:09 +0000744 // we are about to read it.
745
746 if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
747 {
748 llvm::MachO::load_command load_cmd;
749 uint32_t load_cmd_offset = offset;
750 load_cmd.cmd = data.GetU32 (&offset);
751 load_cmd.cmdsize = data.GetU32 (&offset);
752 switch (load_cmd.cmd)
753 {
754 case llvm::MachO::LoadCommandSegment32:
755 {
756 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
757 // We are putting 4 uint32_t values 4 uint64_t values so
758 // we have to use multiple 32 bit gets below.
759 segment.vmaddr = data.GetU32 (&offset);
760 segment.vmsize = data.GetU32 (&offset);
761 segment.fileoff = data.GetU32 (&offset);
762 segment.filesize = data.GetU32 (&offset);
763 // Extract maxprot, initprot, nsects and flags all at once
764 data.GetU32(&offset, &segment.maxprot, 4);
Greg Claytondf0b7d52011-07-08 04:11:42 +0000765 image_info.segments.push_back (segment);
Greg Clayton7b242382011-07-08 00:48:09 +0000766 }
767 break;
768
769 case llvm::MachO::LoadCommandSegment64:
770 {
771 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
772 // Extract vmaddr, vmsize, fileoff, and filesize all at once
773 data.GetU64(&offset, &segment.vmaddr, 4);
774 // Extract maxprot, initprot, nsects and flags all at once
775 data.GetU32(&offset, &segment.maxprot, 4);
Greg Claytondf0b7d52011-07-08 04:11:42 +0000776 image_info.segments.push_back (segment);
Greg Clayton7b242382011-07-08 00:48:09 +0000777 }
778 break;
779
780 case llvm::MachO::LoadCommandUUID:
Greg Claytondf0b7d52011-07-08 04:11:42 +0000781 image_info.uuid.SetBytes(data.GetData (&offset, 16));
Greg Clayton7b242382011-07-08 00:48:09 +0000782 break;
783
784 default:
785 break;
786 }
787 // Set offset to be the beginning of the next load command.
788 offset = load_cmd_offset + load_cmd.cmdsize;
789 }
790 }
791#if 0
792 // No slide in the kernel...
793
794 // All sections listed in the dyld image info structure will all
795 // either be fixed up already, or they will all be off by a single
796 // slide amount that is determined by finding the first segment
797 // that is at file offset zero which also has bytes (a file size
798 // that is greater than zero) in the object file.
799
800 // Determine the slide amount (if any)
Greg Claytondf0b7d52011-07-08 04:11:42 +0000801 const size_t num_sections = image_info.segments.size();
Greg Clayton7b242382011-07-08 00:48:09 +0000802 for (size_t i = 0; i < num_sections; ++i)
803 {
804 // Iterate through the object file sections to find the
805 // first section that starts of file offset zero and that
806 // has bytes in the file...
Greg Claytondf0b7d52011-07-08 04:11:42 +0000807 if (image_info.segments[i].fileoff == 0 && image_info.segments[i].filesize > 0)
Greg Clayton7b242382011-07-08 00:48:09 +0000808 {
Greg Claytondf0b7d52011-07-08 04:11:42 +0000809 image_info.slide = image_info.address - image_info.segments[i].vmaddr;
Greg Clayton7b242382011-07-08 00:48:09 +0000810 // We have found the slide amount, so we can exit
811 // this for loop.
812 break;
813 }
814 }
815#endif
Greg Claytondf0b7d52011-07-08 04:11:42 +0000816 if (image_info.uuid.IsValid())
817 {
818 bool did_create = false;
819 if (FindTargetModule(image_info, true, &did_create))
820 {
821 if (did_create)
822 image_info.module_create_stop_id = m_process->GetStopID();
823 }
824 }
Greg Clayton7b242382011-07-08 00:48:09 +0000825 return cmd_idx;
826}
827
828//----------------------------------------------------------------------
829// Dump a Segment to the file handle provided.
830//----------------------------------------------------------------------
831void
Greg Clayton374972e2011-07-09 17:15:55 +0000832DynamicLoaderMacOSXKernel::Segment::PutToLog (Log *log, addr_t slide) const
Greg Clayton7b242382011-07-08 00:48:09 +0000833{
834 if (log)
835 {
836 if (slide == 0)
837 log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)",
838 name.AsCString(""),
839 vmaddr + slide,
840 vmaddr + slide + vmsize);
841 else
842 log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx",
843 name.AsCString(""),
844 vmaddr + slide,
845 vmaddr + slide + vmsize,
846 slide);
847 }
848}
849
850const DynamicLoaderMacOSXKernel::Segment *
851DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::FindSegment (const ConstString &name) const
852{
853 const size_t num_segments = segments.size();
854 for (size_t i=0; i<num_segments; ++i)
855 {
856 if (segments[i].name == name)
857 return &segments[i];
858 }
859 return NULL;
860}
861
862
863//----------------------------------------------------------------------
864// Dump an image info structure to the file handle provided.
865//----------------------------------------------------------------------
866void
867DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
868{
869 if (log == NULL)
870 return;
871 uint8_t *u = (uint8_t *)uuid.GetBytes();
Greg Clayton7b242382011-07-08 00:48:09 +0000872
873 if (address == LLDB_INVALID_ADDRESS)
874 {
875 if (u)
876 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000877 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 +0000878 u[ 0], u[ 1], u[ 2], u[ 3],
879 u[ 4], u[ 5], u[ 6], u[ 7],
880 u[ 8], u[ 9], u[10], u[11],
881 u[12], u[13], u[14], u[15],
882 name);
883 }
884 else
Greg Claytona63d08c2011-07-19 03:57:15 +0000885 log->Printf("\tname=\"%s\" (UNLOADED)", name);
Greg Clayton7b242382011-07-08 00:48:09 +0000886 }
887 else
888 {
889 if (u)
890 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000891 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\"",
892 address, size, version, load_tag, flags, reference_list,
893 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
894 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
Greg Clayton7b242382011-07-08 00:48:09 +0000895 name);
896 }
897 else
898 {
Greg Claytona63d08c2011-07-19 03:57:15 +0000899 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\"",
900 address, address+size, version, load_tag, flags, reference_list,
901 name);
Greg Clayton7b242382011-07-08 00:48:09 +0000902 }
903 for (uint32_t i=0; i<segments.size(); ++i)
904 segments[i].PutToLog(log, 0);
905 }
906}
907
908//----------------------------------------------------------------------
909// Dump the _dyld_all_image_infos members and all current image infos
910// that we have parsed to the file handle provided.
911//----------------------------------------------------------------------
912void
913DynamicLoaderMacOSXKernel::PutToLog(Log *log) const
914{
915 if (log == NULL)
916 return;
917
918 Mutex::Locker locker(m_mutex);
Greg Claytona63d08c2011-07-19 03:57:15 +0000919 log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
Greg Clayton0d9fc762011-07-08 03:21:57 +0000920 m_kext_summary_header_addr.GetFileAddress(),
Greg Clayton7b242382011-07-08 00:48:09 +0000921 m_kext_summary_header.version,
922 m_kext_summary_header.entry_size,
Greg Claytona63d08c2011-07-19 03:57:15 +0000923 m_kext_summary_header.entry_count);
Greg Clayton7b242382011-07-08 00:48:09 +0000924
925 size_t i;
926 const size_t count = m_kext_summaries.size();
927 if (count > 0)
928 {
929 log->PutCString("Loaded:");
930 for (i = 0; i<count; i++)
931 m_kext_summaries[i].PutToLog(log);
932 }
933}
934
935void
936DynamicLoaderMacOSXKernel::PrivateInitialize(Process *process)
937{
938 DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
939 Clear(true);
940 m_process = process;
941 m_process->GetTarget().GetSectionLoadList().Clear();
942}
943
Greg Clayton374972e2011-07-09 17:15:55 +0000944void
945DynamicLoaderMacOSXKernel::SetNotificationBreakpointIfNeeded ()
Greg Clayton7b242382011-07-08 00:48:09 +0000946{
Greg Clayton374972e2011-07-09 17:15:55 +0000947 if (m_break_id == LLDB_INVALID_BREAK_ID)
948 {
949 DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
950
Greg Claytond16e1e52011-07-12 17:06:17 +0000951
Greg Clayton374972e2011-07-09 17:15:55 +0000952 const bool internal_bp = false;
Greg Claytond16e1e52011-07-12 17:06:17 +0000953 const LazyBool skip_prologue = eLazyBoolNo;
Greg Clayton374972e2011-07-09 17:15:55 +0000954 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&m_kernel.module_sp->GetFileSpec(),
955 "OSKextLoadedKextSummariesUpdated",
956 eFunctionNameTypeFull,
Greg Claytond16e1e52011-07-12 17:06:17 +0000957 internal_bp,
958 skip_prologue).get();
Greg Clayton374972e2011-07-09 17:15:55 +0000959
960 bp->SetCallback (DynamicLoaderMacOSXKernel::BreakpointHitCallback, this, true);
961 m_break_id = bp->GetID();
962 }
Greg Clayton7b242382011-07-08 00:48:09 +0000963}
964
965//----------------------------------------------------------------------
966// Member function that gets called when the process state changes.
967//----------------------------------------------------------------------
968void
969DynamicLoaderMacOSXKernel::PrivateProcessStateChanged (Process *process, StateType state)
970{
971 DEBUG_PRINTF("DynamicLoaderMacOSXKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state));
972 switch (state)
973 {
974 case eStateConnected:
975 case eStateAttaching:
976 case eStateLaunching:
977 case eStateInvalid:
978 case eStateUnloaded:
979 case eStateExited:
980 case eStateDetached:
981 Clear(false);
982 break;
983
984 case eStateStopped:
Greg Clayton374972e2011-07-09 17:15:55 +0000985 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +0000986 break;
987
988 case eStateRunning:
989 case eStateStepping:
990 case eStateCrashed:
991 case eStateSuspended:
992 break;
993
994 default:
995 break;
996 }
997}
998
999ThreadPlanSP
1000DynamicLoaderMacOSXKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1001{
1002 ThreadPlanSP thread_plan_sp;
Greg Clayton374972e2011-07-09 17:15:55 +00001003 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
1004 if (log)
1005 log->Printf ("Could not find symbol for step through.");
Greg Clayton7b242382011-07-08 00:48:09 +00001006 return thread_plan_sp;
1007}
1008
1009Error
1010DynamicLoaderMacOSXKernel::CanLoadImage ()
1011{
1012 Error error;
1013 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel");
1014 return error;
1015}
1016
1017void
1018DynamicLoaderMacOSXKernel::Initialize()
1019{
1020 PluginManager::RegisterPlugin (GetPluginNameStatic(),
1021 GetPluginDescriptionStatic(),
1022 CreateInstance);
1023}
1024
1025void
1026DynamicLoaderMacOSXKernel::Terminate()
1027{
1028 PluginManager::UnregisterPlugin (CreateInstance);
1029}
1030
1031
1032const char *
1033DynamicLoaderMacOSXKernel::GetPluginNameStatic()
1034{
1035 return "dynamic-loader.macosx-kernel";
1036}
1037
1038const char *
1039DynamicLoaderMacOSXKernel::GetPluginDescriptionStatic()
1040{
1041 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel.";
1042}
1043
1044
1045//------------------------------------------------------------------
1046// PluginInterface protocol
1047//------------------------------------------------------------------
1048const char *
1049DynamicLoaderMacOSXKernel::GetPluginName()
1050{
1051 return "DynamicLoaderMacOSXKernel";
1052}
1053
1054const char *
1055DynamicLoaderMacOSXKernel::GetShortPluginName()
1056{
1057 return GetPluginNameStatic();
1058}
1059
1060uint32_t
1061DynamicLoaderMacOSXKernel::GetPluginVersion()
1062{
1063 return 1;
1064}
1065