summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lldb/source/Plugins/Process/POSIX
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:33:06 +0000
commit061da546b983eb767bad15e67af1174fb0bcf31c (patch)
tree83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/source/Plugins/Process/POSIX
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz
wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/source/Plugins/Process/POSIX')
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt12
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp330
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.h59
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp178
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h53
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp61
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.h168
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp31
-rw-r--r--gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h39
9 files changed, 931 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt
new file mode 100644
index 00000000000..fd74f816d1a
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_lldb_library(lldbPluginProcessPOSIX PLUGIN
+ CrashReason.cpp
+ NativeProcessELF.cpp
+ ProcessMessage.cpp
+ ProcessPOSIXLog.cpp
+
+ LINK_LIBS
+ lldbPluginProcessUtility
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
new file mode 100644
index 00000000000..b872269fdfe
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.cpp
@@ -0,0 +1,330 @@
+//===-- CrashReason.cpp -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CrashReason.h"
+
+#include "llvm/Support/raw_ostream.h"
+
+#include <sstream>
+
+namespace {
+
+void AppendFaultAddr(std::string &str, lldb::addr_t addr) {
+ std::stringstream ss;
+ ss << " (fault address: 0x" << std::hex << addr << ")";
+ str += ss.str();
+}
+
+#if defined(si_lower) && defined(si_upper)
+void AppendBounds(std::string &str, lldb::addr_t lower_bound,
+ lldb::addr_t upper_bound, lldb::addr_t addr) {
+ llvm::raw_string_ostream stream(str);
+ if ((unsigned long)addr < lower_bound)
+ stream << ": lower bound violation ";
+ else
+ stream << ": upper bound violation ";
+ stream << "(fault address: 0x";
+ stream.write_hex(addr);
+ stream << ", lower bound: 0x";
+ stream.write_hex(lower_bound);
+ stream << ", upper bound: 0x";
+ stream.write_hex(upper_bound);
+ stream << ")";
+ stream.flush();
+}
+#endif
+
+CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) {
+ assert(info.si_signo == SIGSEGV);
+
+ switch (info.si_code) {
+#ifdef SI_KERNEL
+ case SI_KERNEL:
+ // Some platforms will occasionally send nonstandard spurious SI_KERNEL
+ // codes. One way to get this is via unaligned SIMD loads.
+ return CrashReason::eInvalidAddress; // for lack of anything better
+#endif
+ case SEGV_MAPERR:
+ return CrashReason::eInvalidAddress;
+ case SEGV_ACCERR:
+ return CrashReason::ePrivilegedAddress;
+#ifndef SEGV_BNDERR
+#define SEGV_BNDERR 3
+#endif
+ case SEGV_BNDERR:
+ return CrashReason::eBoundViolation;
+ }
+
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) {
+ assert(info.si_signo == SIGILL);
+
+ switch (info.si_code) {
+ case ILL_ILLOPC:
+ return CrashReason::eIllegalOpcode;
+ case ILL_ILLOPN:
+ return CrashReason::eIllegalOperand;
+ case ILL_ILLADR:
+ return CrashReason::eIllegalAddressingMode;
+ case ILL_ILLTRP:
+ return CrashReason::eIllegalTrap;
+ case ILL_PRVOPC:
+ return CrashReason::ePrivilegedOpcode;
+ case ILL_PRVREG:
+ return CrashReason::ePrivilegedRegister;
+ case ILL_COPROC:
+ return CrashReason::eCoprocessorError;
+ case ILL_BADSTK:
+ return CrashReason::eInternalStackError;
+ }
+
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) {
+ assert(info.si_signo == SIGFPE);
+
+ switch (info.si_code) {
+ case FPE_INTDIV:
+ return CrashReason::eIntegerDivideByZero;
+ case FPE_INTOVF:
+ return CrashReason::eIntegerOverflow;
+ case FPE_FLTDIV:
+ return CrashReason::eFloatDivideByZero;
+ case FPE_FLTOVF:
+ return CrashReason::eFloatOverflow;
+ case FPE_FLTUND:
+ return CrashReason::eFloatUnderflow;
+ case FPE_FLTRES:
+ return CrashReason::eFloatInexactResult;
+ case FPE_FLTINV:
+ return CrashReason::eFloatInvalidOperation;
+ case FPE_FLTSUB:
+ return CrashReason::eFloatSubscriptRange;
+ }
+
+ return CrashReason::eInvalidCrashReason;
+}
+
+CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) {
+ assert(info.si_signo == SIGBUS);
+
+ switch (info.si_code) {
+ case BUS_ADRALN:
+ return CrashReason::eIllegalAlignment;
+ case BUS_ADRERR:
+ return CrashReason::eIllegalAddress;
+ case BUS_OBJERR:
+ return CrashReason::eHardwareError;
+ }
+
+ return CrashReason::eInvalidCrashReason;
+}
+}
+
+std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) {
+ std::string str;
+
+// make sure that siginfo_t has the bound fields available.
+#if defined(si_lower) && defined(si_upper)
+ if (reason == CrashReason::eBoundViolation) {
+ str = "signal SIGSEGV";
+ AppendBounds(str, reinterpret_cast<uintptr_t>(info.si_lower),
+ reinterpret_cast<uintptr_t>(info.si_upper),
+ reinterpret_cast<uintptr_t>(info.si_addr));
+ return str;
+ }
+#endif
+
+ return GetCrashReasonString(reason,
+ reinterpret_cast<uintptr_t>(info.si_addr));
+}
+
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) {
+ std::string str;
+
+ switch (reason) {
+ default:
+ str = "unknown crash reason";
+ break;
+
+ case CrashReason::eInvalidAddress:
+ str = "signal SIGSEGV: invalid address";
+ AppendFaultAddr(str, fault_addr);
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "signal SIGSEGV: address access protected";
+ AppendFaultAddr(str, fault_addr);
+ break;
+ case CrashReason::eBoundViolation:
+ str = "signal SIGSEGV: bound violation";
+ break;
+ case CrashReason::eIllegalOpcode:
+ str = "signal SIGILL: illegal instruction";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "signal SIGILL: illegal instruction operand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "signal SIGILL: illegal addressing mode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "signal SIGILL: illegal trap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "signal SIGILL: privileged instruction";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "signal SIGILL: privileged register";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "signal SIGILL: coprocessor error";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "signal SIGILL: internal stack error";
+ break;
+ case CrashReason::eIllegalAlignment:
+ str = "signal SIGBUS: illegal alignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "signal SIGBUS: illegal address";
+ break;
+ case CrashReason::eHardwareError:
+ str = "signal SIGBUS: hardware error";
+ break;
+ case CrashReason::eIntegerDivideByZero:
+ str = "signal SIGFPE: integer divide by zero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "signal SIGFPE: integer overflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "signal SIGFPE: floating point divide by zero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "signal SIGFPE: floating point overflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "signal SIGFPE: floating point underflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "signal SIGFPE: inexact floating point result";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "signal SIGFPE: invalid floating point operation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "signal SIGFPE: invalid floating point subscript range";
+ break;
+ }
+
+ return str;
+}
+
+const char *CrashReasonAsString(CrashReason reason) {
+ const char *str = nullptr;
+
+ switch (reason) {
+ case CrashReason::eInvalidCrashReason:
+ str = "eInvalidCrashReason";
+ break;
+
+ // SIGSEGV crash reasons.
+ case CrashReason::eInvalidAddress:
+ str = "eInvalidAddress";
+ break;
+ case CrashReason::ePrivilegedAddress:
+ str = "ePrivilegedAddress";
+ break;
+ case CrashReason::eBoundViolation:
+ str = "eBoundViolation";
+ break;
+
+ // SIGILL crash reasons.
+ case CrashReason::eIllegalOpcode:
+ str = "eIllegalOpcode";
+ break;
+ case CrashReason::eIllegalOperand:
+ str = "eIllegalOperand";
+ break;
+ case CrashReason::eIllegalAddressingMode:
+ str = "eIllegalAddressingMode";
+ break;
+ case CrashReason::eIllegalTrap:
+ str = "eIllegalTrap";
+ break;
+ case CrashReason::ePrivilegedOpcode:
+ str = "ePrivilegedOpcode";
+ break;
+ case CrashReason::ePrivilegedRegister:
+ str = "ePrivilegedRegister";
+ break;
+ case CrashReason::eCoprocessorError:
+ str = "eCoprocessorError";
+ break;
+ case CrashReason::eInternalStackError:
+ str = "eInternalStackError";
+ break;
+
+ // SIGBUS crash reasons:
+ case CrashReason::eIllegalAlignment:
+ str = "eIllegalAlignment";
+ break;
+ case CrashReason::eIllegalAddress:
+ str = "eIllegalAddress";
+ break;
+ case CrashReason::eHardwareError:
+ str = "eHardwareError";
+ break;
+
+ // SIGFPE crash reasons:
+ case CrashReason::eIntegerDivideByZero:
+ str = "eIntegerDivideByZero";
+ break;
+ case CrashReason::eIntegerOverflow:
+ str = "eIntegerOverflow";
+ break;
+ case CrashReason::eFloatDivideByZero:
+ str = "eFloatDivideByZero";
+ break;
+ case CrashReason::eFloatOverflow:
+ str = "eFloatOverflow";
+ break;
+ case CrashReason::eFloatUnderflow:
+ str = "eFloatUnderflow";
+ break;
+ case CrashReason::eFloatInexactResult:
+ str = "eFloatInexactResult";
+ break;
+ case CrashReason::eFloatInvalidOperation:
+ str = "eFloatInvalidOperation";
+ break;
+ case CrashReason::eFloatSubscriptRange:
+ str = "eFloatSubscriptRange";
+ break;
+ }
+ return str;
+}
+
+CrashReason GetCrashReason(const siginfo_t &info) {
+ switch (info.si_signo) {
+ case SIGSEGV:
+ return GetCrashReasonForSIGSEGV(info);
+ case SIGBUS:
+ return GetCrashReasonForSIGBUS(info);
+ case SIGFPE:
+ return GetCrashReasonForSIGFPE(info);
+ case SIGILL:
+ return GetCrashReasonForSIGILL(info);
+ }
+
+ assert(false && "unexpected signal");
+ return CrashReason::eInvalidCrashReason;
+}
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.h b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.h
new file mode 100644
index 00000000000..9b4784a1e68
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/CrashReason.h
@@ -0,0 +1,59 @@
+//===-- CrashReason.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CrashReason_H_
+#define liblldb_CrashReason_H_
+
+#include "lldb/lldb-types.h"
+
+#include <signal.h>
+
+#include <string>
+
+enum class CrashReason {
+ eInvalidCrashReason,
+
+ // SIGSEGV crash reasons.
+ eInvalidAddress,
+ ePrivilegedAddress,
+ eBoundViolation,
+
+ // SIGILL crash reasons.
+ eIllegalOpcode,
+ eIllegalOperand,
+ eIllegalAddressingMode,
+ eIllegalTrap,
+ ePrivilegedOpcode,
+ ePrivilegedRegister,
+ eCoprocessorError,
+ eInternalStackError,
+
+ // SIGBUS crash reasons,
+ eIllegalAlignment,
+ eIllegalAddress,
+ eHardwareError,
+
+ // SIGFPE crash reasons,
+ eIntegerDivideByZero,
+ eIntegerOverflow,
+ eFloatDivideByZero,
+ eFloatOverflow,
+ eFloatUnderflow,
+ eFloatInexactResult,
+ eFloatInvalidOperation,
+ eFloatSubscriptRange
+};
+
+std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr);
+std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info);
+
+const char *CrashReasonAsString(CrashReason reason);
+
+CrashReason GetCrashReason(const siginfo_t &info);
+
+#endif // #ifndef liblldb_CrashReason_H_
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp
new file mode 100644
index 00000000000..058dc5ae233
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.cpp
@@ -0,0 +1,178 @@
+//===-- NativeProcessELF.cpp ---------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeProcessELF.h"
+
+#include "lldb/Utility/DataExtractor.h"
+
+namespace lldb_private {
+
+llvm::Optional<uint64_t>
+NativeProcessELF::GetAuxValue(enum AuxVector::EntryType type) {
+ if (m_aux_vector == nullptr) {
+ auto buffer_or_error = GetAuxvData();
+ if (!buffer_or_error)
+ return llvm::None;
+ DataExtractor auxv_data(buffer_or_error.get()->getBufferStart(),
+ buffer_or_error.get()->getBufferSize(),
+ GetByteOrder(), GetAddressByteSize());
+ m_aux_vector = std::make_unique<AuxVector>(auxv_data);
+ }
+
+ return m_aux_vector->GetAuxValue(type);
+}
+
+lldb::addr_t NativeProcessELF::GetSharedLibraryInfoAddress() {
+ if (!m_shared_library_info_addr.hasValue()) {
+ if (GetAddressByteSize() == 8)
+ m_shared_library_info_addr =
+ GetELFImageInfoAddress<llvm::ELF::Elf64_Ehdr, llvm::ELF::Elf64_Phdr,
+ llvm::ELF::Elf64_Dyn>();
+ else
+ m_shared_library_info_addr =
+ GetELFImageInfoAddress<llvm::ELF::Elf32_Ehdr, llvm::ELF::Elf32_Phdr,
+ llvm::ELF::Elf32_Dyn>();
+ }
+
+ return m_shared_library_info_addr.getValue();
+}
+
+template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
+lldb::addr_t NativeProcessELF::GetELFImageInfoAddress() {
+ llvm::Optional<uint64_t> maybe_phdr_addr =
+ GetAuxValue(AuxVector::AUXV_AT_PHDR);
+ llvm::Optional<uint64_t> maybe_phdr_entry_size =
+ GetAuxValue(AuxVector::AUXV_AT_PHENT);
+ llvm::Optional<uint64_t> maybe_phdr_num_entries =
+ GetAuxValue(AuxVector::AUXV_AT_PHNUM);
+ if (!maybe_phdr_addr || !maybe_phdr_entry_size || !maybe_phdr_num_entries)
+ return LLDB_INVALID_ADDRESS;
+ lldb::addr_t phdr_addr = *maybe_phdr_addr;
+ size_t phdr_entry_size = *maybe_phdr_entry_size;
+ size_t phdr_num_entries = *maybe_phdr_num_entries;
+
+ // Find the PT_DYNAMIC segment (.dynamic section) in the program header and
+ // what the load bias by calculating the difference of the program header
+ // load address and its virtual address.
+ lldb::offset_t load_bias;
+ bool found_load_bias = false;
+ lldb::addr_t dynamic_section_addr = 0;
+ uint64_t dynamic_section_size = 0;
+ bool found_dynamic_section = false;
+ ELF_PHDR phdr_entry;
+ for (size_t i = 0; i < phdr_num_entries; i++) {
+ size_t bytes_read;
+ auto error = ReadMemory(phdr_addr + i * phdr_entry_size, &phdr_entry,
+ sizeof(phdr_entry), bytes_read);
+ if (!error.Success())
+ return LLDB_INVALID_ADDRESS;
+ if (phdr_entry.p_type == llvm::ELF::PT_PHDR) {
+ load_bias = phdr_addr - phdr_entry.p_vaddr;
+ found_load_bias = true;
+ }
+
+ if (phdr_entry.p_type == llvm::ELF::PT_DYNAMIC) {
+ dynamic_section_addr = phdr_entry.p_vaddr;
+ dynamic_section_size = phdr_entry.p_memsz;
+ found_dynamic_section = true;
+ }
+ }
+
+ if (!found_load_bias || !found_dynamic_section)
+ return LLDB_INVALID_ADDRESS;
+
+ // Find the DT_DEBUG entry in the .dynamic section
+ dynamic_section_addr += load_bias;
+ ELF_DYN dynamic_entry;
+ size_t dynamic_num_entries = dynamic_section_size / sizeof(dynamic_entry);
+ for (size_t i = 0; i < dynamic_num_entries; i++) {
+ size_t bytes_read;
+ auto error = ReadMemory(dynamic_section_addr + i * sizeof(dynamic_entry),
+ &dynamic_entry, sizeof(dynamic_entry), bytes_read);
+ if (!error.Success())
+ return LLDB_INVALID_ADDRESS;
+ // Return the &DT_DEBUG->d_ptr which points to r_debug which contains the
+ // link_map.
+ if (dynamic_entry.d_tag == llvm::ELF::DT_DEBUG) {
+ return dynamic_section_addr + i * sizeof(dynamic_entry) +
+ sizeof(dynamic_entry.d_tag);
+ }
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+template <typename T>
+llvm::Expected<SVR4LibraryInfo>
+NativeProcessELF::ReadSVR4LibraryInfo(lldb::addr_t link_map_addr) {
+ ELFLinkMap<T> link_map;
+ size_t bytes_read;
+ auto error =
+ ReadMemory(link_map_addr, &link_map, sizeof(link_map), bytes_read);
+ if (!error.Success())
+ return error.ToError();
+
+ char name_buffer[PATH_MAX];
+ llvm::Expected<llvm::StringRef> string_or_error = ReadCStringFromMemory(
+ link_map.l_name, &name_buffer[0], sizeof(name_buffer), bytes_read);
+ if (!string_or_error)
+ return string_or_error.takeError();
+
+ SVR4LibraryInfo info;
+ info.name = string_or_error->str();
+ info.link_map = link_map_addr;
+ info.base_addr = link_map.l_addr;
+ info.ld_addr = link_map.l_ld;
+ info.next = link_map.l_next;
+
+ return info;
+}
+
+llvm::Expected<std::vector<SVR4LibraryInfo>>
+NativeProcessELF::GetLoadedSVR4Libraries() {
+ // Address of DT_DEBUG.d_ptr which points to r_debug
+ lldb::addr_t info_address = GetSharedLibraryInfoAddress();
+ if (info_address == LLDB_INVALID_ADDRESS)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid shared library info address");
+ // Address of r_debug
+ lldb::addr_t address = 0;
+ size_t bytes_read;
+ auto status =
+ ReadMemory(info_address, &address, GetAddressByteSize(), bytes_read);
+ if (!status.Success())
+ return status.ToError();
+ if (address == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid r_debug address");
+ // Read r_debug.r_map
+ lldb::addr_t link_map = 0;
+ status = ReadMemory(address + GetAddressByteSize(), &link_map,
+ GetAddressByteSize(), bytes_read);
+ if (!status.Success())
+ return status.ToError();
+ if (address == 0)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Invalid link_map address");
+
+ std::vector<SVR4LibraryInfo> library_list;
+ while (link_map) {
+ llvm::Expected<SVR4LibraryInfo> info =
+ GetAddressByteSize() == 8 ? ReadSVR4LibraryInfo<uint64_t>(link_map)
+ : ReadSVR4LibraryInfo<uint32_t>(link_map);
+ if (!info)
+ return info.takeError();
+ if (!info->name.empty() && info->base_addr != 0)
+ library_list.push_back(*info);
+ link_map = info->next;
+ }
+
+ return library_list;
+}
+
+} // namespace lldb_private
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
new file mode 100644
index 00000000000..4fb513baebf
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/NativeProcessELF.h
@@ -0,0 +1,53 @@
+//===-- NativeProcessELF.h ------------------------------------ -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_NativeProcessELF_H_
+#define liblldb_NativeProcessELF_H_
+
+#include "Plugins/Process/Utility/AuxVector.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "llvm/BinaryFormat/ELF.h"
+
+namespace lldb_private {
+
+/// \class NativeProcessELF
+/// Abstract class that extends \a NativeProcessProtocol with ELF specific
+/// logic. Meant to be subclassed by ELF based NativeProcess* implementations.
+class NativeProcessELF : public NativeProcessProtocol {
+ using NativeProcessProtocol::NativeProcessProtocol;
+
+protected:
+ template <typename T> struct ELFLinkMap {
+ T l_addr;
+ T l_name;
+ T l_ld;
+ T l_next;
+ T l_prev;
+ };
+
+ llvm::Optional<uint64_t> GetAuxValue(enum AuxVector::EntryType type);
+
+ lldb::addr_t GetSharedLibraryInfoAddress() override;
+
+ template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
+ lldb::addr_t GetELFImageInfoAddress();
+
+ llvm::Expected<std::vector<SVR4LibraryInfo>>
+ GetLoadedSVR4Libraries() override;
+
+ template <typename T>
+ llvm::Expected<SVR4LibraryInfo>
+ ReadSVR4LibraryInfo(lldb::addr_t link_map_addr);
+
+ std::unique_ptr<AuxVector> m_aux_vector;
+ llvm::Optional<lldb::addr_t> m_shared_library_info_addr;
+};
+
+} // namespace lldb_private
+
+#endif \ No newline at end of file
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
new file mode 100644
index 00000000000..66286dd3d9e
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -0,0 +1,61 @@
+//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ProcessMessage.h"
+
+using namespace lldb_private;
+
+const char *ProcessMessage::PrintCrashReason() const {
+ return CrashReasonAsString(m_crash_reason);
+}
+
+const char *ProcessMessage::PrintKind(Kind kind) {
+ const char *str = nullptr;
+
+ switch (kind) {
+ case eInvalidMessage:
+ str = "eInvalidMessage";
+ break;
+ case eAttachMessage:
+ str = "eAttachMessage";
+ break;
+ case eExitMessage:
+ str = "eExitMessage";
+ break;
+ case eLimboMessage:
+ str = "eLimboMessage";
+ break;
+ case eSignalMessage:
+ str = "eSignalMessage";
+ break;
+ case eSignalDeliveredMessage:
+ str = "eSignalDeliveredMessage";
+ break;
+ case eTraceMessage:
+ str = "eTraceMessage";
+ break;
+ case eBreakpointMessage:
+ str = "eBreakpointMessage";
+ break;
+ case eWatchpointMessage:
+ str = "eWatchpointMessage";
+ break;
+ case eCrashMessage:
+ str = "eCrashMessage";
+ break;
+ case eNewThreadMessage:
+ str = "eNewThreadMessage";
+ break;
+ case eExecMessage:
+ str = "eExecMessage";
+ break;
+ }
+ return str;
+}
+
+const char *ProcessMessage::PrintKind() const { return PrintKind(m_kind); }
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.h b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.h
new file mode 100644
index 00000000000..d9c10caaa95
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -0,0 +1,168 @@
+//===-- ProcessMessage.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessMessage_H_
+#define liblldb_ProcessMessage_H_
+
+#include "CrashReason.h"
+
+#include <cassert>
+#include <string>
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+class ProcessMessage {
+public:
+ /// The type of signal this message can correspond to.
+ enum Kind {
+ eInvalidMessage,
+ eAttachMessage,
+ eExitMessage,
+ eLimboMessage,
+ eSignalMessage,
+ eSignalDeliveredMessage,
+ eTraceMessage,
+ eBreakpointMessage,
+ eWatchpointMessage,
+ eCrashMessage,
+ eNewThreadMessage,
+ eExecMessage
+ };
+
+ ProcessMessage()
+ : m_tid(LLDB_INVALID_PROCESS_ID), m_kind(eInvalidMessage),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0),
+ m_addr(0) {}
+
+ Kind GetKind() const { return m_kind; }
+
+ lldb::tid_t GetTID() const { return m_tid; }
+
+ /// Indicates that the process \p pid has successfully attached.
+ static ProcessMessage Attach(lldb::pid_t pid) {
+ return ProcessMessage(pid, eAttachMessage);
+ }
+
+ /// Indicates that the thread \p tid is about to exit with status \p status.
+ static ProcessMessage Limbo(lldb::tid_t tid, int status) {
+ return ProcessMessage(tid, eLimboMessage, status);
+ }
+
+ /// Indicates that the thread \p tid had the signal \p signum delivered.
+ static ProcessMessage Signal(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalMessage, signum);
+ }
+
+ /// Indicates that a signal \p signum generated by the debugging process was
+ /// delivered to the thread \p tid.
+ static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
+ return ProcessMessage(tid, eSignalDeliveredMessage, signum);
+ }
+
+ /// Indicates that the thread \p tid encountered a trace point.
+ static ProcessMessage Trace(lldb::tid_t tid) {
+ return ProcessMessage(tid, eTraceMessage);
+ }
+
+ /// Indicates that the thread \p tid encountered a break point.
+ static ProcessMessage Break(lldb::tid_t tid) {
+ return ProcessMessage(tid, eBreakpointMessage);
+ }
+
+ static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
+ return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
+ }
+
+ /// Indicates that the thread \p tid crashed.
+ static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, int signo,
+ lldb::addr_t fault_addr) {
+ ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
+ message.m_crash_reason = reason;
+ return message;
+ }
+
+ /// Indicates that the thread \p child_tid was spawned.
+ static ProcessMessage NewThread(lldb::tid_t parent_tid,
+ lldb::tid_t child_tid) {
+ return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
+ }
+
+ /// Indicates that the thread \p tid is about to exit with status \p status.
+ static ProcessMessage Exit(lldb::tid_t tid, int status) {
+ return ProcessMessage(tid, eExitMessage, status);
+ }
+
+ /// Indicates that the thread \p pid has exec'd.
+ static ProcessMessage Exec(lldb::tid_t tid) {
+ return ProcessMessage(tid, eExecMessage);
+ }
+
+ int GetExitStatus() const {
+ assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
+ return m_status;
+ }
+
+ int GetSignal() const {
+ assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
+ GetKind() == eSignalDeliveredMessage);
+ return m_status;
+ }
+
+ int GetStopStatus() const {
+ assert(GetKind() == eSignalMessage);
+ return m_status;
+ }
+
+ CrashReason GetCrashReason() const {
+ assert(GetKind() == eCrashMessage);
+ return m_crash_reason;
+ }
+
+ lldb::addr_t GetFaultAddress() const {
+ assert(GetKind() == eCrashMessage);
+ return m_addr;
+ }
+
+ lldb::addr_t GetHWAddress() const {
+ assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
+ return m_addr;
+ }
+
+ lldb::tid_t GetChildTID() const {
+ assert(GetKind() == eNewThreadMessage);
+ return m_child_tid;
+ }
+
+ const char *PrintCrashReason() const;
+
+ const char *PrintKind() const;
+
+ static const char *PrintKind(Kind);
+
+private:
+ ProcessMessage(lldb::tid_t tid, Kind kind, int status = 0,
+ lldb::addr_t addr = 0)
+ : m_tid(tid), m_kind(kind),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(status),
+ m_addr(addr), m_child_tid(0) {}
+
+ ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
+ : m_tid(tid), m_kind(kind),
+ m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0),
+ m_addr(0), m_child_tid(child_tid) {}
+
+ lldb::tid_t m_tid;
+ Kind m_kind : 8;
+ CrashReason m_crash_reason;
+ int m_status;
+ lldb::addr_t m_addr;
+ lldb::tid_t m_child_tid;
+};
+
+#endif // #ifndef liblldb_ProcessMessage_H_
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
new file mode 100644
index 00000000000..a17558bfe7c
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
@@ -0,0 +1,31 @@
+//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ProcessPOSIXLog.h"
+
+#include "llvm/Support/Threading.h"
+
+using namespace lldb_private;
+
+static constexpr Log::Category g_categories[] = {
+ {{"break"}, {"log breakpoints"}, POSIX_LOG_BREAKPOINTS},
+ {{"memory"}, {"log memory reads and writes"}, POSIX_LOG_MEMORY},
+ {{"process"}, {"log process events and activities"}, POSIX_LOG_PROCESS},
+ {{"ptrace"}, {"log all calls to ptrace"}, POSIX_LOG_PTRACE},
+ {{"registers"}, {"log register read/writes"}, POSIX_LOG_REGISTERS},
+ {{"thread"}, {"log thread events and activities"}, POSIX_LOG_THREAD},
+ {{"watch"}, {"log watchpoint related activities"}, POSIX_LOG_WATCHPOINTS},
+};
+
+Log::Channel ProcessPOSIXLog::g_channel(g_categories, POSIX_LOG_DEFAULT);
+
+void ProcessPOSIXLog::Initialize() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() { Log::Register("posix", g_channel); });
+}
diff --git a/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
new file mode 100644
index 00000000000..c0147c43410
--- /dev/null
+++ b/gnu/llvm/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -0,0 +1,39 @@
+//===-- ProcessPOSIXLog.h -----------------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessPOSIXLog_h_
+#define liblldb_ProcessPOSIXLog_h_
+
+
+#include "lldb/Utility/Log.h"
+
+#define POSIX_LOG_PROCESS (1u << 1)
+#define POSIX_LOG_THREAD (1u << 2)
+#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define POSIX_LOG_PTRACE (1u << 5)
+#define POSIX_LOG_REGISTERS (1u << 6)
+#define POSIX_LOG_BREAKPOINTS (1u << 7)
+#define POSIX_LOG_WATCHPOINTS (1u << 8)
+#define POSIX_LOG_ALL (UINT32_MAX)
+#define POSIX_LOG_DEFAULT POSIX_LOG_PROCESS
+
+namespace lldb_private {
+class ProcessPOSIXLog {
+ static Log::Channel g_channel;
+
+public:
+ static void Initialize();
+
+ static Log *GetLogIfAllCategoriesSet(uint32_t mask) {
+ return g_channel.GetLogIfAll(mask);
+ }
+};
+}
+
+#endif // liblldb_ProcessPOSIXLog_h_