10eae32dcSDimitry Andric //===-- ThreadFreeBSDKernel.cpp -------------------------------------------===//
20eae32dcSDimitry Andric //
30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60eae32dcSDimitry Andric //
70eae32dcSDimitry Andric //===----------------------------------------------------------------------===//
80eae32dcSDimitry Andric
90eae32dcSDimitry Andric #include "ThreadFreeBSDKernel.h"
100eae32dcSDimitry Andric
110eae32dcSDimitry Andric #include "lldb/Target/Unwind.h"
120eae32dcSDimitry Andric #include "lldb/Utility/Log.h"
130eae32dcSDimitry Andric
140eae32dcSDimitry Andric #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
150eae32dcSDimitry Andric #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
160eae32dcSDimitry Andric #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
170eae32dcSDimitry Andric #include "ProcessFreeBSDKernel.h"
180eae32dcSDimitry Andric #include "RegisterContextFreeBSDKernel_arm64.h"
190eae32dcSDimitry Andric #include "RegisterContextFreeBSDKernel_i386.h"
200eae32dcSDimitry Andric #include "RegisterContextFreeBSDKernel_x86_64.h"
210eae32dcSDimitry Andric #include "ThreadFreeBSDKernel.h"
220eae32dcSDimitry Andric
230eae32dcSDimitry Andric using namespace lldb;
240eae32dcSDimitry Andric using namespace lldb_private;
250eae32dcSDimitry Andric
ThreadFreeBSDKernel(Process & process,lldb::tid_t tid,lldb::addr_t pcb_addr,std::string thread_name)260eae32dcSDimitry Andric ThreadFreeBSDKernel::ThreadFreeBSDKernel(Process &process, lldb::tid_t tid,
27*04eeddc0SDimitry Andric lldb::addr_t pcb_addr,
28*04eeddc0SDimitry Andric std::string thread_name)
29*04eeddc0SDimitry Andric : Thread(process, tid), m_thread_name(std::move(thread_name)),
30*04eeddc0SDimitry Andric m_pcb_addr(pcb_addr) {}
310eae32dcSDimitry Andric
~ThreadFreeBSDKernel()320eae32dcSDimitry Andric ThreadFreeBSDKernel::~ThreadFreeBSDKernel() {}
330eae32dcSDimitry Andric
RefreshStateAfterStop()340eae32dcSDimitry Andric void ThreadFreeBSDKernel::RefreshStateAfterStop() {}
350eae32dcSDimitry Andric
GetRegisterContext()360eae32dcSDimitry Andric lldb::RegisterContextSP ThreadFreeBSDKernel::GetRegisterContext() {
370eae32dcSDimitry Andric if (!m_reg_context_sp)
380eae32dcSDimitry Andric m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
390eae32dcSDimitry Andric return m_reg_context_sp;
400eae32dcSDimitry Andric }
410eae32dcSDimitry Andric
420eae32dcSDimitry Andric lldb::RegisterContextSP
CreateRegisterContextForFrame(StackFrame * frame)430eae32dcSDimitry Andric ThreadFreeBSDKernel::CreateRegisterContextForFrame(StackFrame *frame) {
440eae32dcSDimitry Andric RegisterContextSP reg_ctx_sp;
450eae32dcSDimitry Andric uint32_t concrete_frame_idx = 0;
460eae32dcSDimitry Andric
470eae32dcSDimitry Andric if (frame)
480eae32dcSDimitry Andric concrete_frame_idx = frame->GetConcreteFrameIndex();
490eae32dcSDimitry Andric
500eae32dcSDimitry Andric if (concrete_frame_idx == 0) {
510eae32dcSDimitry Andric if (m_thread_reg_ctx_sp)
520eae32dcSDimitry Andric return m_thread_reg_ctx_sp;
530eae32dcSDimitry Andric
540eae32dcSDimitry Andric ProcessFreeBSDKernel *process =
550eae32dcSDimitry Andric static_cast<ProcessFreeBSDKernel *>(GetProcess().get());
560eae32dcSDimitry Andric ArchSpec arch = process->GetTarget().GetArchitecture();
570eae32dcSDimitry Andric
580eae32dcSDimitry Andric switch (arch.GetMachine()) {
590eae32dcSDimitry Andric case llvm::Triple::aarch64:
600eae32dcSDimitry Andric m_thread_reg_ctx_sp =
610eae32dcSDimitry Andric std::make_shared<RegisterContextFreeBSDKernel_arm64>(
620eae32dcSDimitry Andric *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch, 0),
630eae32dcSDimitry Andric m_pcb_addr);
640eae32dcSDimitry Andric break;
650eae32dcSDimitry Andric case llvm::Triple::x86:
66*04eeddc0SDimitry Andric m_thread_reg_ctx_sp = std::make_shared<RegisterContextFreeBSDKernel_i386>(
670eae32dcSDimitry Andric *this, new RegisterContextFreeBSD_i386(arch), m_pcb_addr);
680eae32dcSDimitry Andric break;
690eae32dcSDimitry Andric case llvm::Triple::x86_64:
700eae32dcSDimitry Andric m_thread_reg_ctx_sp =
710eae32dcSDimitry Andric std::make_shared<RegisterContextFreeBSDKernel_x86_64>(
720eae32dcSDimitry Andric *this, new RegisterContextFreeBSD_x86_64(arch), m_pcb_addr);
730eae32dcSDimitry Andric break;
740eae32dcSDimitry Andric default:
750eae32dcSDimitry Andric assert(false && "Unsupported architecture passed to ThreadFreeBSDKernel");
760eae32dcSDimitry Andric break;
770eae32dcSDimitry Andric }
780eae32dcSDimitry Andric
790eae32dcSDimitry Andric reg_ctx_sp = m_thread_reg_ctx_sp;
800eae32dcSDimitry Andric } else {
810eae32dcSDimitry Andric reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
820eae32dcSDimitry Andric }
830eae32dcSDimitry Andric return reg_ctx_sp;
840eae32dcSDimitry Andric }
850eae32dcSDimitry Andric
CalculateStopInfo()860eae32dcSDimitry Andric bool ThreadFreeBSDKernel::CalculateStopInfo() { return false; }
87