blob: 67958c97d79eccc49167c2ddc103fd331cf80a98 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- DynamicLoaderMacOSXDYLD.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"
Jim Inghamb66cd072010-09-28 01:25:32 +000018#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#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 "DynamicLoaderMacOSXDYLD.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026
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;
Greg Clayton1674b122010-07-21 22:12:05 +000037using namespace llvm::MachO;
Chris Lattner24943d22010-06-08 16:52:24 +000038
39/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
40/// I am putting it here so I can invoke it in the Trampoline code here, but
41/// it should be moved to the ObjC Runtime support when it is set up.
42
Greg Claytonab429022010-12-12 21:03:32 +000043
44DynamicLoaderMacOSXDYLD::DYLDImageInfo *
Greg Clayton0467c782011-02-04 18:53:10 +000045DynamicLoaderMacOSXDYLD::GetImageInfo (const FileSpec &file_spec, const lldb_private::UUID &uuid)
Greg Claytonab429022010-12-12 21:03:32 +000046{
47 DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
48 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
49 {
50 if (pos->uuid == uuid && pos->file_spec == file_spec)
51 return &(*pos);
52 }
53
54 if (m_dyld.uuid == uuid && m_dyld.file_spec == file_spec)
55 return &m_dyld;
56
57 return NULL;
58}
59
Chris Lattner24943d22010-06-08 16:52:24 +000060//----------------------------------------------------------------------
61// Create an instance of this class. This function is filled into
62// the plugin info class that gets handed out by the plugin factory and
63// allows the lldb to instantiate an instance of this class.
64//----------------------------------------------------------------------
65DynamicLoader *
Greg Clayton75c703d2011-02-16 04:46:07 +000066DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
Chris Lattner24943d22010-06-08 16:52:24 +000067{
Greg Clayton75c703d2011-02-16 04:46:07 +000068 bool create = force;
69 if (!create)
70 {
71 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
72 if (triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple)
73 create = true;
74 }
75
76 if (create)
77 return new DynamicLoaderMacOSXDYLD (process);
78 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000079}
80
81//----------------------------------------------------------------------
82// Constructor
83//----------------------------------------------------------------------
84DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
85 DynamicLoader(process),
86 m_dyld(),
87 m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
88 m_dyld_all_image_infos(),
Greg Clayton20d338f2010-11-18 05:57:03 +000089 m_dyld_all_image_infos_stop_id (UINT32_MAX),
Chris Lattner24943d22010-06-08 16:52:24 +000090 m_break_id(LLDB_INVALID_BREAK_ID),
91 m_dyld_image_infos(),
Greg Clayton20d338f2010-11-18 05:57:03 +000092 m_dyld_image_infos_stop_id (UINT32_MAX),
Jim Inghamb66cd072010-09-28 01:25:32 +000093 m_mutex(Mutex::eMutexTypeRecursive)
Chris Lattner24943d22010-06-08 16:52:24 +000094{
95}
96
97//----------------------------------------------------------------------
98// Destructor
99//----------------------------------------------------------------------
100DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
101{
102 Clear(true);
103}
104
105//------------------------------------------------------------------
106/// Called after attaching a process.
107///
108/// Allow DynamicLoader plug-ins to execute some code after
109/// attaching to a process.
110//------------------------------------------------------------------
111void
112DynamicLoaderMacOSXDYLD::DidAttach ()
113{
114 PrivateInitialize(m_process);
Greg Clayton20d338f2010-11-18 05:57:03 +0000115 LocateDYLD ();
Chris Lattner24943d22010-06-08 16:52:24 +0000116 SetNotificationBreakpoint ();
Chris Lattner24943d22010-06-08 16:52:24 +0000117}
118
119//------------------------------------------------------------------
120/// Called after attaching a process.
121///
122/// Allow DynamicLoader plug-ins to execute some code after
123/// attaching to a process.
124//------------------------------------------------------------------
125void
126DynamicLoaderMacOSXDYLD::DidLaunch ()
127{
128 PrivateInitialize(m_process);
Greg Clayton20d338f2010-11-18 05:57:03 +0000129 LocateDYLD ();
Chris Lattner24943d22010-06-08 16:52:24 +0000130 SetNotificationBreakpoint ();
Chris Lattner24943d22010-06-08 16:52:24 +0000131}
132
133
134//----------------------------------------------------------------------
135// Clear out the state of this class.
136//----------------------------------------------------------------------
137void
138DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
139{
140 Mutex::Locker locker(m_mutex);
141
142 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
143 m_process->ClearBreakpointSiteByID(m_break_id);
144
145 if (clear_process)
146 m_process = NULL;
147 m_dyld.Clear(false);
148 m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
149 m_dyld_all_image_infos.Clear();
150 m_break_id = LLDB_INVALID_BREAK_ID;
151 m_dyld_image_infos.clear();
152}
153
154//----------------------------------------------------------------------
155// Check if we have found DYLD yet
156//----------------------------------------------------------------------
157bool
158DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
159{
160 return LLDB_BREAK_ID_IS_VALID (m_break_id);
161}
162
163//----------------------------------------------------------------------
164// Try and figure out where dyld is by first asking the Process
165// if it knows (which currently calls down in the the lldb::Process
166// to get the DYLD info (available on SnowLeopard only). If that fails,
167// then check in the default addresses.
168//----------------------------------------------------------------------
169bool
170DynamicLoaderMacOSXDYLD::LocateDYLD()
171{
172 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
173 m_dyld_all_image_infos_addr = m_process->GetImageInfoAddress ();
174
175 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
176 {
177 if (ReadAllImageInfosStructure ())
178 {
179 if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
180 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
181 else
182 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
183 }
184 }
185
186 // Check some default values
187 Module *executable = m_process->GetTarget().GetExecutableModule().get();
188
189 if (executable)
190 {
191 if (executable->GetArchitecture().GetAddressByteSize() == 8)
192 {
193 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
194 }
195#if defined (__arm__)
196 else
197 {
198 ArchSpec arm_arch("arm");
199 if (arm_arch == executable->Arch())
200 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
201 }
202#endif
203 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
204 }
205 return false;
206}
207
208//----------------------------------------------------------------------
209// Assume that dyld is in memory at ADDR and try to parse it's load
210// commands
211//----------------------------------------------------------------------
212bool
213DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
214{
215 DataExtractor data; // Load command data
216 if (ReadMachHeader (addr, &m_dyld.header, &data))
217 {
Greg Clayton1674b122010-07-21 22:12:05 +0000218 if (m_dyld.header.filetype == HeaderFileTypeDynamicLinkEditor)
Chris Lattner24943d22010-06-08 16:52:24 +0000219 {
220 m_dyld.address = addr;
221 ModuleSP dyld_module_sp;
222 if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
223 {
224 if (m_dyld.file_spec)
225 {
Greg Claytoncf015052010-06-11 03:25:34 +0000226 ArchSpec dyld_arch(eArchTypeMachO, m_dyld.header.cputype, m_dyld.header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +0000227 dyld_module_sp = m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld.file_spec);
228
229 if (dyld_module_sp.get() == NULL || dyld_module_sp->GetArchitecture() != dyld_arch)
230 {
231 dyld_module_sp = m_process->GetTarget().GetSharedModule (m_dyld.file_spec,
232 dyld_arch,
233 &m_dyld.uuid);
234 }
235
236 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
237 }
238 }
239
240 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
241 {
242 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
243 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
244 if (symbol)
Greg Claytoneea26402010-09-14 23:36:40 +0000245 m_dyld_all_image_infos_addr = symbol->GetValue().GetLoadAddress(&m_process->GetTarget());
Chris Lattner24943d22010-06-08 16:52:24 +0000246 }
247
248 // Update all image infos
249 UpdateAllImageInfos();
250
251 // If we didn't have an executable before, but now we do, then the
252 // dyld module shared pointer might be unique and we may need to add
253 // it again (since Target::SetExecutableModule() will clear the
254 // images). So append the dyld module back to the list if it is
255 /// unique!
Greg Claytonab429022010-12-12 21:03:32 +0000256 if (m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
Chris Lattner24943d22010-06-08 16:52:24 +0000257 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
258
259 return true;
260 }
261 }
262 return false;
263}
264
265bool
266DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
267{
268 return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
269}
270
271bool
272DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
273{
274 bool changed = false;
275 if (module)
276 {
277 ObjectFile *image_object_file = module->GetObjectFile();
278 if (image_object_file)
279 {
280 SectionList *section_list = image_object_file->GetSectionList ();
281 if (section_list)
282 {
283 uint32_t num_sections = section_list->GetSize();
284 for (uint32_t i=0; i<num_sections; ++i)
285 {
286 Section* section = section_list->GetSectionAtIndex (i).get();
287 if (section)
288 {
289 const addr_t new_section_load_addr = section->GetFileAddress ();
Greg Claytoneea26402010-09-14 23:36:40 +0000290 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
Chris Lattner24943d22010-06-08 16:52:24 +0000291 if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
292 old_section_load_addr != new_section_load_addr)
293 {
Greg Claytoneea26402010-09-14 23:36:40 +0000294 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
Chris Lattner24943d22010-06-08 16:52:24 +0000295 changed = true;
296 }
297 }
298 }
299 }
300 }
301 }
302 return changed;
303}
304
305//----------------------------------------------------------------------
306// Update the load addresses for all segments in MODULE using the
307// updated INFO that is passed in.
308//----------------------------------------------------------------------
309bool
310DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, struct DYLDImageInfo& info)
311{
312 bool changed = false;
313 if (module)
314 {
315 ObjectFile *image_object_file = module->GetObjectFile();
316 if (image_object_file)
317 {
318 SectionList *section_list = image_object_file->GetSectionList ();
319 if (section_list)
320 {
321 // All sections listed in the dyld image info structure will all
322 // either be fixed up already, or they will all be off by a single
323 // slide amount that is determined by finding the first segment
324 // that is at file offset zero which also has bytes (a file size
325 // that is greater than zero) in the object file.
326
327 // Determine the slide amount (if any)
328 info.slide = 0;
329 const size_t num_sections = section_list->GetSize();
330 size_t sect_idx = 0;
331 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
332 {
333 // Iterate through the object file sections to find the
334 // first section that starts of file offset zero and that
335 // has bytes in the file...
336 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
337 if (section)
338 {
339 // Find the first section that begins at file offset zero
340 // a file size (skip page zero).
341 if (section->GetFileOffset() == 0 && section->GetFileSize() > 0)
342 {
343 // We have now found the section, lets match it up
344 // with the section in the dyld image info structure.
345 const Segment *dyld_segment = info.FindSegment (section->GetName());
346 if (dyld_segment)
347 info.slide = info.address - dyld_segment->addr;
348 // We have found the slide amount, so we can exit
349 // this for loop.
350 break;
351 }
352 }
353 }
354
355 // We now know the slide amount, so go through all sections
356 // and update the load addresses with the correct values.
357 uint32_t num_segments = info.segments.size();
358 for (uint32_t i=0; i<num_segments; ++i)
359 {
360 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
361 assert (section_sp.get() != NULL);
362 const addr_t new_section_load_addr = info.segments[i].addr + info.slide;
Greg Claytoneea26402010-09-14 23:36:40 +0000363 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000364 if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
365 old_section_load_addr != new_section_load_addr)
366 {
Greg Claytoneea26402010-09-14 23:36:40 +0000367 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000368 changed = true;
369 }
370 }
371 }
372 }
373 }
374 return changed;
375}
376
377//----------------------------------------------------------------------
378// Update the load addresses for all segments in MODULE using the
379// updated INFO that is passed in.
380//----------------------------------------------------------------------
381bool
382DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, struct DYLDImageInfo& info)
383{
384 bool changed = false;
385 if (module)
386 {
387 ObjectFile *image_object_file = module->GetObjectFile();
388 if (image_object_file)
389 {
390 SectionList *section_list = image_object_file->GetSectionList ();
391 if (section_list)
392 {
393 uint32_t num_segments = info.segments.size();
394 for (uint32_t i=0; i<num_segments; ++i)
395 {
396 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
397 assert (section_sp.get() != NULL);
398 const addr_t old_section_load_addr = info.segments[i].addr + info.slide;
Greg Claytoneea26402010-09-14 23:36:40 +0000399 if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000400 changed = true;
401 }
402 }
403 }
404 }
405 return changed;
406}
407
408
409//----------------------------------------------------------------------
410// Static callback function that gets called when our DYLD notification
411// breakpoint gets hit. We update all of our image infos and then
412// let our super class DynamicLoader class decide if we should stop
413// or not (based on global preference).
414//----------------------------------------------------------------------
415bool
416DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
417{
418 // Let the event know that the images have changed
419 DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
420 dyld_instance->UpdateAllImageInfos();
421 // Return true to stop the target, false to just let the target run
422 return dyld_instance->GetStopWhenImagesChange();
423}
424
425bool
426DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
427{
428 Mutex::Locker locker(m_mutex);
Greg Clayton20d338f2010-11-18 05:57:03 +0000429
430 // the all image infos is already valid for this process stop ID
431 if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
432 return true;
433
Chris Lattner24943d22010-06-08 16:52:24 +0000434 m_dyld_all_image_infos.Clear();
435 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
436 {
Greg Clayton395fc332011-02-15 21:59:32 +0000437 ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
Greg Clayton20d338f2010-11-18 05:57:03 +0000438 uint32_t addr_size = 4;
439 if (m_dyld_all_image_infos_addr > UINT32_MAX)
440 addr_size = 8;
441
Chris Lattner24943d22010-06-08 16:52:24 +0000442 uint8_t buf[256];
Greg Clayton20d338f2010-11-18 05:57:03 +0000443 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
444 uint32_t offset = 0;
445
Jason Molenda1f3af542010-06-10 01:21:21 +0000446 const size_t count_v2 = sizeof (uint32_t) + // version
447 sizeof (uint32_t) + // infoArrayCount
448 addr_size + // infoArray
449 addr_size + // notification
450 addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad
451 addr_size; // dyldImageLoadAddress
452 const size_t count_v11 = count_v2 +
453 addr_size + // jitInfo
454 addr_size + // dyldVersion
455 addr_size + // errorMessage
456 addr_size + // terminationFlags
457 addr_size + // coreSymbolicationShmPage
458 addr_size + // systemOrderFlag
459 addr_size + // uuidArrayCount
460 addr_size + // uuidArray
461 addr_size + // dyldAllImageInfosAddress
462 addr_size + // initialImageCount
463 addr_size + // errorKind
464 addr_size + // errorClientOfDylibPath
465 addr_size + // errorTargetDylibPath
466 addr_size; // errorSymbol
467 assert (sizeof (buf) > count_v11);
468
469 int count;
Chris Lattner24943d22010-06-08 16:52:24 +0000470 Error error;
Jason Molenda1f3af542010-06-10 01:21:21 +0000471 if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
472 {
Jason Molenda1f3af542010-06-10 01:21:21 +0000473 m_dyld_all_image_infos.version = data.GetU32(&offset);
Greg Clayton20d338f2010-11-18 05:57:03 +0000474 // If anything in the high byte is set, we probably got the byte
475 // order incorrect (the process might not have it set correctly
476 // yet due to attaching to a program without a specified file).
477 if (m_dyld_all_image_infos.version & 0xff000000)
478 {
479 // We have guessed the wrong byte order. Swap it and try
480 // reading the version again.
481 if (byte_order == eByteOrderLittle)
482 byte_order = eByteOrderBig;
483 else
484 byte_order = eByteOrderLittle;
485
486 data.SetByteOrder (byte_order);
487 offset = 0;
488 m_dyld_all_image_infos.version = data.GetU32(&offset);
489 }
Jason Molenda1f3af542010-06-10 01:21:21 +0000490 }
491 else
492 {
493 return false;
494 }
495
496 if (m_dyld_all_image_infos.version >= 11)
497 count = count_v11;
498 else
499 count = count_v2;
500
Chris Lattner24943d22010-06-08 16:52:24 +0000501 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
502 if (bytes_read == count)
503 {
Greg Clayton20d338f2010-11-18 05:57:03 +0000504 offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000505 m_dyld_all_image_infos.version = data.GetU32(&offset);
506 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
507 m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
508 m_dyld_all_image_infos.notification = data.GetPointer(&offset);
509 m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
Jason Molenda1f3af542010-06-10 01:21:21 +0000510 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
511 // Adjust for padding.
512 offset += addr_size - 2;
513 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
514 if (m_dyld_all_image_infos.version >= 11)
Chris Lattner24943d22010-06-08 16:52:24 +0000515 {
Jason Molenda1f3af542010-06-10 01:21:21 +0000516 offset += addr_size * 8;
517 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
518
519 // When we started, we were given the actual address of the all_image_infos
520 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
521 // m_dyld_all_image_infos_addr and is the most accurate address we have.
522
523 // We read the dyld_all_image_infos struct from memory; it contains its own address.
524 // If the address in the struct does not match the actual address,
525 // the dyld we're looking at has been loaded at a different location (slid) from
526 // where it intended to load. The addresses in the dyld_all_image_infos struct
527 // are the original, non-slid addresses, and need to be adjusted. Most importantly
528 // the address of dyld and the notification address need to be adjusted.
529
530 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
531 {
532 uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
533 uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
534 m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
535 m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
536 }
Chris Lattner24943d22010-06-08 16:52:24 +0000537 }
Greg Clayton20d338f2010-11-18 05:57:03 +0000538 m_dyld_all_image_infos_stop_id = m_process->GetStopID();
Chris Lattner24943d22010-06-08 16:52:24 +0000539 return true;
540 }
541 }
542 return false;
543}
544
545//----------------------------------------------------------------------
546// If we have found where the "_dyld_all_image_infos" lives in memory,
547// read the current info from it, and then update all image load
548// addresses (or lack thereof).
549//----------------------------------------------------------------------
550uint32_t
551DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
552{
Greg Claytone005f2c2010-11-06 01:53:30 +0000553 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Chris Lattner24943d22010-06-08 16:52:24 +0000554 if (ReadAllImageInfosStructure ())
555 {
556 Mutex::Locker locker(m_mutex);
Greg Clayton20d338f2010-11-18 05:57:03 +0000557 if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
558 m_dyld_image_infos.size();
559
Chris Lattner24943d22010-06-08 16:52:24 +0000560 uint32_t idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000561 uint32_t i = 0;
562 DYLDImageInfo::collection old_dyld_all_image_infos;
563 old_dyld_all_image_infos.swap(m_dyld_image_infos);
564
565 // If we made it here, we are assuming that the all dylib info data should
566 // be valid, lets read the info array.
Greg Clayton20d338f2010-11-18 05:57:03 +0000567 const ByteOrder endian = m_dyld.GetByteOrder();
568 const uint32_t addr_size = m_dyld.GetAddressByteSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000569
570 if (m_dyld_all_image_infos.dylib_info_count > 0)
571 {
572 if (m_dyld_all_image_infos.dylib_info_addr == 0)
573 {
574 // DYLD is updating the images right now...
575 }
576 else
577 {
578 m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
579 const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
580 DataBufferHeap info_data(count, 0);
581 Error error;
582 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr,
583 info_data.GetBytes(),
584 info_data.GetByteSize(),
585 error);
586 if (bytes_read == count)
587 {
588 uint32_t info_data_offset = 0;
589 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
590 for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++)
591 {
592 assert (i < m_dyld_image_infos.size());
593 m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
594 lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
595 m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
596
597 char raw_path[PATH_MAX];
598 m_process->ReadMemory (path_addr, raw_path, sizeof(raw_path), error);
Greg Clayton537a7a82010-10-20 20:54:39 +0000599 m_dyld_image_infos[i].file_spec.SetFile(raw_path, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000600 }
601 assert(i == m_dyld_all_image_infos.dylib_info_count);
602
603 UpdateAllImageInfosHeaderAndLoadCommands();
604 }
605 else
606 {
607 DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
608 m_dyld_image_infos.clear();
609 }
610 }
611 }
612 else
613 {
614 m_dyld_image_infos.clear();
615 }
616
617 // If our new list is smaller than our old list, we have unloaded
618 // some shared libraries
Greg Claytonab429022010-12-12 21:03:32 +0000619 if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size())
Chris Lattner24943d22010-06-08 16:52:24 +0000620 {
621 ModuleList unloaded_module_list;
Greg Claytonab429022010-12-12 21:03:32 +0000622 if (old_dyld_all_image_infos.size() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000623 {
Greg Claytonab429022010-12-12 21:03:32 +0000624 // This is the first time we are loading shared libraries,
625 // we need to make sure to trim anything that isn't in the
626 // m_dyld_image_infos out of the target module list since
627 // we might have shared libraries that got loaded from
628 // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH
629 // environment variables...
630 ModuleList& images = m_process->GetTarget().GetImages();
631 const size_t num_images = images.GetSize();
632 for (idx = 0; idx < num_images; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000633 {
Greg Claytonab429022010-12-12 21:03:32 +0000634 ModuleSP module_sp (images.GetModuleAtIndex (idx));
635
636 if (GetImageInfo (module_sp->GetFileSpec(), module_sp->GetUUID()) == NULL)
637 unloaded_module_list.AppendIfNeeded (module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000638 }
639 }
Greg Claytonab429022010-12-12 21:03:32 +0000640 else
Greg Clayton9d2993d2010-11-03 04:08:06 +0000641 {
Greg Claytonab429022010-12-12 21:03:32 +0000642 uint32_t old_idx;
643 for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx)
Greg Clayton9d2993d2010-11-03 04:08:06 +0000644 {
Greg Claytonab429022010-12-12 21:03:32 +0000645 for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
Greg Clayton9d2993d2010-11-03 04:08:06 +0000646 {
Greg Claytonab429022010-12-12 21:03:32 +0000647 if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec)
648 {
649 old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS;
650 break;
651 }
652 }
653 }
654
Greg Claytonab429022010-12-12 21:03:32 +0000655 for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
656 {
657 if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS)
658 {
659 if (log)
660 old_dyld_all_image_infos[old_idx].PutToLog (log.get());
661 ModuleSP unload_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (old_dyld_all_image_infos[old_idx].file_spec));
662 if (unload_image_module_sp.get())
663 {
664 if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx]))
665 unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
666 }
Greg Clayton9d2993d2010-11-03 04:08:06 +0000667 }
668 }
669 }
670
Chris Lattner24943d22010-06-08 16:52:24 +0000671 if (unloaded_module_list.GetSize() > 0)
Greg Clayton427f2902010-12-14 02:59:59 +0000672 {
673 if (log)
674 {
675 log->PutCString("Unloaded:");
676 unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
677 }
Chris Lattner24943d22010-06-08 16:52:24 +0000678 m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
Greg Clayton427f2902010-12-14 02:59:59 +0000679 }
Chris Lattner24943d22010-06-08 16:52:24 +0000680 }
Greg Clayton9d2993d2010-11-03 04:08:06 +0000681 else
682 {
683 if (log)
Greg Claytone005f2c2010-11-06 01:53:30 +0000684 PutToLog(log.get());
Greg Clayton9d2993d2010-11-03 04:08:06 +0000685 }
Greg Clayton20d338f2010-11-18 05:57:03 +0000686 m_dyld_image_infos_stop_id = m_process->GetStopID();
Chris Lattner24943d22010-06-08 16:52:24 +0000687 }
688 else
689 {
690 m_dyld_image_infos.clear();
691 }
692
693 const uint32_t num_dylibs = m_dyld_image_infos.size();
694 if (num_dylibs > 0)
695 {
696 ModuleList loaded_module_list;
697 for (uint32_t idx = 0; idx<num_dylibs; ++idx)
698 {
Greg Claytoncf015052010-06-11 03:25:34 +0000699 ArchSpec arch_spec(eArchTypeMachO, m_dyld_image_infos[idx].header.cputype, m_dyld_image_infos[idx].header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +0000700 ModuleSP image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (m_dyld_image_infos[idx].file_spec));
701 if (image_module_sp.get() == NULL || image_module_sp->GetArchitecture() != arch_spec)
702 {
703 image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
704 arch_spec,
705 &m_dyld_image_infos[idx].uuid);
706 }
707
708 if (image_module_sp)
709 {
Greg Clayton236c1c72010-09-07 23:40:05 +0000710 if (m_dyld_image_infos[idx].header.filetype == HeaderFileTypeDynamicLinkEditor)
711 image_module_sp->SetIsDynamicLinkEditor (true);
712
Chris Lattner24943d22010-06-08 16:52:24 +0000713 ObjectFile *objfile = image_module_sp->GetObjectFile ();
714 if (objfile)
715 {
716 SectionList *sections = objfile->GetSectionList();
717 if (sections)
718 {
719 ConstString commpage_dbstr("__commpage");
720 Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
721 if (commpage_section)
722 {
723 FileSpec objfile_file_spec(objfile->GetFileSpec());
724 ModuleSP commpage_image_module_sp(m_process->GetTarget().GetImages().FindFirstModuleForFileSpec (objfile_file_spec, &commpage_dbstr));
725 if (commpage_image_module_sp.get() == NULL)
726 {
727 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
728 arch_spec,
729 &m_dyld_image_infos[idx].uuid,
730 &commpage_dbstr,
731 objfile->GetOffset() + commpage_section->GetOffset());
732 UpdateCommPageLoadAddress(commpage_image_module_sp.get());
733 }
734 }
735 }
736 }
737
738 // UpdateImageLoadAddress will return true if any segments
739 // change load address. We need to check this so we don't
740 // mention that all loaded shared libraries are newly loaded
741 // each time we hit out dyld breakpoint since dyld will list all
742 // shared libraries each time.
743 if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
744 {
Greg Claytonab429022010-12-12 21:03:32 +0000745 loaded_module_list.AppendIfNeeded (image_module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000746 }
747 }
748 }
Chris Lattner24943d22010-06-08 16:52:24 +0000749 if (loaded_module_list.GetSize() > 0)
750 {
751 // FIXME: This should really be in the Runtime handlers class, which should get
752 // called by the target's ModulesDidLoad, but we're doing it all locally for now
753 // to save time.
754 // Also, I'm assuming there can be only one libobjc dylib loaded...
755
Jim Inghamb66cd072010-09-28 01:25:32 +0000756 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
757 if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
Chris Lattner24943d22010-06-08 16:52:24 +0000758 {
759 size_t num_modules = loaded_module_list.GetSize();
760 for (int i = 0; i < num_modules; i++)
761 {
Jim Inghamb66cd072010-09-28 01:25:32 +0000762 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
Chris Lattner24943d22010-06-08 16:52:24 +0000763 {
Jim Inghamb66cd072010-09-28 01:25:32 +0000764 objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
Chris Lattner24943d22010-06-08 16:52:24 +0000765 break;
766 }
767 }
768 }
Greg Clayton427f2902010-12-14 02:59:59 +0000769 if (log)
770 loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
Chris Lattner24943d22010-06-08 16:52:24 +0000771 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
772 }
773 }
774 return m_dyld_image_infos.size();
775}
776
777//----------------------------------------------------------------------
778// Read a mach_header at ADDR into HEADER, and also fill in the load
779// command data into LOAD_COMMAND_DATA if it is non-NULL.
780//
781// Returns true if we succeed, false if we fail for any reason.
782//----------------------------------------------------------------------
783bool
Greg Clayton1674b122010-07-21 22:12:05 +0000784DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, mach_header *header, DataExtractor *load_command_data)
Chris Lattner24943d22010-06-08 16:52:24 +0000785{
Greg Clayton1674b122010-07-21 22:12:05 +0000786 DataBufferHeap header_bytes(sizeof(mach_header), 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000787 Error error;
788 size_t bytes_read = m_process->ReadMemory (addr,
789 header_bytes.GetBytes(),
790 header_bytes.GetByteSize(),
791 error);
Greg Clayton1674b122010-07-21 22:12:05 +0000792 if (bytes_read == sizeof(mach_header))
Chris Lattner24943d22010-06-08 16:52:24 +0000793 {
794 uint32_t offset = 0;
795 ::memset (header, 0, sizeof(header));
796
797 // Get the magic byte unswapped so we can figure out what we are dealing with
Greg Claytoncd548032011-02-01 01:31:41 +0000798 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
Chris Lattner24943d22010-06-08 16:52:24 +0000799 header->magic = data.GetU32(&offset);
800 lldb::addr_t load_cmd_addr = addr;
801 data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
802 switch (header->magic)
803 {
Greg Clayton1674b122010-07-21 22:12:05 +0000804 case llvm::MachO::HeaderMagic32:
805 case llvm::MachO::HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000806 data.SetAddressByteSize(4);
Greg Clayton1674b122010-07-21 22:12:05 +0000807 load_cmd_addr += sizeof(mach_header);
Chris Lattner24943d22010-06-08 16:52:24 +0000808 break;
809
Greg Clayton1674b122010-07-21 22:12:05 +0000810 case llvm::MachO::HeaderMagic64:
811 case llvm::MachO::HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000812 data.SetAddressByteSize(8);
Greg Clayton1674b122010-07-21 22:12:05 +0000813 load_cmd_addr += sizeof(mach_header_64);
Chris Lattner24943d22010-06-08 16:52:24 +0000814 break;
815
816 default:
817 return false;
818 }
819
820 // Read the rest of dyld's mach header
Greg Clayton1674b122010-07-21 22:12:05 +0000821 if (data.GetU32(&offset, &header->cputype, (sizeof(mach_header)/sizeof(uint32_t)) - 1))
Chris Lattner24943d22010-06-08 16:52:24 +0000822 {
823 if (load_command_data == NULL)
824 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
825
826 DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
827
828 size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
829 load_cmd_data_sp->GetBytes(),
830 load_cmd_data_sp->GetByteSize(),
831 error);
832
833 if (load_cmd_bytes_read == header->sizeofcmds)
834 {
835 // Set the load command data and also set the correct endian
836 // swap settings and the correct address size
837 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
838 load_command_data->SetByteOrder(data.GetByteOrder());
839 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
840 return true; // We successfully read the mach_header and the load command data
841 }
842
843 return false; // We weren't able to read the load command data
844 }
845 }
846 return false; // We failed the read the mach_header
847}
848
849
850//----------------------------------------------------------------------
851// Parse the load commands for an image
852//----------------------------------------------------------------------
853uint32_t
854DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, struct DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
855{
856 uint32_t offset = 0;
857 uint32_t cmd_idx;
858 Segment segment;
859 dylib_info.Clear (true);
860
861 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
862 {
863 // Clear out any load command specific data from DYLIB_INFO since
864 // we are about to read it.
865
Greg Clayton1674b122010-07-21 22:12:05 +0000866 if (data.ValidOffsetForDataOfSize (offset, sizeof(load_command)))
Chris Lattner24943d22010-06-08 16:52:24 +0000867 {
Greg Clayton1674b122010-07-21 22:12:05 +0000868 load_command load_cmd;
Chris Lattner24943d22010-06-08 16:52:24 +0000869 uint32_t load_cmd_offset = offset;
870 load_cmd.cmd = data.GetU32 (&offset);
871 load_cmd.cmdsize = data.GetU32 (&offset);
872 switch (load_cmd.cmd)
873 {
Greg Clayton1674b122010-07-21 22:12:05 +0000874 case LoadCommandSegment32:
Chris Lattner24943d22010-06-08 16:52:24 +0000875 {
876 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
877 segment.addr = data.GetU32 (&offset);
878 segment.size = data.GetU32 (&offset);
879 dylib_info.segments.push_back (segment);
880 }
881 break;
882
Greg Clayton1674b122010-07-21 22:12:05 +0000883 case LoadCommandSegment64:
Chris Lattner24943d22010-06-08 16:52:24 +0000884 {
885 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
886 segment.addr = data.GetU64 (&offset);
887 segment.size = data.GetU64 (&offset);
888 dylib_info.segments.push_back (segment);
889 }
890 break;
891
Greg Clayton1674b122010-07-21 22:12:05 +0000892 case LoadCommandDynamicLinkerIdent:
Chris Lattner24943d22010-06-08 16:52:24 +0000893 if (lc_id_dylinker)
894 {
895 uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
896 const char *path = data.PeekCStr (name_offset);
Greg Clayton537a7a82010-10-20 20:54:39 +0000897 lc_id_dylinker->SetFile (path, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000898 }
899 break;
900
Greg Clayton1674b122010-07-21 22:12:05 +0000901 case LoadCommandUUID:
Chris Lattner24943d22010-06-08 16:52:24 +0000902 dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
903 break;
904
905 default:
906 break;
907 }
908 // Set offset to be the beginning of the next load command.
909 offset = load_cmd_offset + load_cmd.cmdsize;
910 }
911 }
912 return cmd_idx;
913}
914
915//----------------------------------------------------------------------
916// Read the mach_header and load commands for each image that the
917// _dyld_all_image_infos structure points to and cache the results.
918//----------------------------------------------------------------------
919void
920DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
921{
922 uint32_t exe_idx = UINT32_MAX;
923 // Read any UUID values that we can get
924 for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
925 {
926 if (!m_dyld_image_infos[i].UUIDValid())
927 {
928 DataExtractor data; // Load command data
929 if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
930 continue;
931
932 ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
933
Greg Clayton1674b122010-07-21 22:12:05 +0000934 if (m_dyld_image_infos[i].header.filetype == HeaderFileTypeExecutable)
Chris Lattner24943d22010-06-08 16:52:24 +0000935 exe_idx = i;
936 }
937 }
938
939 if (exe_idx < m_dyld_image_infos.size())
940 {
941 bool set_executable = false;
Greg Claytoncf015052010-06-11 03:25:34 +0000942 ArchSpec dyld_exe_arch_spec(eArchTypeMachO, m_dyld_image_infos[exe_idx].header.cputype, m_dyld_image_infos[exe_idx].header.cpusubtype);
Chris Lattner24943d22010-06-08 16:52:24 +0000943 ModuleSP exe_module_sp(m_process->GetTarget().GetExecutableModule());
944 if (exe_module_sp.get())
945 {
946 if (exe_module_sp->GetFileSpec() != m_dyld_image_infos[exe_idx].file_spec ||
947 exe_module_sp->GetArchitecture() != dyld_exe_arch_spec)
948 set_executable = true;
949 }
950 else
951 set_executable = true;
952
953 if (set_executable)
954 {
955 exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
956 dyld_exe_arch_spec,
957 &m_dyld_image_infos[exe_idx].uuid);
958 if (exe_module_sp.get())
959 {
960 // If we found the file where it purported to be, then it should
961 // be safe to load dependent images.
962 bool get_dependent_images = exe_module_sp->GetFileSpec() == m_dyld_image_infos[exe_idx].file_spec;
963
964 m_process->GetTarget().SetExecutableModule (exe_module_sp, get_dependent_images);
965 }
966 }
967 }
968}
969
970//----------------------------------------------------------------------
971// Dump a Segment to the file handle provided.
972//----------------------------------------------------------------------
973void
974DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
975{
976 if (log)
977 log->Printf("\t\t%16s [0x%16.16llx - 0x%16.16llx)", name.AsCString(""), addr + slide, addr + slide + size);
978}
979
980const DynamicLoaderMacOSXDYLD::Segment *
981DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
982{
983 const size_t num_segments = segments.size();
984 for (size_t i=0; i<num_segments; ++i)
985 {
986 if (segments[i].name == name)
987 return &segments[i];
988 }
989 return NULL;
990}
991
992
993//----------------------------------------------------------------------
994// Dump an image info structure to the file handle provided.
995//----------------------------------------------------------------------
996void
997DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
998{
999 if (log == NULL)
1000 return;
1001 uint8_t *u = (uint8_t *)uuid.GetBytes();
1002
1003 if (address == LLDB_INVALID_ADDRESS)
1004 {
1005 if (u)
1006 {
1007 log->Printf("\t modtime=0x%8.8llx 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 path='%s/%s' (UNLOADED)",
1008 mod_date,
1009 u[ 0], u[ 1], u[ 2], u[ 3],
1010 u[ 4], u[ 5], u[ 6], u[ 7],
1011 u[ 8], u[ 9], u[10], u[11],
1012 u[12], u[13], u[14], u[15],
1013 file_spec.GetDirectory().AsCString(),
1014 file_spec.GetFilename().AsCString());
1015 }
1016 else
1017 log->Printf("\t modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
1018 mod_date,
1019 file_spec.GetDirectory().AsCString(),
1020 file_spec.GetFilename().AsCString());
1021 }
1022 else
1023 {
1024 if (u)
1025 {
1026 log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx 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 path='%s/%s'",
1027 address,
1028 mod_date,
1029 u[ 0], u[ 1], u[ 2], u[ 3],
1030 u[ 4], u[ 5], u[ 6], u[ 7],
1031 u[ 8], u[ 9], u[10], u[11],
1032 u[12], u[13], u[14], u[15],
1033 file_spec.GetDirectory().AsCString(),
1034 file_spec.GetFilename().AsCString());
1035 }
1036 else
1037 {
1038 log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
1039 address,
1040 mod_date,
1041 file_spec.GetDirectory().AsCString(),
1042 file_spec.GetFilename().AsCString());
1043
1044 }
1045 for (uint32_t i=0; i<segments.size(); ++i)
1046 segments[i].PutToLog(log, slide);
1047 }
1048}
1049
1050//----------------------------------------------------------------------
1051// Dump the _dyld_all_image_infos members and all current image infos
1052// that we have parsed to the file handle provided.
1053//----------------------------------------------------------------------
1054void
1055DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
1056{
1057 if (log == NULL)
1058 return;
1059
1060 Mutex::Locker locker(m_mutex);
1061 log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
1062 m_dyld_all_image_infos.version,
1063 m_dyld_all_image_infos.dylib_info_count,
1064 (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
1065 (uint64_t)m_dyld_all_image_infos.notification);
1066 size_t i;
1067 const size_t count = m_dyld_image_infos.size();
1068 if (count > 0)
1069 {
Greg Clayton9d2993d2010-11-03 04:08:06 +00001070 log->PutCString("Loaded:");
Chris Lattner24943d22010-06-08 16:52:24 +00001071 for (i = 0; i<count; i++)
1072 m_dyld_image_infos[i].PutToLog(log);
1073 }
1074}
1075
Chris Lattner24943d22010-06-08 16:52:24 +00001076void
1077DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
1078{
1079 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1080 Clear(true);
1081 m_process = process;
Greg Clayton58e844b2010-12-08 05:08:21 +00001082 m_process->GetTarget().GetSectionLoadList().Clear();
Chris Lattner24943d22010-06-08 16:52:24 +00001083}
1084
1085bool
1086DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1087{
1088 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1089 if (m_break_id == LLDB_INVALID_BREAK_ID)
1090 {
1091 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1092 {
1093 Address so_addr;
1094 // Set the notification breakpoint and install a breakpoint
1095 // callback function that will get called each time the
1096 // breakpoint gets hit. We will use this to track when shared
1097 // libraries get loaded/unloaded.
1098
Greg Claytoneea26402010-09-14 23:36:40 +00001099 if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
Chris Lattner24943d22010-06-08 16:52:24 +00001100 {
1101 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1102 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1103 m_break_id = dyld_break->GetID();
1104 }
1105 }
1106 }
1107 return m_break_id != LLDB_INVALID_BREAK_ID;
1108}
1109
Jim Ingham7508e732010-08-09 23:31:02 +00001110//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001111// Member function that gets called when the process state changes.
1112//----------------------------------------------------------------------
1113void
1114DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1115{
1116 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1117 switch (state)
1118 {
Greg Claytone71e2582011-02-04 01:58:07 +00001119 case eStateConnected:
Chris Lattner24943d22010-06-08 16:52:24 +00001120 case eStateAttaching:
1121 case eStateLaunching:
1122 case eStateInvalid:
1123 case eStateUnloaded:
1124 case eStateExited:
1125 case eStateDetached:
1126 Clear(false);
1127 break;
1128
1129 case eStateStopped:
1130 // Keep trying find dyld and set our notification breakpoint each time
1131 // we stop until we succeed
1132 if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1133 {
1134 if (NeedToLocateDYLD ())
1135 LocateDYLD ();
1136
1137 SetNotificationBreakpoint ();
1138 }
1139 break;
1140
1141 case eStateRunning:
1142 case eStateStepping:
1143 case eStateCrashed:
1144 case eStateSuspended:
1145 break;
1146
1147 default:
1148 break;
1149 }
1150}
1151
1152ThreadPlanSP
1153DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1154{
1155 ThreadPlanSP thread_plan_sp;
1156 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1157 const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1158 Symbol *current_symbol = current_context.symbol;
Greg Claytone005f2c2010-11-06 01:53:30 +00001159 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +00001160
1161 if (current_symbol != NULL)
1162 {
1163 if (current_symbol->IsTrampoline())
1164 {
Jim Ingham17454cf2010-09-14 22:03:00 +00001165 const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1166
Chris Lattner24943d22010-06-08 16:52:24 +00001167 if (trampoline_name)
1168 {
1169 SymbolContextList target_symbols;
1170 ModuleList &images = thread.GetProcess().GetTarget().GetImages();
1171 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1172 // FIXME - Make the Run to Address take multiple addresses, and
1173 // run to any of them.
Jim Ingham17454cf2010-09-14 22:03:00 +00001174 uint32_t num_symbols = target_symbols.GetSize();
1175 if (num_symbols == 1)
Chris Lattner24943d22010-06-08 16:52:24 +00001176 {
1177 SymbolContext context;
1178 AddressRange addr_range;
1179 if (target_symbols.GetContextAtIndex(0, context))
1180 {
1181 context.GetAddressRange (eSymbolContextEverything, addr_range);
1182 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others));
1183 }
Jim Ingham17454cf2010-09-14 22:03:00 +00001184 else
Chris Lattner24943d22010-06-08 16:52:24 +00001185 {
Jim Ingham17454cf2010-09-14 22:03:00 +00001186 if (log)
1187 log->Printf ("Couldn't resolve the symbol context.");
1188 }
1189 }
1190 else if (num_symbols > 1)
1191 {
1192 std::vector<lldb::addr_t> addresses;
1193 addresses.resize (num_symbols);
1194 for (uint32_t i = 0; i < num_symbols; i++)
1195 {
1196 SymbolContext context;
1197 AddressRange addr_range;
1198 if (target_symbols.GetContextAtIndex(i, context))
1199 {
1200 context.GetAddressRange (eSymbolContextEverything, addr_range);
Greg Claytoneea26402010-09-14 23:36:40 +00001201 lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
Jim Ingham17454cf2010-09-14 22:03:00 +00001202 addresses[i] = load_addr;
1203 }
1204 }
1205 if (addresses.size() > 0)
1206 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1207 else
1208 {
1209 if (log)
1210 log->Printf ("Couldn't resolve the symbol contexts.");
Chris Lattner24943d22010-06-08 16:52:24 +00001211 }
1212 }
1213 else
1214 {
Chris Lattner24943d22010-06-08 16:52:24 +00001215 if (log)
1216 {
1217 log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1218 }
1219 }
1220 }
1221 }
1222 }
Jim Ingham17454cf2010-09-14 22:03:00 +00001223 else
1224 {
1225 if (log)
1226 log->Printf ("Could not find symbol for step through.");
1227 }
Chris Lattner24943d22010-06-08 16:52:24 +00001228
Chris Lattner24943d22010-06-08 16:52:24 +00001229 return thread_plan_sp;
1230}
1231
Greg Clayton0baa3942010-11-04 01:54:29 +00001232Error
1233DynamicLoaderMacOSXDYLD::CanLoadImage ()
1234{
1235 Error error;
1236 // In order for us to tell if we can load a shared library we verify that
1237 // the dylib_info_addr isn't zero (which means no shared libraries have
1238 // been set yet, or dyld is currently mucking with the shared library list).
1239 if (ReadAllImageInfosStructure ())
1240 {
1241 // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
1242 // TODO: check the malloc lock?
1243 // TODO: check the objective C lock?
1244 if (m_dyld_all_image_infos.dylib_info_addr != 0)
1245 return error; // Success
1246 }
1247
1248 error.SetErrorString("unsafe to load or unload shared libraries");
1249 return error;
1250}
1251
Chris Lattner24943d22010-06-08 16:52:24 +00001252void
1253DynamicLoaderMacOSXDYLD::Initialize()
1254{
1255 PluginManager::RegisterPlugin (GetPluginNameStatic(),
1256 GetPluginDescriptionStatic(),
1257 CreateInstance);
1258}
1259
1260void
1261DynamicLoaderMacOSXDYLD::Terminate()
1262{
1263 PluginManager::UnregisterPlugin (CreateInstance);
1264}
1265
1266
1267const char *
1268DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1269{
1270 return "dynamic-loader.macosx-dyld";
1271}
1272
1273const char *
1274DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1275{
1276 return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1277}
1278
1279
1280//------------------------------------------------------------------
1281// PluginInterface protocol
1282//------------------------------------------------------------------
1283const char *
1284DynamicLoaderMacOSXDYLD::GetPluginName()
1285{
1286 return "DynamicLoaderMacOSXDYLD";
1287}
1288
1289const char *
1290DynamicLoaderMacOSXDYLD::GetShortPluginName()
1291{
1292 return GetPluginNameStatic();
1293}
1294
1295uint32_t
1296DynamicLoaderMacOSXDYLD::GetPluginVersion()
1297{
1298 return 1;
1299}
1300
1301void
1302DynamicLoaderMacOSXDYLD::GetPluginCommandHelp (const char *command, Stream *strm)
1303{
1304}
1305
1306Error
1307DynamicLoaderMacOSXDYLD::ExecutePluginCommand (Args &command, Stream *strm)
1308{
1309 Error error;
1310 error.SetErrorString("No plug-in command are currently supported.");
1311 return error;
1312}
1313
1314Log *
1315DynamicLoaderMacOSXDYLD::EnablePluginLogging (Stream *strm, Args &command)
1316{
1317 return NULL;
1318}
1319
1320