DynamicLoaderMacOSXDYLD.cpp revision 6e3dc10663891a232585968ddd3b19df563dbb96
1//===-- 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" 18#include "lldb/Target/ObjCLanguageRuntime.h" 19#include "lldb/Target/RegisterContext.h" 20#include "lldb/Target/Target.h" 21#include "lldb/Target/Thread.h" 22#include "lldb/Target/ThreadPlanRunToAddress.h" 23#include "lldb/Target/StackFrame.h" 24 25#include "DynamicLoaderMacOSXDYLD.h" 26 27//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 28#ifdef ENABLE_DEBUG_PRINTF 29#include <stdio.h> 30#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 31#else 32#define DEBUG_PRINTF(fmt, ...) 33#endif 34 35using namespace lldb; 36using namespace lldb_private; 37 38/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here. 39/// I am putting it here so I can invoke it in the Trampoline code here, but 40/// it should be moved to the ObjC Runtime support when it is set up. 41 42 43DynamicLoaderMacOSXDYLD::DYLDImageInfo * 44DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module) 45{ 46 const UUID &module_uuid = module->GetUUID(); 47 DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end(); 48 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(); 68 for (pos = m_dyld_image_infos.begin(); pos != end; ++pos) 69 { 70 if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false) 71 return &(*pos); 72 } 73 74 if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false) 75 return &m_dyld; 76 77 return NULL; 78} 79 80//---------------------------------------------------------------------- 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 * 86DynamicLoaderMacOSXDYLD::CreateInstance (Process* process, bool force) 87{ 88 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; 99} 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(), 109 m_dyld_all_image_infos_stop_id (UINT32_MAX), 110 m_break_id(LLDB_INVALID_BREAK_ID), 111 m_dyld_image_infos(), 112 m_dyld_image_infos_stop_id (UINT32_MAX), 113 m_mutex(Mutex::eMutexTypeRecursive) 114{ 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); 135 LocateDYLD (); 136 SetNotificationBreakpoint (); 137} 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); 149 LocateDYLD (); 150 SetNotificationBreakpoint (); 151} 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 228ModuleSP 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 257//---------------------------------------------------------------------- 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 { 267 if (m_dyld.header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor) 268 { 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 { 275 dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL); 276 277 if (dyld_module_sp) 278 UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld); 279 } 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) 287 m_dyld_all_image_infos_addr = symbol->GetValue().GetLoadAddress(&m_process->GetTarget()); 288 } 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! 298 if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp)) 299 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 (); 332 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section); 333 if (old_section_load_addr == LLDB_INVALID_ADDRESS || 334 old_section_load_addr != new_section_load_addr) 335 { 336 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ())) 337 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 352DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info) 353{ 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 // We now know the slide amount, so go through all sections 364 // and update the load addresses with the correct values. 365 uint32_t num_segments = info.segments.size(); 366 for (uint32_t i=0; i<num_segments; ++i) 367 { 368 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 369 assert (section_sp.get() != NULL); 370 const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide; 371 const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get()); 372 if (old_section_load_addr == LLDB_INVALID_ADDRESS || 373 old_section_load_addr != new_section_load_addr) 374 { 375 if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr)) 376 changed = true; 377 } 378 } 379 } 380 } 381 } 382 return changed; 383} 384 385//---------------------------------------------------------------------- 386// Update the load addresses for all segments in MODULE using the 387// updated INFO that is passed in. 388//---------------------------------------------------------------------- 389bool 390DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info) 391{ 392 bool changed = false; 393 if (module) 394 { 395 ObjectFile *image_object_file = module->GetObjectFile(); 396 if (image_object_file) 397 { 398 SectionList *section_list = image_object_file->GetSectionList (); 399 if (section_list) 400 { 401 uint32_t num_segments = info.segments.size(); 402 for (uint32_t i=0; i<num_segments; ++i) 403 { 404 SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name)); 405 assert (section_sp.get() != NULL); 406 const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide; 407 if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr)) 408 changed = true; 409 } 410 } 411 } 412 } 413 return changed; 414} 415 416 417//---------------------------------------------------------------------- 418// Static callback function that gets called when our DYLD notification 419// breakpoint gets hit. We update all of our image infos and then 420// let our super class DynamicLoader class decide if we should stop 421// or not (based on global preference). 422//---------------------------------------------------------------------- 423bool 424DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 425{ 426 // Let the event know that the images have changed 427 DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton; 428 dyld_instance->UpdateAllImageInfos(); 429 // Return true to stop the target, false to just let the target run 430 return dyld_instance->GetStopWhenImagesChange(); 431} 432 433bool 434DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure () 435{ 436 Mutex::Locker locker(m_mutex); 437 438 // the all image infos is already valid for this process stop ID 439 if (m_process->GetStopID() == m_dyld_all_image_infos_stop_id) 440 return true; 441 442 m_dyld_all_image_infos.Clear(); 443 if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) 444 { 445 ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder(); 446 uint32_t addr_size = 4; 447 if (m_dyld_all_image_infos_addr > UINT32_MAX) 448 addr_size = 8; 449 450 uint8_t buf[256]; 451 DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 452 uint32_t offset = 0; 453 454 const size_t count_v2 = sizeof (uint32_t) + // version 455 sizeof (uint32_t) + // infoArrayCount 456 addr_size + // infoArray 457 addr_size + // notification 458 addr_size + // processDetachedFromSharedRegion + libSystemInitialized + pad 459 addr_size; // dyldImageLoadAddress 460 const size_t count_v11 = count_v2 + 461 addr_size + // jitInfo 462 addr_size + // dyldVersion 463 addr_size + // errorMessage 464 addr_size + // terminationFlags 465 addr_size + // coreSymbolicationShmPage 466 addr_size + // systemOrderFlag 467 addr_size + // uuidArrayCount 468 addr_size + // uuidArray 469 addr_size + // dyldAllImageInfosAddress 470 addr_size + // initialImageCount 471 addr_size + // errorKind 472 addr_size + // errorClientOfDylibPath 473 addr_size + // errorTargetDylibPath 474 addr_size; // errorSymbol 475 assert (sizeof (buf) > count_v11); 476 477 int count; 478 Error error; 479 if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4) 480 { 481 m_dyld_all_image_infos.version = data.GetU32(&offset); 482 // If anything in the high byte is set, we probably got the byte 483 // order incorrect (the process might not have it set correctly 484 // yet due to attaching to a program without a specified file). 485 if (m_dyld_all_image_infos.version & 0xff000000) 486 { 487 // We have guessed the wrong byte order. Swap it and try 488 // reading the version again. 489 if (byte_order == eByteOrderLittle) 490 byte_order = eByteOrderBig; 491 else 492 byte_order = eByteOrderLittle; 493 494 data.SetByteOrder (byte_order); 495 offset = 0; 496 m_dyld_all_image_infos.version = data.GetU32(&offset); 497 } 498 } 499 else 500 { 501 return false; 502 } 503 504 if (m_dyld_all_image_infos.version >= 11) 505 count = count_v11; 506 else 507 count = count_v2; 508 509 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error); 510 if (bytes_read == count) 511 { 512 offset = 0; 513 m_dyld_all_image_infos.version = data.GetU32(&offset); 514 m_dyld_all_image_infos.dylib_info_count = data.GetU32(&offset); 515 m_dyld_all_image_infos.dylib_info_addr = data.GetPointer(&offset); 516 m_dyld_all_image_infos.notification = data.GetPointer(&offset); 517 m_dyld_all_image_infos.processDetachedFromSharedRegion = data.GetU8(&offset); 518 m_dyld_all_image_infos.libSystemInitialized = data.GetU8(&offset); 519 // Adjust for padding. 520 offset += addr_size - 2; 521 m_dyld_all_image_infos.dyldImageLoadAddress = data.GetPointer(&offset); 522 if (m_dyld_all_image_infos.version >= 11) 523 { 524 offset += addr_size * 8; 525 uint64_t dyld_all_image_infos_addr = data.GetPointer(&offset); 526 527 // When we started, we were given the actual address of the all_image_infos 528 // struct (probably via TASK_DYLD_INFO) in memory - this address is stored in 529 // m_dyld_all_image_infos_addr and is the most accurate address we have. 530 531 // We read the dyld_all_image_infos struct from memory; it contains its own address. 532 // If the address in the struct does not match the actual address, 533 // the dyld we're looking at has been loaded at a different location (slid) from 534 // where it intended to load. The addresses in the dyld_all_image_infos struct 535 // are the original, non-slid addresses, and need to be adjusted. Most importantly 536 // the address of dyld and the notification address need to be adjusted. 537 538 if (dyld_all_image_infos_addr != m_dyld_all_image_infos_addr) 539 { 540 uint64_t image_infos_offset = dyld_all_image_infos_addr - m_dyld_all_image_infos.dyldImageLoadAddress; 541 uint64_t notification_offset = m_dyld_all_image_infos.notification - m_dyld_all_image_infos.dyldImageLoadAddress; 542 m_dyld_all_image_infos.dyldImageLoadAddress = m_dyld_all_image_infos_addr - image_infos_offset; 543 m_dyld_all_image_infos.notification = m_dyld_all_image_infos.dyldImageLoadAddress + notification_offset; 544 } 545 } 546 m_dyld_all_image_infos_stop_id = m_process->GetStopID(); 547 return true; 548 } 549 } 550 return false; 551} 552 553//---------------------------------------------------------------------- 554// If we have found where the "_dyld_all_image_infos" lives in memory, 555// read the current info from it, and then update all image load 556// addresses (or lack thereof). 557//---------------------------------------------------------------------- 558uint32_t 559DynamicLoaderMacOSXDYLD::UpdateAllImageInfos() 560{ 561 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 562 ModuleList& target_images = m_process->GetTarget().GetImages(); 563 564 if (ReadAllImageInfosStructure ()) 565 { 566 Mutex::Locker locker(m_mutex); 567 if (m_process->GetStopID() == m_dyld_image_infos_stop_id) 568 m_dyld_image_infos.size(); 569 570 uint32_t idx; 571 uint32_t i = 0; 572 // Since we can't downsize a vector, we must do this using the swap method 573 DYLDImageInfo::collection old_dyld_all_image_infos; 574 old_dyld_all_image_infos.swap(m_dyld_image_infos); 575 576 // If we made it here, we are assuming that the all dylib info data should 577 // be valid, lets read the info array. 578 const ByteOrder endian = m_dyld.GetByteOrder(); 579 const uint32_t addr_size = m_dyld.GetAddressByteSize(); 580 581 if (m_dyld_all_image_infos.dylib_info_count > 0) 582 { 583 if (m_dyld_all_image_infos.dylib_info_addr == 0) 584 { 585 // DYLD is updating the images right now... 586 } 587 else 588 { 589 m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count); 590 const size_t count = m_dyld_image_infos.size() * 3 * addr_size; 591 DataBufferHeap info_data(count, 0); 592 Error error; 593 const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr, 594 info_data.GetBytes(), 595 info_data.GetByteSize(), 596 error); 597 if (bytes_read == count) 598 { 599 uint32_t info_data_offset = 0; 600 DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size); 601 for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++) 602 { 603 assert (i < m_dyld_image_infos.size()); 604 m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset); 605 lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); 606 m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); 607 608 char raw_path[PATH_MAX]; 609 m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path)); 610 char raw_path2[PATH_MAX];// TODO: remove after assertion doesn't assert 611 m_process->ReadMemory (path_addr, raw_path2, sizeof(raw_path2), error);// TODO: remove after assertion doesn't assert 612 assert (strcmp (raw_path, raw_path2) == 0);// TODO: remove after assertion doesn't assert 613 m_dyld_image_infos[i].file_spec.SetFile(raw_path, true); 614 } 615 assert(i == m_dyld_all_image_infos.dylib_info_count); 616 617 UpdateAllImageInfosHeaderAndLoadCommands(); 618 } 619 else 620 { 621 DEBUG_PRINTF( "unable to read all data for all_dylib_infos."); 622 m_dyld_image_infos.clear(); 623 } 624 } 625 } 626 627 // If our new list is smaller than our old list, we have unloaded 628 // some shared libraries 629 if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size()) 630 { 631 ModuleList unloaded_module_list; 632 if (old_dyld_all_image_infos.size() == 0) 633 { 634 // This is the first time we are loading shared libraries, 635 // we need to make sure to trim anything that isn't in the 636 // m_dyld_image_infos out of the target module list since 637 // we might have shared libraries that got loaded from 638 // elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH 639 // environment variables... 640 const size_t num_images = target_images.GetSize(); 641 for (idx = 0; idx < num_images; ++idx) 642 { 643 ModuleSP module_sp (target_images.GetModuleAtIndex (idx)); 644 645 if (GetImageInfo (module_sp.get()) == NULL) 646 unloaded_module_list.AppendIfNeeded (module_sp); 647 } 648 } 649 else 650 { 651 uint32_t old_idx; 652 for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx) 653 { 654 for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx) 655 { 656 if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec) 657 { 658 old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS; 659 break; 660 } 661 } 662 } 663 664 for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx) 665 { 666 if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS) 667 { 668 if (log) 669 old_dyld_all_image_infos[old_idx].PutToLog (log.get()); 670 ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL)); 671 if (unload_image_module_sp.get()) 672 { 673 if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx])) 674 unloaded_module_list.AppendIfNeeded (unload_image_module_sp); 675 } 676 } 677 } 678 } 679 680 if (unloaded_module_list.GetSize() > 0) 681 { 682 if (log) 683 { 684 log->PutCString("Unloaded:"); 685 unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload"); 686 } 687 m_process->GetTarget().ModulesDidUnload (unloaded_module_list); 688 } 689 } 690 else 691 { 692 if (log) 693 PutToLog(log.get()); 694 } 695 m_dyld_image_infos_stop_id = m_process->GetStopID(); 696 } 697 else 698 { 699 m_dyld_image_infos.clear(); 700 } 701 702 const uint32_t num_dylibs = m_dyld_image_infos.size(); 703 if (num_dylibs > 0) 704 { 705 ModuleList loaded_module_list; 706 for (uint32_t idx = 0; idx<num_dylibs; ++idx) 707 { 708 ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL)); 709 710 if (image_module_sp) 711 { 712 if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor) 713 image_module_sp->SetIsDynamicLinkEditor (true); 714 715 ObjectFile *objfile = image_module_sp->GetObjectFile (); 716 if (objfile) 717 { 718 SectionList *sections = objfile->GetSectionList(); 719 if (sections) 720 { 721 ConstString commpage_dbstr("__commpage"); 722 Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get(); 723 if (commpage_section) 724 { 725 const FileSpec objfile_file_spec = objfile->GetFileSpec(); 726 ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ()); 727 ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr)); 728 if (!commpage_image_module_sp) 729 { 730 commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec, 731 arch, 732 NULL, 733 &commpage_dbstr, 734 objfile->GetOffset() + commpage_section->GetFileOffset()); 735 } 736 if (commpage_image_module_sp) 737 UpdateCommPageLoadAddress (commpage_image_module_sp.get()); 738 } 739 } 740 } 741 742 // UpdateImageLoadAddress will return true if any segments 743 // change load address. We need to check this so we don't 744 // mention that all loaded shared libraries are newly loaded 745 // each time we hit out dyld breakpoint since dyld will list all 746 // shared libraries each time. 747 if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx])) 748 { 749 loaded_module_list.AppendIfNeeded (image_module_sp); 750 } 751 } 752 } 753 if (loaded_module_list.GetSize() > 0) 754 { 755 // FIXME: This should really be in the Runtime handlers class, which should get 756 // called by the target's ModulesDidLoad, but we're doing it all locally for now 757 // to save time. 758 // Also, I'm assuming there can be only one libobjc dylib loaded... 759 760 ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime(); 761 if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary()) 762 { 763 size_t num_modules = loaded_module_list.GetSize(); 764 for (int i = 0; i < num_modules; i++) 765 { 766 if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i))) 767 { 768 objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i)); 769 break; 770 } 771 } 772 } 773 if (log) 774 loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad"); 775 m_process->GetTarget().ModulesDidLoad (loaded_module_list); 776 } 777 } 778 return m_dyld_image_infos.size(); 779} 780 781//---------------------------------------------------------------------- 782// Read a mach_header at ADDR into HEADER, and also fill in the load 783// command data into LOAD_COMMAND_DATA if it is non-NULL. 784// 785// Returns true if we succeed, false if we fail for any reason. 786//---------------------------------------------------------------------- 787bool 788DynamicLoaderMacOSXDYLD::ReadMachHeader (lldb::addr_t addr, llvm::MachO::mach_header *header, DataExtractor *load_command_data) 789{ 790 DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0); 791 Error error; 792 size_t bytes_read = m_process->ReadMemory (addr, 793 header_bytes.GetBytes(), 794 header_bytes.GetByteSize(), 795 error); 796 if (bytes_read == sizeof(llvm::MachO::mach_header)) 797 { 798 uint32_t offset = 0; 799 ::memset (header, 0, sizeof(header)); 800 801 // Get the magic byte unswapped so we can figure out what we are dealing with 802 DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), lldb::endian::InlHostByteOrder(), 4); 803 header->magic = data.GetU32(&offset); 804 lldb::addr_t load_cmd_addr = addr; 805 data.SetByteOrder(DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header->magic)); 806 switch (header->magic) 807 { 808 case llvm::MachO::HeaderMagic32: 809 case llvm::MachO::HeaderMagic32Swapped: 810 data.SetAddressByteSize(4); 811 load_cmd_addr += sizeof(llvm::MachO::mach_header); 812 break; 813 814 case llvm::MachO::HeaderMagic64: 815 case llvm::MachO::HeaderMagic64Swapped: 816 data.SetAddressByteSize(8); 817 load_cmd_addr += sizeof(llvm::MachO::mach_header_64); 818 break; 819 820 default: 821 return false; 822 } 823 824 // Read the rest of dyld's mach header 825 if (data.GetU32(&offset, &header->cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1)) 826 { 827 if (load_command_data == NULL) 828 return true; // We were able to read the mach_header and weren't asked to read the load command bytes 829 830 DataBufferSP load_cmd_data_sp(new DataBufferHeap(header->sizeofcmds, 0)); 831 832 size_t load_cmd_bytes_read = m_process->ReadMemory (load_cmd_addr, 833 load_cmd_data_sp->GetBytes(), 834 load_cmd_data_sp->GetByteSize(), 835 error); 836 837 if (load_cmd_bytes_read == header->sizeofcmds) 838 { 839 // Set the load command data and also set the correct endian 840 // swap settings and the correct address size 841 load_command_data->SetData(load_cmd_data_sp, 0, header->sizeofcmds); 842 load_command_data->SetByteOrder(data.GetByteOrder()); 843 load_command_data->SetAddressByteSize(data.GetAddressByteSize()); 844 return true; // We successfully read the mach_header and the load command data 845 } 846 847 return false; // We weren't able to read the load command data 848 } 849 } 850 return false; // We failed the read the mach_header 851} 852 853 854//---------------------------------------------------------------------- 855// Parse the load commands for an image 856//---------------------------------------------------------------------- 857uint32_t 858DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker) 859{ 860 uint32_t offset = 0; 861 uint32_t cmd_idx; 862 Segment segment; 863 dylib_info.Clear (true); 864 865 for (cmd_idx = 0; cmd_idx < dylib_info.header.ncmds; cmd_idx++) 866 { 867 // Clear out any load command specific data from DYLIB_INFO since 868 // we are about to read it. 869 870 if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command))) 871 { 872 llvm::MachO::load_command load_cmd; 873 uint32_t load_cmd_offset = offset; 874 load_cmd.cmd = data.GetU32 (&offset); 875 load_cmd.cmdsize = data.GetU32 (&offset); 876 switch (load_cmd.cmd) 877 { 878 case llvm::MachO::LoadCommandSegment32: 879 { 880 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 881 // We are putting 4 uint32_t values 4 uint64_t values so 882 // we have to use multiple 32 bit gets below. 883 segment.vmaddr = data.GetU32 (&offset); 884 segment.vmsize = data.GetU32 (&offset); 885 segment.fileoff = data.GetU32 (&offset); 886 segment.filesize = data.GetU32 (&offset); 887 // Extract maxprot, initprot, nsects and flags all at once 888 data.GetU32(&offset, &segment.maxprot, 4); 889 dylib_info.segments.push_back (segment); 890 } 891 break; 892 893 case llvm::MachO::LoadCommandSegment64: 894 { 895 segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16); 896 // Extract vmaddr, vmsize, fileoff, and filesize all at once 897 data.GetU64(&offset, &segment.vmaddr, 4); 898 // Extract maxprot, initprot, nsects and flags all at once 899 data.GetU32(&offset, &segment.maxprot, 4); 900 dylib_info.segments.push_back (segment); 901 } 902 break; 903 904 case llvm::MachO::LoadCommandDynamicLinkerIdent: 905 if (lc_id_dylinker) 906 { 907 uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset); 908 const char *path = data.PeekCStr (name_offset); 909 lc_id_dylinker->SetFile (path, true); 910 } 911 break; 912 913 case llvm::MachO::LoadCommandUUID: 914 dylib_info.uuid.SetBytes(data.GetData (&offset, 16)); 915 break; 916 917 default: 918 break; 919 } 920 // Set offset to be the beginning of the next load command. 921 offset = load_cmd_offset + load_cmd.cmdsize; 922 } 923 } 924 925 // All sections listed in the dyld image info structure will all 926 // either be fixed up already, or they will all be off by a single 927 // slide amount that is determined by finding the first segment 928 // that is at file offset zero which also has bytes (a file size 929 // that is greater than zero) in the object file. 930 931 // Determine the slide amount (if any) 932 const size_t num_sections = dylib_info.segments.size(); 933 for (size_t i = 0; i < num_sections; ++i) 934 { 935 // Iterate through the object file sections to find the 936 // first section that starts of file offset zero and that 937 // has bytes in the file... 938 if (dylib_info.segments[i].fileoff == 0 && dylib_info.segments[i].filesize > 0) 939 { 940 dylib_info.slide = dylib_info.address - dylib_info.segments[i].vmaddr; 941 // We have found the slide amount, so we can exit 942 // this for loop. 943 break; 944 } 945 } 946 return cmd_idx; 947} 948 949//---------------------------------------------------------------------- 950// Read the mach_header and load commands for each image that the 951// _dyld_all_image_infos structure points to and cache the results. 952//---------------------------------------------------------------------- 953void 954DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands() 955{ 956 uint32_t exe_idx = UINT32_MAX; 957 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 958 // Read any UUID values that we can get 959 for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++) 960 { 961 if (!m_dyld_image_infos[i].UUIDValid()) 962 { 963 DataExtractor data; // Load command data 964 if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data)) 965 continue; 966 967 ParseLoadCommands (data, m_dyld_image_infos[i], NULL); 968 969 if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable) 970 exe_idx = i; 971 972 if (log) 973 m_dyld_image_infos[i].PutToLog (log.get()); 974 } 975 } 976 977 if (exe_idx < m_dyld_image_infos.size()) 978 { 979 ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL)); 980 981 if (!exe_module_sp) 982 { 983 ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ()); 984 exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec, 985 exe_arch_spec, 986 &m_dyld_image_infos[exe_idx].uuid); 987 } 988 989 if (exe_module_sp) 990 { 991 if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModule().get()) 992 { 993 // Don't load dependent images since we are in dyld where we will know 994 // and find out about all images that are loaded 995 bool get_dependent_images = false; 996 m_process->GetTarget().SetExecutableModule (exe_module_sp, 997 get_dependent_images); 998 } 999 } 1000 } 1001} 1002 1003//---------------------------------------------------------------------- 1004// Dump a Segment to the file handle provided. 1005//---------------------------------------------------------------------- 1006void 1007DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const 1008{ 1009 if (log) 1010 { 1011 if (slide == 0) 1012 log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)", 1013 name.AsCString(""), 1014 vmaddr + slide, 1015 vmaddr + slide + vmsize); 1016 else 1017 log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx", 1018 name.AsCString(""), 1019 vmaddr + slide, 1020 vmaddr + slide + vmsize, 1021 slide); 1022 } 1023} 1024 1025const DynamicLoaderMacOSXDYLD::Segment * 1026DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const 1027{ 1028 const size_t num_segments = segments.size(); 1029 for (size_t i=0; i<num_segments; ++i) 1030 { 1031 if (segments[i].name == name) 1032 return &segments[i]; 1033 } 1034 return NULL; 1035} 1036 1037 1038//---------------------------------------------------------------------- 1039// Dump an image info structure to the file handle provided. 1040//---------------------------------------------------------------------- 1041void 1042DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const 1043{ 1044 if (log == NULL) 1045 return; 1046 uint8_t *u = (uint8_t *)uuid.GetBytes(); 1047 1048 if (address == LLDB_INVALID_ADDRESS) 1049 { 1050 if (u) 1051 { 1052 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)", 1053 mod_date, 1054 u[ 0], u[ 1], u[ 2], u[ 3], 1055 u[ 4], u[ 5], u[ 6], u[ 7], 1056 u[ 8], u[ 9], u[10], u[11], 1057 u[12], u[13], u[14], u[15], 1058 file_spec.GetDirectory().AsCString(), 1059 file_spec.GetFilename().AsCString()); 1060 } 1061 else 1062 log->Printf("\t modtime=0x%8.8llx path='%s/%s' (UNLOADED)", 1063 mod_date, 1064 file_spec.GetDirectory().AsCString(), 1065 file_spec.GetFilename().AsCString()); 1066 } 1067 else 1068 { 1069 if (u) 1070 { 1071 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'", 1072 address, 1073 mod_date, 1074 u[ 0], u[ 1], u[ 2], u[ 3], 1075 u[ 4], u[ 5], u[ 6], u[ 7], 1076 u[ 8], u[ 9], u[10], u[11], 1077 u[12], u[13], u[14], u[15], 1078 file_spec.GetDirectory().AsCString(), 1079 file_spec.GetFilename().AsCString()); 1080 } 1081 else 1082 { 1083 log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'", 1084 address, 1085 mod_date, 1086 file_spec.GetDirectory().AsCString(), 1087 file_spec.GetFilename().AsCString()); 1088 1089 } 1090 for (uint32_t i=0; i<segments.size(); ++i) 1091 segments[i].PutToLog(log, slide); 1092 } 1093} 1094 1095//---------------------------------------------------------------------- 1096// Dump the _dyld_all_image_infos members and all current image infos 1097// that we have parsed to the file handle provided. 1098//---------------------------------------------------------------------- 1099void 1100DynamicLoaderMacOSXDYLD::PutToLog(Log *log) const 1101{ 1102 if (log == NULL) 1103 return; 1104 1105 Mutex::Locker locker(m_mutex); 1106 log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }", 1107 m_dyld_all_image_infos.version, 1108 m_dyld_all_image_infos.dylib_info_count, 1109 (uint64_t)m_dyld_all_image_infos.dylib_info_addr, 1110 (uint64_t)m_dyld_all_image_infos.notification); 1111 size_t i; 1112 const size_t count = m_dyld_image_infos.size(); 1113 if (count > 0) 1114 { 1115 log->PutCString("Loaded:"); 1116 for (i = 0; i<count; i++) 1117 m_dyld_image_infos[i].PutToLog(log); 1118 } 1119} 1120 1121void 1122DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process) 1123{ 1124 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 1125 Clear(true); 1126 m_process = process; 1127 m_process->GetTarget().GetSectionLoadList().Clear(); 1128} 1129 1130bool 1131DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint () 1132{ 1133 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 1134 if (m_break_id == LLDB_INVALID_BREAK_ID) 1135 { 1136 if (m_dyld_all_image_infos.notification != LLDB_INVALID_ADDRESS) 1137 { 1138 Address so_addr; 1139 // Set the notification breakpoint and install a breakpoint 1140 // callback function that will get called each time the 1141 // breakpoint gets hit. We will use this to track when shared 1142 // libraries get loaded/unloaded. 1143 1144 if (m_process->GetTarget().GetSectionLoadList().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr)) 1145 { 1146 Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get(); 1147 dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true); 1148 m_break_id = dyld_break->GetID(); 1149 } 1150 } 1151 } 1152 return m_break_id != LLDB_INVALID_BREAK_ID; 1153} 1154 1155//---------------------------------------------------------------------- 1156// Member function that gets called when the process state changes. 1157//---------------------------------------------------------------------- 1158void 1159DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state) 1160{ 1161 DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 1162 switch (state) 1163 { 1164 case eStateConnected: 1165 case eStateAttaching: 1166 case eStateLaunching: 1167 case eStateInvalid: 1168 case eStateUnloaded: 1169 case eStateExited: 1170 case eStateDetached: 1171 Clear(false); 1172 break; 1173 1174 case eStateStopped: 1175 // Keep trying find dyld and set our notification breakpoint each time 1176 // we stop until we succeed 1177 if (!DidSetNotificationBreakpoint () && m_process->IsAlive()) 1178 { 1179 if (NeedToLocateDYLD ()) 1180 LocateDYLD (); 1181 1182 SetNotificationBreakpoint (); 1183 } 1184 break; 1185 1186 case eStateRunning: 1187 case eStateStepping: 1188 case eStateCrashed: 1189 case eStateSuspended: 1190 break; 1191 1192 default: 1193 break; 1194 } 1195} 1196 1197ThreadPlanSP 1198DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 1199{ 1200 ThreadPlanSP thread_plan_sp; 1201 StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get(); 1202 const SymbolContext ¤t_context = current_frame->GetSymbolContext(eSymbolContextSymbol); 1203 Symbol *current_symbol = current_context.symbol; 1204 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 1205 1206 if (current_symbol != NULL) 1207 { 1208 if (current_symbol->IsTrampoline()) 1209 { 1210 const ConstString &trampoline_name = current_symbol->GetMangled().GetName(Mangled::ePreferMangled); 1211 1212 if (trampoline_name) 1213 { 1214 SymbolContextList target_symbols; 1215 ModuleList &images = thread.GetProcess().GetTarget().GetImages(); 1216 images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, target_symbols); 1217 // FIXME - Make the Run to Address take multiple addresses, and 1218 // run to any of them. 1219 uint32_t num_symbols = target_symbols.GetSize(); 1220 if (num_symbols == 1) 1221 { 1222 SymbolContext context; 1223 AddressRange addr_range; 1224 if (target_symbols.GetContextAtIndex(0, context)) 1225 { 1226 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); 1227 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addr_range.GetBaseAddress(), stop_others)); 1228 } 1229 else 1230 { 1231 if (log) 1232 log->Printf ("Couldn't resolve the symbol context."); 1233 } 1234 } 1235 else if (num_symbols > 1) 1236 { 1237 std::vector<lldb::addr_t> addresses; 1238 addresses.resize (num_symbols); 1239 for (uint32_t i = 0; i < num_symbols; i++) 1240 { 1241 SymbolContext context; 1242 AddressRange addr_range; 1243 if (target_symbols.GetContextAtIndex(i, context)) 1244 { 1245 context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range); 1246 lldb::addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(&thread.GetProcess().GetTarget()); 1247 addresses[i] = load_addr; 1248 } 1249 } 1250 if (addresses.size() > 0) 1251 thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, addresses, stop_others)); 1252 else 1253 { 1254 if (log) 1255 log->Printf ("Couldn't resolve the symbol contexts."); 1256 } 1257 } 1258 else 1259 { 1260 if (log) 1261 { 1262 log->Printf ("Could not find symbol for trampoline target: \"%s\"", trampoline_name.AsCString()); 1263 } 1264 } 1265 } 1266 } 1267 } 1268 else 1269 { 1270 if (log) 1271 log->Printf ("Could not find symbol for step through."); 1272 } 1273 1274 return thread_plan_sp; 1275} 1276 1277Error 1278DynamicLoaderMacOSXDYLD::CanLoadImage () 1279{ 1280 Error error; 1281 // In order for us to tell if we can load a shared library we verify that 1282 // the dylib_info_addr isn't zero (which means no shared libraries have 1283 // been set yet, or dyld is currently mucking with the shared library list). 1284 if (ReadAllImageInfosStructure ()) 1285 { 1286 // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib? 1287 // TODO: check the malloc lock? 1288 // TODO: check the objective C lock? 1289 if (m_dyld_all_image_infos.dylib_info_addr != 0) 1290 return error; // Success 1291 } 1292 1293 error.SetErrorString("unsafe to load or unload shared libraries"); 1294 return error; 1295} 1296 1297void 1298DynamicLoaderMacOSXDYLD::Initialize() 1299{ 1300 PluginManager::RegisterPlugin (GetPluginNameStatic(), 1301 GetPluginDescriptionStatic(), 1302 CreateInstance); 1303} 1304 1305void 1306DynamicLoaderMacOSXDYLD::Terminate() 1307{ 1308 PluginManager::UnregisterPlugin (CreateInstance); 1309} 1310 1311 1312const char * 1313DynamicLoaderMacOSXDYLD::GetPluginNameStatic() 1314{ 1315 return "dynamic-loader.macosx-dyld"; 1316} 1317 1318const char * 1319DynamicLoaderMacOSXDYLD::GetPluginDescriptionStatic() 1320{ 1321 return "Dynamic loader plug-in that watches for shared library loads/unloads in MacOSX user processes."; 1322} 1323 1324 1325//------------------------------------------------------------------ 1326// PluginInterface protocol 1327//------------------------------------------------------------------ 1328const char * 1329DynamicLoaderMacOSXDYLD::GetPluginName() 1330{ 1331 return "DynamicLoaderMacOSXDYLD"; 1332} 1333 1334const char * 1335DynamicLoaderMacOSXDYLD::GetShortPluginName() 1336{ 1337 return GetPluginNameStatic(); 1338} 1339 1340uint32_t 1341DynamicLoaderMacOSXDYLD::GetPluginVersion() 1342{ 1343 return 1; 1344} 1345 1346