aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/elf-core/ThreadElfCore.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
commit14f1b3e8826ce43b978db93a62d1166055db5394 (patch)
tree0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Plugins/Process/elf-core/ThreadElfCore.cpp
parent4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff)
Notes
Diffstat (limited to 'source/Plugins/Process/elf-core/ThreadElfCore.cpp')
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp496
1 files changed, 299 insertions, 197 deletions
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index e4cfa68044f1..86b15c0d2fbe 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -14,24 +14,24 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
-#include "ThreadElfCore.h"
-#include "ProcessElfCore.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
-#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "ProcessElfCore.h"
#include "RegisterContextPOSIXCore_arm.h"
#include "RegisterContextPOSIXCore_arm64.h"
#include "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
#include "RegisterContextPOSIXCore_s390x.h"
#include "RegisterContextPOSIXCore_x86_64.h"
+#include "ThreadElfCore.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,223 +39,325 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Construct a Thread object with given data
//----------------------------------------------------------------------
-ThreadElfCore::ThreadElfCore (Process &process, const ThreadData &td) :
- Thread(process, td.tid),
- m_thread_name(td.name),
- m_thread_reg_ctx_sp (),
- m_signo(td.signo),
- m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset),
- m_vregset_data(td.vregset)
-{
-}
+ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
+ : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
+ m_signo(td.signo), m_gpregset_data(td.gpregset),
+ m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
-ThreadElfCore::~ThreadElfCore ()
-{
- DestroyThread();
+ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
+
+void ThreadElfCore::RefreshStateAfterStop() {
+ GetRegisterContext()->InvalidateIfNeeded(false);
}
-void
-ThreadElfCore::RefreshStateAfterStop()
-{
- GetRegisterContext()->InvalidateIfNeeded (false);
+void ThreadElfCore::ClearStackFrames() {
+ Unwind *unwinder = GetUnwinder();
+ if (unwinder)
+ unwinder->Clear();
+ Thread::ClearStackFrames();
}
-void
-ThreadElfCore::ClearStackFrames ()
-{
- Unwind *unwinder = GetUnwinder ();
- if (unwinder)
- unwinder->Clear();
- Thread::ClearStackFrames();
+RegisterContextSP ThreadElfCore::GetRegisterContext() {
+ if (m_reg_context_sp.get() == NULL) {
+ m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+ }
+ return m_reg_context_sp;
}
RegisterContextSP
-ThreadElfCore::GetRegisterContext ()
-{
- if (m_reg_context_sp.get() == NULL) {
- m_reg_context_sp = CreateRegisterContextForFrame (NULL);
+ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
+ RegisterContextSP reg_ctx_sp;
+ uint32_t concrete_frame_idx = 0;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ if (frame)
+ concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+ if (concrete_frame_idx == 0) {
+ if (m_thread_reg_ctx_sp)
+ return m_thread_reg_ctx_sp;
+
+ ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
+ ArchSpec arch = process->GetArchitecture();
+ RegisterInfoInterface *reg_interface = NULL;
+
+ switch (arch.GetTriple().getOS()) {
+ case llvm::Triple::FreeBSD: {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(arch);
+ break;
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextFreeBSD_arm(arch);
+ break;
+ case llvm::Triple::ppc:
+ reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
+ break;
+ case llvm::Triple::ppc64:
+ reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
+ break;
+ case llvm::Triple::mips64:
+ reg_interface = new RegisterContextFreeBSD_mips64(arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextFreeBSD_i386(arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextFreeBSD_x86_64(arch);
+ break;
+ default:
+ break;
+ }
+ break;
}
- return m_reg_context_sp;
-}
-RegisterContextSP
-ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
-{
- RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
- Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
- if (concrete_frame_idx == 0)
- {
- if (m_thread_reg_ctx_sp)
- return m_thread_reg_ctx_sp;
-
- ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
- ArchSpec arch = process->GetArchitecture();
- RegisterInfoInterface *reg_interface = NULL;
-
- switch (arch.GetTriple().getOS())
- {
- case llvm::Triple::FreeBSD:
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextFreeBSD_arm64(arch);
- break;
- case llvm::Triple::arm:
- reg_interface = new RegisterContextFreeBSD_arm(arch);
- break;
- case llvm::Triple::ppc:
- reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
- break;
- case llvm::Triple::ppc64:
- reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
- break;
- case llvm::Triple::mips64:
- reg_interface = new RegisterContextFreeBSD_mips64(arch);
- break;
- case llvm::Triple::x86:
- reg_interface = new RegisterContextFreeBSD_i386(arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextFreeBSD_x86_64(arch);
- break;
- default:
- break;
- }
- break;
- }
-
- case llvm::Triple::Linux:
- {
- switch (arch.GetMachine())
- {
- case llvm::Triple::arm:
- reg_interface = new RegisterContextLinux_arm(arch);
- break;
- case llvm::Triple::aarch64:
- reg_interface = new RegisterContextLinux_arm64(arch);
- break;
- case llvm::Triple::systemz:
- reg_interface = new RegisterContextLinux_s390x(arch);
- break;
- case llvm::Triple::x86_64:
- reg_interface = new RegisterContextLinux_x86_64(arch);
- break;
- default:
- break;
- }
- break;
- }
-
- default:
- break;
- }
-
- if (!reg_interface) {
- if (log)
- log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
- __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
- assert (false && "Architecture or OS not supported");
- }
-
- switch (arch.GetMachine())
- {
- case llvm::Triple::aarch64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::arm:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::mips64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
- break;
- case llvm::Triple::systemz:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
- break;
- default:
- break;
- }
-
- reg_ctx_sp = m_thread_reg_ctx_sp;
+ case llvm::Triple::Linux: {
+ switch (arch.GetMachine()) {
+ case llvm::Triple::arm:
+ reg_interface = new RegisterContextLinux_arm(arch);
+ break;
+ case llvm::Triple::aarch64:
+ reg_interface = new RegisterInfoPOSIX_arm64(arch);
+ break;
+ case llvm::Triple::systemz:
+ reg_interface = new RegisterContextLinux_s390x(arch);
+ break;
+ case llvm::Triple::x86:
+ reg_interface = new RegisterContextLinux_i386(arch);
+ break;
+ case llvm::Triple::x86_64:
+ reg_interface = new RegisterContextLinux_x86_64(arch);
+ break;
+ default:
+ break;
+ }
+ break;
}
- else if (m_unwinder_ap.get())
- {
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+
+ default:
+ break;
}
- return reg_ctx_sp;
-}
-bool
-ThreadElfCore::CalculateStopInfo ()
-{
- ProcessSP process_sp (GetProcess());
- if (process_sp)
- {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
- return true;
+ if (!reg_interface) {
+ if (log)
+ log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
+ __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
+ assert(false && "Architecture or OS not supported");
}
- return false;
+
+ switch (arch.GetMachine()) {
+ case llvm::Triple::aarch64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::arm:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::mips64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data,
+ m_vregset_data));
+ break;
+ case llvm::Triple::systemz:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
+ *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ break;
+ default:
+ break;
+ }
+
+ reg_ctx_sp = m_thread_reg_ctx_sp;
+ } else if (m_unwinder_ap.get()) {
+ reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
+ }
+ return reg_ctx_sp;
+}
+
+bool ThreadElfCore::CalculateStopInfo() {
+ ProcessSP process_sp(GetProcess());
+ if (process_sp) {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
+ return true;
+ }
+ return false;
}
//----------------------------------------------------------------
// Parse PRSTATUS from NOTE entry
//----------------------------------------------------------------
-ELFLinuxPrStatus::ELFLinuxPrStatus()
-{
- memset(this, 0, sizeof(ELFLinuxPrStatus));
+ELFLinuxPrStatus::ELFLinuxPrStatus() {
+ memset(this, 0, sizeof(ELFLinuxPrStatus));
}
-bool
-ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
-{
- ByteOrder byteorder = data.GetByteOrder();
- size_t len;
- switch(arch.GetCore())
- {
- case ArchSpec::eCore_s390x_generic:
- case ArchSpec::eCore_x86_64_x86_64:
- len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
- return len == ELFLINUXPRSTATUS64_SIZE;
- default:
- return false;
- }
+Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ pr_cursig = data.GetU16(&offset);
+ offset += 2; // pad
+
+ pr_sigpend = data.GetU32(&offset);
+ pr_sighold = data.GetU32(&offset);
+
+ pr_pid = data.GetU32(&offset);
+ pr_ppid = data.GetU32(&offset);
+ pr_pgrp = data.GetU32(&offset);
+ pr_sid = data.GetU32(&offset);
+
+ pr_utime.tv_sec = data.GetU32(&offset);
+ pr_utime.tv_usec = data.GetU32(&offset);
+
+ pr_stime.tv_sec = data.GetU32(&offset);
+ pr_stime.tv_usec = data.GetU32(&offset);
+
+ pr_cutime.tv_sec = data.GetU32(&offset);
+ pr_cutime.tv_usec = data.GetU32(&offset);
+
+ pr_cstime.tv_sec = data.GetU32(&offset);
+ pr_cstime.tv_usec = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
}
//----------------------------------------------------------------
// Parse PRPSINFO from NOTE entry
//----------------------------------------------------------------
-ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
-{
- memset(this, 0, sizeof(ELFLinuxPrPsInfo));
+ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
+ memset(this, 0, sizeof(ELFLinuxPrPsInfo));
}
-bool
-ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
-{
- ByteOrder byteorder = data.GetByteOrder();
- size_t len;
- switch(arch.GetCore())
- {
- case ArchSpec::eCore_s390x_generic:
- case ArchSpec::eCore_x86_64_x86_64:
- len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
- return len == ELFLINUXPRPSINFO64_SIZE;
- default:
- return false;
- }
+Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this);
+ break;
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ size_t size = 0;
+ offset_t offset = 0;
+
+ pr_state = data.GetU8(&offset);
+ pr_sname = data.GetU8(&offset);
+ pr_zomb = data.GetU8(&offset);
+ pr_nice = data.GetU8(&offset);
+
+ pr_flag = data.GetU32(&offset);
+ pr_uid = data.GetU16(&offset);
+ pr_gid = data.GetU16(&offset);
+
+ pr_pid = data.GetU32(&offset);
+ pr_ppid = data.GetU32(&offset);
+ pr_pgrp = data.GetU32(&offset);
+ pr_sid = data.GetU32(&offset);
+
+ size = 16;
+ data.ExtractBytes(offset, size, byteorder, pr_fname);
+ offset += size;
+
+ size = 80;
+ data.ExtractBytes(offset, size, byteorder, pr_psargs);
+ offset += size;
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
}
+//----------------------------------------------------------------
+// Parse SIGINFO from NOTE entry
+//----------------------------------------------------------------
+ELFLinuxSigInfo::ELFLinuxSigInfo() {
+ memset(this, 0, sizeof(ELFLinuxSigInfo));
+}
+
+Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
+ Error error;
+ ByteOrder byteorder = data.GetByteOrder();
+ if (GetSize(arch) > data.GetByteSize()) {
+ error.SetErrorStringWithFormat(
+ "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
+ GetSize(arch), data.GetByteSize());
+ return error;
+ }
+
+ switch (arch.GetCore()) {
+ case ArchSpec::eCore_x86_64_x86_64:
+ data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
+ break;
+ case ArchSpec::eCore_s390x_generic:
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486: {
+ // Parsing from a 32 bit ELF core file, and populating/reusing the structure
+ // properly, because the struct is for the 64 bit version
+ offset_t offset = 0;
+ si_signo = data.GetU32(&offset);
+ si_code = data.GetU32(&offset);
+ si_errno = data.GetU32(&offset);
+
+ break;
+ }
+ default:
+ error.SetErrorStringWithFormat("ELFLinuxSigInfo::%s Unknown architecture",
+ __FUNCTION__);
+ break;
+ }
+
+ return error;
+}