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