| //===----------------------------------------------------------------------===// | |
| // | |
| // 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 "ThreadFreeBSDKernelCore.h" | |
| #include "lldb/Target/StopInfo.h" | |
| #include "lldb/Target/Unwind.h" | |
| #include "lldb/Utility/Log.h" | |
| #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" | |
| #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" | |
| #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" | |
| #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" | |
| #include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" | |
| #include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h" | |
| #include "ProcessFreeBSDKernelCore.h" | |
| #include "RegisterContextFreeBSDKernelCore_arm.h" | |
| #include "RegisterContextFreeBSDKernelCore_arm64.h" | |
| #include "RegisterContextFreeBSDKernelCore_i386.h" | |
| #include "RegisterContextFreeBSDKernelCore_ppc64le.h" | |
| #include "RegisterContextFreeBSDKernelCore_riscv64.h" | |
| #include "RegisterContextFreeBSDKernelCore_x86_64.h" | |
| using namespace lldb; | |
| using namespace lldb_private; | |
| ThreadFreeBSDKernelCore::ThreadFreeBSDKernelCore(Process &process, | |
| lldb::tid_t tid, | |
| lldb::addr_t pcb_addr, | |
| std::string thread_name) | |
| : Thread(process, tid), m_thread_name(std::move(thread_name)), | |
| m_pcb_addr(pcb_addr) {} | |
| ThreadFreeBSDKernelCore::~ThreadFreeBSDKernelCore() {} | |
| void ThreadFreeBSDKernelCore::RefreshStateAfterStop() {} | |
| lldb::RegisterContextSP ThreadFreeBSDKernelCore::GetRegisterContext() { | |
| if (!m_reg_context_sp) | |
| m_reg_context_sp = CreateRegisterContextForFrame(nullptr); | |
| return m_reg_context_sp; | |
| } | |
| lldb::RegisterContextSP | |
| ThreadFreeBSDKernelCore::CreateRegisterContextForFrame(StackFrame *frame) { | |
| RegisterContextSP reg_ctx_sp; | |
| uint32_t concrete_frame_idx = 0; | |
| if (frame) | |
| concrete_frame_idx = frame->GetConcreteFrameIndex(); | |
| if (concrete_frame_idx == 0) { | |
| if (m_thread_reg_ctx_sp) | |
| return m_thread_reg_ctx_sp; | |
| ProcessFreeBSDKernelCore *process = | |
| static_cast<ProcessFreeBSDKernelCore *>(GetProcess().get()); | |
| ArchSpec arch = process->GetTarget().GetArchitecture(); | |
| switch (arch.GetMachine()) { | |
| case llvm::Triple::aarch64: | |
| m_thread_reg_ctx_sp = | |
| std::make_shared<RegisterContextFreeBSDKernelCore_arm64>( | |
| *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch, 0), | |
| m_pcb_addr); | |
| break; | |
| case llvm::Triple::arm: | |
| m_thread_reg_ctx_sp = | |
| std::make_shared<RegisterContextFreeBSDKernelCore_arm>( | |
| *this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_pcb_addr); | |
| break; | |
| case llvm::Triple::ppc64le: | |
| m_thread_reg_ctx_sp = | |
| std::make_shared<RegisterContextFreeBSDKernelCore_ppc64le>( | |
| *this, new RegisterInfoPOSIX_ppc64le(arch), m_pcb_addr); | |
| break; | |
| case llvm::Triple::riscv64: | |
| m_thread_reg_ctx_sp = | |
| std::make_shared<RegisterContextFreeBSDKernelCore_riscv64>( | |
| *this, std::make_unique<RegisterInfoPOSIX_riscv64>(arch, 0), | |
| m_pcb_addr); | |
| break; | |
| case llvm::Triple::x86: | |
| m_thread_reg_ctx_sp = | |
| std::make_shared<RegisterContextFreeBSDKernelCore_i386>( | |
| *this, new RegisterContextFreeBSD_i386(arch), m_pcb_addr); | |
| break; | |
| case llvm::Triple::x86_64: | |
| m_thread_reg_ctx_sp = | |
| std::make_shared<RegisterContextFreeBSDKernelCore_x86_64>( | |
| *this, new RegisterContextFreeBSD_x86_64(arch), m_pcb_addr); | |
| break; | |
| default: | |
| assert(false && | |
| "Unsupported architecture passed to ThreadFreeBSDKernelCore"); | |
| break; | |
| } | |
| reg_ctx_sp = m_thread_reg_ctx_sp; | |
| } else { | |
| reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); | |
| } | |
| return reg_ctx_sp; | |
| } | |
| bool ThreadFreeBSDKernelCore::CalculateStopInfo() { | |
| if (m_is_crashed) { | |
| // Set a stop reason for crashing threads only so that they get selected | |
| // preferentially. | |
| SetStopInfo(StopInfo::CreateStopReasonWithException(*this, "kernel panic")); | |
| return true; | |
| } | |
| return false; | |
| } |