28 #include "llvm/BinaryFormat/ELF.h"
29 #include "llvm/Support/Threading.h"
38 namespace ELF = llvm::ELF;
43 return "ELF core dump plug-in.";
51 lldb::ListenerSP listener_sp,
54 lldb::ProcessSP process_sp;
55 if (crash_file && !can_connect) {
59 const size_t header_size =
sizeof(llvm::ELF::Elf64_Ehdr);
62 crash_file->
GetPath(), header_size, 0);
63 if (data_sp && data_sp->GetByteSize() == header_size &&
68 if (elf_header.
Parse(data, &data_offset)) {
73 if (elf_header.
e_type == llvm::ELF::ET_CORE)
74 process_sp = std::make_shared<ProcessElfCore>(target_sp, listener_sp,
83 bool plugin_specified_by_name) {
86 ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
88 nullptr,
nullptr,
nullptr));
89 if (m_core_module_sp) {
90 ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
100 lldb::ListenerSP listener_sp,
126 last_entry->
data.GetRangeEnd() == range_entry.
data.GetRangeBase() &&
129 last_entry->
data.SetRangeEnd(range_entry.
data.GetRangeEnd());
137 ((header.
p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
138 ((header.
p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
139 ((header.
p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
163 error.SetErrorString(
"invalid core module");
168 if (core ==
nullptr) {
169 error.SetErrorString(
"invalid core object file");
173 llvm::ArrayRef<elf::ELFProgramHeader> segments = core->
ProgramHeaders();
174 if (segments.size() == 0) {
175 error.SetErrorString(
"core file has no segments");
183 bool ranges_are_sorted =
true;
195 if (H.p_type == llvm::ELF::PT_NOTE) {
200 if (H.p_type == llvm::ELF::PT_LOAD) {
202 if (vm_addr > last_addr)
203 ranges_are_sorted =
false;
205 }
else if (H.p_type == llvm::ELF::PT_AARCH64_MEMTAG_MTE) {
207 if (tag_addr > last_addr)
208 ranges_are_sorted =
false;
209 tag_addr = last_addr;
213 if (!ranges_are_sorted) {
231 bool siginfo_signal_found =
false;
232 bool prstatus_signal_found =
false;
235 if (thread_data.signo != 0)
236 siginfo_signal_found =
true;
237 if (thread_data.prstatus_sig != 0)
238 prstatus_signal_found =
true;
240 if (!siginfo_signal_found) {
243 if (prstatus_signal_found) {
245 thread_data.signo = thread_data.prstatus_sig;
256 if (!exe_module_sp) {
276 m_dyld_up.reset(DynamicLoader::FindPlugin(
287 for (
lldb::tid_t tid = 0; tid < num_threads; ++tid) {
292 return new_thread_list.
GetSize(
false) > 0;
306 if (lldb::ABISP abi_sp =
GetABI())
307 addr = abi_sp->FixAnyAddress(addr);
319 if (permission_entry) {
320 if (permission_entry->
Contains(load_addr)) {
323 const Flags permissions(permission_entry->
data);
325 ? MemoryRegionInfo::eYes
326 : MemoryRegionInfo::eNo);
328 ? MemoryRegionInfo::eYes
329 : MemoryRegionInfo::eNo);
331 ? MemoryRegionInfo::eYes
332 : MemoryRegionInfo::eNo);
333 region_info.
SetMapped(MemoryRegionInfo::eYes);
343 }
else if (load_addr < permission_entry->GetRangeBase()) {
349 region_info.
SetMapped(MemoryRegionInfo::eNo);
360 region_info.
SetMapped(MemoryRegionInfo::eNo);
369 if (core_objfile ==
nullptr)
375 if (address_range ==
nullptr || address_range->
GetRangeEnd() < addr) {
376 error.SetErrorStringWithFormat(
"core file does not contain 0x%" PRIx64,
385 size_t bytes_to_read = size;
386 size_t bytes_copied = 0;
392 if (file_start == file_end)
397 if (file_end > file_start + offset)
398 bytes_left = file_end - (file_start + offset);
400 if (bytes_to_read > bytes_left)
401 bytes_to_read = bytes_left;
406 core_objfile->
CopyData(offset + file_start, bytes_to_read, buf);
411 llvm::Expected<std::vector<lldb::addr_t>>
414 if (core_objfile ==
nullptr)
415 return llvm::createStringError(llvm::inconvertibleErrorCode(),
416 "No core object file.");
418 llvm::Expected<const MemoryTagManager *> tag_manager_or_err =
420 if (!tag_manager_or_err)
421 return tag_manager_or_err.takeError();
431 if (!tag_entry || (addr + len) >= tag_entry->
GetRangeEnd())
432 return llvm::createStringError(llvm::inconvertibleErrorCode(),
433 "No tag segment that covers this range.");
438 return core_objfile->
CopyData(offset, length, dst);
450 static llvm::once_flag g_once_flag;
452 llvm::call_once(g_once_flag, []() {
472 int pr_version = data.
GetU32(&offset);
477 LLDB_LOGF(log,
"FreeBSD PRSTATUS unexpected version %d", pr_version);
500 int pr_version = data.
GetU32(&offset);
505 LLDB_LOGF(log,
"FreeBSD PRPSINFO unexpected version %d", pr_version);
525 return llvm::make_error<llvm::StringError>(
526 "Error parsing NetBSD core(5) notes: Unsupported procinfo version",
527 llvm::inconvertibleErrorCode());
531 return llvm::make_error<llvm::StringError>(
532 "Error parsing NetBSD core(5) notes: Unsupported procinfo size",
533 llvm::inconvertibleErrorCode());
535 cpi_signo = data.
GetU32(&offset);
542 cpi_pid = data.
GetU32(&offset);
552 cpi_nlwps = data.
GetU32(&offset);
555 cpi_siglwp = data.
GetU32(&offset);
557 return llvm::Error::success();
564 int version = data.
GetU32(&offset);
572 llvm::Expected<std::vector<CoreNote>>
575 std::vector<CoreNote> result;
579 if (!note.
Parse(segment, &offset))
580 return llvm::make_error<llvm::StringError>(
581 "Unable to parse note segment", llvm::inconvertibleErrorCode());
583 size_t note_start = offset;
584 size_t note_size = llvm::alignTo(note.
n_descsz, 4);
586 result.push_back({note,
DataExtractor(segment, note_start, note_size)});
590 return std::move(result);
595 bool lp64 = (arch.
GetMachine() == llvm::Triple::aarch64 ||
599 bool have_prstatus =
false;
600 bool have_prpsinfo =
false;
602 for (
const auto ¬e : notes) {
603 if (note.info.n_name !=
"FreeBSD")
606 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
607 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
612 have_prstatus =
false;
613 have_prpsinfo =
false;
616 switch (note.info.n_type) {
617 case ELF::NT_PRSTATUS:
618 have_prstatus =
true;
621 case ELF::NT_PRPSINFO:
622 have_prpsinfo =
true;
625 case ELF::NT_FREEBSD_THRMISC: {
627 thread_data.
name = note.data.GetCStr(&offset, 20);
630 case ELF::NT_FREEBSD_PROCSTAT_AUXV:
635 thread_data.
notes.push_back(note);
639 if (!have_prstatus) {
640 return llvm::make_error<llvm::StringError>(
641 "Could not find NT_PRSTATUS note in core file.",
642 llvm::inconvertibleErrorCode());
645 return llvm::Error::success();
672 bool had_nt_regs =
false;
681 for (
const auto ¬e : notes) {
682 llvm::StringRef name = note.info.n_name;
684 if (name ==
"NetBSD-CORE") {
694 }
else if (name.consume_front(
"NetBSD-CORE@")) {
696 if (name.getAsInteger(10, tid))
697 return llvm::make_error<llvm::StringError>(
698 "Error parsing NetBSD core(5) notes: Cannot convert LWP ID "
700 llvm::inconvertibleErrorCode());
703 case llvm::Triple::aarch64: {
714 thread_data.
tid = tid;
716 return llvm::make_error<llvm::StringError>(
717 "Could not find general purpose registers note in core file.",
718 llvm::inconvertibleErrorCode());
721 if (!had_nt_regs || tid != thread_data.
tid)
722 return llvm::make_error<llvm::StringError>(
723 "Error parsing NetBSD core(5) notes: Unexpected order "
724 "of NOTEs PT_GETFPREG before PT_GETREG",
725 llvm::inconvertibleErrorCode());
726 thread_data.
notes.push_back(note);
729 case llvm::Triple::x86: {
740 thread_data.
tid = tid;
742 return llvm::make_error<llvm::StringError>(
743 "Could not find general purpose registers note in core file.",
744 llvm::inconvertibleErrorCode());
747 if (!had_nt_regs || tid != thread_data.
tid)
748 return llvm::make_error<llvm::StringError>(
749 "Error parsing NetBSD core(5) notes: Unexpected order "
750 "of NOTEs PT_GETFPREG before PT_GETREG",
751 llvm::inconvertibleErrorCode());
752 thread_data.
notes.push_back(note);
755 case llvm::Triple::x86_64: {
766 thread_data.
tid = tid;
768 return llvm::make_error<llvm::StringError>(
769 "Could not find general purpose registers note in core file.",
770 llvm::inconvertibleErrorCode());
773 if (!had_nt_regs || tid != thread_data.
tid)
774 return llvm::make_error<llvm::StringError>(
775 "Error parsing NetBSD core(5) notes: Unexpected order "
776 "of NOTEs PT_GETFPREG before PT_GETREG",
777 llvm::inconvertibleErrorCode());
778 thread_data.
notes.push_back(note);
792 return llvm::make_error<llvm::StringError>(
793 "Error parsing NetBSD core(5) notes: No threads information "
794 "specified in notes",
795 llvm::inconvertibleErrorCode());
798 return llvm::make_error<llvm::StringError>(
799 "Error parsing NetBSD core(5) notes: Mismatch between the number "
800 "of LWPs in netbsd_elfcore_procinfo and the number of LWPs specified "
802 llvm::inconvertibleErrorCode());
814 if (data.tid == siglwp) {
822 return llvm::make_error<llvm::StringError>(
823 "Error parsing NetBSD core(5) notes: Signal passed to unknown LWP",
824 llvm::inconvertibleErrorCode());
827 return llvm::Error::success();
832 for (
const auto ¬e : notes) {
835 if (!llvm::StringRef(note.info.n_name).startswith(
"OpenBSD"))
838 switch (note.info.n_type) {
849 thread_data.
notes.push_back(note);
854 return llvm::make_error<llvm::StringError>(
855 "Could not find general purpose registers note in core file.",
856 llvm::inconvertibleErrorCode());
859 return llvm::Error::success();
876 bool have_prstatus =
false;
877 bool have_prpsinfo =
false;
879 for (
const auto ¬e : notes) {
880 if (note.info.n_name !=
"CORE" && note.info.n_name !=
"LINUX")
883 if ((note.info.n_type == ELF::NT_PRSTATUS && have_prstatus) ||
884 (note.info.n_type == ELF::NT_PRPSINFO && have_prpsinfo)) {
889 have_prstatus =
false;
890 have_prpsinfo =
false;
893 switch (note.info.n_type) {
894 case ELF::NT_PRSTATUS: {
895 have_prstatus =
true;
903 size_t len = note.data.GetByteSize() - header_size;
907 case ELF::NT_PRPSINFO: {
908 have_prpsinfo =
true;
917 case ELF::NT_SIGINFO: {
928 const uint64_t count = note.data.GetAddress(&offset);
929 note.data.GetAddress(&offset);
930 for (uint64_t i = 0; i < count; ++i) {
932 entry.
start = note.data.GetAddress(&offset);
933 entry.
end = note.data.GetAddress(&offset);
934 entry.
file_ofs = note.data.GetAddress(&offset);
937 for (uint64_t i = 0; i < count; ++i) {
938 const char *path = note.data.GetCStr(&offset);
948 thread_data.
notes.push_back(note);
955 return llvm::Error::success();
964 assert(segment_header.
p_type == llvm::ELF::PT_NOTE);
968 return notes_or_error.takeError();
970 case llvm::Triple::FreeBSD:
972 case llvm::Triple::Linux:
974 case llvm::Triple::NetBSD:
976 case llvm::Triple::OpenBSD:
979 return llvm::make_error<llvm::StringError>(
980 "Don't know how to parse core file. Unsupported OS.",
981 llvm::inconvertibleErrorCode());
1000 if (target_arch.
IsMIPS()) {
1020 const bool add_exe_file_as_first_arg =
false;
1022 add_exe_file_as_first_arg);