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