1 //===-- DynamicLoaderDarwinKernel.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/Debugger.h" 14 #include "lldb/Core/Log.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/ModuleSpec.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Core/Section.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Host/Symbols.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/StackFrame.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/Thread.h" 26 #include "lldb/Target/ThreadPlanRunToAddress.h" 27 28 29 #include "DynamicLoaderDarwinKernel.h" 30 31 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN 32 #ifdef ENABLE_DEBUG_PRINTF 33 #include <stdio.h> 34 #define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) 35 #else 36 #define DEBUG_PRINTF(fmt, ...) 37 #endif 38 39 using namespace lldb; 40 using namespace lldb_private; 41 42 static PropertyDefinition 43 g_properties[] = 44 { 45 { "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." }, 46 { NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL } 47 }; 48 49 enum { 50 ePropertyLoadKexts 51 }; 52 53 class DynamicLoaderDarwinKernelProperties : public Properties 54 { 55 public: 56 57 static ConstString & 58 GetSettingName () 59 { 60 static ConstString g_setting_name("darwin-kernel"); 61 return g_setting_name; 62 } 63 64 DynamicLoaderDarwinKernelProperties() : 65 Properties () 66 { 67 m_collection_sp.reset (new OptionValueProperties(GetSettingName())); 68 m_collection_sp->Initialize(g_properties); 69 } 70 71 virtual 72 ~DynamicLoaderDarwinKernelProperties() 73 { 74 } 75 76 bool 77 GetLoadKexts() const 78 { 79 const uint32_t idx = ePropertyLoadKexts; 80 return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0); 81 } 82 83 }; 84 85 typedef STD_SHARED_PTR(DynamicLoaderDarwinKernelProperties) DynamicLoaderDarwinKernelPropertiesSP; 86 87 static const DynamicLoaderDarwinKernelPropertiesSP & 88 GetGlobalProperties() 89 { 90 static DynamicLoaderDarwinKernelPropertiesSP g_settings_sp; 91 if (!g_settings_sp) 92 g_settings_sp.reset (new DynamicLoaderDarwinKernelProperties ()); 93 return g_settings_sp; 94 } 95 96 //---------------------------------------------------------------------- 97 // Create an instance of this class. This function is filled into 98 // the plugin info class that gets handed out by the plugin factory and 99 // allows the lldb to instantiate an instance of this class. 100 //---------------------------------------------------------------------- 101 DynamicLoader * 102 DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force) 103 { 104 bool create = force; 105 if (!create) 106 { 107 Module* exe_module = process->GetTarget().GetExecutableModulePointer(); 108 if (exe_module) 109 { 110 ObjectFile *object_file = exe_module->GetObjectFile(); 111 if (object_file) 112 { 113 create = (object_file->GetStrata() == ObjectFile::eStrataKernel); 114 } 115 } 116 117 if (create) 118 { 119 const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); 120 switch (triple_ref.getOS()) 121 { 122 case llvm::Triple::Darwin: 123 case llvm::Triple::MacOSX: 124 case llvm::Triple::IOS: 125 create = triple_ref.getVendor() == llvm::Triple::Apple; 126 break; 127 default: 128 create = false; 129 break; 130 } 131 } 132 } 133 134 if (create) 135 { 136 process->SetCanJIT(false); 137 return new DynamicLoaderDarwinKernel (process); 138 } 139 return NULL; 140 } 141 142 //---------------------------------------------------------------------- 143 // Constructor 144 //---------------------------------------------------------------------- 145 DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) : 146 DynamicLoader(process), 147 m_kernel(), 148 m_kext_summary_header_ptr_addr (), 149 m_kext_summary_header_addr (), 150 m_kext_summary_header (), 151 m_kext_summaries(), 152 m_mutex(Mutex::eMutexTypeRecursive), 153 m_break_id (LLDB_INVALID_BREAK_ID) 154 { 155 } 156 157 //---------------------------------------------------------------------- 158 // Destructor 159 //---------------------------------------------------------------------- 160 DynamicLoaderDarwinKernel::~DynamicLoaderDarwinKernel() 161 { 162 Clear(true); 163 } 164 165 void 166 DynamicLoaderDarwinKernel::UpdateIfNeeded() 167 { 168 LoadKernelModuleIfNeeded(); 169 SetNotificationBreakpointIfNeeded (); 170 } 171 //------------------------------------------------------------------ 172 /// Called after attaching a process. 173 /// 174 /// Allow DynamicLoader plug-ins to execute some code after 175 /// attaching to a process. 176 //------------------------------------------------------------------ 177 void 178 DynamicLoaderDarwinKernel::DidAttach () 179 { 180 PrivateInitialize(m_process); 181 UpdateIfNeeded(); 182 } 183 184 //------------------------------------------------------------------ 185 /// Called after attaching a process. 186 /// 187 /// Allow DynamicLoader plug-ins to execute some code after 188 /// attaching to a process. 189 //------------------------------------------------------------------ 190 void 191 DynamicLoaderDarwinKernel::DidLaunch () 192 { 193 PrivateInitialize(m_process); 194 UpdateIfNeeded(); 195 } 196 197 198 //---------------------------------------------------------------------- 199 // Clear out the state of this class. 200 //---------------------------------------------------------------------- 201 void 202 DynamicLoaderDarwinKernel::Clear (bool clear_process) 203 { 204 Mutex::Locker locker(m_mutex); 205 206 if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id)) 207 m_process->ClearBreakpointSiteByID(m_break_id); 208 209 if (clear_process) 210 m_process = NULL; 211 m_kernel.Clear(false); 212 m_kext_summary_header_ptr_addr.Clear(); 213 m_kext_summary_header_addr.Clear(); 214 m_kext_summaries.clear(); 215 m_break_id = LLDB_INVALID_BREAK_ID; 216 } 217 218 219 bool 220 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process) 221 { 222 if (IsLoaded()) 223 return true; 224 225 if (module_sp) 226 { 227 bool changed = false; 228 if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed)) 229 load_process_stop_id = process->GetStopID(); 230 } 231 return false; 232 } 233 234 bool 235 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process) 236 { 237 if (IsLoaded()) 238 return true; 239 240 bool uuid_is_valid = uuid.IsValid(); 241 bool memory_module_is_kernel = false; 242 243 Target &target = process->GetTarget(); 244 ModuleSP memory_module_sp; 245 246 // If this is a kext and the user asked us to ignore kexts, don't try to load it. 247 if (kernel_image == false && GetGlobalProperties()->GetLoadKexts() == false) 248 { 249 return false; 250 } 251 252 // Use the memory module as the module if we have one 253 if (address != LLDB_INVALID_ADDRESS) 254 { 255 FileSpec file_spec; 256 if (module_sp) 257 file_spec = module_sp->GetFileSpec(); 258 else 259 file_spec.SetFile (name, false); 260 261 memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false); 262 if (memory_module_sp && !uuid_is_valid) 263 { 264 uuid = memory_module_sp->GetUUID(); 265 uuid_is_valid = uuid.IsValid(); 266 } 267 if (memory_module_sp->GetObjectFile() 268 && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable 269 && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel) 270 { 271 memory_module_is_kernel = true; 272 if (memory_module_sp->GetArchitecture().IsValid()) 273 { 274 target.SetArchitecture(memory_module_sp->GetArchitecture()); 275 } 276 } 277 } 278 279 if (!module_sp) 280 { 281 if (uuid_is_valid) 282 { 283 ModuleList &target_images = target.GetImages(); 284 module_sp = target_images.FindModule(uuid); 285 286 if (!module_sp) 287 { 288 ModuleSpec module_spec; 289 module_spec.GetUUID() = uuid; 290 module_spec.GetArchitecture() = target.GetArchitecture(); 291 292 // For the kernel, we really do need an on-disk file copy of the 293 // binary. 294 bool force_symbols_search = false; 295 if (memory_module_is_kernel) 296 { 297 force_symbols_search = true; 298 } 299 300 if (Symbols::DownloadObjectAndSymbolFile (module_spec, force_symbols_search)) 301 { 302 if (module_spec.GetFileSpec().Exists()) 303 { 304 module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture())); 305 if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec)) 306 { 307 ModuleList loaded_module_list; 308 loaded_module_list.Append (module_sp); 309 target.ModulesDidLoad (loaded_module_list); 310 } 311 } 312 } 313 314 // Ask the Target to find this file on the local system, if possible. 315 // This will search in the list of currently-loaded files, look in the 316 // standard search paths on the system, and on a Mac it will try calling 317 // the DebugSymbols framework with the UUID to find the binary via its 318 // search methods. 319 if (!module_sp) 320 { 321 module_sp = target.GetSharedModule (module_spec); 322 } 323 } 324 } 325 } 326 327 328 if (memory_module_sp && module_sp) 329 { 330 if (module_sp->GetUUID() == memory_module_sp->GetUUID()) 331 { 332 target.GetImages().Append(module_sp); 333 if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get()) 334 { 335 target.SetExecutableModule (module_sp, false); 336 } 337 338 ObjectFile *ondisk_object_file = module_sp->GetObjectFile(); 339 ObjectFile *memory_object_file = memory_module_sp->GetObjectFile(); 340 if (memory_object_file && ondisk_object_file) 341 { 342 SectionList *ondisk_section_list = ondisk_object_file->GetSectionList (); 343 SectionList *memory_section_list = memory_object_file->GetSectionList (); 344 if (memory_section_list && ondisk_section_list) 345 { 346 const uint32_t num_ondisk_sections = ondisk_section_list->GetSize(); 347 // There may be CTF sections in the memory image so we can't 348 // always just compare the number of sections (which are actually 349 // segments in mach-o parlance) 350 uint32_t sect_idx = 0; 351 352 // Use the memory_module's addresses for each section to set the 353 // file module's load address as appropriate. We don't want to use 354 // a single slide value for the entire kext - different segments may 355 // be slid different amounts by the kext loader. 356 357 uint32_t num_sections_loaded = 0; 358 for (sect_idx=0; sect_idx<num_ondisk_sections; ++sect_idx) 359 { 360 SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx)); 361 if (ondisk_section_sp) 362 { 363 const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get(); 364 if (memory_section) 365 { 366 target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section_sp, memory_section->GetFileAddress()); 367 ++num_sections_loaded; 368 } 369 } 370 } 371 if (num_sections_loaded > 0) 372 load_process_stop_id = process->GetStopID(); 373 else 374 module_sp.reset(); // No sections were loaded 375 } 376 else 377 module_sp.reset(); // One or both section lists 378 } 379 else 380 module_sp.reset(); // One or both object files missing 381 } 382 else 383 module_sp.reset(); // UUID mismatch 384 } 385 386 bool is_loaded = IsLoaded(); 387 388 if (so_address.IsValid()) 389 { 390 if (is_loaded) 391 so_address.SetLoadAddress (address, &target); 392 else 393 target.GetImages().ResolveFileAddress (address, so_address); 394 395 } 396 397 if (is_loaded && module_sp && memory_module_is_kernel) 398 { 399 Stream *s = &target.GetDebugger().GetOutputStream(); 400 if (s) 401 { 402 char uuidbuf[64]; 403 s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf))); 404 s->Printf ("Load Address: 0x%llx\n", address); 405 if (module_sp->GetFileSpec().GetDirectory().IsEmpty()) 406 { 407 s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString()); 408 } 409 else 410 { 411 s->Printf ("Loaded kernel file %s/%s\n", 412 module_sp->GetFileSpec().GetDirectory().AsCString(), 413 module_sp->GetFileSpec().GetFilename().AsCString()); 414 } 415 s->Flush (); 416 } 417 } 418 return is_loaded; 419 } 420 421 uint32_t 422 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize () 423 { 424 if (module_sp) 425 return module_sp->GetArchitecture().GetAddressByteSize(); 426 return 0; 427 } 428 429 lldb::ByteOrder 430 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder() 431 { 432 if (module_sp) 433 return module_sp->GetArchitecture().GetByteOrder(); 434 return lldb::endian::InlHostByteOrder(); 435 } 436 437 lldb_private::ArchSpec 438 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const 439 { 440 if (module_sp) 441 return module_sp->GetArchitecture(); 442 return lldb_private::ArchSpec (); 443 } 444 445 446 //---------------------------------------------------------------------- 447 // Load the kernel module and initialize the "m_kernel" member. Return 448 // true _only_ if the kernel is loaded the first time through (subsequent 449 // calls to this function should return false after the kernel has been 450 // already loaded). 451 //---------------------------------------------------------------------- 452 void 453 DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() 454 { 455 if (!m_kext_summary_header_ptr_addr.IsValid()) 456 { 457 m_kernel.Clear(false); 458 m_kernel.module_sp = m_process->GetTarget().GetExecutableModule(); 459 m_kernel.kernel_image = true; 460 461 ConstString kernel_name("mach_kernel"); 462 if (m_kernel.module_sp.get() 463 && m_kernel.module_sp->GetObjectFile() 464 && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty()) 465 { 466 kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename(); 467 } 468 strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name)); 469 m_kernel.name[sizeof (m_kernel.name) - 1] = '\0'; 470 471 if (m_kernel.address == LLDB_INVALID_ADDRESS) 472 { 473 m_kernel.address = m_process->GetImageInfoAddress (); 474 if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp) 475 { 476 // We didn't get a hint from the process, so we will 477 // try the kernel at the address that it exists at in 478 // the file if we have one 479 ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile(); 480 if (kernel_object_file) 481 { 482 addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget()); 483 addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress(); 484 if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) 485 { 486 m_kernel.address = load_address; 487 if (load_address != file_address) 488 { 489 // Don't accidentally relocate the kernel to the File address -- 490 // the Load address has already been set to its actual in-memory address. 491 // Mark it as IsLoaded. 492 m_kernel.load_process_stop_id = m_process->GetStopID(); 493 } 494 } 495 else 496 { 497 m_kernel.address = file_address; 498 } 499 } 500 } 501 } 502 503 if (m_kernel.address != LLDB_INVALID_ADDRESS) 504 { 505 if (!m_kernel.LoadImageUsingMemoryModule (m_process)) 506 { 507 m_kernel.LoadImageAtFileAddress (m_process); 508 } 509 } 510 511 if (m_kernel.IsLoaded() && m_kernel.module_sp) 512 { 513 static ConstString kext_summary_symbol ("gLoadedKextSummaries"); 514 const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData); 515 if (symbol) 516 { 517 m_kext_summary_header_ptr_addr = symbol->GetAddress(); 518 // Update all image infos 519 ReadAllKextSummaries (); 520 } 521 } 522 else 523 { 524 m_kernel.Clear(false); 525 } 526 } 527 } 528 529 //---------------------------------------------------------------------- 530 // Static callback function that gets called when our DYLD notification 531 // breakpoint gets hit. We update all of our image infos and then 532 // let our super class DynamicLoader class decide if we should stop 533 // or not (based on global preference). 534 //---------------------------------------------------------------------- 535 bool 536 DynamicLoaderDarwinKernel::BreakpointHitCallback (void *baton, 537 StoppointCallbackContext *context, 538 user_id_t break_id, 539 user_id_t break_loc_id) 540 { 541 return static_cast<DynamicLoaderDarwinKernel*>(baton)->BreakpointHit (context, break_id, break_loc_id); 542 } 543 544 bool 545 DynamicLoaderDarwinKernel::BreakpointHit (StoppointCallbackContext *context, 546 user_id_t break_id, 547 user_id_t break_loc_id) 548 { 549 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 550 if (log) 551 log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n"); 552 553 ReadAllKextSummaries (); 554 555 if (log) 556 PutToLog(log.get()); 557 558 return GetStopWhenImagesChange(); 559 } 560 561 562 bool 563 DynamicLoaderDarwinKernel::ReadKextSummaryHeader () 564 { 565 Mutex::Locker locker(m_mutex); 566 567 // the all image infos is already valid for this process stop ID 568 569 m_kext_summaries.clear(); 570 if (m_kext_summary_header_ptr_addr.IsValid()) 571 { 572 const uint32_t addr_size = m_kernel.GetAddressByteSize (); 573 const ByteOrder byte_order = m_kernel.GetByteOrder(); 574 Error error; 575 // Read enough bytes for a "OSKextLoadedKextSummaryHeader" structure 576 // which is currenty 4 uint32_t and a pointer. 577 uint8_t buf[24]; 578 DataExtractor data (buf, sizeof(buf), byte_order, addr_size); 579 const size_t count = 4 * sizeof(uint32_t) + addr_size; 580 const bool prefer_file_cache = false; 581 if (m_process->GetTarget().ReadPointerFromMemory (m_kext_summary_header_ptr_addr, 582 prefer_file_cache, 583 error, 584 m_kext_summary_header_addr)) 585 { 586 // We got a valid address for our kext summary header and make sure it isn't NULL 587 if (m_kext_summary_header_addr.IsValid() && 588 m_kext_summary_header_addr.GetFileAddress() != 0) 589 { 590 const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error); 591 if (bytes_read == count) 592 { 593 uint32_t offset = 0; 594 m_kext_summary_header.version = data.GetU32(&offset); 595 if (m_kext_summary_header.version >= 2) 596 { 597 m_kext_summary_header.entry_size = data.GetU32(&offset); 598 } 599 else 600 { 601 // Versions less than 2 didn't have an entry size, it was hard coded 602 m_kext_summary_header.entry_size = KERNEL_MODULE_ENTRY_SIZE_VERSION_1; 603 } 604 m_kext_summary_header.entry_count = data.GetU32(&offset); 605 return true; 606 } 607 } 608 } 609 } 610 m_kext_summary_header_addr.Clear(); 611 return false; 612 } 613 614 615 bool 616 DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, 617 uint32_t count) 618 { 619 OSKextLoadedKextSummary::collection kext_summaries; 620 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 621 if (log) 622 log->Printf ("Adding %d modules.\n", count); 623 624 Mutex::Locker locker(m_mutex); 625 626 if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries)) 627 return false; 628 629 Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream(); 630 if (s) 631 s->Printf ("Loading %d kext modules ", count); 632 for (uint32_t i = 0; i < count; i++) 633 { 634 if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process)) 635 kext_summaries[i].LoadImageAtFileAddress (m_process); 636 637 if (s) 638 s->Printf ("."); 639 640 if (log) 641 kext_summaries[i].PutToLog (log.get()); 642 } 643 if (s) 644 { 645 s->Printf (" done.\n"); 646 s->Flush (); 647 } 648 649 bool return_value = AddModulesUsingImageInfos (kext_summaries); 650 return return_value; 651 } 652 653 // Adds the modules in image_infos to m_kext_summaries. 654 // NB don't call this passing in m_kext_summaries. 655 656 bool 657 DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos) 658 { 659 // Now add these images to the main list. 660 ModuleList loaded_module_list; 661 662 for (uint32_t idx = 0; idx < image_infos.size(); ++idx) 663 { 664 OSKextLoadedKextSummary &image_info = image_infos[idx]; 665 m_kext_summaries.push_back(image_info); 666 667 if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id) 668 loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp); 669 } 670 671 if (loaded_module_list.GetSize() > 0) 672 { 673 m_process->GetTarget().ModulesDidLoad (loaded_module_list); 674 } 675 return true; 676 } 677 678 679 uint32_t 680 DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr, 681 uint32_t image_infos_count, 682 OSKextLoadedKextSummary::collection &image_infos) 683 { 684 const ByteOrder endian = m_kernel.GetByteOrder(); 685 const uint32_t addr_size = m_kernel.GetAddressByteSize(); 686 687 image_infos.resize(image_infos_count); 688 const size_t count = image_infos.size() * m_kext_summary_header.entry_size; 689 DataBufferHeap data(count, 0); 690 Error error; 691 692 const bool prefer_file_cache = false; 693 const size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary_addr, 694 prefer_file_cache, 695 data.GetBytes(), 696 data.GetByteSize(), 697 error); 698 if (bytes_read == count) 699 { 700 701 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size); 702 uint32_t i=0; 703 for (uint32_t kext_summary_offset = 0; 704 i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size); 705 ++i, kext_summary_offset += m_kext_summary_header.entry_size) 706 { 707 uint32_t offset = kext_summary_offset; 708 const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME); 709 if (name_data == NULL) 710 break; 711 memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME); 712 image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16)); 713 image_infos[i].address = extractor.GetU64(&offset); 714 if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget())) 715 m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address); 716 image_infos[i].size = extractor.GetU64(&offset); 717 image_infos[i].version = extractor.GetU64(&offset); 718 image_infos[i].load_tag = extractor.GetU32(&offset); 719 image_infos[i].flags = extractor.GetU32(&offset); 720 if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size) 721 { 722 image_infos[i].reference_list = extractor.GetU64(&offset); 723 } 724 else 725 { 726 image_infos[i].reference_list = 0; 727 } 728 // printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n", 729 // i, 730 // KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data, 731 // image_infos[i].address, 732 // image_infos[i].size, 733 // image_infos[i].version, 734 // image_infos[i].load_tag, 735 // image_infos[i].flags); 736 } 737 if (i < image_infos.size()) 738 image_infos.resize(i); 739 } 740 else 741 { 742 image_infos.clear(); 743 } 744 return image_infos.size(); 745 } 746 747 bool 748 DynamicLoaderDarwinKernel::ReadAllKextSummaries () 749 { 750 LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER)); 751 752 Mutex::Locker locker(m_mutex); 753 754 if (ReadKextSummaryHeader ()) 755 { 756 if (m_kext_summary_header.entry_count > 0 && m_kext_summary_header_addr.IsValid()) 757 { 758 Address summary_addr (m_kext_summary_header_addr); 759 summary_addr.Slide(m_kext_summary_header.GetSize()); 760 if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count)) 761 { 762 m_kext_summaries.clear(); 763 } 764 return true; 765 } 766 } 767 return false; 768 } 769 770 //---------------------------------------------------------------------- 771 // Dump an image info structure to the file handle provided. 772 //---------------------------------------------------------------------- 773 void 774 DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const 775 { 776 if (log == NULL) 777 return; 778 const uint8_t *u = (uint8_t *)uuid.GetBytes(); 779 780 if (address == LLDB_INVALID_ADDRESS) 781 { 782 if (u) 783 { 784 log->Printf("\tuuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\" (UNLOADED)", 785 u[ 0], u[ 1], u[ 2], u[ 3], 786 u[ 4], u[ 5], u[ 6], u[ 7], 787 u[ 8], u[ 9], u[10], u[11], 788 u[12], u[13], u[14], u[15], 789 name); 790 } 791 else 792 log->Printf("\tname=\"%s\" (UNLOADED)", name); 793 } 794 else 795 { 796 if (u) 797 { 798 log->Printf("\taddr=0x%16.16llx size=0x%16.16llx version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"", 799 address, size, version, load_tag, flags, reference_list, 800 u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7], 801 u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15], 802 name); 803 } 804 else 805 { 806 log->Printf("\t[0x%16.16llx - 0x%16.16llx) version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx name=\"%s\"", 807 address, address+size, version, load_tag, flags, reference_list, 808 name); 809 } 810 } 811 } 812 813 //---------------------------------------------------------------------- 814 // Dump the _dyld_all_image_infos members and all current image infos 815 // that we have parsed to the file handle provided. 816 //---------------------------------------------------------------------- 817 void 818 DynamicLoaderDarwinKernel::PutToLog(Log *log) const 819 { 820 if (log == NULL) 821 return; 822 823 Mutex::Locker locker(m_mutex); 824 log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }", 825 m_kext_summary_header_addr.GetFileAddress(), 826 m_kext_summary_header.version, 827 m_kext_summary_header.entry_size, 828 m_kext_summary_header.entry_count); 829 830 size_t i; 831 const size_t count = m_kext_summaries.size(); 832 if (count > 0) 833 { 834 log->PutCString("Loaded:"); 835 for (i = 0; i<count; i++) 836 m_kext_summaries[i].PutToLog(log); 837 } 838 } 839 840 void 841 DynamicLoaderDarwinKernel::PrivateInitialize(Process *process) 842 { 843 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 844 Clear(true); 845 m_process = process; 846 } 847 848 void 849 DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded () 850 { 851 if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp) 852 { 853 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState())); 854 855 856 const bool internal_bp = true; 857 const LazyBool skip_prologue = eLazyBoolNo; 858 FileSpecList module_spec_list; 859 module_spec_list.Append (m_kernel.module_sp->GetFileSpec()); 860 Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list, 861 NULL, 862 "OSKextLoadedKextSummariesUpdated", 863 eFunctionNameTypeFull, 864 skip_prologue, 865 internal_bp).get(); 866 867 bp->SetCallback (DynamicLoaderDarwinKernel::BreakpointHitCallback, this, true); 868 m_break_id = bp->GetID(); 869 } 870 } 871 872 //---------------------------------------------------------------------- 873 // Member function that gets called when the process state changes. 874 //---------------------------------------------------------------------- 875 void 876 DynamicLoaderDarwinKernel::PrivateProcessStateChanged (Process *process, StateType state) 877 { 878 DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s(%s)\n", __FUNCTION__, StateAsCString(state)); 879 switch (state) 880 { 881 case eStateConnected: 882 case eStateAttaching: 883 case eStateLaunching: 884 case eStateInvalid: 885 case eStateUnloaded: 886 case eStateExited: 887 case eStateDetached: 888 Clear(false); 889 break; 890 891 case eStateStopped: 892 UpdateIfNeeded(); 893 break; 894 895 case eStateRunning: 896 case eStateStepping: 897 case eStateCrashed: 898 case eStateSuspended: 899 break; 900 901 default: 902 break; 903 } 904 } 905 906 ThreadPlanSP 907 DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) 908 { 909 ThreadPlanSP thread_plan_sp; 910 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 911 if (log) 912 log->Printf ("Could not find symbol for step through."); 913 return thread_plan_sp; 914 } 915 916 Error 917 DynamicLoaderDarwinKernel::CanLoadImage () 918 { 919 Error error; 920 error.SetErrorString("always unsafe to load or unload shared libraries in the darwin kernel"); 921 return error; 922 } 923 924 void 925 DynamicLoaderDarwinKernel::Initialize() 926 { 927 PluginManager::RegisterPlugin (GetPluginNameStatic(), 928 GetPluginDescriptionStatic(), 929 CreateInstance, 930 DebuggerInitialize); 931 } 932 933 void 934 DynamicLoaderDarwinKernel::Terminate() 935 { 936 PluginManager::UnregisterPlugin (CreateInstance); 937 } 938 939 void 940 DynamicLoaderDarwinKernel::DebuggerInitialize (lldb_private::Debugger &debugger) 941 { 942 if (!PluginManager::GetSettingForDynamicLoaderPlugin (debugger, DynamicLoaderDarwinKernelProperties::GetSettingName())) 943 { 944 const bool is_global_setting = true; 945 PluginManager::CreateSettingForDynamicLoaderPlugin (debugger, 946 GetGlobalProperties()->GetValueProperties(), 947 ConstString ("Properties for the DynamicLoaderDarwinKernel plug-in."), 948 is_global_setting); 949 } 950 } 951 952 const char * 953 DynamicLoaderDarwinKernel::GetPluginNameStatic() 954 { 955 return "dynamic-loader.darwin-kernel"; 956 } 957 958 const char * 959 DynamicLoaderDarwinKernel::GetPluginDescriptionStatic() 960 { 961 return "Dynamic loader plug-in that watches for shared library loads/unloads in the MacOSX kernel."; 962 } 963 964 965 //------------------------------------------------------------------ 966 // PluginInterface protocol 967 //------------------------------------------------------------------ 968 const char * 969 DynamicLoaderDarwinKernel::GetPluginName() 970 { 971 return "DynamicLoaderDarwinKernel"; 972 } 973 974 const char * 975 DynamicLoaderDarwinKernel::GetShortPluginName() 976 { 977 return GetPluginNameStatic(); 978 } 979 980 uint32_t 981 DynamicLoaderDarwinKernel::GetPluginVersion() 982 { 983 return 1; 984 } 985 986 lldb::ByteOrder 987 DynamicLoaderDarwinKernel::GetByteOrderFromMagic (uint32_t magic) 988 { 989 switch (magic) 990 { 991 case llvm::MachO::HeaderMagic32: 992 case llvm::MachO::HeaderMagic64: 993 return lldb::endian::InlHostByteOrder(); 994 995 case llvm::MachO::HeaderMagic32Swapped: 996 case llvm::MachO::HeaderMagic64Swapped: 997 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 998 return lldb::eByteOrderLittle; 999 else 1000 return lldb::eByteOrderBig; 1001 1002 default: 1003 break; 1004 } 1005 return lldb::eByteOrderInvalid; 1006 } 1007 1008