blob: 0b06b4c3bfcf73b5c4f8fe71b10ea72d998ef505 [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;
Chris Lattner24943d22010-06-08 16:52:24 +000037
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
Greg Claytonab429022010-12-12 21:03:32 +000042
43DynamicLoaderMacOSXDYLD::DYLDImageInfo *
Greg Clayton24bc5d92011-03-30 18:16:51 +000044DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
Greg Claytonab429022010-12-12 21:03:32 +000045{
Greg Clayton24bc5d92011-03-30 18:16:51 +000046 const UUID &module_uuid = module->GetUUID();
Greg Claytonab429022010-12-12 21:03:32 +000047 DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
Greg Clayton24bc5d92011-03-30 18:16:51 +000048
49 // First try just by UUID as it is the safest.
50 if (module_uuid.IsValid())
51 {
52 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
53 {
54 if (pos->uuid == module_uuid)
55 return &(*pos);
56 }
57
58 if (m_dyld.uuid == module_uuid)
59 return &m_dyld;
60 }
61
62 // Next try by platform path only for things that don't have a valid UUID
63 // since if a file has a valid UUID in real life it should also in the
64 // dyld info. This is the next safest because the paths in the dyld info
65 // are platform paths, not local paths. For local debugging platform == local
66 // paths.
67 const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
Greg Claytonab429022010-12-12 21:03:32 +000068 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
69 {
Greg Clayton24bc5d92011-03-30 18:16:51 +000070 if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
Greg Claytonab429022010-12-12 21:03:32 +000071 return &(*pos);
72 }
73
Greg Clayton24bc5d92011-03-30 18:16:51 +000074 if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
Greg Claytonab429022010-12-12 21:03:32 +000075 return &m_dyld;
76
77 return NULL;
78}
79
Chris Lattner24943d22010-06-08 16:52:24 +000080//----------------------------------------------------------------------
81// Create an instance of this class. This function is filled into
82// the plugin info class that gets handed out by the plugin factory and
83// allows the lldb to instantiate an instance of this class.
84//----------------------------------------------------------------------
85DynamicLoader *
Greg Clayton75c703d2011-02-16 04:46:07 +000086DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force)
Chris Lattner24943d22010-06-08 16:52:24 +000087{
Greg Clayton75c703d2011-02-16 04:46:07 +000088 bool create = force;
89 if (!create)
90 {
91 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
92 if (triple_ref.getOS() == llvm::Triple::Darwin && triple_ref.getVendor() == llvm::Triple::Apple)
93 create = true;
94 }
95
96 if (create)
97 return new DynamicLoaderMacOSXDYLD (process);
98 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000099}
100
101//----------------------------------------------------------------------
102// Constructor
103//----------------------------------------------------------------------
104DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
105 DynamicLoader(process),
106 m_dyld(),
107 m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
108 m_dyld_all_image_infos(),
Greg Clayton20d338f2010-11-18 05:57:03 +0000109 m_dyld_all_image_infos_stop_id (UINT32_MAX),
Chris Lattner24943d22010-06-08 16:52:24 +0000110 m_break_id(LLDB_INVALID_BREAK_ID),
111 m_dyld_image_infos(),
Greg Clayton20d338f2010-11-18 05:57:03 +0000112 m_dyld_image_infos_stop_id (UINT32_MAX),
Jim Inghamb66cd072010-09-28 01:25:32 +0000113 m_mutex(Mutex::eMutexTypeRecursive)
Chris Lattner24943d22010-06-08 16:52:24 +0000114{
115}
116
117//----------------------------------------------------------------------
118// Destructor
119//----------------------------------------------------------------------
120DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
121{
122 Clear(true);
123}
124
125//------------------------------------------------------------------
126/// Called after attaching a process.
127///
128/// Allow DynamicLoader plug-ins to execute some code after
129/// attaching to a process.
130//------------------------------------------------------------------
131void
132DynamicLoaderMacOSXDYLD::DidAttach ()
133{
134 PrivateInitialize(m_process);
Greg Clayton20d338f2010-11-18 05:57:03 +0000135 LocateDYLD ();
Chris Lattner24943d22010-06-08 16:52:24 +0000136 SetNotificationBreakpoint ();
Chris Lattner24943d22010-06-08 16:52:24 +0000137}
138
139//------------------------------------------------------------------
140/// Called after attaching a process.
141///
142/// Allow DynamicLoader plug-ins to execute some code after
143/// attaching to a process.
144//------------------------------------------------------------------
145void
146DynamicLoaderMacOSXDYLD::DidLaunch ()
147{
148 PrivateInitialize(m_process);
Greg Clayton20d338f2010-11-18 05:57:03 +0000149 LocateDYLD ();
Chris Lattner24943d22010-06-08 16:52:24 +0000150 SetNotificationBreakpoint ();
Chris Lattner24943d22010-06-08 16:52:24 +0000151}
152
153
154//----------------------------------------------------------------------
155// Clear out the state of this class.
156//----------------------------------------------------------------------
157void
158DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
159{
160 Mutex::Locker locker(m_mutex);
161
162 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
163 m_process->ClearBreakpointSiteByID(m_break_id);
164
165 if (clear_process)
166 m_process = NULL;
167 m_dyld.Clear(false);
168 m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
169 m_dyld_all_image_infos.Clear();
170 m_break_id = LLDB_INVALID_BREAK_ID;
171 m_dyld_image_infos.clear();
172}
173
174//----------------------------------------------------------------------
175// Check if we have found DYLD yet
176//----------------------------------------------------------------------
177bool
178DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
179{
180 return LLDB_BREAK_ID_IS_VALID (m_break_id);
181}
182
183//----------------------------------------------------------------------
184// Try and figure out where dyld is by first asking the Process
185// if it knows (which currently calls down in the the lldb::Process
186// to get the DYLD info (available on SnowLeopard only). If that fails,
187// then check in the default addresses.
188//----------------------------------------------------------------------
189bool
190DynamicLoaderMacOSXDYLD::LocateDYLD()
191{
192 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
193 m_dyld_all_image_infos_addr = m_process->GetImageInfoAddress ();
194
195 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
196 {
197 if (ReadAllImageInfosStructure ())
198 {
199 if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
200 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
201 else
202 return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
203 }
204 }
205
206 // Check some default values
207 Module *executable = m_process->GetTarget().GetExecutableModule().get();
208
209 if (executable)
210 {
211 if (executable->GetArchitecture().GetAddressByteSize() == 8)
212 {
213 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
214 }
215#if defined (__arm__)
216 else
217 {
218 ArchSpec arm_arch("arm");
219 if (arm_arch == executable->Arch())
220 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
221 }
222#endif
223 return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
224 }
225 return false;
226}
227
Greg Clayton24bc5d92011-03-30 18:16:51 +0000228ModuleSP
229DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
230{
231 if (did_create_ptr)
232 *did_create_ptr = false;
233 ModuleSP module_sp;
234 ModuleList &target_images = m_process->GetTarget().GetImages();
235 const bool image_info_uuid_is_valid = image_info.uuid.IsValid();
236 if (image_info_uuid_is_valid)
237 module_sp = target_images.FindModule(image_info.uuid);
238
239 if (!module_sp)
240 {
241 ArchSpec arch(image_info.GetArchitecture ());
242
243 module_sp = target_images.FindFirstModuleForFileSpec (image_info.file_spec, &arch, NULL);
244
245 if (can_create && !module_sp)
246 {
247 module_sp = m_process->GetTarget().GetSharedModule (image_info.file_spec,
248 arch,
249 image_info_uuid_is_valid ? &image_info.uuid : NULL);
250 if (did_create_ptr)
251 *did_create_ptr = module_sp;
252 }
253 }
254 return module_sp;
255}
256
Chris Lattner24943d22010-06-08 16:52:24 +0000257//----------------------------------------------------------------------
258// Assume that dyld is in memory at ADDR and try to parse it's load
259// commands
260//----------------------------------------------------------------------
261bool
262DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
263{
264 DataExtractor data; // Load command data
265 if (ReadMachHeader (addr, &m_dyld.header, &data))
266 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000267 if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
Chris Lattner24943d22010-06-08 16:52:24 +0000268 {
269 m_dyld.address = addr;
270 ModuleSP dyld_module_sp;
271 if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec))
272 {
273 if (m_dyld.file_spec)
274 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000275 dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000276
Greg Clayton24bc5d92011-03-30 18:16:51 +0000277 if (dyld_module_sp)
278 UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
Chris Lattner24943d22010-06-08 16:52:24 +0000279 }
280 }
281
282 if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
283 {
284 static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
285 const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
286 if (symbol)
Greg Claytoneea26402010-09-14 23:36:40 +0000287 m_dyld_all_image_infos_addr = symbol->GetValue().GetLoadAddress(&m_process->GetTarget());
Chris Lattner24943d22010-06-08 16:52:24 +0000288 }
289
290 // Update all image infos
291 UpdateAllImageInfos();
292
293 // If we didn't have an executable before, but now we do, then the
294 // dyld module shared pointer might be unique and we may need to add
295 // it again (since Target::SetExecutableModule() will clear the
296 // images). So append the dyld module back to the list if it is
297 /// unique!
Greg Claytonab429022010-12-12 21:03:32 +0000298 if (m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
Chris Lattner24943d22010-06-08 16:52:24 +0000299 UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
300
301 return true;
302 }
303 }
304 return false;
305}
306
307bool
308DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
309{
310 return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
311}
312
313bool
314DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
315{
316 bool changed = false;
317 if (module)
318 {
319 ObjectFile *image_object_file = module->GetObjectFile();
320 if (image_object_file)
321 {
322 SectionList *section_list = image_object_file->GetSectionList ();
323 if (section_list)
324 {
325 uint32_t num_sections = section_list->GetSize();
326 for (uint32_t i=0; i<num_sections; ++i)
327 {
328 Section* section = section_list->GetSectionAtIndex (i).get();
329 if (section)
330 {
331 const addr_t new_section_load_addr = section->GetFileAddress ();
Greg Claytoneea26402010-09-14 23:36:40 +0000332 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
Chris Lattner24943d22010-06-08 16:52:24 +0000333 if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
334 old_section_load_addr != new_section_load_addr)
335 {
Greg Claytoneea26402010-09-14 23:36:40 +0000336 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
Chris Lattner24943d22010-06-08 16:52:24 +0000337 changed = true;
338 }
339 }
340 }
341 }
342 }
343 }
344 return changed;
345}
346
347//----------------------------------------------------------------------
348// Update the load addresses for all segments in MODULE using the
349// updated INFO that is passed in.
350//----------------------------------------------------------------------
351bool
Greg Clayton24bc5d92011-03-30 18:16:51 +0000352DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
Chris Lattner24943d22010-06-08 16:52:24 +0000353{
354 bool changed = false;
355 if (module)
356 {
357 ObjectFile *image_object_file = module->GetObjectFile();
358 if (image_object_file)
359 {
360 SectionList *section_list = image_object_file->GetSectionList ();
361 if (section_list)
362 {
363 // All sections listed in the dyld image info structure will all
364 // either be fixed up already, or they will all be off by a single
365 // slide amount that is determined by finding the first segment
366 // that is at file offset zero which also has bytes (a file size
367 // that is greater than zero) in the object file.
368
369 // Determine the slide amount (if any)
370 info.slide = 0;
371 const size_t num_sections = section_list->GetSize();
372 size_t sect_idx = 0;
373 for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
374 {
375 // Iterate through the object file sections to find the
376 // first section that starts of file offset zero and that
377 // has bytes in the file...
378 Section *section = section_list->GetSectionAtIndex (sect_idx).get();
379 if (section)
380 {
381 // Find the first section that begins at file offset zero
382 // a file size (skip page zero).
383 if (section->GetFileOffset() == 0 && section->GetFileSize() > 0)
384 {
385 // We have now found the section, lets match it up
386 // with the section in the dyld image info structure.
387 const Segment *dyld_segment = info.FindSegment (section->GetName());
388 if (dyld_segment)
389 info.slide = info.address - dyld_segment->addr;
390 // We have found the slide amount, so we can exit
391 // this for loop.
392 break;
393 }
394 }
395 }
396
397 // We now know the slide amount, so go through all sections
398 // and update the load addresses with the correct values.
399 uint32_t num_segments = info.segments.size();
400 for (uint32_t i=0; i<num_segments; ++i)
401 {
402 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
403 assert (section_sp.get() != NULL);
404 const addr_t new_section_load_addr = info.segments[i].addr + info.slide;
Greg Claytoneea26402010-09-14 23:36:40 +0000405 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000406 if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
407 old_section_load_addr != new_section_load_addr)
408 {
Greg Claytoneea26402010-09-14 23:36:40 +0000409 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000410 changed = true;
411 }
412 }
413 }
414 }
415 }
416 return changed;
417}
418
419//----------------------------------------------------------------------
420// Update the load addresses for all segments in MODULE using the
421// updated INFO that is passed in.
422//----------------------------------------------------------------------
423bool
Greg Clayton24bc5d92011-03-30 18:16:51 +0000424DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
Chris Lattner24943d22010-06-08 16:52:24 +0000425{
426 bool changed = false;
427 if (module)
428 {
429 ObjectFile *image_object_file = module->GetObjectFile();
430 if (image_object_file)
431 {
432 SectionList *section_list = image_object_file->GetSectionList ();
433 if (section_list)
434 {
435 uint32_t num_segments = info.segments.size();
436 for (uint32_t i=0; i<num_segments; ++i)
437 {
438 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
439 assert (section_sp.get() != NULL);
440 const addr_t old_section_load_addr = info.segments[i].addr + info.slide;
Greg Claytoneea26402010-09-14 23:36:40 +0000441 if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
Chris Lattner24943d22010-06-08 16:52:24 +0000442 changed = true;
443 }
444 }
445 }
446 }
447 return changed;
448}
449
450
451//----------------------------------------------------------------------
452// Static callback function that gets called when our DYLD notification
453// breakpoint gets hit. We update all of our image infos and then
454// let our super class DynamicLoader class decide if we should stop
455// or not (based on global preference).
456//----------------------------------------------------------------------
457bool
458DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
459{
460 // Let the event know that the images have changed
461 DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
462 dyld_instance->UpdateAllImageInfos();
463 // Return true to stop the target, false to just let the target run
464 return dyld_instance->GetStopWhenImagesChange();
465}
466
467bool
468DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
469{
470 Mutex::Locker locker(m_mutex);
Greg Clayton20d338f2010-11-18 05:57:03 +0000471
472 // the all image infos is already valid for this process stop ID
473 if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id)
474 return true;
475
Chris Lattner24943d22010-06-08 16:52:24 +0000476 m_dyld_all_image_infos.Clear();
477 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
478 {
Greg Clayton395fc332011-02-15 21:59:32 +0000479 ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
Greg Clayton20d338f2010-11-18 05:57:03 +0000480 uint32_t addr_size = 4;
481 if (m_dyld_all_image_infos_addr > UINT32_MAX)
482 addr_size = 8;
483
Chris Lattner24943d22010-06-08 16:52:24 +0000484 uint8_t buf[256];
Greg Clayton20d338f2010-11-18 05:57:03 +0000485 DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
486 uint32_t offset = 0;
487
Jason Molenda1f3af542010-06-10 01:21:21 +0000488 const size_t count_v2 = sizeof (uint32_t) + // version
489 sizeof (uint32_t) + // infoArrayCount
490 addr_size + // infoArray
491 addr_size + // notification
492 addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad
493 addr_size; // dyldImageLoadAddress
494 const size_t count_v11 = count_v2 +
495 addr_size + // jitInfo
496 addr_size + // dyldVersion
497 addr_size + // errorMessage
498 addr_size + // terminationFlags
499 addr_size + // coreSymbolicationShmPage
500 addr_size + // systemOrderFlag
501 addr_size + // uuidArrayCount
502 addr_size + // uuidArray
503 addr_size + // dyldAllImageInfosAddress
504 addr_size + // initialImageCount
505 addr_size + // errorKind
506 addr_size + // errorClientOfDylibPath
507 addr_size + // errorTargetDylibPath
508 addr_size; // errorSymbol
509 assert (sizeof (buf) > count_v11);
510
511 int count;
Chris Lattner24943d22010-06-08 16:52:24 +0000512 Error error;
Jason Molenda1f3af542010-06-10 01:21:21 +0000513 if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
514 {
Jason Molenda1f3af542010-06-10 01:21:21 +0000515 m_dyld_all_image_infos.version = data.GetU32(&offset);
Greg Clayton20d338f2010-11-18 05:57:03 +0000516 // If anything in the high byte is set, we probably got the byte
517 // order incorrect (the process might not have it set correctly
518 // yet due to attaching to a program without a specified file).
519 if (m_dyld_all_image_infos.version & 0xff000000)
520 {
521 // We have guessed the wrong byte order. Swap it and try
522 // reading the version again.
523 if (byte_order == eByteOrderLittle)
524 byte_order = eByteOrderBig;
525 else
526 byte_order = eByteOrderLittle;
527
528 data.SetByteOrder (byte_order);
529 offset = 0;
530 m_dyld_all_image_infos.version = data.GetU32(&offset);
531 }
Jason Molenda1f3af542010-06-10 01:21:21 +0000532 }
533 else
534 {
535 return false;
536 }
537
538 if (m_dyld_all_image_infos.version >= 11)
539 count = count_v11;
540 else
541 count = count_v2;
542
Chris Lattner24943d22010-06-08 16:52:24 +0000543 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
544 if (bytes_read == count)
545 {
Greg Clayton20d338f2010-11-18 05:57:03 +0000546 offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000547 m_dyld_all_image_infos.version = data.GetU32(&offset);
548 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset);
549 m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset);
550 m_dyld_all_image_infos.notification = data.GetPointer(&offset);
551 m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset);
Jason Molenda1f3af542010-06-10 01:21:21 +0000552 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset);
553 // Adjust for padding.
554 offset += addr_size - 2;
555 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset);
556 if (m_dyld_all_image_infos.version >= 11)
Chris Lattner24943d22010-06-08 16:52:24 +0000557 {
Jason Molenda1f3af542010-06-10 01:21:21 +0000558 offset += addr_size * 8;
559 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset);
560
561 // When we started, we were given the actual address of the all_image_infos
562 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in
563 // m_dyld_all_image_infos_addr and is the most accurate address we have.
564
565 // We read the dyld_all_image_infos struct from memory; it contains its own address.
566 // If the address in the struct does not match the actual address,
567 // the dyld we're looking at has been loaded at a different location (slid) from
568 // where it intended to load. The addresses in the dyld_all_image_infos struct
569 // are the original, non-slid addresses, and need to be adjusted. Most importantly
570 // the address of dyld and the notification address need to be adjusted.
571
572 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr)
573 {
574 uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress;
575 uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress;
576 m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset;
577 m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset;
578 }
Chris Lattner24943d22010-06-08 16:52:24 +0000579 }
Greg Clayton20d338f2010-11-18 05:57:03 +0000580 m_dyld_all_image_infos_stop_id = m_process->GetStopID();
Chris Lattner24943d22010-06-08 16:52:24 +0000581 return true;
582 }
583 }
584 return false;
585}
586
587//----------------------------------------------------------------------
588// If we have found where the "_dyld_all_image_infos" lives in memory,
589// read the current info from it, and then update all image load
590// addresses (or lack thereof).
591//----------------------------------------------------------------------
592uint32_t
593DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
594{
Greg Claytone005f2c2010-11-06 01:53:30 +0000595 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Greg Clayton24bc5d92011-03-30 18:16:51 +0000596 ModuleList& target_images = m_process->GetTarget().GetImages();
597
Chris Lattner24943d22010-06-08 16:52:24 +0000598 if (ReadAllImageInfosStructure ())
599 {
600 Mutex::Locker locker(m_mutex);
Greg Clayton20d338f2010-11-18 05:57:03 +0000601 if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
602 m_dyld_image_infos.size();
603
Chris Lattner24943d22010-06-08 16:52:24 +0000604 uint32_t idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000605 uint32_t i = 0;
606 DYLDImageInfo::collection old_dyld_all_image_infos;
607 old_dyld_all_image_infos.swap(m_dyld_image_infos);
608
609 // If we made it here, we are assuming that the all dylib info data should
610 // be valid, lets read the info array.
Greg Clayton20d338f2010-11-18 05:57:03 +0000611 const ByteOrder endian = m_dyld.GetByteOrder();
612 const uint32_t addr_size = m_dyld.GetAddressByteSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000613
614 if (m_dyld_all_image_infos.dylib_info_count > 0)
615 {
616 if (m_dyld_all_image_infos.dylib_info_addr == 0)
617 {
618 // DYLD is updating the images right now...
619 }
620 else
621 {
622 m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
623 const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
624 DataBufferHeap info_data(count, 0);
625 Error error;
626 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr,
627 info_data.GetBytes(),
628 info_data.GetByteSize(),
629 error);
630 if (bytes_read == count)
631 {
632 uint32_t info_data_offset = 0;
633 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
634 for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++)
635 {
636 assert (i < m_dyld_image_infos.size());
637 m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
638 lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
639 m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
640
641 char raw_path[PATH_MAX];
642 m_process->ReadMemory (path_addr, raw_path, sizeof(raw_path), error);
Greg Clayton537a7a82010-10-20 20:54:39 +0000643 m_dyld_image_infos[i].file_spec.SetFile(raw_path, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000644 }
645 assert(i == m_dyld_all_image_infos.dylib_info_count);
646
647 UpdateAllImageInfosHeaderAndLoadCommands();
648 }
649 else
650 {
651 DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
652 m_dyld_image_infos.clear();
653 }
654 }
655 }
656 else
657 {
658 m_dyld_image_infos.clear();
659 }
660
661 // If our new list is smaller than our old list, we have unloaded
662 // some shared libraries
Greg Claytonab429022010-12-12 21:03:32 +0000663 if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size())
Chris Lattner24943d22010-06-08 16:52:24 +0000664 {
665 ModuleList unloaded_module_list;
Greg Claytonab429022010-12-12 21:03:32 +0000666 if (old_dyld_all_image_infos.size() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000667 {
Greg Claytonab429022010-12-12 21:03:32 +0000668 // This is the first time we are loading shared libraries,
669 // we need to make sure to trim anything that isn't in the
670 // m_dyld_image_infos out of the target module list since
671 // we might have shared libraries that got loaded from
672 // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH
673 // environment variables...
Greg Clayton24bc5d92011-03-30 18:16:51 +0000674 const size_t num_images = target_images.GetSize();
Greg Claytonab429022010-12-12 21:03:32 +0000675 for (idx = 0; idx < num_images; ++idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000676 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000677 ModuleSP module_sp (target_images.GetModuleAtIndex (idx));
Greg Claytonab429022010-12-12 21:03:32 +0000678
Greg Clayton24bc5d92011-03-30 18:16:51 +0000679 if (GetImageInfo (module_sp.get()) == NULL)
Greg Claytonab429022010-12-12 21:03:32 +0000680 unloaded_module_list.AppendIfNeeded (module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000681 }
682 }
Greg Claytonab429022010-12-12 21:03:32 +0000683 else
Greg Clayton9d2993d2010-11-03 04:08:06 +0000684 {
Greg Claytonab429022010-12-12 21:03:32 +0000685 uint32_t old_idx;
686 for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx)
Greg Clayton9d2993d2010-11-03 04:08:06 +0000687 {
Greg Claytonab429022010-12-12 21:03:32 +0000688 for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
Greg Clayton9d2993d2010-11-03 04:08:06 +0000689 {
Greg Claytonab429022010-12-12 21:03:32 +0000690 if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec)
691 {
692 old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS;
693 break;
694 }
695 }
696 }
697
Greg Claytonab429022010-12-12 21:03:32 +0000698 for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
699 {
700 if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS)
701 {
702 if (log)
703 old_dyld_all_image_infos[old_idx].PutToLog (log.get());
Greg Clayton24bc5d92011-03-30 18:16:51 +0000704 ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL));
Greg Claytonab429022010-12-12 21:03:32 +0000705 if (unload_image_module_sp.get())
706 {
707 if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx]))
708 unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
709 }
Greg Clayton9d2993d2010-11-03 04:08:06 +0000710 }
711 }
712 }
713
Chris Lattner24943d22010-06-08 16:52:24 +0000714 if (unloaded_module_list.GetSize() > 0)
Greg Clayton427f2902010-12-14 02:59:59 +0000715 {
716 if (log)
717 {
718 log->PutCString("Unloaded:");
719 unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
720 }
Chris Lattner24943d22010-06-08 16:52:24 +0000721 m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
Greg Clayton427f2902010-12-14 02:59:59 +0000722 }
Chris Lattner24943d22010-06-08 16:52:24 +0000723 }
Greg Clayton9d2993d2010-11-03 04:08:06 +0000724 else
725 {
726 if (log)
Greg Claytone005f2c2010-11-06 01:53:30 +0000727 PutToLog(log.get());
Greg Clayton9d2993d2010-11-03 04:08:06 +0000728 }
Greg Clayton20d338f2010-11-18 05:57:03 +0000729 m_dyld_image_infos_stop_id = m_process->GetStopID();
Chris Lattner24943d22010-06-08 16:52:24 +0000730 }
731 else
732 {
733 m_dyld_image_infos.clear();
734 }
735
736 const uint32_t num_dylibs = m_dyld_image_infos.size();
737 if (num_dylibs > 0)
738 {
739 ModuleList loaded_module_list;
740 for (uint32_t idx = 0; idx<num_dylibs; ++idx)
741 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000742 ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL));
Chris Lattner24943d22010-06-08 16:52:24 +0000743
744 if (image_module_sp)
745 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000746 if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
Greg Clayton236c1c72010-09-07 23:40:05 +0000747 image_module_sp->SetIsDynamicLinkEditor (true);
748
Chris Lattner24943d22010-06-08 16:52:24 +0000749 ObjectFile *objfile = image_module_sp->GetObjectFile ();
750 if (objfile)
751 {
752 SectionList *sections = objfile->GetSectionList();
753 if (sections)
754 {
755 ConstString commpage_dbstr("__commpage");
756 Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
757 if (commpage_section)
758 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000759 const FileSpec objfile_file_spec = objfile->GetFileSpec();
760 ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ());
761 ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr));
762 if (!commpage_image_module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000763 {
764 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000765 arch,
Chris Lattner24943d22010-06-08 16:52:24 +0000766 &m_dyld_image_infos[idx].uuid,
767 &commpage_dbstr,
768 objfile->GetOffset() + commpage_section->GetOffset());
Chris Lattner24943d22010-06-08 16:52:24 +0000769 }
Greg Clayton24bc5d92011-03-30 18:16:51 +0000770 if (commpage_image_module_sp)
771 UpdateCommPageLoadAddress (commpage_image_module_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000772 }
773 }
774 }
775
776 // UpdateImageLoadAddress will return true if any segments
777 // change load address. We need to check this so we don't
778 // mention that all loaded shared libraries are newly loaded
779 // each time we hit out dyld breakpoint since dyld will list all
780 // shared libraries each time.
781 if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
782 {
Greg Claytonab429022010-12-12 21:03:32 +0000783 loaded_module_list.AppendIfNeeded (image_module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000784 }
785 }
786 }
Chris Lattner24943d22010-06-08 16:52:24 +0000787 if (loaded_module_list.GetSize() > 0)
788 {
789 // FIXME: This should really be in the Runtime handlers class, which should get
790 // called by the target's ModulesDidLoad, but we're doing it all locally for now
791 // to save time.
792 // Also, I'm assuming there can be only one libobjc dylib loaded...
793
Jim Inghamb66cd072010-09-28 01:25:32 +0000794 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
795 if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
Chris Lattner24943d22010-06-08 16:52:24 +0000796 {
797 size_t num_modules = loaded_module_list.GetSize();
798 for (int i = 0; i < num_modules; i++)
799 {
Jim Inghamb66cd072010-09-28 01:25:32 +0000800 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
Chris Lattner24943d22010-06-08 16:52:24 +0000801 {
Jim Inghamb66cd072010-09-28 01:25:32 +0000802 objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
Chris Lattner24943d22010-06-08 16:52:24 +0000803 break;
804 }
805 }
806 }
Greg Clayton427f2902010-12-14 02:59:59 +0000807 if (log)
808 loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
Chris Lattner24943d22010-06-08 16:52:24 +0000809 m_process->GetTarget().ModulesDidLoad (loaded_module_list);
810 }
811 }
812 return m_dyld_image_infos.size();
813}
814
815//----------------------------------------------------------------------
816// Read a mach_header at ADDR into HEADER, and also fill in the load
817// command data into LOAD_COMMAND_DATA if it is non-NULL.
818//
819// Returns true if we succeed, false if we fail for any reason.
820//----------------------------------------------------------------------
821bool
Greg Clayton24bc5d92011-03-30 18:16:51 +0000822DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data)
Chris Lattner24943d22010-06-08 16:52:24 +0000823{
Greg Clayton24bc5d92011-03-30 18:16:51 +0000824 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000825 Error error;
826 size_t bytes_read = m_process->ReadMemory (addr,
827 header_bytes.GetBytes(),
828 header_bytes.GetByteSize(),
829 error);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000830 if (bytes_read == sizeof(llvm::MachO::mach_header))
Chris Lattner24943d22010-06-08 16:52:24 +0000831 {
832 uint32_t offset = 0;
833 ::memset (header, 0, sizeof(header));
834
835 // Get the magic byte unswapped so we can figure out what we are dealing with
Greg Claytoncd548032011-02-01 01:31:41 +0000836 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4);
Chris Lattner24943d22010-06-08 16:52:24 +0000837 header->magic = data.GetU32(&offset);
838 lldb::addr_t load_cmd_addr = addr;
839 data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic));
840 switch (header->magic)
841 {
Greg Clayton1674b122010-07-21 22:12:05 +0000842 case llvm::MachO::HeaderMagic32:
843 case llvm::MachO::HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000844 data.SetAddressByteSize(4);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000845 load_cmd_addr += sizeof(llvm::MachO::mach_header);
Chris Lattner24943d22010-06-08 16:52:24 +0000846 break;
847
Greg Clayton1674b122010-07-21 22:12:05 +0000848 case llvm::MachO::HeaderMagic64:
849 case llvm::MachO::HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000850 data.SetAddressByteSize(8);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000851 load_cmd_addr += sizeof(llvm::MachO::mach_header_64);
Chris Lattner24943d22010-06-08 16:52:24 +0000852 break;
853
854 default:
855 return false;
856 }
857
858 // Read the rest of dyld's mach header
Greg Clayton24bc5d92011-03-30 18:16:51 +0000859 if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
Chris Lattner24943d22010-06-08 16:52:24 +0000860 {
861 if (load_command_data == NULL)
862 return true; // We were able to read the mach_header and weren't asked to read the load command bytes
863
864 DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0));
865
866 size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr,
867 load_cmd_data_sp->GetBytes(),
868 load_cmd_data_sp->GetByteSize(),
869 error);
870
871 if (load_cmd_bytes_read == header->sizeofcmds)
872 {
873 // Set the load command data and also set the correct endian
874 // swap settings and the correct address size
875 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds);
876 load_command_data->SetByteOrder(data.GetByteOrder());
877 load_command_data->SetAddressByteSize(data.GetAddressByteSize());
878 return true; // We successfully read the mach_header and the load command data
879 }
880
881 return false; // We weren't able to read the load command data
882 }
883 }
884 return false; // We failed the read the mach_header
885}
886
887
888//----------------------------------------------------------------------
889// Parse the load commands for an image
890//----------------------------------------------------------------------
891uint32_t
Greg Clayton24bc5d92011-03-30 18:16:51 +0000892DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
Chris Lattner24943d22010-06-08 16:52:24 +0000893{
894 uint32_t offset = 0;
895 uint32_t cmd_idx;
896 Segment segment;
897 dylib_info.Clear (true);
898
899 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++)
900 {
901 // Clear out any load command specific data from DYLIB_INFO since
902 // we are about to read it.
903
Greg Clayton24bc5d92011-03-30 18:16:51 +0000904 if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
Chris Lattner24943d22010-06-08 16:52:24 +0000905 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000906 llvm::MachO::load_command load_cmd;
Chris Lattner24943d22010-06-08 16:52:24 +0000907 uint32_t load_cmd_offset = offset;
908 load_cmd.cmd = data.GetU32 (&offset);
909 load_cmd.cmdsize = data.GetU32 (&offset);
910 switch (load_cmd.cmd)
911 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000912 case llvm::MachO::LoadCommandSegment32:
Chris Lattner24943d22010-06-08 16:52:24 +0000913 {
914 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
915 segment.addr = data.GetU32 (&offset);
916 segment.size = data.GetU32 (&offset);
917 dylib_info.segments.push_back (segment);
918 }
919 break;
920
Greg Clayton24bc5d92011-03-30 18:16:51 +0000921 case llvm::MachO::LoadCommandSegment64:
Chris Lattner24943d22010-06-08 16:52:24 +0000922 {
923 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
924 segment.addr = data.GetU64 (&offset);
925 segment.size = data.GetU64 (&offset);
926 dylib_info.segments.push_back (segment);
927 }
928 break;
929
Greg Clayton24bc5d92011-03-30 18:16:51 +0000930 case llvm::MachO::LoadCommandDynamicLinkerIdent:
Chris Lattner24943d22010-06-08 16:52:24 +0000931 if (lc_id_dylinker)
932 {
933 uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
934 const char *path = data.PeekCStr (name_offset);
Greg Clayton537a7a82010-10-20 20:54:39 +0000935 lc_id_dylinker->SetFile (path, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000936 }
937 break;
938
Greg Clayton24bc5d92011-03-30 18:16:51 +0000939 case llvm::MachO::LoadCommandUUID:
Chris Lattner24943d22010-06-08 16:52:24 +0000940 dylib_info.uuid.SetBytes(data.GetData (&offset, 16));
941 break;
942
943 default:
944 break;
945 }
946 // Set offset to be the beginning of the next load command.
947 offset = load_cmd_offset + load_cmd.cmdsize;
948 }
949 }
950 return cmd_idx;
951}
952
953//----------------------------------------------------------------------
954// Read the mach_header and load commands for each image that the
955// _dyld_all_image_infos structure points to and cache the results.
956//----------------------------------------------------------------------
957void
958DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
959{
960 uint32_t exe_idx = UINT32_MAX;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000961 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Chris Lattner24943d22010-06-08 16:52:24 +0000962 // Read any UUID values that we can get
963 for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
964 {
965 if (!m_dyld_image_infos[i].UUIDValid())
966 {
967 DataExtractor data; // Load command data
968 if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
969 continue;
970
971 ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
972
Greg Clayton24bc5d92011-03-30 18:16:51 +0000973 if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
Chris Lattner24943d22010-06-08 16:52:24 +0000974 exe_idx = i;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000975
976 if (log)
977 m_dyld_image_infos[i].PutToLog (log.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000978 }
979 }
980
981 if (exe_idx < m_dyld_image_infos.size())
982 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000983 ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL));
Chris Lattner24943d22010-06-08 16:52:24 +0000984
Greg Clayton24bc5d92011-03-30 18:16:51 +0000985 if (!exe_module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000986 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000987 ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ());
Chris Lattner24943d22010-06-08 16:52:24 +0000988 exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000989 exe_arch_spec,
Chris Lattner24943d22010-06-08 16:52:24 +0000990 &m_dyld_image_infos[exe_idx].uuid);
Greg Clayton24bc5d92011-03-30 18:16:51 +0000991 }
992
993 if (exe_module_sp)
994 {
995 if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModule().get())
Chris Lattner24943d22010-06-08 16:52:24 +0000996 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000997 // Don't load dependent images since we are in dyld where we will know
998 // and find out about all images that are loaded
999 bool get_dependent_images = false;
1000 m_process->GetTarget().SetExecutableModule (exe_module_sp,
1001 get_dependent_images);
Chris Lattner24943d22010-06-08 16:52:24 +00001002 }
1003 }
1004 }
1005}
1006
1007//----------------------------------------------------------------------
1008// Dump a Segment to the file handle provided.
1009//----------------------------------------------------------------------
1010void
1011DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
1012{
1013 if (log)
1014 log->Printf("\t\t%16s [0x%16.16llx - 0x%16.16llx)", name.AsCString(""), addr + slide, addr + slide + size);
1015}
1016
1017const DynamicLoaderMacOSXDYLD::Segment *
1018DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
1019{
1020 const size_t num_segments = segments.size();
1021 for (size_t i=0; i<num_segments; ++i)
1022 {
1023 if (segments[i].name == name)
1024 return &segments[i];
1025 }
1026 return NULL;
1027}
1028
1029
1030//----------------------------------------------------------------------
1031// Dump an image info structure to the file handle provided.
1032//----------------------------------------------------------------------
1033void
1034DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
1035{
1036 if (log == NULL)
1037 return;
1038 uint8_t *u = (uint8_t *)uuid.GetBytes();
1039
1040 if (address == LLDB_INVALID_ADDRESS)
1041 {
1042 if (u)
1043 {
1044 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)",
1045 mod_date,
1046 u[ 0], u[ 1], u[ 2], u[ 3],
1047 u[ 4], u[ 5], u[ 6], u[ 7],
1048 u[ 8], u[ 9], u[10], u[11],
1049 u[12], u[13], u[14], u[15],
1050 file_spec.GetDirectory().AsCString(),
1051 file_spec.GetFilename().AsCString());
1052 }
1053 else
1054 log->Printf("\t modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
1055 mod_date,
1056 file_spec.GetDirectory().AsCString(),
1057 file_spec.GetFilename().AsCString());
1058 }
1059 else
1060 {
1061 if (u)
1062 {
1063 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'",
1064 address,
1065 mod_date,
1066 u[ 0], u[ 1], u[ 2], u[ 3],
1067 u[ 4], u[ 5], u[ 6], u[ 7],
1068 u[ 8], u[ 9], u[10], u[11],
1069 u[12], u[13], u[14], u[15],
1070 file_spec.GetDirectory().AsCString(),
1071 file_spec.GetFilename().AsCString());
1072 }
1073 else
1074 {
1075 log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
1076 address,
1077 mod_date,
1078 file_spec.GetDirectory().AsCString(),
1079 file_spec.GetFilename().AsCString());
1080
1081 }
1082 for (uint32_t i=0; i<segments.size(); ++i)
1083 segments[i].PutToLog(log, slide);
1084 }
1085}
1086
1087//----------------------------------------------------------------------
1088// Dump the _dyld_all_image_infos members and all current image infos
1089// that we have parsed to the file handle provided.
1090//----------------------------------------------------------------------
1091void
1092DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const
1093{
1094 if (log == NULL)
1095 return;
1096
1097 Mutex::Locker locker(m_mutex);
1098 log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
1099 m_dyld_all_image_infos.version,
1100 m_dyld_all_image_infos.dylib_info_count,
1101 (uint64_t)m_dyld_all_image_infos.dylib_info_addr,
1102 (uint64_t)m_dyld_all_image_infos.notification);
1103 size_t i;
1104 const size_t count = m_dyld_image_infos.size();
1105 if (count > 0)
1106 {
Greg Clayton9d2993d2010-11-03 04:08:06 +00001107 log->PutCString("Loaded:");
Chris Lattner24943d22010-06-08 16:52:24 +00001108 for (i = 0; i<count; i++)
1109 m_dyld_image_infos[i].PutToLog(log);
1110 }
1111}
1112
Chris Lattner24943d22010-06-08 16:52:24 +00001113void
1114DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
1115{
1116 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1117 Clear(true);
1118 m_process = process;
Greg Clayton58e844b2010-12-08 05:08:21 +00001119 m_process->GetTarget().GetSectionLoadList().Clear();
Chris Lattner24943d22010-06-08 16:52:24 +00001120}
1121
1122bool
1123DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
1124{
1125 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
1126 if (m_break_id == LLDB_INVALID_BREAK_ID)
1127 {
1128 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS)
1129 {
1130 Address so_addr;
1131 // Set the notification breakpoint and install a breakpoint
1132 // callback function that will get called each time the
1133 // breakpoint gets hit. We will use this to track when shared
1134 // libraries get loaded/unloaded.
1135
Greg Claytoneea26402010-09-14 23:36:40 +00001136 if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr))
Chris Lattner24943d22010-06-08 16:52:24 +00001137 {
1138 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
1139 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
1140 m_break_id = dyld_break->GetID();
1141 }
1142 }
1143 }
1144 return m_break_id != LLDB_INVALID_BREAK_ID;
1145}
1146
Jim Ingham7508e732010-08-09 23:31:02 +00001147//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +00001148// Member function that gets called when the process state changes.
1149//----------------------------------------------------------------------
1150void
1151DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
1152{
1153 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
1154 switch (state)
1155 {
Greg Claytone71e2582011-02-04 01:58:07 +00001156 case eStateConnected:
Chris Lattner24943d22010-06-08 16:52:24 +00001157 case eStateAttaching:
1158 case eStateLaunching:
1159 case eStateInvalid:
1160 case eStateUnloaded:
1161 case eStateExited:
1162 case eStateDetached:
1163 Clear(false);
1164 break;
1165
1166 case eStateStopped:
1167 // Keep trying find dyld and set our notification breakpoint each time
1168 // we stop until we succeed
1169 if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
1170 {
1171 if (NeedToLocateDYLD ())
1172 LocateDYLD ();
1173
1174 SetNotificationBreakpoint ();
1175 }
1176 break;
1177
1178 case eStateRunning:
1179 case eStateStepping:
1180 case eStateCrashed:
1181 case eStateSuspended:
1182 break;
1183
1184 default:
1185 break;
1186 }
1187}
1188
1189ThreadPlanSP
1190DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
1191{
1192 ThreadPlanSP thread_plan_sp;
1193 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
1194 const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
1195 Symbol *current_symbol = current_context.symbol;
Greg Claytone005f2c2010-11-06 01:53:30 +00001196 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner24943d22010-06-08 16:52:24 +00001197
1198 if (current_symbol != NULL)
1199 {
1200 if (current_symbol->IsTrampoline())
1201 {
Jim Ingham17454cf2010-09-14 22:03:00 +00001202 const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled);
1203
Chris Lattner24943d22010-06-08 16:52:24 +00001204 if (trampoline_name)
1205 {
1206 SymbolContextList target_symbols;
1207 ModuleList &images = thread.GetProcess().GetTarget().GetImages();
1208 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols);
1209 // FIXME - Make the Run to Address take multiple addresses, and
1210 // run to any of them.
Jim Ingham17454cf2010-09-14 22:03:00 +00001211 uint32_t num_symbols = target_symbols.GetSize();
1212 if (num_symbols == 1)
Chris Lattner24943d22010-06-08 16:52:24 +00001213 {
1214 SymbolContext context;
1215 AddressRange addr_range;
1216 if (target_symbols.GetContextAtIndex(0, context))
1217 {
1218 context.GetAddressRange (eSymbolContextEverything, addr_range);
1219 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others));
1220 }
Jim Ingham17454cf2010-09-14 22:03:00 +00001221 else
Chris Lattner24943d22010-06-08 16:52:24 +00001222 {
Jim Ingham17454cf2010-09-14 22:03:00 +00001223 if (log)
1224 log->Printf ("Couldn't resolve the symbol context.");
1225 }
1226 }
1227 else if (num_symbols > 1)
1228 {
1229 std::vector<lldb::addr_t> addresses;
1230 addresses.resize (num_symbols);
1231 for (uint32_t i = 0; i < num_symbols; i++)
1232 {
1233 SymbolContext context;
1234 AddressRange addr_range;
1235 if (target_symbols.GetContextAtIndex(i, context))
1236 {
1237 context.GetAddressRange (eSymbolContextEverything, addr_range);
Greg Claytoneea26402010-09-14 23:36:40 +00001238 lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget());
Jim Ingham17454cf2010-09-14 22:03:00 +00001239 addresses[i] = load_addr;
1240 }
1241 }
1242 if (addresses.size() > 0)
1243 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others));
1244 else
1245 {
1246 if (log)
1247 log->Printf ("Couldn't resolve the symbol contexts.");
Chris Lattner24943d22010-06-08 16:52:24 +00001248 }
1249 }
1250 else
1251 {
Chris Lattner24943d22010-06-08 16:52:24 +00001252 if (log)
1253 {
1254 log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString());
1255 }
1256 }
1257 }
1258 }
1259 }
Jim Ingham17454cf2010-09-14 22:03:00 +00001260 else
1261 {
1262 if (log)
1263 log->Printf ("Could not find symbol for step through.");
1264 }
Chris Lattner24943d22010-06-08 16:52:24 +00001265
Chris Lattner24943d22010-06-08 16:52:24 +00001266 return thread_plan_sp;
1267}
1268
Greg Clayton0baa3942010-11-04 01:54:29 +00001269Error
1270DynamicLoaderMacOSXDYLD::CanLoadImage ()
1271{
1272 Error error;
1273 // In order for us to tell if we can load a shared library we verify that
1274 // the dylib_info_addr isn't zero (which means no shared libraries have
1275 // been set yet, or dyld is currently mucking with the shared library list).
1276 if (ReadAllImageInfosStructure ())
1277 {
1278 // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
1279 // TODO: check the malloc lock?
1280 // TODO: check the objective C lock?
1281 if (m_dyld_all_image_infos.dylib_info_addr != 0)
1282 return error; // Success
1283 }
1284
1285 error.SetErrorString("unsafe to load or unload shared libraries");
1286 return error;
1287}
1288
Chris Lattner24943d22010-06-08 16:52:24 +00001289void
1290DynamicLoaderMacOSXDYLD::Initialize()
1291{
1292 PluginManager::RegisterPlugin (GetPluginNameStatic(),
1293 GetPluginDescriptionStatic(),
1294 CreateInstance);
1295}
1296
1297void
1298DynamicLoaderMacOSXDYLD::Terminate()
1299{
1300 PluginManager::UnregisterPlugin (CreateInstance);
1301}
1302
1303
1304const char *
1305DynamicLoaderMacOSXDYLD::GetPluginNameStatic()
1306{
1307 return "dynamic-loader.macosx-dyld";
1308}
1309
1310const char *
1311DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic()
1312{
1313 return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes.";
1314}
1315
1316
1317//------------------------------------------------------------------
1318// PluginInterface protocol
1319//------------------------------------------------------------------
1320const char *
1321DynamicLoaderMacOSXDYLD::GetPluginName()
1322{
1323 return "DynamicLoaderMacOSXDYLD";
1324}
1325
1326const char *
1327DynamicLoaderMacOSXDYLD::GetShortPluginName()
1328{
1329 return GetPluginNameStatic();
1330}
1331
1332uint32_t
1333DynamicLoaderMacOSXDYLD::GetPluginVersion()
1334{
1335 return 1;
1336}
1337