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