1 //===-- ProcessMachCore.cpp ------------------------------------------*- C++ 2 //-*-===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is distributed under the University of Illinois Open Source 7 // License. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 // C Includes 12 #include <errno.h> 13 #include <stdlib.h> 14 15 // C++ Includes 16 #include "llvm/Support/MathExtras.h" 17 #include "llvm/Support/Threading.h" 18 #include <mutex> 19 20 // Other libraries and framework includes 21 #include "lldb/Core/DataBuffer.h" 22 #include "lldb/Core/Debugger.h" 23 #include "lldb/Core/Log.h" 24 #include "lldb/Core/Module.h" 25 #include "lldb/Core/ModuleSpec.h" 26 #include "lldb/Core/PluginManager.h" 27 #include "lldb/Core/Section.h" 28 #include "lldb/Core/State.h" 29 #include "lldb/Host/Host.h" 30 #include "lldb/Symbol/ObjectFile.h" 31 #include "lldb/Target/MemoryRegionInfo.h" 32 #include "lldb/Target/Target.h" 33 #include "lldb/Target/Thread.h" 34 35 // Project includes 36 #include "ProcessMachCore.h" 37 #include "StopInfoMachException.h" 38 #include "ThreadMachCore.h" 39 40 // Needed for the plug-in names for the dynamic loaders. 41 #include "lldb/Utility/SafeMachO.h" 42 43 #include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" 44 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" 45 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" 46 47 using namespace lldb; 48 using namespace lldb_private; 49 50 ConstString ProcessMachCore::GetPluginNameStatic() { 51 static ConstString g_name("mach-o-core"); 52 return g_name; 53 } 54 55 const char *ProcessMachCore::GetPluginDescriptionStatic() { 56 return "Mach-O core file debugging plug-in."; 57 } 58 59 void ProcessMachCore::Terminate() { 60 PluginManager::UnregisterPlugin(ProcessMachCore::CreateInstance); 61 } 62 63 lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp, 64 ListenerSP listener_sp, 65 const FileSpec *crash_file) { 66 lldb::ProcessSP process_sp; 67 if (crash_file) { 68 const size_t header_size = sizeof(llvm::MachO::mach_header); 69 lldb::DataBufferSP data_sp(crash_file->ReadFileContents(0, header_size)); 70 if (data_sp && data_sp->GetByteSize() == header_size) { 71 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4); 72 73 lldb::offset_t data_offset = 0; 74 llvm::MachO::mach_header mach_header; 75 if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) { 76 if (mach_header.filetype == llvm::MachO::MH_CORE) 77 process_sp.reset( 78 new ProcessMachCore(target_sp, listener_sp, *crash_file)); 79 } 80 } 81 } 82 return process_sp; 83 } 84 85 bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp, 86 bool plugin_specified_by_name) { 87 if (plugin_specified_by_name) 88 return true; 89 90 // For now we are just making sure the file exists for a given module 91 if (!m_core_module_sp && m_core_file.Exists()) { 92 // Don't add the Target's architecture to the ModuleSpec - we may be working 93 // with a core file that doesn't have the correct cpusubtype in the header 94 // but we should still try to use it - 95 // ModuleSpecList::FindMatchingModuleSpec 96 // enforces a strict arch mach. 97 ModuleSpec core_module_spec(m_core_file); 98 Error error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, 99 NULL, NULL, NULL)); 100 101 if (m_core_module_sp) { 102 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 103 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile) 104 return true; 105 } 106 } 107 return false; 108 } 109 110 //---------------------------------------------------------------------- 111 // ProcessMachCore constructor 112 //---------------------------------------------------------------------- 113 ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, 114 ListenerSP listener_sp, 115 const FileSpec &core_file) 116 : Process(target_sp, listener_sp), m_core_aranges(), m_core_range_infos(), 117 m_core_module_sp(), m_core_file(core_file), 118 m_dyld_addr(LLDB_INVALID_ADDRESS), 119 m_mach_kernel_addr(LLDB_INVALID_ADDRESS), m_dyld_plugin_name() {} 120 121 //---------------------------------------------------------------------- 122 // Destructor 123 //---------------------------------------------------------------------- 124 ProcessMachCore::~ProcessMachCore() { 125 Clear(); 126 // We need to call finalize on the process before destroying ourselves 127 // to make sure all of the broadcaster cleanup goes as planned. If we 128 // destruct this class, then Process::~Process() might have problems 129 // trying to fully destroy the broadcaster. 130 Finalize(); 131 } 132 133 //---------------------------------------------------------------------- 134 // PluginInterface 135 //---------------------------------------------------------------------- 136 ConstString ProcessMachCore::GetPluginName() { return GetPluginNameStatic(); } 137 138 uint32_t ProcessMachCore::GetPluginVersion() { return 1; } 139 140 bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) { 141 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER | 142 LIBLLDB_LOG_PROCESS)); 143 llvm::MachO::mach_header header; 144 Error error; 145 if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header)) 146 return false; 147 if (header.magic == llvm::MachO::MH_CIGAM || 148 header.magic == llvm::MachO::MH_CIGAM_64) { 149 header.magic = llvm::ByteSwap_32(header.magic); 150 header.cputype = llvm::ByteSwap_32(header.cputype); 151 header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype); 152 header.filetype = llvm::ByteSwap_32(header.filetype); 153 header.ncmds = llvm::ByteSwap_32(header.ncmds); 154 header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds); 155 header.flags = llvm::ByteSwap_32(header.flags); 156 } 157 158 // TODO: swap header if needed... 159 // printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, 160 // header.magic, header.filetype); 161 if (header.magic == llvm::MachO::MH_MAGIC || 162 header.magic == llvm::MachO::MH_MAGIC_64) { 163 // Check MH_EXECUTABLE to see if we can find the mach image 164 // that contains the shared library list. The dynamic loader 165 // (dyld) is what contains the list for user applications, 166 // and the mach kernel contains a global that has the list 167 // of kexts to load 168 switch (header.filetype) { 169 case llvm::MachO::MH_DYLINKER: 170 // printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr); 171 // Address of dyld "struct mach_header" in the core file 172 if (log) 173 log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a user " 174 "process dyld binary image at 0x%" PRIx64, 175 addr); 176 m_dyld_addr = addr; 177 return true; 178 179 case llvm::MachO::MH_EXECUTE: 180 // printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr); 181 // Check MH_EXECUTABLE file types to see if the dynamic link object flag 182 // is NOT set. If it isn't, then we have a mach_kernel. 183 if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) { 184 if (log) 185 log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a mach " 186 "kernel binary image at 0x%" PRIx64, 187 addr); 188 // Address of the mach kernel "struct mach_header" in the core file. 189 m_mach_kernel_addr = addr; 190 return true; 191 } 192 break; 193 } 194 } 195 return false; 196 } 197 198 //---------------------------------------------------------------------- 199 // Process Control 200 //---------------------------------------------------------------------- 201 Error ProcessMachCore::DoLoadCore() { 202 Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER | 203 LIBLLDB_LOG_PROCESS)); 204 Error error; 205 if (!m_core_module_sp) { 206 error.SetErrorString("invalid core module"); 207 return error; 208 } 209 210 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 211 if (core_objfile == NULL) { 212 error.SetErrorString("invalid core object file"); 213 return error; 214 } 215 216 if (core_objfile->GetNumThreadContexts() == 0) { 217 error.SetErrorString("core file doesn't contain any LC_THREAD load " 218 "commands, or the LC_THREAD architecture is not " 219 "supported in this lldb"); 220 return error; 221 } 222 223 SectionList *section_list = core_objfile->GetSectionList(); 224 if (section_list == NULL) { 225 error.SetErrorString("core file has no sections"); 226 return error; 227 } 228 229 const uint32_t num_sections = section_list->GetNumSections(0); 230 if (num_sections == 0) { 231 error.SetErrorString("core file has no sections"); 232 return error; 233 } 234 235 SetCanJIT(false); 236 237 llvm::MachO::mach_header header; 238 DataExtractor data(&header, sizeof(header), 239 m_core_module_sp->GetArchitecture().GetByteOrder(), 240 m_core_module_sp->GetArchitecture().GetAddressByteSize()); 241 242 bool ranges_are_sorted = true; 243 addr_t vm_addr = 0; 244 for (uint32_t i = 0; i < num_sections; ++i) { 245 Section *section = section_list->GetSectionAtIndex(i).get(); 246 if (section) { 247 lldb::addr_t section_vm_addr = section->GetFileAddress(); 248 FileRange file_range(section->GetFileOffset(), section->GetFileSize()); 249 VMRangeToFileOffset::Entry range_entry( 250 section_vm_addr, section->GetByteSize(), file_range); 251 252 if (vm_addr > section_vm_addr) 253 ranges_are_sorted = false; 254 vm_addr = section->GetFileAddress(); 255 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); 256 // printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 257 // 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n", 258 // i, 259 // range_entry.GetRangeBase(), 260 // range_entry.GetRangeEnd(), 261 // range_entry.data.GetRangeBase(), 262 // range_entry.data.GetRangeEnd()); 263 264 if (last_entry && 265 last_entry->GetRangeEnd() == range_entry.GetRangeBase() && 266 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) { 267 last_entry->SetRangeEnd(range_entry.GetRangeEnd()); 268 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd()); 269 // puts("combine"); 270 } else { 271 m_core_aranges.Append(range_entry); 272 } 273 // Some core files don't fill in the permissions correctly. If that is the 274 // case 275 // assume read + execute so clients don't think the memory is not 276 // readable, 277 // or executable. The memory isn't writable since this plug-in doesn't 278 // implement 279 // DoWriteMemory. 280 uint32_t permissions = section->GetPermissions(); 281 if (permissions == 0) 282 permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable; 283 m_core_range_infos.Append(VMRangeToPermissions::Entry( 284 section_vm_addr, section->GetByteSize(), permissions)); 285 } 286 } 287 if (!ranges_are_sorted) { 288 m_core_aranges.Sort(); 289 m_core_range_infos.Sort(); 290 } 291 292 if (m_dyld_addr == LLDB_INVALID_ADDRESS || 293 m_mach_kernel_addr == LLDB_INVALID_ADDRESS) { 294 // We need to locate the main executable in the memory ranges 295 // we have in the core file. We need to search for both a user-process dyld 296 // binary 297 // and a kernel binary in memory; we must look at all the pages in the 298 // binary so 299 // we don't miss one or the other. Step through all memory segments 300 // searching for 301 // a kernel binary and for a user process dyld -- we'll decide which to 302 // prefer 303 // later if both are present. 304 305 const size_t num_core_aranges = m_core_aranges.GetSize(); 306 for (size_t i = 0; i < num_core_aranges; ++i) { 307 const VMRangeToFileOffset::Entry *entry = 308 m_core_aranges.GetEntryAtIndex(i); 309 lldb::addr_t section_vm_addr_start = entry->GetRangeBase(); 310 lldb::addr_t section_vm_addr_end = entry->GetRangeEnd(); 311 for (lldb::addr_t section_vm_addr = section_vm_addr_start; 312 section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) { 313 GetDynamicLoaderAddress(section_vm_addr); 314 } 315 } 316 } 317 318 if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { 319 // In the case of multiple kernel images found in the core file via 320 // exhaustive 321 // search, we may not pick the correct one. See if the 322 // DynamicLoaderDarwinKernel's 323 // search heuristics might identify the correct one. 324 // Most of the time, I expect the address from SearchForDarwinKernel() will 325 // be the 326 // same as the address we found via exhaustive search. 327 328 if (GetTarget().GetArchitecture().IsValid() == false && 329 m_core_module_sp.get()) { 330 GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture()); 331 } 332 333 // SearchForDarwinKernel will end up calling back into this this class in 334 // the GetImageInfoAddress 335 // method which will give it the m_mach_kernel_addr/m_dyld_addr it already 336 // has. Save that aside 337 // and set m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily 338 // so 339 // DynamicLoaderDarwinKernel does a real search for the kernel using its own 340 // heuristics. 341 342 addr_t saved_mach_kernel_addr = m_mach_kernel_addr; 343 addr_t saved_user_dyld_addr = m_dyld_addr; 344 m_mach_kernel_addr = LLDB_INVALID_ADDRESS; 345 m_dyld_addr = LLDB_INVALID_ADDRESS; 346 347 addr_t better_kernel_address = 348 DynamicLoaderDarwinKernel::SearchForDarwinKernel(this); 349 350 m_mach_kernel_addr = saved_mach_kernel_addr; 351 m_dyld_addr = saved_user_dyld_addr; 352 353 if (better_kernel_address != LLDB_INVALID_ADDRESS) { 354 if (log) 355 log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address " 356 "from DynamicLoaderDarwinKernel"); 357 m_mach_kernel_addr = better_kernel_address; 358 } 359 } 360 361 // If we found both a user-process dyld and a kernel binary, we need to decide 362 // which to prefer. 363 if (GetCorefilePreference() == eKernelCorefile) { 364 if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { 365 if (log) 366 log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image " 367 "at 0x%" PRIx64, 368 m_mach_kernel_addr); 369 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); 370 } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) { 371 if (log) 372 log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld " 373 "image at 0x%" PRIx64, 374 m_dyld_addr); 375 m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); 376 } 377 } else { 378 if (m_dyld_addr != LLDB_INVALID_ADDRESS) { 379 if (log) 380 log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld " 381 "image at 0x%" PRIx64, 382 m_dyld_addr); 383 m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); 384 } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { 385 if (log) 386 log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image " 387 "at 0x%" PRIx64, 388 m_mach_kernel_addr); 389 m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); 390 } 391 } 392 393 if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) { 394 // For non-user process core files, the permissions on the core file 395 // segments are usually 396 // meaningless, they may be just "read", because we're dealing with kernel 397 // coredumps or 398 // early startup coredumps and the dumper is grabbing pages of memory 399 // without knowing 400 // what they are. If they aren't marked as "exeuctable", that can break the 401 // unwinder 402 // which will check a pc value to see if it is in an executable segment and 403 // stop the 404 // backtrace early if it is not ("executable" and "unknown" would both be 405 // fine, but 406 // "not executable" will break the unwinder). 407 size_t core_range_infos_size = m_core_range_infos.GetSize(); 408 for (size_t i = 0; i < core_range_infos_size; i++) { 409 VMRangeToPermissions::Entry *ent = 410 m_core_range_infos.GetMutableEntryAtIndex(i); 411 ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable; 412 } 413 } 414 415 // Even if the architecture is set in the target, we need to override 416 // it to match the core file which is always single arch. 417 ArchSpec arch(m_core_module_sp->GetArchitecture()); 418 if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) { 419 arch.SetTriple("i386", GetTarget().GetPlatform().get()); 420 } 421 if (arch.IsValid()) 422 GetTarget().SetArchitecture(arch); 423 424 return error; 425 } 426 427 lldb_private::DynamicLoader *ProcessMachCore::GetDynamicLoader() { 428 if (m_dyld_ap.get() == NULL) 429 m_dyld_ap.reset(DynamicLoader::FindPlugin( 430 this, 431 m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString())); 432 return m_dyld_ap.get(); 433 } 434 435 bool ProcessMachCore::UpdateThreadList(ThreadList &old_thread_list, 436 ThreadList &new_thread_list) { 437 if (old_thread_list.GetSize(false) == 0) { 438 // Make up the thread the first time this is called so we can setup our one 439 // and only 440 // core thread state. 441 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 442 443 if (core_objfile) { 444 const uint32_t num_threads = core_objfile->GetNumThreadContexts(); 445 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) { 446 ThreadSP thread_sp(new ThreadMachCore(*this, tid)); 447 new_thread_list.AddThread(thread_sp); 448 } 449 } 450 } else { 451 const uint32_t num_threads = old_thread_list.GetSize(false); 452 for (uint32_t i = 0; i < num_threads; ++i) 453 new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false)); 454 } 455 return new_thread_list.GetSize(false) > 0; 456 } 457 458 void ProcessMachCore::RefreshStateAfterStop() { 459 // Let all threads recover from stopping and do any clean up based 460 // on the previous thread state (if any). 461 m_thread_list.RefreshStateAfterStop(); 462 // SetThreadStopInfo (m_last_stop_packet); 463 } 464 465 Error ProcessMachCore::DoDestroy() { return Error(); } 466 467 //------------------------------------------------------------------ 468 // Process Queries 469 //------------------------------------------------------------------ 470 471 bool ProcessMachCore::IsAlive() { return true; } 472 473 bool ProcessMachCore::WarnBeforeDetach() const { return false; } 474 475 //------------------------------------------------------------------ 476 // Process Memory 477 //------------------------------------------------------------------ 478 size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size, 479 Error &error) { 480 // Don't allow the caching that lldb_private::Process::ReadMemory does 481 // since in core files we have it all cached our our core file anyway. 482 return DoReadMemory(addr, buf, size, error); 483 } 484 485 size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size, 486 Error &error) { 487 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 488 size_t bytes_read = 0; 489 490 if (core_objfile) { 491 //---------------------------------------------------------------------- 492 // Segments are not always contiguous in mach-o core files. We have core 493 // files that have segments like: 494 // Address Size File off File size 495 // ---------- ---------- ---------- ---------- 496 // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0 497 // 0x00000000 __TEXT 498 // LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000 --- --- 0 499 // 0x00000000 __TEXT 500 // LC_SEGMENT 0x000f7000 0x00001000 0x1d60aee8 0x00001000 --- --- 0 501 // 0x00000000 __TEXT 502 // 503 // Any if the user executes the following command: 504 // 505 // (lldb) mem read 0xf6ff0 506 // 507 // We would attempt to read 32 bytes from 0xf6ff0 but would only 508 // get 16 unless we loop through consecutive memory ranges that are 509 // contiguous in the address space, but not in the file data. 510 //---------------------------------------------------------------------- 511 while (bytes_read < size) { 512 const addr_t curr_addr = addr + bytes_read; 513 const VMRangeToFileOffset::Entry *core_memory_entry = 514 m_core_aranges.FindEntryThatContains(curr_addr); 515 516 if (core_memory_entry) { 517 const addr_t offset = curr_addr - core_memory_entry->GetRangeBase(); 518 const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr; 519 const size_t bytes_to_read = 520 std::min(size - bytes_read, (size_t)bytes_left); 521 const size_t curr_bytes_read = core_objfile->CopyData( 522 core_memory_entry->data.GetRangeBase() + offset, bytes_to_read, 523 (char *)buf + bytes_read); 524 if (curr_bytes_read == 0) 525 break; 526 bytes_read += curr_bytes_read; 527 } else { 528 // Only set the error if we didn't read any bytes 529 if (bytes_read == 0) 530 error.SetErrorStringWithFormat( 531 "core file does not contain 0x%" PRIx64, curr_addr); 532 break; 533 } 534 } 535 } 536 537 return bytes_read; 538 } 539 540 Error ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr, 541 MemoryRegionInfo ®ion_info) { 542 region_info.Clear(); 543 const VMRangeToPermissions::Entry *permission_entry = 544 m_core_range_infos.FindEntryThatContainsOrFollows(load_addr); 545 if (permission_entry) { 546 if (permission_entry->Contains(load_addr)) { 547 region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase()); 548 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd()); 549 const Flags permissions(permission_entry->data); 550 region_info.SetReadable(permissions.Test(ePermissionsReadable) 551 ? MemoryRegionInfo::eYes 552 : MemoryRegionInfo::eNo); 553 region_info.SetWritable(permissions.Test(ePermissionsWritable) 554 ? MemoryRegionInfo::eYes 555 : MemoryRegionInfo::eNo); 556 region_info.SetExecutable(permissions.Test(ePermissionsExecutable) 557 ? MemoryRegionInfo::eYes 558 : MemoryRegionInfo::eNo); 559 region_info.SetMapped(MemoryRegionInfo::eYes); 560 } else if (load_addr < permission_entry->GetRangeBase()) { 561 region_info.GetRange().SetRangeBase(load_addr); 562 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase()); 563 region_info.SetReadable(MemoryRegionInfo::eNo); 564 region_info.SetWritable(MemoryRegionInfo::eNo); 565 region_info.SetExecutable(MemoryRegionInfo::eNo); 566 region_info.SetMapped(MemoryRegionInfo::eNo); 567 } 568 return Error(); 569 } 570 571 region_info.GetRange().SetRangeBase(load_addr); 572 region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); 573 region_info.SetReadable(MemoryRegionInfo::eNo); 574 region_info.SetWritable(MemoryRegionInfo::eNo); 575 region_info.SetExecutable(MemoryRegionInfo::eNo); 576 region_info.SetMapped(MemoryRegionInfo::eNo); 577 return Error(); 578 } 579 580 void ProcessMachCore::Clear() { m_thread_list.Clear(); } 581 582 void ProcessMachCore::Initialize() { 583 static llvm::once_flag g_once_flag; 584 585 llvm::call_once(g_once_flag, []() { 586 PluginManager::RegisterPlugin(GetPluginNameStatic(), 587 GetPluginDescriptionStatic(), CreateInstance); 588 }); 589 } 590 591 addr_t ProcessMachCore::GetImageInfoAddress() { 592 // If we found both a user-process dyld and a kernel binary, we need to decide 593 // which to prefer. 594 if (GetCorefilePreference() == eKernelCorefile) { 595 if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { 596 return m_mach_kernel_addr; 597 } 598 return m_dyld_addr; 599 } else { 600 if (m_dyld_addr != LLDB_INVALID_ADDRESS) { 601 return m_dyld_addr; 602 } 603 return m_mach_kernel_addr; 604 } 605 } 606 607 lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() { 608 return m_core_module_sp->GetObjectFile(); 609 } 610