1 //===-- ProcessElfCore.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 // C Includes 11 #include <stdlib.h> 12 13 // C++ Includes 14 #include <mutex> 15 16 // Other libraries and framework includes 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/ModuleSpec.h" 19 #include "lldb/Core/PluginManager.h" 20 #include "lldb/Core/Section.h" 21 #include "lldb/Target/DynamicLoader.h" 22 #include "lldb/Target/MemoryRegionInfo.h" 23 #include "lldb/Target/Target.h" 24 #include "lldb/Target/UnixSignals.h" 25 #include "lldb/Utility/DataBufferHeap.h" 26 #include "lldb/Utility/Log.h" 27 #include "lldb/Utility/State.h" 28 29 #include "llvm/BinaryFormat/ELF.h" 30 #include "llvm/Support/Threading.h" 31 32 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" 33 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 34 #include "Plugins/Process/elf-core/RegisterUtilities.h" 35 #include "ProcessElfCore.h" 36 #include "ThreadElfCore.h" 37 38 using namespace lldb_private; 39 40 ConstString ProcessElfCore::GetPluginNameStatic() { 41 static ConstString g_name("elf-core"); 42 return g_name; 43 } 44 45 const char *ProcessElfCore::GetPluginDescriptionStatic() { 46 return "ELF core dump plug-in."; 47 } 48 49 void ProcessElfCore::Terminate() { 50 PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance); 51 } 52 53 lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, 54 lldb::ListenerSP listener_sp, 55 const FileSpec *crash_file) { 56 lldb::ProcessSP process_sp; 57 if (crash_file) { 58 // Read enough data for a ELF32 header or ELF64 header Note: Here we care 59 // about e_type field only, so it is safe to ignore possible presence of 60 // the header extension. 61 const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr); 62 63 auto data_sp = FileSystem::Instance().CreateDataBuffer( 64 crash_file->GetPath(), header_size, 0); 65 if (data_sp && data_sp->GetByteSize() == header_size && 66 elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) { 67 elf::ELFHeader elf_header; 68 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4); 69 lldb::offset_t data_offset = 0; 70 if (elf_header.Parse(data, &data_offset)) { 71 if (elf_header.e_type == llvm::ELF::ET_CORE) 72 process_sp.reset( 73 new ProcessElfCore(target_sp, listener_sp, *crash_file)); 74 } 75 } 76 } 77 return process_sp; 78 } 79 80 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, 81 bool plugin_specified_by_name) { 82 // For now we are just making sure the file exists for a given module 83 if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { 84 ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture()); 85 Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, 86 NULL, NULL, NULL)); 87 if (m_core_module_sp) { 88 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 89 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile) 90 return true; 91 } 92 } 93 return false; 94 } 95 96 //---------------------------------------------------------------------- 97 // ProcessElfCore constructor 98 //---------------------------------------------------------------------- 99 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, 100 lldb::ListenerSP listener_sp, 101 const FileSpec &core_file) 102 : Process(target_sp, listener_sp), m_core_file(core_file) {} 103 104 //---------------------------------------------------------------------- 105 // Destructor 106 //---------------------------------------------------------------------- 107 ProcessElfCore::~ProcessElfCore() { 108 Clear(); 109 // We need to call finalize on the process before destroying ourselves to 110 // make sure all of the broadcaster cleanup goes as planned. If we destruct 111 // this class, then Process::~Process() might have problems trying to fully 112 // destroy the broadcaster. 113 Finalize(); 114 } 115 116 //---------------------------------------------------------------------- 117 // PluginInterface 118 //---------------------------------------------------------------------- 119 ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); } 120 121 uint32_t ProcessElfCore::GetPluginVersion() { return 1; } 122 123 lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( 124 const elf::ELFProgramHeader *header) { 125 const lldb::addr_t addr = header->p_vaddr; 126 FileRange file_range(header->p_offset, header->p_filesz); 127 VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range); 128 129 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); 130 if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() && 131 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() && 132 last_entry->GetByteSize() == last_entry->data.GetByteSize()) { 133 last_entry->SetRangeEnd(range_entry.GetRangeEnd()); 134 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd()); 135 } else { 136 m_core_aranges.Append(range_entry); 137 } 138 139 // Keep a separate map of permissions that that isn't coalesced so all ranges 140 // are maintained. 141 const uint32_t permissions = 142 ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) | 143 ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) | 144 ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u); 145 146 m_core_range_infos.Append( 147 VMRangeToPermissions::Entry(addr, header->p_memsz, permissions)); 148 149 return addr; 150 } 151 152 //---------------------------------------------------------------------- 153 // Process Control 154 //---------------------------------------------------------------------- 155 Status ProcessElfCore::DoLoadCore() { 156 Status error; 157 if (!m_core_module_sp) { 158 error.SetErrorString("invalid core module"); 159 return error; 160 } 161 162 ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile()); 163 if (core == NULL) { 164 error.SetErrorString("invalid core object file"); 165 return error; 166 } 167 168 const uint32_t num_segments = core->GetProgramHeaderCount(); 169 if (num_segments == 0) { 170 error.SetErrorString("core file has no segments"); 171 return error; 172 } 173 174 SetCanJIT(false); 175 176 m_thread_data_valid = true; 177 178 bool ranges_are_sorted = true; 179 lldb::addr_t vm_addr = 0; 180 /// Walk through segments and Thread and Address Map information. 181 /// PT_NOTE - Contains Thread and Register information 182 /// PT_LOAD - Contains a contiguous range of Process Address Space 183 for (uint32_t i = 1; i <= num_segments; i++) { 184 const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i); 185 assert(header != NULL); 186 187 DataExtractor data = core->GetSegmentDataByIndex(i); 188 189 // Parse thread contexts and auxv structure 190 if (header->p_type == llvm::ELF::PT_NOTE) { 191 if (llvm::Error error = ParseThreadContextsFromNoteSegment(header, data)) 192 return Status(std::move(error)); 193 } 194 // PT_LOAD segments contains address map 195 if (header->p_type == llvm::ELF::PT_LOAD) { 196 lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header); 197 if (vm_addr > last_addr) 198 ranges_are_sorted = false; 199 vm_addr = last_addr; 200 } 201 } 202 203 if (!ranges_are_sorted) { 204 m_core_aranges.Sort(); 205 m_core_range_infos.Sort(); 206 } 207 208 // Even if the architecture is set in the target, we need to override it to 209 // match the core file which is always single arch. 210 ArchSpec arch(m_core_module_sp->GetArchitecture()); 211 212 ArchSpec target_arch = GetTarget().GetArchitecture(); 213 ArchSpec core_arch(m_core_module_sp->GetArchitecture()); 214 target_arch.MergeFrom(core_arch); 215 GetTarget().SetArchitecture(target_arch); 216 217 SetUnixSignals(UnixSignals::Create(GetArchitecture())); 218 219 // Ensure we found at least one thread that was stopped on a signal. 220 bool siginfo_signal_found = false; 221 bool prstatus_signal_found = false; 222 // Check we found a signal in a SIGINFO note. 223 for (const auto &thread_data : m_thread_data) { 224 if (thread_data.signo != 0) 225 siginfo_signal_found = true; 226 if (thread_data.prstatus_sig != 0) 227 prstatus_signal_found = true; 228 } 229 if (!siginfo_signal_found) { 230 // If we don't have signal from SIGINFO use the signal from each threads 231 // PRSTATUS note. 232 if (prstatus_signal_found) { 233 for (auto &thread_data : m_thread_data) 234 thread_data.signo = thread_data.prstatus_sig; 235 } else if (m_thread_data.size() > 0) { 236 // If all else fails force the first thread to be SIGSTOP 237 m_thread_data.begin()->signo = 238 GetUnixSignals()->GetSignalNumberFromName("SIGSTOP"); 239 } 240 } 241 242 // Core files are useless without the main executable. See if we can locate 243 // the main executable using data we found in the core file notes. 244 lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); 245 if (!exe_module_sp) { 246 // The first entry in the NT_FILE might be our executable 247 if (!m_nt_file_entries.empty()) { 248 ModuleSpec exe_module_spec; 249 exe_module_spec.GetArchitecture() = arch; 250 exe_module_spec.GetFileSpec().SetFile( 251 m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native); 252 if (exe_module_spec.GetFileSpec()) { 253 exe_module_sp = GetTarget().GetSharedModule(exe_module_spec); 254 if (exe_module_sp) 255 GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo); 256 } 257 } 258 } 259 return error; 260 } 261 262 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() { 263 if (m_dyld_ap.get() == NULL) 264 m_dyld_ap.reset(DynamicLoader::FindPlugin( 265 this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString())); 266 return m_dyld_ap.get(); 267 } 268 269 bool ProcessElfCore::UpdateThreadList(ThreadList &old_thread_list, 270 ThreadList &new_thread_list) { 271 const uint32_t num_threads = GetNumThreadContexts(); 272 if (!m_thread_data_valid) 273 return false; 274 275 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) { 276 const ThreadData &td = m_thread_data[tid]; 277 lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td)); 278 new_thread_list.AddThread(thread_sp); 279 } 280 return new_thread_list.GetSize(false) > 0; 281 } 282 283 void ProcessElfCore::RefreshStateAfterStop() {} 284 285 Status ProcessElfCore::DoDestroy() { return Status(); } 286 287 //------------------------------------------------------------------ 288 // Process Queries 289 //------------------------------------------------------------------ 290 291 bool ProcessElfCore::IsAlive() { return true; } 292 293 //------------------------------------------------------------------ 294 // Process Memory 295 //------------------------------------------------------------------ 296 size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size, 297 Status &error) { 298 // Don't allow the caching that lldb_private::Process::ReadMemory does since 299 // in core files we have it all cached our our core file anyway. 300 return DoReadMemory(addr, buf, size, error); 301 } 302 303 Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, 304 MemoryRegionInfo ®ion_info) { 305 region_info.Clear(); 306 const VMRangeToPermissions::Entry *permission_entry = 307 m_core_range_infos.FindEntryThatContainsOrFollows(load_addr); 308 if (permission_entry) { 309 if (permission_entry->Contains(load_addr)) { 310 region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase()); 311 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd()); 312 const Flags permissions(permission_entry->data); 313 region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable) 314 ? MemoryRegionInfo::eYes 315 : MemoryRegionInfo::eNo); 316 region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable) 317 ? MemoryRegionInfo::eYes 318 : MemoryRegionInfo::eNo); 319 region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable) 320 ? MemoryRegionInfo::eYes 321 : MemoryRegionInfo::eNo); 322 region_info.SetMapped(MemoryRegionInfo::eYes); 323 } else if (load_addr < permission_entry->GetRangeBase()) { 324 region_info.GetRange().SetRangeBase(load_addr); 325 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase()); 326 region_info.SetReadable(MemoryRegionInfo::eNo); 327 region_info.SetWritable(MemoryRegionInfo::eNo); 328 region_info.SetExecutable(MemoryRegionInfo::eNo); 329 region_info.SetMapped(MemoryRegionInfo::eNo); 330 } 331 return Status(); 332 } 333 334 region_info.GetRange().SetRangeBase(load_addr); 335 region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); 336 region_info.SetReadable(MemoryRegionInfo::eNo); 337 region_info.SetWritable(MemoryRegionInfo::eNo); 338 region_info.SetExecutable(MemoryRegionInfo::eNo); 339 region_info.SetMapped(MemoryRegionInfo::eNo); 340 return Status(); 341 } 342 343 size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 344 Status &error) { 345 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 346 347 if (core_objfile == NULL) 348 return 0; 349 350 // Get the address range 351 const VMRangeToFileOffset::Entry *address_range = 352 m_core_aranges.FindEntryThatContains(addr); 353 if (address_range == NULL || address_range->GetRangeEnd() < addr) { 354 error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64, 355 addr); 356 return 0; 357 } 358 359 // Convert the address into core file offset 360 const lldb::addr_t offset = addr - address_range->GetRangeBase(); 361 const lldb::addr_t file_start = address_range->data.GetRangeBase(); 362 const lldb::addr_t file_end = address_range->data.GetRangeEnd(); 363 size_t bytes_to_read = size; // Number of bytes to read from the core file 364 size_t bytes_copied = 0; // Number of bytes actually read from the core file 365 size_t zero_fill_size = 0; // Padding 366 lldb::addr_t bytes_left = 367 0; // Number of bytes available in the core file from the given address 368 369 // Don't proceed if core file doesn't contain the actual data for this 370 // address range. 371 if (file_start == file_end) 372 return 0; 373 374 // Figure out how many on-disk bytes remain in this segment starting at the 375 // given offset 376 if (file_end > file_start + offset) 377 bytes_left = file_end - (file_start + offset); 378 379 // Figure out how many bytes we need to zero-fill if we are reading more 380 // bytes than available in the on-disk segment 381 if (bytes_to_read > bytes_left) { 382 zero_fill_size = bytes_to_read - bytes_left; 383 bytes_to_read = bytes_left; 384 } 385 386 // If there is data available on the core file read it 387 if (bytes_to_read) 388 bytes_copied = 389 core_objfile->CopyData(offset + file_start, bytes_to_read, buf); 390 391 assert(zero_fill_size <= size); 392 // Pad remaining bytes 393 if (zero_fill_size) 394 memset(((char *)buf) + bytes_copied, 0, zero_fill_size); 395 396 return bytes_copied + zero_fill_size; 397 } 398 399 void ProcessElfCore::Clear() { 400 m_thread_list.Clear(); 401 402 SetUnixSignals(std::make_shared<UnixSignals>()); 403 } 404 405 void ProcessElfCore::Initialize() { 406 static llvm::once_flag g_once_flag; 407 408 llvm::call_once(g_once_flag, []() { 409 PluginManager::RegisterPlugin(GetPluginNameStatic(), 410 GetPluginDescriptionStatic(), CreateInstance); 411 }); 412 } 413 414 lldb::addr_t ProcessElfCore::GetImageInfoAddress() { 415 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile(); 416 Address addr = obj_file->GetImageInfoAddress(&GetTarget()); 417 418 if (addr.IsValid()) 419 return addr.GetLoadAddress(&GetTarget()); 420 return LLDB_INVALID_ADDRESS; 421 } 422 423 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. 424 static void ParseFreeBSDPrStatus(ThreadData &thread_data, 425 const DataExtractor &data, 426 const ArchSpec &arch) { 427 lldb::offset_t offset = 0; 428 bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 || 429 arch.GetMachine() == llvm::Triple::mips64 || 430 arch.GetMachine() == llvm::Triple::ppc64 || 431 arch.GetMachine() == llvm::Triple::x86_64); 432 int pr_version = data.GetU32(&offset); 433 434 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 435 if (log) { 436 if (pr_version > 1) 437 log->Printf("FreeBSD PRSTATUS unexpected version %d", pr_version); 438 } 439 440 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate 441 if (lp64) 442 offset += 32; 443 else 444 offset += 16; 445 446 thread_data.signo = data.GetU32(&offset); // pr_cursig 447 thread_data.tid = data.GetU32(&offset); // pr_pid 448 if (lp64) 449 offset += 4; 450 451 size_t len = data.GetByteSize() - offset; 452 thread_data.gpregset = DataExtractor(data, offset, len); 453 } 454 455 static void ParseNetBSDProcInfo(ThreadData &thread_data, 456 const DataExtractor &data) { 457 lldb::offset_t offset = 0; 458 459 int version = data.GetU32(&offset); 460 if (version != 1) 461 return; 462 463 offset += 4; 464 thread_data.signo = data.GetU32(&offset); 465 } 466 467 static void ParseOpenBSDProcInfo(ThreadData &thread_data, 468 const DataExtractor &data) { 469 lldb::offset_t offset = 0; 470 471 int version = data.GetU32(&offset); 472 if (version != 1) 473 return; 474 475 offset += 4; 476 thread_data.signo = data.GetU32(&offset); 477 } 478 479 llvm::Expected<std::vector<CoreNote>> 480 ProcessElfCore::parseSegment(const DataExtractor &segment) { 481 lldb::offset_t offset = 0; 482 std::vector<CoreNote> result; 483 484 while (offset < segment.GetByteSize()) { 485 ELFNote note = ELFNote(); 486 if (!note.Parse(segment, &offset)) 487 return llvm::make_error<llvm::StringError>( 488 "Unable to parse note segment", llvm::inconvertibleErrorCode()); 489 490 size_t note_start = offset; 491 size_t note_size = llvm::alignTo(note.n_descsz, 4); 492 DataExtractor note_data(segment, note_start, note_size); 493 494 result.push_back({note, note_data}); 495 offset += note_size; 496 } 497 498 return std::move(result); 499 } 500 501 llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) { 502 bool have_prstatus = false; 503 bool have_prpsinfo = false; 504 ThreadData thread_data; 505 for (const auto ¬e : notes) { 506 if (note.info.n_name != "FreeBSD") 507 continue; 508 509 if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) || 510 (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) { 511 assert(thread_data.gpregset.GetByteSize() > 0); 512 // Add the new thread to thread list 513 m_thread_data.push_back(thread_data); 514 thread_data = ThreadData(); 515 have_prstatus = false; 516 have_prpsinfo = false; 517 } 518 519 switch (note.info.n_type) { 520 case FREEBSD::NT_PRSTATUS: 521 have_prstatus = true; 522 ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture()); 523 break; 524 case FREEBSD::NT_PRPSINFO: 525 have_prpsinfo = true; 526 break; 527 case FREEBSD::NT_THRMISC: { 528 lldb::offset_t offset = 0; 529 thread_data.name = note.data.GetCStr(&offset, 20); 530 break; 531 } 532 case FREEBSD::NT_PROCSTAT_AUXV: 533 // FIXME: FreeBSD sticks an int at the beginning of the note 534 m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4); 535 break; 536 default: 537 thread_data.notes.push_back(note); 538 break; 539 } 540 } 541 if (!have_prstatus) { 542 return llvm::make_error<llvm::StringError>( 543 "Could not find NT_PRSTATUS note in core file.", 544 llvm::inconvertibleErrorCode()); 545 } 546 m_thread_data.push_back(thread_data); 547 return llvm::Error::success(); 548 } 549 550 llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) { 551 ThreadData thread_data; 552 for (const auto ¬e : notes) { 553 // NetBSD per-thread information is stored in notes named "NetBSD-CORE@nnn" 554 // so match on the initial part of the string. 555 if (!llvm::StringRef(note.info.n_name).startswith("NetBSD-CORE")) 556 continue; 557 558 switch (note.info.n_type) { 559 case NETBSD::NT_PROCINFO: 560 ParseNetBSDProcInfo(thread_data, note.data); 561 break; 562 case NETBSD::NT_AUXV: 563 m_auxv = note.data; 564 break; 565 566 case NETBSD::NT_AMD64_REGS: 567 if (GetArchitecture().GetMachine() == llvm::Triple::x86_64) 568 thread_data.gpregset = note.data; 569 break; 570 default: 571 thread_data.notes.push_back(note); 572 break; 573 } 574 } 575 if (thread_data.gpregset.GetByteSize() == 0) { 576 return llvm::make_error<llvm::StringError>( 577 "Could not find general purpose registers note in core file.", 578 llvm::inconvertibleErrorCode()); 579 } 580 m_thread_data.push_back(thread_data); 581 return llvm::Error::success(); 582 } 583 584 llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) { 585 ThreadData thread_data; 586 for (const auto ¬e : notes) { 587 // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so 588 // match on the initial part of the string. 589 if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD")) 590 continue; 591 592 switch (note.info.n_type) { 593 case OPENBSD::NT_PROCINFO: 594 ParseOpenBSDProcInfo(thread_data, note.data); 595 break; 596 case OPENBSD::NT_AUXV: 597 m_auxv = note.data; 598 break; 599 case OPENBSD::NT_REGS: 600 thread_data.gpregset = note.data; 601 break; 602 default: 603 thread_data.notes.push_back(note); 604 break; 605 } 606 } 607 if (thread_data.gpregset.GetByteSize() == 0) { 608 return llvm::make_error<llvm::StringError>( 609 "Could not find general purpose registers note in core file.", 610 llvm::inconvertibleErrorCode()); 611 } 612 m_thread_data.push_back(thread_data); 613 return llvm::Error::success(); 614 } 615 616 /// A description of a linux process usually contains the following NOTE 617 /// entries: 618 /// - NT_PRPSINFO - General process information like pid, uid, name, ... 619 /// - NT_SIGINFO - Information about the signal that terminated the process 620 /// - NT_AUXV - Process auxiliary vector 621 /// - NT_FILE - Files mapped into memory 622 /// 623 /// Additionally, for each thread in the process the core file will contain at 624 /// least the NT_PRSTATUS note, containing the thread id and general purpose 625 /// registers. It may include additional notes for other register sets (floating 626 /// point and vector registers, ...). The tricky part here is that some of these 627 /// notes have "CORE" in their owner fields, while other set it to "LINUX". 628 llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { 629 const ArchSpec &arch = GetArchitecture(); 630 bool have_prstatus = false; 631 bool have_prpsinfo = false; 632 ThreadData thread_data; 633 for (const auto ¬e : notes) { 634 if (note.info.n_name != "CORE" && note.info.n_name != "LINUX") 635 continue; 636 637 if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) || 638 (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) { 639 assert(thread_data.gpregset.GetByteSize() > 0); 640 // Add the new thread to thread list 641 m_thread_data.push_back(thread_data); 642 thread_data = ThreadData(); 643 have_prstatus = false; 644 have_prpsinfo = false; 645 } 646 647 switch (note.info.n_type) { 648 case LINUX::NT_PRSTATUS: { 649 have_prstatus = true; 650 ELFLinuxPrStatus prstatus; 651 Status status = prstatus.Parse(note.data, arch); 652 if (status.Fail()) 653 return status.ToError(); 654 thread_data.prstatus_sig = prstatus.pr_cursig; 655 thread_data.tid = prstatus.pr_pid; 656 uint32_t header_size = ELFLinuxPrStatus::GetSize(arch); 657 size_t len = note.data.GetByteSize() - header_size; 658 thread_data.gpregset = DataExtractor(note.data, header_size, len); 659 break; 660 } 661 case LINUX::NT_PRPSINFO: { 662 have_prpsinfo = true; 663 ELFLinuxPrPsInfo prpsinfo; 664 Status status = prpsinfo.Parse(note.data, arch); 665 if (status.Fail()) 666 return status.ToError(); 667 thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname))); 668 SetID(prpsinfo.pr_pid); 669 break; 670 } 671 case LINUX::NT_SIGINFO: { 672 ELFLinuxSigInfo siginfo; 673 Status status = siginfo.Parse(note.data, arch); 674 if (status.Fail()) 675 return status.ToError(); 676 thread_data.signo = siginfo.si_signo; 677 break; 678 } 679 case LINUX::NT_FILE: { 680 m_nt_file_entries.clear(); 681 lldb::offset_t offset = 0; 682 const uint64_t count = note.data.GetAddress(&offset); 683 note.data.GetAddress(&offset); // Skip page size 684 for (uint64_t i = 0; i < count; ++i) { 685 NT_FILE_Entry entry; 686 entry.start = note.data.GetAddress(&offset); 687 entry.end = note.data.GetAddress(&offset); 688 entry.file_ofs = note.data.GetAddress(&offset); 689 m_nt_file_entries.push_back(entry); 690 } 691 for (uint64_t i = 0; i < count; ++i) { 692 const char *path = note.data.GetCStr(&offset); 693 if (path && path[0]) 694 m_nt_file_entries[i].path.SetCString(path); 695 } 696 break; 697 } 698 case LINUX::NT_AUXV: 699 m_auxv = note.data; 700 break; 701 default: 702 thread_data.notes.push_back(note); 703 break; 704 } 705 } 706 // Add last entry in the note section 707 if (have_prstatus) 708 m_thread_data.push_back(thread_data); 709 return llvm::Error::success(); 710 } 711 712 /// Parse Thread context from PT_NOTE segment and store it in the thread list 713 /// A note segment consists of one or more NOTE entries, but their types and 714 /// meaning differ depending on the OS. 715 llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( 716 const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) { 717 assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE); 718 719 auto notes_or_error = parseSegment(segment_data); 720 if(!notes_or_error) 721 return notes_or_error.takeError(); 722 switch (GetArchitecture().GetTriple().getOS()) { 723 case llvm::Triple::FreeBSD: 724 return parseFreeBSDNotes(*notes_or_error); 725 case llvm::Triple::Linux: 726 return parseLinuxNotes(*notes_or_error); 727 case llvm::Triple::NetBSD: 728 return parseNetBSDNotes(*notes_or_error); 729 case llvm::Triple::OpenBSD: 730 return parseOpenBSDNotes(*notes_or_error); 731 default: 732 return llvm::make_error<llvm::StringError>( 733 "Don't know how to parse core file. Unsupported OS.", 734 llvm::inconvertibleErrorCode()); 735 } 736 } 737 738 uint32_t ProcessElfCore::GetNumThreadContexts() { 739 if (!m_thread_data_valid) 740 DoLoadCore(); 741 return m_thread_data.size(); 742 } 743 744 ArchSpec ProcessElfCore::GetArchitecture() { 745 ArchSpec arch; 746 m_core_module_sp->GetObjectFile()->GetArchitecture(arch); 747 748 ArchSpec target_arch = GetTarget().GetArchitecture(); 749 arch.MergeFrom(target_arch); 750 751 // On MIPS there is no way to differentiate betwenn 32bit and 64bit core 752 // files and this information can't be merged in from the target arch so we 753 // fail back to unconditionally returning the target arch in this config. 754 if (target_arch.IsMIPS()) { 755 return target_arch; 756 } 757 758 return arch; 759 } 760 761 const lldb::DataBufferSP ProcessElfCore::GetAuxvData() { 762 const uint8_t *start = m_auxv.GetDataStart(); 763 size_t len = m_auxv.GetByteSize(); 764 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len)); 765 return buffer; 766 } 767 768 bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) { 769 info.Clear(); 770 info.SetProcessID(GetID()); 771 info.SetArchitecture(GetArchitecture()); 772 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); 773 if (module_sp) { 774 const bool add_exe_file_as_first_arg = false; 775 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), 776 add_exe_file_as_first_arg); 777 } 778 return true; 779 } 780