From: ASOU Masato Subject: Re: lldb: Kernel corefile support To: Yuichiro NAITO Cc: tech@openbsd.org, Masato ASOU Date: Thu, 11 Jul 2024 12:28:53 +0200 I tested this patch on following machines. - AMD box (64 bits) - Intel (64 bits) + ESXi virtual environment - AMD (64 bits) + ESXi virtual environment And it is fine for me. ok asou@. The patch contain support arm64. However, I have no arm64 architecture. Can I commit this patch or anybody test on arm64 architecture? -- ASOU Masato 2024年6月5日(水) 5:45 Yuichiro NAITO : > > Hi, I ported the lldb OpenBSD kernel core file plugin from FreeBSD. > It works on amd64 architecture. I also ported i386 and arm64 architectures > for my technical challenge to learn them. I know lldb is not compiled on i386 > and the 'dumpsys' kernel function doesn't work on arm64. > > My plugin reads the 'pcb' structure to get a stack frame of a crashed thread > and all 'proc' threads. To read the 'pcb' structure, it needs to include > . I'm not sure how to get the offsets of the stack pointer and > the frame pointer of 'pcb' in another way. > > An example backtrace and thread list that is stopped by 'sysctl ddb.trigger=1' > with a bsd.gdb kernel. > > Is my patch OK? > > # lldb bsd.1 -c bsd.1.core > (lldb) target create "bsd.1" --core "bsd.1.core" > Core file '/var/crash/bsd.1.core' (x86_64) was loaded. > (lldb) bt > * thread #1, name = 'Crashed Thread' > * frame #0: 0xffffffff8114dcfc bsd.1`db_fncall(addr=, have_addr=, count=, modif=) at db_command.c:808:11 > frame #1: 0xffffffff8114dcfc bsd.1`db_fncall(addr=, have_addr=, count=, modif=) at db_command.c:808:11 > frame #2: 0xffffffff8114d96e bsd.1`db_command(last_cmdp=0xffffffff825a7fc0, cmd_table=) at db_command.c:292:3 > frame #3: 0xffffffff8114eb0a bsd.1`db_command_loop at db_command.c:738:3 > frame #4: 0xffffffff81fe6219 bsd.1`db_trap(type=, code=) at db_trap.c:92:3 > frame #5: 0xffffffff815c9a51 bsd.1`db_ktrap(type=1, code=0, regs=0xffff80001ca8a010) at db_interface.c:150:2 > frame #6: 0xffffffff81a303f7 bsd.1`kerntrap(frame=0x0000000000000000) at trap.c:323:7 > frame #7: 0xffffffff821001ce bsd.1`alltraps_kern + 126 > frame #8: 0xffffffff815ca5b4 bsd.1`db_enter [inlined] breakpoint at cpufunc.h:414:2 > frame #9: 0xffffffff815ca5b3 bsd.1`db_enter at db_interface.c:436:2 > frame #10: 0xffffffff81af3b7a bsd.1`ddb_sysctl(name=, namelen=, oldp=, oldlenp=, newp=, newlen=, p=0xffff80001ca52a68) at db_usrreq.c:81:5 > frame #11: 0xffffffff81db2a5b bsd.1`sys_sysctl(p=0x0000000000000001, v=0x00007be0397e0d30, retval=) at kern_sysctl.c:254:10 > frame #12: 0xffffffff81a30de1 bsd.1`syscall [inlined] mi_syscall(p=0xffff80001ca8a210, code=-2120020511, callp=, argp=0xffff80001ca8a2a0, retval=) at syscall_mi.h:180:10 > frame #13: 0xffffffff81a30dbc bsd.1`syscall(frame=0xffff80001ca8a2a0) at trap.c:577:10 > frame #14: 0xffffffff820ff134 bsd.1`Xsyscall_meltdown + 308 > frame #15: 0xffffffff820ff055 bsd.1`Xsyscall_meltdown + 85 > frame #16: 0xffff80001ca8a2a0 > frame #17: 0x00000ab61a54eedb > (lldb) thread list > Process 0 stopped > * thread #1: tid = 0x0000, 0xffffffff8114dcfc bsd.1`db_fncall(addr=, have_addr=, count=, modif=) at db_command.c:808:11, name = 'Crashed Thread' > thread #2: tid = 0x4d1b1, name = '(pid:27380) sysctl (cpu 0)' > thread #3: tid = 0x33db6, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:4343) ksh' > thread #4: tid = 0x2baf4, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:61728) cron' > thread #5: tid = 0x3dde2, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:74120) avahi-daemon' > thread #6: tid = 0x1f57f, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:62798) dbus-daemon' > thread #7: tid = 0x329c, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:68716) sndiod' > thread #8: tid = 0x7772, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:6352) sndiod' > thread #9: tid = 0x16b9a, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:16751) smtpd' > thread #10: tid = 0x23a11, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:47666) smtpd' > thread #11: tid = 0x470ba, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:35809) smtpd' > thread #12: tid = 0x517e5, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:23758) smtpd' > thread #13: tid = 0x49bbc, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:50263) smtpd' > thread #14: tid = 0x64ea2, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:64209) smtpd' > thread #15: tid = 0x73ee5, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:9349) smtpd' > thread #16: tid = 0x7fba2, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:77759) sshd' > thread #17: tid = 0x19050, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:3913) ntpd' > thread #18: tid = 0x41e7b, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:76783) ntpd' > thread #19: tid = 0x1133, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:6608) ntpd' > thread #20: tid = 0x30ec7, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:48134) pflogd' > thread #21: tid = 0x4b79c, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:12813) pflogd' > thread #22: tid = 0x611bf, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:74795) syslogd' > thread #23: tid = 0x7a02d, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:12529) syslogd' > thread #24: tid = 0x26d34, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:3765) resolvd' > thread #25: tid = 0x5bfb, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:57496) dhcpleased' > thread #26: tid = 0x7d804, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:49745) dhcpleased' > thread #27: tid = 0x728f4, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:49185) dhcpleased' > thread #28: tid = 0x7122c, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:68535) slaacd' > thread #29: tid = 0x5fa71, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:7648) slaacd' > thread #30: tid = 0x4cf5a, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:49587) slaacd' > thread #31: tid = 0x7eeea, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:6793) smr' > thread #32: tid = 0x5f4c9, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:73371) zerothread' > thread #33: tid = 0x5e195, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:59627) aiodoned' > thread #34: tid = 0x38817, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:47650) update' > thread #35: tid = 0x773fb, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:83391) cleaner' > thread #36: tid = 0x13986, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:4549) reaper' > thread #37: tid = 0x2aa52, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:59949) pagedaemon' > thread #38: tid = 0x6c4a2, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:62370) acpi0' > thread #39: tid = 0x1d72e, 0xffffffff8196b002 bsd.1`sched_idle(v=) at kern_sched.c:183:27, name = '(pid:42019) idle3 (cpu 3)' > thread #40: tid = 0x41e3, 0xffffffff8196b002 bsd.1`sched_idle(v=) at kern_sched.c:183:27, name = '(pid:57382) idle2 (cpu 2)' > thread #41: tid = 0x2ff0d, 0xffffffff8196b002 bsd.1`sched_idle(v=) at kern_sched.c:183:27, name = '(pid:56434) idle1 (cpu 1)' > thread #42: tid = 0x2d73b, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:8366) softnet3' > thread #43: tid = 0x47810, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:63010) softnet2' > thread #44: tid = 0xc228, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:80989) softnet1' > thread #45: tid = 0x017b, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:44883) softnet0' > thread #46: tid = 0x555b9, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:80021) systqmp' > thread #47: tid = 0x3a5ce, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:32001) systq' > thread #48: tid = 0x75b43, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:89538) softclockmp' > thread #49: tid = 0x27cbd, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:56248) softclock' > thread #50: tid = 0x55f80, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:73828) idle0' > thread #51: tid = 0x6f358, 0xffffffff81f32cb8 bsd.1`mi_switch at sched_bsd.c:419:3, name = '(pid:1) init' > * thread #1: tid = 0x0000, 0xffffffff8114dcfc bsd.1`db_fncall(addr=, have_addr=, count=, modif=) at db_command.c:808:11, name = 'Crashed Thread' > > > diff --git a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp > index 7aa5620b14d..cec6c50a007 100644 > --- a/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp > +++ b/gnu/llvm/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp > @@ -25,6 +25,7 @@ > #include "lldb/Utility/State.h" > #include "lldb/Utility/Status.h" > #include "lldb/Utility/StreamString.h" > +#include "Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.h" > > // Define these constants from OpenBSD mman.h for use when targeting remote > // openbsd systems even when host has different values. > @@ -91,6 +92,7 @@ void PlatformOpenBSD::Initialize() { > PlatformOpenBSD::GetPluginNameStatic(false), > PlatformOpenBSD::GetPluginDescriptionStatic(false), > PlatformOpenBSD::CreateInstance, nullptr); > + ProcessOpenBSDKernel::Initialize(); > } > } > > @@ -98,6 +100,7 @@ void PlatformOpenBSD::Terminate() { > if (g_initialize_count > 0) { > if (--g_initialize_count == 0) { > PluginManager::UnregisterPlugin(PlatformOpenBSD::CreateInstance); > + ProcessOpenBSDKernel::Terminate(); > } > } > > diff --git a/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt > index ec35a428a88..2c5f2cf59cb 100644 > --- a/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt > +++ b/gnu/llvm/lldb/source/Plugins/Process/CMakeLists.txt > @@ -22,3 +22,4 @@ add_subdirectory(elf-core) > add_subdirectory(mach-core) > add_subdirectory(minidump) > add_subdirectory(FreeBSDKernel) > +add_subdirectory(OpenBSDKernel) > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/CMakeLists.txt b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/CMakeLists.txt > new file mode 100644 > index 00000000000..40976662fb3 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/CMakeLists.txt > @@ -0,0 +1,14 @@ > +add_lldb_library(lldbPluginProcessOpenBSDKernel PLUGIN > + ProcessOpenBSDKernel.cpp > + RegisterContextOpenBSDKernel_arm64.cpp > + RegisterContextOpenBSDKernel_i386.cpp > + RegisterContextOpenBSDKernel_x86_64.cpp > + ThreadOpenBSDKernel.cpp > + > + LINK_LIBS > + lldbCore > + lldbTarget > + kvm > + LINK_COMPONENTS > + Support > + ) > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.cpp > new file mode 100644 > index 00000000000..300a35d4051 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.cpp > @@ -0,0 +1,223 @@ > +//===-- ProcessOpenBSDKernel.cpp ------------------------------------------===// > +// > +// 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 "lldb/Core/Module.h" > +#include "lldb/Core/PluginManager.h" > +#include "lldb/Target/DynamicLoader.h" > + > +#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h" > +#include "ProcessOpenBSDKernel.h" > +#include "ThreadOpenBSDKernel.h" > + > +#if defined(__OpenBSD__) > +#include > +#define _KERNEL > +#include > +#include > +#undef _KERNEL > +#endif > + > +using namespace lldb; > +using namespace lldb_private; > + > +LLDB_PLUGIN_DEFINE(ProcessOpenBSDKernel) > + > +namespace { > + > +#if defined(__OpenBSD__) > +class ProcessOpenBSDKernelKVM : public ProcessOpenBSDKernel { > +public: > + ProcessOpenBSDKernelKVM(lldb::TargetSP target_sp, lldb::ListenerSP listener, > + kvm_t *fvc); > + > + ~ProcessOpenBSDKernelKVM(); > + > + size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, > + lldb_private::Status &error) override; > + > +private: > + kvm_t *m_kvm; > + > + const char *GetError(); > +}; > +#endif // defined(__OpenBSD__) > + > +} // namespace > + > +ProcessOpenBSDKernel::ProcessOpenBSDKernel(lldb::TargetSP target_sp, > + ListenerSP listener_sp) > + : PostMortemProcess(target_sp, listener_sp) {} > + > +lldb::ProcessSP ProcessOpenBSDKernel::CreateInstance(lldb::TargetSP target_sp, > + ListenerSP listener_sp, > + const FileSpec *crash_file, > + bool can_connect) { > + ModuleSP executable = target_sp->GetExecutableModule(); > + if (crash_file && !can_connect && executable) { > +#if defined(__OpenBSD__) > + kvm_t *kvm = > + kvm_open(executable->GetFileSpec().GetPath().c_str(), > + crash_file->GetPath().c_str(), nullptr, O_RDONLY, nullptr); > + if (kvm) > + return std::make_shared(target_sp, listener_sp, > + kvm); > +#endif > + } > + return nullptr; > +} > + > +void ProcessOpenBSDKernel::Initialize() { > + static llvm::once_flag g_once_flag; > + > + llvm::call_once(g_once_flag, []() { > + PluginManager::RegisterPlugin(GetPluginNameStatic(), > + GetPluginDescriptionStatic(), CreateInstance); > + }); > +} > + > +void ProcessOpenBSDKernel::Terminate() { > + PluginManager::UnregisterPlugin(ProcessOpenBSDKernel::CreateInstance); > +} > + > +Status ProcessOpenBSDKernel::DoDestroy() { return Status(); } > + > +bool ProcessOpenBSDKernel::CanDebug(lldb::TargetSP target_sp, > + bool plugin_specified_by_name) { > + return true; > +} > + > +void ProcessOpenBSDKernel::RefreshStateAfterStop() {} > + > +bool ProcessOpenBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, > + ThreadList &new_thread_list) { > + if (old_thread_list.GetSize(false) == 0) { > + // Make up the thread the first time this is called so we can set our one > + // and only core thread state up. > + > + // We cannot construct a thread without a register context as that crashes > + // LLDB but we can construct a process without threads to provide minimal > + // memory reading support. > + switch (GetTarget().GetArchitecture().GetMachine()) { > + case llvm::Triple::aarch64: > + case llvm::Triple::x86: > + case llvm::Triple::x86_64: > + break; > + default: > + return false; > + } > + > + Status error; > + int32_t i; > + lldb::addr_t dumppcb = FindSymbol("dumppcb"); > + uint32_t offset_p_list = offsetof(proc, p_list); > + uint32_t offset_p_addr = offsetof(proc, p_addr); > + uint32_t offset_p_tid = offsetof(proc, p_tid); > + uint32_t offset_p_p = offsetof(proc, p_p); > + uint32_t offset_ps_comm = offsetof(process, ps_comm); > + uint32_t offset_ps_pid = offsetof(process, ps_pid); > + uint32_t offset_ci_curproc = offsetof(cpu_info, ci_curproc); > + char comm[_MAXCOMLEN]; > + > + int32_t ncpu = ReadSignedIntegerFromMemory(FindSymbol("ncpus"), > + 4, -1, error); > + if (ncpu < 0) > + return false; > + > + lldb::addr_t cpu_procs[ncpu]; > + > + if (dumppcb != LLDB_INVALID_ADDRESS) { > + std::string thread_desc = llvm::formatv("Crashed Thread"); > + ThreadSP thread_sp { > + new ThreadOpenBSDKernel(*this, 0, dumppcb, thread_desc)}; > + new_thread_list.AddThread(thread_sp); > + } > + > + lldb::addr_t cpu_info = FindSymbol("cpu_info"); > + lldb::addr_t cpu_info_array = (cpu_info == LLDB_INVALID_ADDRESS) ? > + ReadPointerFromMemory(FindSymbol("cpu_info_list"), error) : cpu_info; > + for (i = 0; i < ncpu ; i++) { > + lldb::addr_t ci = > + ReadPointerFromMemory(cpu_info_array + sizeof(void*) * i, error); > + cpu_procs[i] = ReadPointerFromMemory(ci + offset_ci_curproc, error); > + } > + > + for (lldb::addr_t proc = ReadPointerFromMemory(FindSymbol("allproc"), error); > + proc != 0 && proc != LLDB_INVALID_ADDRESS; > + proc = ReadPointerFromMemory(proc + offset_p_list, error)) { > + > + lldb::tid_t tid = ReadSignedIntegerFromMemory(proc + offset_p_tid, 4, -1, > + error); > + lldb::addr_t process = ReadPointerFromMemory(proc + offset_p_p, error); > + ReadMemory(process + offset_ps_comm, &comm, sizeof(comm), error); > + u_int32_t pid = ReadSignedIntegerFromMemory(process + offset_ps_pid, 4, > + -1, error); > + lldb::addr_t p_addr = ReadPointerFromMemory(proc + offset_p_addr, error); > + for (i = 0; i < ncpu; i++) > + if (cpu_procs[i] == proc) > + break; > + std::string thread_desc; > + if (i == ncpu) > + thread_desc = llvm::formatv("(pid:{0}) {1}", pid, comm); > + else > + thread_desc = llvm::formatv("(pid:{0}) {1} (cpu {2})", pid, comm, i); > + ThreadSP thread_sp { > + new ThreadOpenBSDKernel(*this, tid, p_addr, thread_desc)}; > + new_thread_list.AddThread(thread_sp); > + } > + } else { > + const uint32_t num_threads = old_thread_list.GetSize(false); > + for (uint32_t i = 0; i < num_threads; ++i) > + new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false)); > + } > + return new_thread_list.GetSize(false) > 0; > +} > + > +Status ProcessOpenBSDKernel::DoLoadCore() { > + // The core is already loaded by CreateInstance(). > + return Status(); > +} > + > +DynamicLoader *ProcessOpenBSDKernel::GetDynamicLoader() { > + if (m_dyld_up.get() == nullptr) > + m_dyld_up.reset(DynamicLoader::FindPlugin( > + this, DynamicLoaderStatic::GetPluginNameStatic())); > + return m_dyld_up.get(); > +} > + > +lldb::addr_t ProcessOpenBSDKernel::FindSymbol(const char *name) { > + ModuleSP mod_sp = GetTarget().GetExecutableModule(); > + const Symbol *sym = mod_sp->FindFirstSymbolWithNameAndType(ConstString(name)); > + return sym ? sym->GetLoadAddress(&GetTarget()) : LLDB_INVALID_ADDRESS; > +} > + > +#if defined(__OpenBSD__) > + > +ProcessOpenBSDKernelKVM::ProcessOpenBSDKernelKVM(lldb::TargetSP target_sp, > + ListenerSP listener_sp, > + kvm_t *fvc) > + : ProcessOpenBSDKernel(target_sp, listener_sp), m_kvm(fvc) {} > + > +ProcessOpenBSDKernelKVM::~ProcessOpenBSDKernelKVM() { > + if (m_kvm) > + kvm_close(m_kvm); > +} > + > +size_t ProcessOpenBSDKernelKVM::DoReadMemory(lldb::addr_t addr, void *buf, > + size_t size, Status &error) { > + ssize_t rd = 0; > + rd = kvm_read(m_kvm, addr, buf, size); > + if (rd < 0 || static_cast(rd) != size) { > + error.SetErrorStringWithFormat("Reading memory failed: %s", GetError()); > + return rd > 0 ? rd : 0; > + } > + return rd; > +} > + > +const char *ProcessOpenBSDKernelKVM::GetError() { return kvm_geterr(m_kvm); } > + > +#endif // defined(__OpenBSD__) > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.h > new file mode 100644 > index 00000000000..666dd9c2c67 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ProcessOpenBSDKernel.h > @@ -0,0 +1,53 @@ > +//===-- ProcessOpenBSDKernel.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 LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_PROCESSOPENBSDKERNEL_H > +#define LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_PROCESSOPENBSDKERNEL_H > + > +#include "lldb/Target/PostMortemProcess.h" > + > +class ProcessOpenBSDKernel : public lldb_private::PostMortemProcess { > +public: > + ProcessOpenBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener); > + > + static lldb::ProcessSP > + CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener, > + const lldb_private::FileSpec *crash_file_path, > + bool can_connect); > + > + static void Initialize(); > + > + static void Terminate(); > + > + static llvm::StringRef GetPluginNameStatic() { return "openbsd-kernel"; } > + > + static llvm::StringRef GetPluginDescriptionStatic() { > + return "OpenBSD kernel vmcore debugging plug-in."; > + } > + > + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } > + > + lldb_private::Status DoDestroy() override; > + > + bool CanDebug(lldb::TargetSP target_sp, > + bool plugin_specified_by_name) override; > + > + void RefreshStateAfterStop() override; > + > + lldb_private::Status DoLoadCore() override; > + > + lldb_private::DynamicLoader *GetDynamicLoader() override; > + > +protected: > + bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, > + lldb_private::ThreadList &new_thread_list) override; > + > + lldb::addr_t FindSymbol(const char* name); > +}; > + > +#endif // LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_PROCESSOPENBSDKERNEL_H > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp > new file mode 100644 > index 00000000000..1ebfc6a799f > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.cpp > @@ -0,0 +1,107 @@ > +//===-- RegisterContextOpenBSDKernel_arm64.cpp ----------------------------===// > +// > +// 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 > +// > +//===----------------------------------------------------------------------===// > + > +#if defined(__OpenBSD__) > +#include > +#include > +#define _KERNEL > +#include > +#undef _KERNEL > +#include > +#include > +#endif > + > +#include "RegisterContextOpenBSDKernel_arm64.h" > +#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" > + > +#include "lldb/Target/Process.h" > +#include "lldb/Target/Thread.h" > +#include "lldb/Utility/RegisterValue.h" > +#include "llvm/Support/Endian.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +RegisterContextOpenBSDKernel_arm64::RegisterContextOpenBSDKernel_arm64( > + Thread &thread, std::unique_ptr register_info_up, > + lldb::addr_t pcb_addr) > + : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)), > + m_pcb_addr(pcb_addr) {} > + > +bool RegisterContextOpenBSDKernel_arm64::ReadGPR() { return true; } > + > +bool RegisterContextOpenBSDKernel_arm64::ReadFPR() { return true; } > + > +bool RegisterContextOpenBSDKernel_arm64::WriteGPR() { > + assert(0); > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_arm64::WriteFPR() { > + assert(0); > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_arm64::ReadRegister( > + const RegisterInfo *reg_info, RegisterValue &value) { > + if (m_pcb_addr == LLDB_INVALID_ADDRESS) > + return false; > + > +#ifdef __aarch64__ > + Status error; > + struct pcb pcb; > + size_t rd = m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), > + error); > + if (rd != sizeof(pcb)) > + return false; > + > + /* > + Usually pcb is written in `cpu_switchto` function. This function writes > + registers as same as the structure of `swichframe` in the stack. > + We read the frame if it is. > + */ > + struct switchframe sf; > + rd = m_thread.GetProcess()->ReadMemory(pcb.pcb_sp, &sf, sizeof(sf), error); > + if (rd != sizeof(sf)) > + return false; > + > + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > + switch (reg) { > +#define REG(x) \ > + case gpr_##x##_arm64: \ > + value = (u_int64_t)sf.sf_##x; \ > + return true; > + > + REG(x19); > + REG(x20); > + REG(x21); > + REG(x22); > + REG(x23); > + REG(x24); > + REG(x25); > + REG(x26); > + REG(x27); > + REG(x28); > + case gpr_fp_arm64: > + value = (u_int64_t)sf.sf_x29; > + return true; > + case gpr_sp_arm64: > + value = (u_int64_t)pcb.pcb_sp; > + return true; > + case gpr_pc_arm64: > + value = (u_int64_t)sf.sf_lr; > + return true; > + } > +#endif > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_arm64::WriteRegister( > + const RegisterInfo *reg_info, const RegisterValue &value) { > + return false; > +} > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.h > new file mode 100644 > index 00000000000..b21a074c3e7 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_arm64.h > @@ -0,0 +1,41 @@ > +//===-- RegisterContextOpenBSDKernel_arm64.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 LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_ARM64_H > +#define LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_ARM64_H > + > +#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" > +#include "Plugins/Process/elf-core/RegisterUtilities.h" > + > +class RegisterContextOpenBSDKernel_arm64 : public RegisterContextPOSIX_arm64 { > +public: > + RegisterContextOpenBSDKernel_arm64( > + lldb_private::Thread &thread, > + std::unique_ptr register_info_up, > + lldb::addr_t pcb_addr); > + > + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, > + lldb_private::RegisterValue &value) override; > + > + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, > + const lldb_private::RegisterValue &value) override; > + > +protected: > + bool ReadGPR() override; > + > + bool ReadFPR() override; > + > + bool WriteGPR() override; > + > + bool WriteFPR() override; > + > +private: > + lldb::addr_t m_pcb_addr; > +}; > + > +#endif // LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_ARM64_H > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > new file mode 100644 > index 00000000000..9a909a4e07d > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.cpp > @@ -0,0 +1,110 @@ > +//===-- RegisterContextOpenBSDKernel_i386.cpp -----------------------------===// > +// > +// 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 > +// > +//===----------------------------------------------------------------------===// > + > +#if defined(__OpenBSD__) > +#include > +#include > +#define _KERNEL > +#include > +#undef _KERNEL > +#include > +#include > +#endif > + > +#include "RegisterContextOpenBSDKernel_i386.h" > + > +#include "lldb/Target/Process.h" > +#include "lldb/Target/Thread.h" > +#include "lldb/Utility/RegisterValue.h" > +#include "llvm/Support/Endian.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +RegisterContextOpenBSDKernel_i386::RegisterContextOpenBSDKernel_i386( > + Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr) > + : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) { > +} > + > +bool RegisterContextOpenBSDKernel_i386::ReadGPR() { return true; } > + > +bool RegisterContextOpenBSDKernel_i386::ReadFPR() { return true; } > + > +bool RegisterContextOpenBSDKernel_i386::WriteGPR() { > + assert(0); > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_i386::WriteFPR() { > + assert(0); > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_i386::ReadRegister( > + const RegisterInfo *reg_info, RegisterValue &value) { > + if (m_pcb_addr == LLDB_INVALID_ADDRESS) > + return false; > + > +#ifdef __i386__ > + struct pcb pcb; > + > + Status error; > + size_t rd = > + m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error); > + if (rd != sizeof(pcb)) > + return false; > + > + if ((pcb.pcb_flags & PCB_SAVECTX) != 0) { > + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > + switch (reg) { > +#define PCBREG(x) \ > + case lldb_##x##_i386: \ > + value = pcb.pcb_##x; \ > + return true; > + PCBREG(ebp); > + PCBREG(esp); > + case lldb_eip_i386: > + value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_ebp + 4, > + error); > + return true; > + } > + return false; > + } > + > + /* > + Usually pcb is written in `cpu_switchto` function. This function writes > + registers as same as the structure of `swichframe` in the stack. > + We read the frame if it is. > + */ > + struct switchframe sf; > + rd = m_thread.GetProcess()->ReadMemory(pcb.pcb_esp, &sf, sizeof(sf), error); > + if (rd != sizeof(sf)) > + return false; > + > + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > + switch (reg) { > +#define SFREG(x) \ > + case lldb_##x##_i386: \ > + value = sf.sf_##x; \ > + return true; > + > + SFREG(edi); > + SFREG(esi); > + SFREG(ebx); > + SFREG(eip); > + PCBREG(ebp); > + PCBREG(esp); > + } > +#endif > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_i386::WriteRegister( > + const RegisterInfo *reg_info, const RegisterValue &value) { > + return false; > +} > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.h > new file mode 100644 > index 00000000000..1d44dedf0c5 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_i386.h > @@ -0,0 +1,41 @@ > +//===-- RegisterContextOpenBSDKernel_i386.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 LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_I386_H > +#define LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_I386_H > + > +#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h" > +#include "Plugins/Process/elf-core/RegisterUtilities.h" > + > +class RegisterContextOpenBSDKernel_i386 : public RegisterContextPOSIX_x86 { > +public: > + RegisterContextOpenBSDKernel_i386( > + lldb_private::Thread &thread, > + lldb_private::RegisterInfoInterface *register_info, > + lldb::addr_t pcb_addr); > + > + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, > + lldb_private::RegisterValue &value) override; > + > + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, > + const lldb_private::RegisterValue &value) override; > + > +protected: > + bool ReadGPR() override; > + > + bool ReadFPR() override; > + > + bool WriteGPR() override; > + > + bool WriteFPR() override; > + > +private: > + lldb::addr_t m_pcb_addr; > +}; > + > +#endif // LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_I386_H > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > new file mode 100644 > index 00000000000..501fa858a92 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.cpp > @@ -0,0 +1,111 @@ > +//===-- RegisterContextOpenBSDKernel_x86_64.cpp ---------------------------===// > +// > +// 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 > +// > +//===----------------------------------------------------------------------===// > + > +#if defined(__OpenBSD__) > +#include > +#include > +#define _KERNEL > +#include > +#undef _KERNEL > +#include > +#include > +#endif > + > +#include "RegisterContextOpenBSDKernel_x86_64.h" > + > +#include "lldb/Target/Process.h" > +#include "lldb/Target/Thread.h" > +#include "lldb/Utility/RegisterValue.h" > +#include "llvm/Support/Endian.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +RegisterContextOpenBSDKernel_x86_64::RegisterContextOpenBSDKernel_x86_64( > + Thread &thread, RegisterInfoInterface *register_info, > + lldb::addr_t pcb) > + : RegisterContextPOSIX_x86(thread, 0, register_info), > + m_pcb_addr(pcb) { > +} > + > +bool RegisterContextOpenBSDKernel_x86_64::ReadGPR() { return true; } > + > +bool RegisterContextOpenBSDKernel_x86_64::ReadFPR() { return true; } > + > +bool RegisterContextOpenBSDKernel_x86_64::WriteGPR() { > + assert(0); > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_x86_64::WriteFPR() { > + assert(0); > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_x86_64::ReadRegister( > + const RegisterInfo *reg_info, RegisterValue &value) { > + Status error; > + > + if (m_pcb_addr == LLDB_INVALID_ADDRESS) > + return false; > + > +#ifdef __amd64__ > + struct pcb pcb; > + size_t rd = m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), > + error); > + if (rd != sizeof(pcb)) > + return false; > + > + /* > + Usually pcb is written in `cpu_switchto` function. This function writes > + registers as same as the structure of `swichframe` in the stack. > + We read the frame if it is. > + */ > + struct switchframe sf; > + rd = m_thread.GetProcess()->ReadMemory(pcb.pcb_rsp, &sf, sizeof(sf), error); > + if (rd != sizeof(sf)) > + return false; > + > + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; > + if (pcb.pcb_rbp == (u_int64_t)sf.sf_rbp) { > +#define SFREG(x) \ > + case lldb_##x##_x86_64: \ > + value = (u_int64_t)sf.sf_##x; \ > + return true; > +#define PCBREG(x) \ > + case lldb_##x##_x86_64: \ > + value = pcb.pcb_##x; \ > + return true; > + switch (reg) { > + SFREG(r15); > + SFREG(r14); > + SFREG(r13); > + SFREG(r12); > + SFREG(rbp); > + SFREG(rbx); > + SFREG(rip); > + PCBREG(rsp); > + } > + } else { > + switch (reg) { > + PCBREG(rbp); > + PCBREG(rsp); > + case lldb_rip_x86_64: > + value = m_thread.GetProcess()->ReadPointerFromMemory(pcb.pcb_rbp + 8, > + error); > + return true; > + } > + } > +#endif > + return false; > +} > + > +bool RegisterContextOpenBSDKernel_x86_64::WriteRegister( > + const RegisterInfo *reg_info, const RegisterValue &value) { > + return false; > +} > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.h > new file mode 100644 > index 00000000000..63c06fd5d9c > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/RegisterContextOpenBSDKernel_x86_64.h > @@ -0,0 +1,41 @@ > +//===-- RegisterContextOpenBSDKernel_x86_64.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 LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_X86_64_H > +#define LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_X86_64_H > + > +#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h" > +#include "Plugins/Process/elf-core/RegisterUtilities.h" > + > +class RegisterContextOpenBSDKernel_x86_64 : public RegisterContextPOSIX_x86 { > +public: > + RegisterContextOpenBSDKernel_x86_64( > + lldb_private::Thread &thread, > + lldb_private::RegisterInfoInterface *register_info, > + lldb::addr_t pcb); > + > + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, > + lldb_private::RegisterValue &value) override; > + > + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, > + const lldb_private::RegisterValue &value) override; > + > +protected: > + bool ReadGPR() override; > + > + bool ReadFPR() override; > + > + bool WriteGPR() override; > + > + bool WriteFPR() override; > + > +private: > + lldb::addr_t m_pcb_addr; > +}; > + > +#endif // LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_REGISTERCONTEXTOPENBSDKERNEL_X86_64_H > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ThreadOpenBSDKernel.cpp b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ThreadOpenBSDKernel.cpp > new file mode 100644 > index 00000000000..921101a418f > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ThreadOpenBSDKernel.cpp > @@ -0,0 +1,86 @@ > +//===-- ThreadOpenBSDKernel.cpp -------------------------------------------===// > +// > +// 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 "ThreadOpenBSDKernel.h" > + > +#include "lldb/Target/Unwind.h" > +#include "lldb/Utility/Log.h" > + > +#include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h" > +#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h" > +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" > +#include "ProcessOpenBSDKernel.h" > +#include "RegisterContextOpenBSDKernel_arm64.h" > +#include "RegisterContextOpenBSDKernel_i386.h" > +#include "RegisterContextOpenBSDKernel_x86_64.h" > +#include "ThreadOpenBSDKernel.h" > + > +using namespace lldb; > +using namespace lldb_private; > + > +ThreadOpenBSDKernel::ThreadOpenBSDKernel(Process &process, lldb::tid_t tid, > + lldb::addr_t pcb, > + std::string thread_name) > + : Thread(process, tid), m_thread_name(std::move(thread_name)), > + m_pcb(pcb) {} > + > +ThreadOpenBSDKernel::~ThreadOpenBSDKernel() {} > + > +void ThreadOpenBSDKernel::RefreshStateAfterStop() {} > + > +lldb::RegisterContextSP ThreadOpenBSDKernel::GetRegisterContext() { > + if (!m_reg_context_sp) > + m_reg_context_sp = CreateRegisterContextForFrame(nullptr); > + return m_reg_context_sp; > +} > + > +lldb::RegisterContextSP > +ThreadOpenBSDKernel::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; > + > + ProcessOpenBSDKernel *process = > + static_cast(GetProcess().get()); > + ArchSpec arch = process->GetTarget().GetArchitecture(); > + > + switch (arch.GetMachine()) { > + case llvm::Triple::aarch64: > + m_thread_reg_ctx_sp = > + std::make_shared( > + *this, std::make_unique(arch, 0), > + m_pcb); > + break; > + case llvm::Triple::x86: > + m_thread_reg_ctx_sp = std::make_shared( > + *this, new RegisterContextOpenBSD_i386(arch), m_pcb); > + break; > + case llvm::Triple::x86_64: > + m_thread_reg_ctx_sp = > + std::make_shared( > + *this, new RegisterContextOpenBSD_x86_64(arch), m_pcb); > + break; > + default: > + assert(false && "Unsupported architecture passed to ThreadOpenBSDKernel"); > + break; > + } > + > + reg_ctx_sp = m_thread_reg_ctx_sp; > + } else { > + reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame); > + } > + return reg_ctx_sp; > +} > + > +bool ThreadOpenBSDKernel::CalculateStopInfo() { return false; } > diff --git a/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ThreadOpenBSDKernel.h b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ThreadOpenBSDKernel.h > new file mode 100644 > index 00000000000..9324eb50712 > --- /dev/null > +++ b/gnu/llvm/lldb/source/Plugins/Process/OpenBSDKernel/ThreadOpenBSDKernel.h > @@ -0,0 +1,50 @@ > +//===-- ThreadOpenBSDKernel.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 LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_THREADOPENBSDKERNEL_H > +#define LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_THREADOPENBSDKERNEL_H > + > +#include "lldb/Target/Thread.h" > + > +class ThreadOpenBSDKernel : public lldb_private::Thread { > +public: > + ThreadOpenBSDKernel(lldb_private::Process &process, lldb::tid_t tid, > + lldb::addr_t pcb, std::string thread_name); > + > + ~ThreadOpenBSDKernel() override; > + > + void RefreshStateAfterStop() override; > + > + lldb::RegisterContextSP GetRegisterContext() override; > + > + lldb::RegisterContextSP > + CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; > + > + const char *GetName() override { > + if (m_thread_name.empty()) > + return nullptr; > + return m_thread_name.c_str(); > + } > + > + void SetName(const char *name) override { > + if (name && name[0]) > + m_thread_name.assign(name); > + else > + m_thread_name.clear(); > + } > + > +protected: > + bool CalculateStopInfo() override; > + > +private: > + std::string m_thread_name; > + lldb::RegisterContextSP m_thread_reg_ctx_sp; > + lldb::addr_t m_pcb; > +}; > + > +#endif // LLDB_SOURCE_PLUGINS_PROCESS_OPENBSDKERNEL_THREADOPENBSDKERNEL_H > diff --git a/gnu/usr.bin/clang/liblldbPluginProcess/Makefile b/gnu/usr.bin/clang/liblldbPluginProcess/Makefile > index a075e152c07..c7b240f6f12 100644 > --- a/gnu/usr.bin/clang/liblldbPluginProcess/Makefile > +++ b/gnu/usr.bin/clang/liblldbPluginProcess/Makefile > @@ -124,6 +124,13 @@ SRCS+= MinidumpTypes.cpp \ > SRCS+= ScriptedProcess.cpp \ > ScriptedThread.cpp > > +# Process/OpenBSDKernel > +SRCS+= ProcessOpenBSDKernel.cpp \ > + RegisterContextOpenBSDKernel_arm64.cpp \ > + RegisterContextOpenBSDKernel_i386.cpp \ > + RegisterContextOpenBSDKernel_x86_64.cpp \ > + ThreadOpenBSDKernel.cpp > + > .PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/OpenBSD > .PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/POSIX > .PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/gdb-remote > @@ -132,6 +139,7 @@ SRCS+= ScriptedProcess.cpp \ > .PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/mach-core > .PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/minidump > .PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/scripted > +.PATH: ${.CURDIR}/../../../llvm/lldb/source/Plugins/Process/OpenBSDKernel > > install: > @# Nothing here so far ... > diff --git a/gnu/usr.bin/clang/lldb/Makefile b/gnu/usr.bin/clang/lldb/Makefile > index 31a1ffc7b8b..652769fd92b 100644 > --- a/gnu/usr.bin/clang/lldb/Makefile > +++ b/gnu/usr.bin/clang/lldb/Makefile > @@ -10,7 +10,7 @@ SRCS= Driver.cpp \ > Platform.cpp \ > Version.cpp > > -LDADD+= -lcurses -ledit -lpanel > +LDADD+= -lcurses -ledit -lpanel -lkvm > > CPPFLAGS+= ${LLDB_INCLUDES} > CPPFLAGS+= ${CLANG_INCLUDES} > > -- > Yuichiro NAITO (naito.yuichiro@gmail.com) >