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