1 //===-- ProcessElfCore.cpp ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <cstdlib> 10 11 #include <memory> 12 #include <mutex> 13 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/ModuleSpec.h" 16 #include "lldb/Core/PluginManager.h" 17 #include "lldb/Core/Section.h" 18 #include "lldb/Target/DynamicLoader.h" 19 #include "lldb/Target/MemoryRegionInfo.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Target/UnixSignals.h" 22 #include "lldb/Utility/DataBufferHeap.h" 23 #include "lldb/Utility/LLDBLog.h" 24 #include "lldb/Utility/Log.h" 25 #include "lldb/Utility/State.h" 26 27 #include "llvm/BinaryFormat/ELF.h" 28 #include "llvm/Support/Threading.h" 29 30 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" 31 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 32 #include "Plugins/Process/elf-core/RegisterUtilities.h" 33 #include "ProcessElfCore.h" 34 #include "ThreadElfCore.h" 35 36 using namespace lldb_private; 37 namespace ELF = llvm::ELF; 38 39 LLDB_PLUGIN_DEFINE(ProcessElfCore) 40 41 llvm::StringRef ProcessElfCore::GetPluginDescriptionStatic() { 42 return "ELF core dump plug-in."; 43 } 44 45 void ProcessElfCore::Terminate() { 46 PluginManager::UnregisterPlugin(ProcessElfCore::CreateInstance); 47 } 48 49 lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, 50 lldb::ListenerSP listener_sp, 51 const FileSpec *crash_file, 52 bool can_connect) { 53 lldb::ProcessSP process_sp; 54 if (crash_file && !can_connect) { 55 // Read enough data for a ELF32 header or ELF64 header Note: Here we care 56 // about e_type field only, so it is safe to ignore possible presence of 57 // the header extension. 58 const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr); 59 60 auto data_sp = FileSystem::Instance().CreateDataBuffer( 61 crash_file->GetPath(), header_size, 0); 62 if (data_sp && data_sp->GetByteSize() == header_size && 63 elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) { 64 elf::ELFHeader elf_header; 65 DataExtractor data(data_sp, lldb::eByteOrderLittle, 4); 66 lldb::offset_t data_offset = 0; 67 if (elf_header.Parse(data, &data_offset)) { 68 // Check whether we're dealing with a raw FreeBSD "full memory dump" 69 // ELF vmcore that needs to be handled via FreeBSDKernel plugin instead. 70 if (elf_header.e_ident[7] == 0xFF && elf_header.e_version == 0) 71 return process_sp; 72 if (elf_header.e_type == llvm::ELF::ET_CORE) 73 process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp, 74 *crash_file); 75 } 76 } 77 } 78 return process_sp; 79 } 80 81 bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, 82 bool plugin_specified_by_name) { 83 // For now we are just making sure the file exists for a given module 84 if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { 85 ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture()); 86 Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, 87 nullptr, nullptr, nullptr)); 88 if (m_core_module_sp) { 89 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 90 if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile) 91 return true; 92 } 93 } 94 return false; 95 } 96 97 // ProcessElfCore constructor 98 ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp, 99 lldb::ListenerSP listener_sp, 100 const FileSpec &core_file) 101 : PostMortemProcess(target_sp, listener_sp), m_core_file(core_file) {} 102 103 // Destructor 104 ProcessElfCore::~ProcessElfCore() { 105 Clear(); 106 // We need to call finalize on the process before destroying ourselves to 107 // make sure all of the broadcaster cleanup goes as planned. If we destruct 108 // this class, then Process::~Process() might have problems trying to fully 109 // destroy the broadcaster. 110 Finalize(); 111 } 112 113 lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( 114 const elf::ELFProgramHeader &header) { 115 const lldb::addr_t addr = header.p_vaddr; 116 FileRange file_range(header.p_offset, header.p_filesz); 117 VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range); 118 119 // Only add to m_core_aranges if the file size is non zero. Some core files 120 // have PT_LOAD segments for all address ranges, but set f_filesz to zero for 121 // the .text sections since they can be retrieved from the object files. 122 if (header.p_filesz > 0) { 123 VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); 124 if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() && 125 last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase() && 126 last_entry->GetByteSize() == last_entry->data.GetByteSize()) { 127 last_entry->SetRangeEnd(range_entry.GetRangeEnd()); 128 last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd()); 129 } else { 130 m_core_aranges.Append(range_entry); 131 } 132 } 133 // Keep a separate map of permissions that that isn't coalesced so all ranges 134 // are maintained. 135 const uint32_t permissions = 136 ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) | 137 ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) | 138 ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u); 139 140 m_core_range_infos.Append( 141 VMRangeToPermissions::Entry(addr, header.p_memsz, permissions)); 142 143 return addr; 144 } 145 146 // Process Control 147 Status ProcessElfCore::DoLoadCore() { 148 Status error; 149 if (!m_core_module_sp) { 150 error.SetErrorString("invalid core module"); 151 return error; 152 } 153 154 ObjectFileELF *core = (ObjectFileELF *)(m_core_module_sp->GetObjectFile()); 155 if (core == nullptr) { 156 error.SetErrorString("invalid core object file"); 157 return error; 158 } 159 160 llvm::ArrayRef<elf::ELFProgramHeader> segments = core->ProgramHeaders(); 161 if (segments.size() == 0) { 162 error.SetErrorString("core file has no segments"); 163 return error; 164 } 165 166 SetCanJIT(false); 167 168 m_thread_data_valid = true; 169 170 bool ranges_are_sorted = true; 171 lldb::addr_t vm_addr = 0; 172 /// Walk through segments and Thread and Address Map information. 173 /// PT_NOTE - Contains Thread and Register information 174 /// PT_LOAD - Contains a contiguous range of Process Address Space 175 for (const elf::ELFProgramHeader &H : segments) { 176 DataExtractor data = core->GetSegmentData(H); 177 178 // Parse thread contexts and auxv structure 179 if (H.p_type == llvm::ELF::PT_NOTE) { 180 if (llvm::Error error = ParseThreadContextsFromNoteSegment(H, data)) 181 return Status(std::move(error)); 182 } 183 // PT_LOAD segments contains address map 184 if (H.p_type == llvm::ELF::PT_LOAD) { 185 lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(H); 186 if (vm_addr > last_addr) 187 ranges_are_sorted = false; 188 vm_addr = last_addr; 189 } 190 } 191 192 if (!ranges_are_sorted) { 193 m_core_aranges.Sort(); 194 m_core_range_infos.Sort(); 195 } 196 197 // Even if the architecture is set in the target, we need to override it to 198 // match the core file which is always single arch. 199 ArchSpec arch(m_core_module_sp->GetArchitecture()); 200 201 ArchSpec target_arch = GetTarget().GetArchitecture(); 202 ArchSpec core_arch(m_core_module_sp->GetArchitecture()); 203 target_arch.MergeFrom(core_arch); 204 GetTarget().SetArchitecture(target_arch); 205 206 SetUnixSignals(UnixSignals::Create(GetArchitecture())); 207 208 // Ensure we found at least one thread that was stopped on a signal. 209 bool siginfo_signal_found = false; 210 bool prstatus_signal_found = false; 211 // Check we found a signal in a SIGINFO note. 212 for (const auto &thread_data : m_thread_data) { 213 if (thread_data.signo != 0) 214 siginfo_signal_found = true; 215 if (thread_data.prstatus_sig != 0) 216 prstatus_signal_found = true; 217 } 218 if (!siginfo_signal_found) { 219 // If we don't have signal from SIGINFO use the signal from each threads 220 // PRSTATUS note. 221 if (prstatus_signal_found) { 222 for (auto &thread_data : m_thread_data) 223 thread_data.signo = thread_data.prstatus_sig; 224 } else if (m_thread_data.size() > 0) { 225 // If all else fails force the first thread to be SIGSTOP 226 m_thread_data.begin()->signo = 227 GetUnixSignals()->GetSignalNumberFromName("SIGSTOP"); 228 } 229 } 230 231 // Core files are useless without the main executable. See if we can locate 232 // the main executable using data we found in the core file notes. 233 lldb::ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); 234 if (!exe_module_sp) { 235 // The first entry in the NT_FILE might be our executable 236 if (!m_nt_file_entries.empty()) { 237 ModuleSpec exe_module_spec; 238 exe_module_spec.GetArchitecture() = arch; 239 exe_module_spec.GetFileSpec().SetFile( 240 m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native); 241 if (exe_module_spec.GetFileSpec()) { 242 exe_module_sp = GetTarget().GetOrCreateModule(exe_module_spec, 243 true /* notify */); 244 if (exe_module_sp) 245 GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo); 246 } 247 } 248 } 249 return error; 250 } 251 252 lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() { 253 if (m_dyld_up.get() == nullptr) 254 m_dyld_up.reset(DynamicLoader::FindPlugin( 255 this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic())); 256 return m_dyld_up.get(); 257 } 258 259 bool ProcessElfCore::DoUpdateThreadList(ThreadList &old_thread_list, 260 ThreadList &new_thread_list) { 261 const uint32_t num_threads = GetNumThreadContexts(); 262 if (!m_thread_data_valid) 263 return false; 264 265 for (lldb::tid_t tid = 0; tid < num_threads; ++tid) { 266 const ThreadData &td = m_thread_data[tid]; 267 lldb::ThreadSP thread_sp(new ThreadElfCore(*this, td)); 268 new_thread_list.AddThread(thread_sp); 269 } 270 return new_thread_list.GetSize(false) > 0; 271 } 272 273 void ProcessElfCore::RefreshStateAfterStop() {} 274 275 Status ProcessElfCore::DoDestroy() { return Status(); } 276 277 // Process Queries 278 279 bool ProcessElfCore::IsAlive() { return true; } 280 281 // Process Memory 282 size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size, 283 Status &error) { 284 // Don't allow the caching that lldb_private::Process::ReadMemory does since 285 // in core files we have it all cached our our core file anyway. 286 return DoReadMemory(addr, buf, size, error); 287 } 288 289 Status ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr, 290 MemoryRegionInfo ®ion_info) { 291 region_info.Clear(); 292 const VMRangeToPermissions::Entry *permission_entry = 293 m_core_range_infos.FindEntryThatContainsOrFollows(load_addr); 294 if (permission_entry) { 295 if (permission_entry->Contains(load_addr)) { 296 region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase()); 297 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd()); 298 const Flags permissions(permission_entry->data); 299 region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable) 300 ? MemoryRegionInfo::eYes 301 : MemoryRegionInfo::eNo); 302 region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable) 303 ? MemoryRegionInfo::eYes 304 : MemoryRegionInfo::eNo); 305 region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable) 306 ? MemoryRegionInfo::eYes 307 : MemoryRegionInfo::eNo); 308 region_info.SetMapped(MemoryRegionInfo::eYes); 309 } else if (load_addr < permission_entry->GetRangeBase()) { 310 region_info.GetRange().SetRangeBase(load_addr); 311 region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase()); 312 region_info.SetReadable(MemoryRegionInfo::eNo); 313 region_info.SetWritable(MemoryRegionInfo::eNo); 314 region_info.SetExecutable(MemoryRegionInfo::eNo); 315 region_info.SetMapped(MemoryRegionInfo::eNo); 316 } 317 return Status(); 318 } 319 320 region_info.GetRange().SetRangeBase(load_addr); 321 region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); 322 region_info.SetReadable(MemoryRegionInfo::eNo); 323 region_info.SetWritable(MemoryRegionInfo::eNo); 324 region_info.SetExecutable(MemoryRegionInfo::eNo); 325 region_info.SetMapped(MemoryRegionInfo::eNo); 326 return Status(); 327 } 328 329 size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 330 Status &error) { 331 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); 332 333 if (core_objfile == nullptr) 334 return 0; 335 336 // Get the address range 337 const VMRangeToFileOffset::Entry *address_range = 338 m_core_aranges.FindEntryThatContains(addr); 339 if (address_range == nullptr || address_range->GetRangeEnd() < addr) { 340 error.SetErrorStringWithFormat("core file does not contain 0x%" PRIx64, 341 addr); 342 return 0; 343 } 344 345 // Convert the address into core file offset 346 const lldb::addr_t offset = addr - address_range->GetRangeBase(); 347 const lldb::addr_t file_start = address_range->data.GetRangeBase(); 348 const lldb::addr_t file_end = address_range->data.GetRangeEnd(); 349 size_t bytes_to_read = size; // Number of bytes to read from the core file 350 size_t bytes_copied = 0; // Number of bytes actually read from the core file 351 lldb::addr_t bytes_left = 352 0; // Number of bytes available in the core file from the given address 353 354 // Don't proceed if core file doesn't contain the actual data for this 355 // address range. 356 if (file_start == file_end) 357 return 0; 358 359 // Figure out how many on-disk bytes remain in this segment starting at the 360 // given offset 361 if (file_end > file_start + offset) 362 bytes_left = file_end - (file_start + offset); 363 364 if (bytes_to_read > bytes_left) 365 bytes_to_read = bytes_left; 366 367 // If there is data available on the core file read it 368 if (bytes_to_read) 369 bytes_copied = 370 core_objfile->CopyData(offset + file_start, bytes_to_read, buf); 371 372 return bytes_copied; 373 } 374 375 void ProcessElfCore::Clear() { 376 m_thread_list.Clear(); 377 378 SetUnixSignals(std::make_shared<UnixSignals>()); 379 } 380 381 void ProcessElfCore::Initialize() { 382 static llvm::once_flag g_once_flag; 383 384 llvm::call_once(g_once_flag, []() { 385 PluginManager::RegisterPlugin(GetPluginNameStatic(), 386 GetPluginDescriptionStatic(), CreateInstance); 387 }); 388 } 389 390 lldb::addr_t ProcessElfCore::GetImageInfoAddress() { 391 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile(); 392 Address addr = obj_file->GetImageInfoAddress(&GetTarget()); 393 394 if (addr.IsValid()) 395 return addr.GetLoadAddress(&GetTarget()); 396 return LLDB_INVALID_ADDRESS; 397 } 398 399 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. 400 static void ParseFreeBSDPrStatus(ThreadData &thread_data, 401 const DataExtractor &data, 402 bool lp64) { 403 lldb::offset_t offset = 0; 404 int pr_version = data.GetU32(&offset); 405 406 Log *log = GetLog(LLDBLog::Process); 407 if (log) { 408 if (pr_version > 1) 409 LLDB_LOGF(log, "FreeBSD PRSTATUS unexpected version %d", pr_version); 410 } 411 412 // Skip padding, pr_statussz, pr_gregsetsz, pr_fpregsetsz, pr_osreldate 413 if (lp64) 414 offset += 32; 415 else 416 offset += 16; 417 418 thread_data.signo = data.GetU32(&offset); // pr_cursig 419 thread_data.tid = data.GetU32(&offset); // pr_pid 420 if (lp64) 421 offset += 4; 422 423 size_t len = data.GetByteSize() - offset; 424 thread_data.gpregset = DataExtractor(data, offset, len); 425 } 426 427 // Parse a FreeBSD NT_PRPSINFO note - see FreeBSD sys/procfs.h for details. 428 static void ParseFreeBSDPrPsInfo(ProcessElfCore &process, 429 const DataExtractor &data, 430 bool lp64) { 431 lldb::offset_t offset = 0; 432 int pr_version = data.GetU32(&offset); 433 434 Log *log = GetLog(LLDBLog::Process); 435 if (log) { 436 if (pr_version > 1) 437 LLDB_LOGF(log, "FreeBSD PRPSINFO unexpected version %d", pr_version); 438 } 439 440 // Skip pr_psinfosz, pr_fname, pr_psargs 441 offset += 108; 442 if (lp64) 443 offset += 4; 444 445 process.SetID(data.GetU32(&offset)); // pr_pid 446 } 447 448 static llvm::Error ParseNetBSDProcInfo(const DataExtractor &data, 449 uint32_t &cpi_nlwps, 450 uint32_t &cpi_signo, 451 uint32_t &cpi_siglwp, 452 uint32_t &cpi_pid) { 453 lldb::offset_t offset = 0; 454 455 uint32_t version = data.GetU32(&offset); 456 if (version != 1) 457 return llvm::make_error<llvm::StringError>( 458 "Error parsing NetBSD core(5) notes: Unsupported procinfo version", 459 llvm::inconvertibleErrorCode()); 460 461 uint32_t cpisize = data.GetU32(&offset); 462 if (cpisize != NETBSD::NT_PROCINFO_SIZE) 463 return llvm::make_error<llvm::StringError>( 464 "Error parsing NetBSD core(5) notes: Unsupported procinfo size", 465 llvm::inconvertibleErrorCode()); 466 467 cpi_signo = data.GetU32(&offset); /* killing signal */ 468 469 offset += NETBSD::NT_PROCINFO_CPI_SIGCODE_SIZE; 470 offset += NETBSD::NT_PROCINFO_CPI_SIGPEND_SIZE; 471 offset += NETBSD::NT_PROCINFO_CPI_SIGMASK_SIZE; 472 offset += NETBSD::NT_PROCINFO_CPI_SIGIGNORE_SIZE; 473 offset += NETBSD::NT_PROCINFO_CPI_SIGCATCH_SIZE; 474 cpi_pid = data.GetU32(&offset); 475 offset += NETBSD::NT_PROCINFO_CPI_PPID_SIZE; 476 offset += NETBSD::NT_PROCINFO_CPI_PGRP_SIZE; 477 offset += NETBSD::NT_PROCINFO_CPI_SID_SIZE; 478 offset += NETBSD::NT_PROCINFO_CPI_RUID_SIZE; 479 offset += NETBSD::NT_PROCINFO_CPI_EUID_SIZE; 480 offset += NETBSD::NT_PROCINFO_CPI_SVUID_SIZE; 481 offset += NETBSD::NT_PROCINFO_CPI_RGID_SIZE; 482 offset += NETBSD::NT_PROCINFO_CPI_EGID_SIZE; 483 offset += NETBSD::NT_PROCINFO_CPI_SVGID_SIZE; 484 cpi_nlwps = data.GetU32(&offset); /* number of LWPs */ 485 486 offset += NETBSD::NT_PROCINFO_CPI_NAME_SIZE; 487 cpi_siglwp = data.GetU32(&offset); /* LWP target of killing signal */ 488 489 return llvm::Error::success(); 490 } 491 492 static void ParseOpenBSDProcInfo(ThreadData &thread_data, 493 const DataExtractor &data) { 494 lldb::offset_t offset = 0; 495 496 int version = data.GetU32(&offset); 497 if (version != 1) 498 return; 499 500 offset += 4; 501 thread_data.signo = data.GetU32(&offset); 502 } 503 504 llvm::Expected<std::vector<CoreNote>> 505 ProcessElfCore::parseSegment(const DataExtractor &segment) { 506 lldb::offset_t offset = 0; 507 std::vector<CoreNote> result; 508 509 while (offset < segment.GetByteSize()) { 510 ELFNote note = ELFNote(); 511 if (!note.Parse(segment, &offset)) 512 return llvm::make_error<llvm::StringError>( 513 "Unable to parse note segment", llvm::inconvertibleErrorCode()); 514 515 size_t note_start = offset; 516 size_t note_size = llvm::alignTo(note.n_descsz, 4); 517 518 result.push_back({note, DataExtractor(segment, note_start, note_size)}); 519 offset += note_size; 520 } 521 522 return std::move(result); 523 } 524 525 llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) { 526 ArchSpec arch = GetArchitecture(); 527 bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 || 528 arch.GetMachine() == llvm::Triple::mips64 || 529 arch.GetMachine() == llvm::Triple::ppc64 || 530 arch.GetMachine() == llvm::Triple::x86_64); 531 bool have_prstatus = false; 532 bool have_prpsinfo = false; 533 ThreadData thread_data; 534 for (const auto ¬e : notes) { 535 if (note.info.n_name != "FreeBSD") 536 continue; 537 538 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) || 539 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) { 540 assert(thread_data.gpregset.GetByteSize() > 0); 541 // Add the new thread to thread list 542 m_thread_data.push_back(thread_data); 543 thread_data = ThreadData(); 544 have_prstatus = false; 545 have_prpsinfo = false; 546 } 547 548 switch (note.info.n_type) { 549 case ELF::NT_PRSTATUS: 550 have_prstatus = true; 551 ParseFreeBSDPrStatus(thread_data, note.data, lp64); 552 break; 553 case ELF::NT_PRPSINFO: 554 have_prpsinfo = true; 555 ParseFreeBSDPrPsInfo(*this, note.data, lp64); 556 break; 557 case ELF::NT_FREEBSD_THRMISC: { 558 lldb::offset_t offset = 0; 559 thread_data.name = note.data.GetCStr(&offset, 20); 560 break; 561 } 562 case ELF::NT_FREEBSD_PROCSTAT_AUXV: 563 // FIXME: FreeBSD sticks an int at the beginning of the note 564 m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4); 565 break; 566 default: 567 thread_data.notes.push_back(note); 568 break; 569 } 570 } 571 if (!have_prstatus) { 572 return llvm::make_error<llvm::StringError>( 573 "Could not find NT_PRSTATUS note in core file.", 574 llvm::inconvertibleErrorCode()); 575 } 576 m_thread_data.push_back(thread_data); 577 return llvm::Error::success(); 578 } 579 580 /// NetBSD specific Thread context from PT_NOTE segment 581 /// 582 /// NetBSD ELF core files use notes to provide information about 583 /// the process's state. The note name is "NetBSD-CORE" for 584 /// information that is global to the process, and "NetBSD-CORE@nn", 585 /// where "nn" is the lwpid of the LWP that the information belongs 586 /// to (such as register state). 587 /// 588 /// NetBSD uses the following note identifiers: 589 /// 590 /// ELF_NOTE_NETBSD_CORE_PROCINFO (value 1) 591 /// Note is a "netbsd_elfcore_procinfo" structure. 592 /// ELF_NOTE_NETBSD_CORE_AUXV (value 2; since NetBSD 8.0) 593 /// Note is an array of AuxInfo structures. 594 /// 595 /// NetBSD also uses ptrace(2) request numbers (the ones that exist in 596 /// machine-dependent space) to identify register info notes. The 597 /// info in such notes is in the same format that ptrace(2) would 598 /// export that information. 599 /// 600 /// For more information see /usr/include/sys/exec_elf.h 601 /// 602 llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) { 603 ThreadData thread_data; 604 bool had_nt_regs = false; 605 606 // To be extracted from struct netbsd_elfcore_procinfo 607 // Used to sanity check of the LWPs of the process 608 uint32_t nlwps = 0; 609 uint32_t signo; // killing signal 610 uint32_t siglwp; // LWP target of killing signal 611 uint32_t pr_pid; 612 613 for (const auto ¬e : notes) { 614 llvm::StringRef name = note.info.n_name; 615 616 if (name == "NetBSD-CORE") { 617 if (note.info.n_type == NETBSD::NT_PROCINFO) { 618 llvm::Error error = ParseNetBSDProcInfo(note.data, nlwps, signo, 619 siglwp, pr_pid); 620 if (error) 621 return error; 622 SetID(pr_pid); 623 } else if (note.info.n_type == NETBSD::NT_AUXV) { 624 m_auxv = note.data; 625 } 626 } else if (name.consume_front("NetBSD-CORE@")) { 627 lldb::tid_t tid; 628 if (name.getAsInteger(10, tid)) 629 return llvm::make_error<llvm::StringError>( 630 "Error parsing NetBSD core(5) notes: Cannot convert LWP ID " 631 "to integer", 632 llvm::inconvertibleErrorCode()); 633 634 switch (GetArchitecture().GetMachine()) { 635 case llvm::Triple::aarch64: { 636 // Assume order PT_GETREGS, PT_GETFPREGS 637 if (note.info.n_type == NETBSD::AARCH64::NT_REGS) { 638 // If this is the next thread, push the previous one first. 639 if (had_nt_regs) { 640 m_thread_data.push_back(thread_data); 641 thread_data = ThreadData(); 642 had_nt_regs = false; 643 } 644 645 thread_data.gpregset = note.data; 646 thread_data.tid = tid; 647 if (thread_data.gpregset.GetByteSize() == 0) 648 return llvm::make_error<llvm::StringError>( 649 "Could not find general purpose registers note in core file.", 650 llvm::inconvertibleErrorCode()); 651 had_nt_regs = true; 652 } else if (note.info.n_type == NETBSD::AARCH64::NT_FPREGS) { 653 if (!had_nt_regs || tid != thread_data.tid) 654 return llvm::make_error<llvm::StringError>( 655 "Error parsing NetBSD core(5) notes: Unexpected order " 656 "of NOTEs PT_GETFPREG before PT_GETREG", 657 llvm::inconvertibleErrorCode()); 658 thread_data.notes.push_back(note); 659 } 660 } break; 661 case llvm::Triple::x86: { 662 // Assume order PT_GETREGS, PT_GETFPREGS 663 if (note.info.n_type == NETBSD::I386::NT_REGS) { 664 // If this is the next thread, push the previous one first. 665 if (had_nt_regs) { 666 m_thread_data.push_back(thread_data); 667 thread_data = ThreadData(); 668 had_nt_regs = false; 669 } 670 671 thread_data.gpregset = note.data; 672 thread_data.tid = tid; 673 if (thread_data.gpregset.GetByteSize() == 0) 674 return llvm::make_error<llvm::StringError>( 675 "Could not find general purpose registers note in core file.", 676 llvm::inconvertibleErrorCode()); 677 had_nt_regs = true; 678 } else if (note.info.n_type == NETBSD::I386::NT_FPREGS) { 679 if (!had_nt_regs || tid != thread_data.tid) 680 return llvm::make_error<llvm::StringError>( 681 "Error parsing NetBSD core(5) notes: Unexpected order " 682 "of NOTEs PT_GETFPREG before PT_GETREG", 683 llvm::inconvertibleErrorCode()); 684 thread_data.notes.push_back(note); 685 } 686 } break; 687 case llvm::Triple::x86_64: { 688 // Assume order PT_GETREGS, PT_GETFPREGS 689 if (note.info.n_type == NETBSD::AMD64::NT_REGS) { 690 // If this is the next thread, push the previous one first. 691 if (had_nt_regs) { 692 m_thread_data.push_back(thread_data); 693 thread_data = ThreadData(); 694 had_nt_regs = false; 695 } 696 697 thread_data.gpregset = note.data; 698 thread_data.tid = tid; 699 if (thread_data.gpregset.GetByteSize() == 0) 700 return llvm::make_error<llvm::StringError>( 701 "Could not find general purpose registers note in core file.", 702 llvm::inconvertibleErrorCode()); 703 had_nt_regs = true; 704 } else if (note.info.n_type == NETBSD::AMD64::NT_FPREGS) { 705 if (!had_nt_regs || tid != thread_data.tid) 706 return llvm::make_error<llvm::StringError>( 707 "Error parsing NetBSD core(5) notes: Unexpected order " 708 "of NOTEs PT_GETFPREG before PT_GETREG", 709 llvm::inconvertibleErrorCode()); 710 thread_data.notes.push_back(note); 711 } 712 } break; 713 default: 714 break; 715 } 716 } 717 } 718 719 // Push the last thread. 720 if (had_nt_regs) 721 m_thread_data.push_back(thread_data); 722 723 if (m_thread_data.empty()) 724 return llvm::make_error<llvm::StringError>( 725 "Error parsing NetBSD core(5) notes: No threads information " 726 "specified in notes", 727 llvm::inconvertibleErrorCode()); 728 729 if (m_thread_data.size() != nlwps) 730 return llvm::make_error<llvm::StringError>( 731 "Error parsing NetBSD core(5) notes: Mismatch between the number " 732 "of LWPs in netbsd_elfcore_procinfo and the number of LWPs specified " 733 "by MD notes", 734 llvm::inconvertibleErrorCode()); 735 736 // Signal targeted at the whole process. 737 if (siglwp == 0) { 738 for (auto &data : m_thread_data) 739 data.signo = signo; 740 } 741 // Signal destined for a particular LWP. 742 else { 743 bool passed = false; 744 745 for (auto &data : m_thread_data) { 746 if (data.tid == siglwp) { 747 data.signo = signo; 748 passed = true; 749 break; 750 } 751 } 752 753 if (!passed) 754 return llvm::make_error<llvm::StringError>( 755 "Error parsing NetBSD core(5) notes: Signal passed to unknown LWP", 756 llvm::inconvertibleErrorCode()); 757 } 758 759 return llvm::Error::success(); 760 } 761 762 llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) { 763 ThreadData thread_data; 764 for (const auto ¬e : notes) { 765 // OpenBSD per-thread information is stored in notes named "OpenBSD@nnn" so 766 // match on the initial part of the string. 767 if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD")) 768 continue; 769 770 switch (note.info.n_type) { 771 case OPENBSD::NT_PROCINFO: 772 ParseOpenBSDProcInfo(thread_data, note.data); 773 break; 774 case OPENBSD::NT_AUXV: 775 m_auxv = note.data; 776 break; 777 case OPENBSD::NT_REGS: 778 thread_data.gpregset = note.data; 779 break; 780 default: 781 thread_data.notes.push_back(note); 782 break; 783 } 784 } 785 if (thread_data.gpregset.GetByteSize() == 0) { 786 return llvm::make_error<llvm::StringError>( 787 "Could not find general purpose registers note in core file.", 788 llvm::inconvertibleErrorCode()); 789 } 790 m_thread_data.push_back(thread_data); 791 return llvm::Error::success(); 792 } 793 794 /// A description of a linux process usually contains the following NOTE 795 /// entries: 796 /// - NT_PRPSINFO - General process information like pid, uid, name, ... 797 /// - NT_SIGINFO - Information about the signal that terminated the process 798 /// - NT_AUXV - Process auxiliary vector 799 /// - NT_FILE - Files mapped into memory 800 /// 801 /// Additionally, for each thread in the process the core file will contain at 802 /// least the NT_PRSTATUS note, containing the thread id and general purpose 803 /// registers. It may include additional notes for other register sets (floating 804 /// point and vector registers, ...). The tricky part here is that some of these 805 /// notes have "CORE" in their owner fields, while other set it to "LINUX". 806 llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { 807 const ArchSpec &arch = GetArchitecture(); 808 bool have_prstatus = false; 809 bool have_prpsinfo = false; 810 ThreadData thread_data; 811 for (const auto ¬e : notes) { 812 if (note.info.n_name != "CORE" && note.info.n_name != "LINUX") 813 continue; 814 815 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) || 816 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) { 817 assert(thread_data.gpregset.GetByteSize() > 0); 818 // Add the new thread to thread list 819 m_thread_data.push_back(thread_data); 820 thread_data = ThreadData(); 821 have_prstatus = false; 822 have_prpsinfo = false; 823 } 824 825 switch (note.info.n_type) { 826 case ELF::NT_PRSTATUS: { 827 have_prstatus = true; 828 ELFLinuxPrStatus prstatus; 829 Status status = prstatus.Parse(note.data, arch); 830 if (status.Fail()) 831 return status.ToError(); 832 thread_data.prstatus_sig = prstatus.pr_cursig; 833 thread_data.tid = prstatus.pr_pid; 834 uint32_t header_size = ELFLinuxPrStatus::GetSize(arch); 835 size_t len = note.data.GetByteSize() - header_size; 836 thread_data.gpregset = DataExtractor(note.data, header_size, len); 837 break; 838 } 839 case ELF::NT_PRPSINFO: { 840 have_prpsinfo = true; 841 ELFLinuxPrPsInfo prpsinfo; 842 Status status = prpsinfo.Parse(note.data, arch); 843 if (status.Fail()) 844 return status.ToError(); 845 thread_data.name.assign (prpsinfo.pr_fname, strnlen (prpsinfo.pr_fname, sizeof (prpsinfo.pr_fname))); 846 SetID(prpsinfo.pr_pid); 847 break; 848 } 849 case ELF::NT_SIGINFO: { 850 ELFLinuxSigInfo siginfo; 851 Status status = siginfo.Parse(note.data, arch); 852 if (status.Fail()) 853 return status.ToError(); 854 thread_data.signo = siginfo.si_signo; 855 break; 856 } 857 case ELF::NT_FILE: { 858 m_nt_file_entries.clear(); 859 lldb::offset_t offset = 0; 860 const uint64_t count = note.data.GetAddress(&offset); 861 note.data.GetAddress(&offset); // Skip page size 862 for (uint64_t i = 0; i < count; ++i) { 863 NT_FILE_Entry entry; 864 entry.start = note.data.GetAddress(&offset); 865 entry.end = note.data.GetAddress(&offset); 866 entry.file_ofs = note.data.GetAddress(&offset); 867 m_nt_file_entries.push_back(entry); 868 } 869 for (uint64_t i = 0; i < count; ++i) { 870 const char *path = note.data.GetCStr(&offset); 871 if (path && path[0]) 872 m_nt_file_entries[i].path.SetCString(path); 873 } 874 break; 875 } 876 case ELF::NT_AUXV: 877 m_auxv = note.data; 878 break; 879 default: 880 thread_data.notes.push_back(note); 881 break; 882 } 883 } 884 // Add last entry in the note section 885 if (have_prstatus) 886 m_thread_data.push_back(thread_data); 887 return llvm::Error::success(); 888 } 889 890 /// Parse Thread context from PT_NOTE segment and store it in the thread list 891 /// A note segment consists of one or more NOTE entries, but their types and 892 /// meaning differ depending on the OS. 893 llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( 894 const elf::ELFProgramHeader &segment_header, 895 const DataExtractor &segment_data) { 896 assert(segment_header.p_type == llvm::ELF::PT_NOTE); 897 898 auto notes_or_error = parseSegment(segment_data); 899 if(!notes_or_error) 900 return notes_or_error.takeError(); 901 switch (GetArchitecture().GetTriple().getOS()) { 902 case llvm::Triple::FreeBSD: 903 return parseFreeBSDNotes(*notes_or_error); 904 case llvm::Triple::Linux: 905 return parseLinuxNotes(*notes_or_error); 906 case llvm::Triple::NetBSD: 907 return parseNetBSDNotes(*notes_or_error); 908 case llvm::Triple::OpenBSD: 909 return parseOpenBSDNotes(*notes_or_error); 910 default: 911 return llvm::make_error<llvm::StringError>( 912 "Don't know how to parse core file. Unsupported OS.", 913 llvm::inconvertibleErrorCode()); 914 } 915 } 916 917 uint32_t ProcessElfCore::GetNumThreadContexts() { 918 if (!m_thread_data_valid) 919 DoLoadCore(); 920 return m_thread_data.size(); 921 } 922 923 ArchSpec ProcessElfCore::GetArchitecture() { 924 ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture(); 925 926 ArchSpec target_arch = GetTarget().GetArchitecture(); 927 arch.MergeFrom(target_arch); 928 929 // On MIPS there is no way to differentiate betwenn 32bit and 64bit core 930 // files and this information can't be merged in from the target arch so we 931 // fail back to unconditionally returning the target arch in this config. 932 if (target_arch.IsMIPS()) { 933 return target_arch; 934 } 935 936 return arch; 937 } 938 939 DataExtractor ProcessElfCore::GetAuxvData() { 940 const uint8_t *start = m_auxv.GetDataStart(); 941 size_t len = m_auxv.GetByteSize(); 942 lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(start, len)); 943 return DataExtractor(buffer, GetByteOrder(), GetAddressByteSize()); 944 } 945 946 bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) { 947 info.Clear(); 948 info.SetProcessID(GetID()); 949 info.SetArchitecture(GetArchitecture()); 950 lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); 951 if (module_sp) { 952 const bool add_exe_file_as_first_arg = false; 953 info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), 954 add_exe_file_as_first_arg); 955 } 956 return true; 957 } 958