mgorny updated this revision to Diff 392352.
mgorny added a comment.

Finish that one tet.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114911/new/

https://reviews.llvm.org/D114911

Files:
  lldb/cmake/modules/LLDBConfig.cmake
  lldb/packages/Python/lldbsuite/test/lldbtest.py
  lldb/source/Plugins/Process/CMakeLists.txt
  lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
  lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
  lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
  
lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
  lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
  
lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
  lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
  
lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
  
lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
  lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
  lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
  
lldb/test/API/functionalities/postmortem/FreeBSDKernel/TestFreeBSDKernelVMCore.py
  lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-amd64.yaml
  lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-arm64.yaml
  lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-i386.yaml
  lldb/test/API/functionalities/postmortem/FreeBSDKernel/vmcore-amd64-full.bz2

Index: lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-i386.yaml
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-i386.yaml
@@ -0,0 +1,38 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_FREEBSD
+  Type:            ET_EXEC
+  Machine:         EM_386
+  Entry:           0x8F9000
+Sections:
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x1AB7B00
+    AddressAlign:    0x80
+    Offset:          0x12B7AB0
+    Size:            0x2D48D8
+Symbols:
+  - Name:            kernbase
+    Index:           SHN_ABS
+    Binding:         STB_GLOBAL
+    Value:           0x800000
+  - Name:            dumppcb
+    Type:            STT_OBJECT
+    Section:         .bss
+    Value:           0x1D2D9A0
+    Size:            0xC0
+  - Name:            hz
+    Type:            STT_OBJECT
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0x1D4053C
+    Size:            0x4
+  - Name:            IdlePDPT
+    Type:            STT_OBJECT
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0x1D8B044
+    Size:            0x4
Index: lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-arm64.yaml
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-arm64.yaml
@@ -0,0 +1,30 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_AARCH64
+  Entry:           0xFFFF000000000800
+Sections:
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0xFFFF000000C35000
+    AddressAlign:    0x1000
+    Size:            0x37F000
+Symbols:
+  - Name:            kernbase
+    Index:           SHN_ABS
+    Binding:         STB_GLOBAL
+    Value:           0xFFFF000000000000
+  - Name:            dumppcb
+    Type:            STT_OBJECT
+    Section:         .bss
+    Value:           0xFFFF000000DF3790
+    Size:            0x560
+  - Name:            hz
+    Type:            STT_OBJECT
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0xFFFF000000E2651C
+    Size:            0x4
Index: lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-amd64.yaml
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/postmortem/FreeBSDKernel/kernel-amd64.yaml
@@ -0,0 +1,38 @@
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  OSABI:           ELFOSABI_FREEBSD
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0xFFFFFFFF8037C000
+Sections:
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0xFFFFFFFF819BA380
+    AddressAlign:    0x80
+    Offset:          0x17BA348
+    Size:            0x445C80
+Symbols:
+  - Name:            kernbase
+    Index:           SHN_ABS
+    Binding:         STB_GLOBAL
+    Value:           0xFFFFFFFF80000000
+  - Name:            KPML4phys
+    Type:            STT_OBJECT
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0xFFFFFFFF81D47EB8
+    Size:            0x8
+  - Name:            dumppcb
+    Type:            STT_OBJECT
+    Section:         .bss
+    Value:           0xFFFFFFFF81CA6868
+    Size:            0x140
+  - Name:            hz
+    Type:            STT_OBJECT
+    Section:         .bss
+    Binding:         STB_GLOBAL
+    Value:           0xFFFFFFFF81CD4C0C
+    Size:            0x4
Index: lldb/test/API/functionalities/postmortem/FreeBSDKernel/TestFreeBSDKernelVMCore.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/postmortem/FreeBSDKernel/TestFreeBSDKernelVMCore.py
@@ -0,0 +1,86 @@
+import bz2
+import shutil
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class FreeBSDKernelVMCoreTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def make_target(self, src_filename):
+        src = self.getSourcePath(src_filename)
+        dest = self.getBuildArtifact("kernel")
+        self.yaml2obj(src, dest, max_size=30*1024*1024)
+        return self.dbg.CreateTarget(dest)
+
+    def make_vmcore(self, src_filename):
+        src = self.getSourcePath(src_filename)
+        dest = self.getBuildArtifact("vmcore")
+        with bz2.open(src, 'rb') as inf:
+            with open(dest, 'wb') as outf:
+                shutil.copyfileobj(inf, outf)
+        return dest
+
+    @skipIfLLVMTargetMissing("X86")
+    def test_amd64_full_vmcore(self):
+        target = self.make_target("kernel-amd64.yaml")
+        vmcore_file = self.make_vmcore("vmcore-amd64-full.bz2")
+        process = target.LoadCore(vmcore_file)
+
+        self.assertTrue(process, PROCESS_IS_VALID)
+        self.assertEqual(process.GetNumThreads(), 1)
+        self.assertEqual(process.GetProcessID(), 0)
+
+        # test memory reading
+        self.expect("expr -- *(int *) &hz", substrs=["(int) $0 = 100"])
+
+        main_mod = target.GetModuleAtIndex(0)
+        hz_addr = (main_mod.FindSymbols("hz")[0].symbol.addr
+                   .GetLoadAddress(target))
+        error = lldb.SBError()
+        self.assertEqual(process.ReadMemory(hz_addr, 4, error),
+                         b'\x64\x00\x00\x00')
+
+        # test backtrace
+        self.assertEqual(
+            [process.GetThreadAtIndex(0).GetFrameAtIndex(i).addr
+             .GetLoadAddress(target)
+             for i in range(11)],
+            [0xffffffff80c09ade,
+             0xffffffff80c09916,
+             0xffffffff80c09d90,
+             0xffffffff80c09b93,
+             0xffffffff80c57d91,
+             0xffffffff80c19e71,
+             0xffffffff80c192bc,
+             0xffffffff80c19933,
+             0xffffffff80c1977f,
+             0xffffffff8108ba8c,
+             0xffffffff810620ce])
+
+        # test registers
+        regs = process.GetThreadAtIndex(0).GetFrameAtIndex(0).GetRegisters()
+        reg_values = {}
+        for regset in regs:
+            for reg in regset:
+                if reg.value is None:
+                    continue
+                reg_values[reg.name] = reg.value
+        self.assertEqual(
+            reg_values,
+            {"rbx": "0x0000000000000000",
+             "rbp": "0xfffffe0085cb2760",
+             "rsp": "0xfffffe0085cb2748",
+             "r12": "0xfffffe0045a6c300",
+             "r13": "0xfffff800033693a8",
+             "r14": "0x0000000000000000",
+             "r15": "0xfffff80003369380",
+             "rip": "0xffffffff80c09ade",
+             })
+
+        self.dbg.DeleteTarget(target)
Index: lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.h
@@ -0,0 +1,36 @@
+//===-- ThreadFreeBSDKernel.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_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
+
+#include "lldb/Target/Thread.h"
+
+class ThreadFreeBSDKernel : public lldb_private::Thread {
+public:
+  ThreadFreeBSDKernel(lldb_private::Process &process, lldb::tid_t tid,
+                      lldb::addr_t pcb_addr);
+
+  ~ThreadFreeBSDKernel() override;
+
+  void RefreshStateAfterStop() override;
+
+  lldb::RegisterContextSP GetRegisterContext() override;
+
+  lldb::RegisterContextSP
+  CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
+
+protected:
+  bool CalculateStopInfo() override;
+
+private:
+  lldb::RegisterContextSP m_thread_reg_ctx_sp;
+  lldb::addr_t m_pcb_addr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_THREADFREEBSDKERNEL_H
Index: lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/ThreadFreeBSDKernel.cpp
@@ -0,0 +1,85 @@
+//===-- ThreadFreeBSDKernel.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 "ThreadFreeBSDKernel.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_arm64.h"
+#include "ProcessFreeBSDKernel.h"
+#include "RegisterContextFreeBSDKernel_arm64.h"
+#include "RegisterContextFreeBSDKernel_i386.h"
+#include "RegisterContextFreeBSDKernel_x86_64.h"
+#include "ThreadFreeBSDKernel.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ThreadFreeBSDKernel::ThreadFreeBSDKernel(Process &process, lldb::tid_t tid,
+                                         lldb::addr_t pcb_addr)
+    : Thread(process, tid), m_pcb_addr(pcb_addr) {}
+
+ThreadFreeBSDKernel::~ThreadFreeBSDKernel() {}
+
+void ThreadFreeBSDKernel::RefreshStateAfterStop() {}
+
+lldb::RegisterContextSP ThreadFreeBSDKernel::GetRegisterContext() {
+  if (!m_reg_context_sp)
+    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
+  return m_reg_context_sp;
+}
+
+lldb::RegisterContextSP
+ThreadFreeBSDKernel::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;
+
+    ProcessFreeBSDKernel *process =
+        static_cast<ProcessFreeBSDKernel *>(GetProcess().get());
+    ArchSpec arch = process->GetTarget().GetArchitecture();
+
+    switch (arch.GetMachine()) {
+    case llvm::Triple::aarch64:
+      m_thread_reg_ctx_sp =
+          std::make_shared<RegisterContextFreeBSDKernel_arm64>(
+              *this, std::make_unique<RegisterInfoPOSIX_arm64>(arch, 0),
+              m_pcb_addr);
+      break;
+    case llvm::Triple::x86:
+      m_thread_reg_ctx_sp =
+          std::make_shared<RegisterContextFreeBSDKernel_i386>(
+              *this, new RegisterContextFreeBSD_i386(arch), m_pcb_addr);
+      break;
+    case llvm::Triple::x86_64:
+      m_thread_reg_ctx_sp =
+          std::make_shared<RegisterContextFreeBSDKernel_x86_64>(
+              *this, new RegisterContextFreeBSD_x86_64(arch), m_pcb_addr);
+      break;
+    default:
+      assert(false && "Unsupported architecture passed to ThreadFreeBSDKernel");
+      break;
+    }
+
+    reg_ctx_sp = m_thread_reg_ctx_sp;
+  } else {
+    reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
+  }
+  return reg_ctx_sp;
+}
+
+bool ThreadFreeBSDKernel::CalculateStopInfo() { return false; }
Index: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_x86_64 : public RegisterContextPOSIX_x86 {
+public:
+  RegisterContextFreeBSDKernel_x86_64(
+      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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_X86_64_H
Index: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_x86_64.cpp
@@ -0,0 +1,88 @@
+//===-- RegisterContextFreeBSDKernel_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
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextFreeBSDKernel_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;
+
+RegisterContextFreeBSDKernel_x86_64::RegisterContextFreeBSDKernel_x86_64(
+    Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr)
+    : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) {
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteGPR() {
+  assert(0);
+  return false;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteFPR() {
+  assert(0);
+  return false;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::ReadRegister(
+    const RegisterInfo *reg_info, RegisterValue &value) {
+  if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+    return false;
+
+  struct {
+    llvm::support::ulittle64_t r15;
+    llvm::support::ulittle64_t r14;
+    llvm::support::ulittle64_t r13;
+    llvm::support::ulittle64_t r12;
+    llvm::support::ulittle64_t rbp;
+    llvm::support::ulittle64_t rsp;
+    llvm::support::ulittle64_t rbx;
+    llvm::support::ulittle64_t rip;
+  } pcb;
+
+  Status error;
+  size_t rd =
+      m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+  if (rd != sizeof(pcb))
+    return false;
+
+  uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+  switch (reg) {
+#define REG(x)                                                                 \
+  case lldb_##x##_x86_64:                                                      \
+    value = pcb.x;                                                             \
+    break;
+
+    REG(r15);
+    REG(r14);
+    REG(r13);
+    REG(r12);
+    REG(rbp);
+    REG(rsp);
+    REG(rbx);
+    REG(rip);
+
+#undef REG
+
+  default:
+    return false;
+  }
+
+  return true;
+}
+
+bool RegisterContextFreeBSDKernel_x86_64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &value) {
+  return false;
+}
Index: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_i386 : public RegisterContextPOSIX_x86 {
+public:
+  RegisterContextFreeBSDKernel_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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_I386_H
Index: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_i386.cpp
@@ -0,0 +1,83 @@
+//===-- RegisterContextFreeBSDKernel_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
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextFreeBSDKernel_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;
+
+RegisterContextFreeBSDKernel_i386::RegisterContextFreeBSDKernel_i386(
+    Thread &thread, RegisterInfoInterface *register_info, lldb::addr_t pcb_addr)
+    : RegisterContextPOSIX_x86(thread, 0, register_info), m_pcb_addr(pcb_addr) {
+}
+
+bool RegisterContextFreeBSDKernel_i386::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_i386::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_i386::WriteGPR() {
+  assert(0);
+  return false;
+}
+
+bool RegisterContextFreeBSDKernel_i386::WriteFPR() {
+  assert(0);
+  return false;
+}
+
+bool RegisterContextFreeBSDKernel_i386::ReadRegister(
+    const RegisterInfo *reg_info, RegisterValue &value) {
+  if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+    return false;
+
+  struct {
+    llvm::support::ulittle32_t edi;
+    llvm::support::ulittle32_t esi;
+    llvm::support::ulittle32_t ebp;
+    llvm::support::ulittle32_t esp;
+    llvm::support::ulittle32_t ebx;
+    llvm::support::ulittle32_t eip;
+  } pcb;
+
+  Status error;
+  size_t rd =
+      m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+  if (rd != sizeof(pcb))
+    return false;
+
+  uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+  switch (reg) {
+#define REG(x)                                                                 \
+  case lldb_##x##_i386:                                                      \
+    value = pcb.x;                                                             \
+    break;
+
+    REG(edi);
+    REG(esi);
+    REG(ebp);
+    REG(esp);
+    REG(eip);
+
+#undef REG
+
+  default:
+    return false;
+  }
+
+  return true;
+}
+
+bool RegisterContextFreeBSDKernel_i386::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &value) {
+  return false;
+}
Index: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.h
@@ -0,0 +1,41 @@
+//===-- RegisterContextFreeBSDKernel_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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+class RegisterContextFreeBSDKernel_arm64 : public RegisterContextPOSIX_arm64 {
+public:
+  RegisterContextFreeBSDKernel_arm64(
+      lldb_private::Thread &thread,
+      std::unique_ptr<RegisterInfoPOSIX_arm64> 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_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNEL_ARM64_H
Index: lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/RegisterContextFreeBSDKernel_arm64.cpp
@@ -0,0 +1,109 @@
+//===-- RegisterContextFreeBSDKernel_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
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextFreeBSDKernel_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;
+
+RegisterContextFreeBSDKernel_arm64::RegisterContextFreeBSDKernel_arm64(
+    Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
+    lldb::addr_t pcb_addr)
+    : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)),
+      m_pcb_addr(pcb_addr) {}
+
+bool RegisterContextFreeBSDKernel_arm64::ReadGPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_arm64::ReadFPR() { return true; }
+
+bool RegisterContextFreeBSDKernel_arm64::WriteGPR() {
+  assert(0);
+  return false;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::WriteFPR() {
+  assert(0);
+  return false;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::ReadRegister(
+    const RegisterInfo *reg_info, RegisterValue &value) {
+  if (m_pcb_addr == LLDB_INVALID_ADDRESS)
+    return false;
+
+  struct {
+    llvm::support::ulittle64_t x[30];
+    llvm::support::ulittle64_t lr;
+    llvm::support::ulittle64_t _reserved;
+    llvm::support::ulittle64_t sp;
+  } pcb;
+
+  Status error;
+  size_t rd =
+      m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
+  if (rd != sizeof(pcb))
+    return false;
+
+  uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+  switch (reg) {
+  case gpr_x0_arm64:
+  case gpr_x1_arm64:
+  case gpr_x2_arm64:
+  case gpr_x3_arm64:
+  case gpr_x4_arm64:
+  case gpr_x5_arm64:
+  case gpr_x6_arm64:
+  case gpr_x7_arm64:
+  case gpr_x8_arm64:
+  case gpr_x9_arm64:
+  case gpr_x10_arm64:
+  case gpr_x11_arm64:
+  case gpr_x12_arm64:
+  case gpr_x13_arm64:
+  case gpr_x14_arm64:
+  case gpr_x15_arm64:
+  case gpr_x16_arm64:
+  case gpr_x17_arm64:
+  case gpr_x18_arm64:
+  case gpr_x19_arm64:
+  case gpr_x20_arm64:
+  case gpr_x21_arm64:
+  case gpr_x22_arm64:
+  case gpr_x23_arm64:
+  case gpr_x24_arm64:
+  case gpr_x25_arm64:
+  case gpr_x26_arm64:
+  case gpr_x27_arm64:
+  case gpr_x28_arm64:
+  case gpr_fp_arm64:
+    assert(gpr_fp_arm64 - gpr_x0_arm64 == 30);
+    value = pcb.x[reg - gpr_x0_arm64];
+    break;
+  case gpr_sp_arm64:
+    value = pcb.sp;
+    break;
+  case gpr_pc_arm64:
+    // The pc of crashing thread is stored in lr.
+    value = pcb.lr;
+    break;
+  default:
+    return false;
+  }
+  return true;
+}
+
+bool RegisterContextFreeBSDKernel_arm64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &value) {
+  return false;
+}
Index: lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -0,0 +1,60 @@
+//===-- ProcessFreeBSDKernel.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_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
+
+#include "lldb/Target/PostMortemProcess.h"
+
+class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
+public:
+  ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+                       const lldb_private::FileSpec &core_file, void *fvc);
+
+  ~ProcessFreeBSDKernel() override;
+
+  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 "freebsd-kernel"; }
+
+  static llvm::StringRef GetPluginDescriptionStatic() {
+    return "FreeBSD 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;
+
+  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+                      lldb_private::Status &error) override;
+
+  lldb_private::DynamicLoader *GetDynamicLoader() override;
+
+protected:
+  bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
+                          lldb_private::ThreadList &new_thread_list) override;
+
+private:
+  void *m_fvc;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
Index: lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -0,0 +1,126 @@
+//===-- ProcessFreeBSDKernel.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 "ProcessFreeBSDKernel.h"
+#include "ThreadFreeBSDKernel.h"
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
+
+#include <fvc.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(ProcessFreeBSDKernel)
+
+ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
+                                           ListenerSP listener_sp,
+                                           const FileSpec &core_file, void *fvc)
+    : PostMortemProcess(target_sp, listener_sp), m_fvc(fvc) {}
+
+ProcessFreeBSDKernel::~ProcessFreeBSDKernel() {
+  if (m_fvc)
+    fvc_close(static_cast<fvc_t *>(m_fvc));
+}
+
+lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp,
+                                                     ListenerSP listener_sp,
+                                                     const FileSpec *crash_file,
+                                                     bool can_connect) {
+  lldb::ProcessSP process_sp;
+  ModuleSP executable = target_sp->GetExecutableModule();
+  if (crash_file && !can_connect && executable) {
+    fvc_t *fvc = fvc_open(
+        executable->GetFileSpec().GetPath().c_str(),
+        crash_file->GetPath().c_str(), nullptr, nullptr, nullptr);
+    if (fvc)
+      process_sp = std::make_shared<ProcessFreeBSDKernel>(
+          target_sp, listener_sp, *crash_file, fvc);
+  }
+  return process_sp;
+}
+
+void ProcessFreeBSDKernel::Initialize() {
+  static llvm::once_flag g_once_flag;
+
+  llvm::call_once(g_once_flag, []() {
+    PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                  GetPluginDescriptionStatic(), CreateInstance);
+  });
+}
+
+void ProcessFreeBSDKernel::Terminate() {
+  PluginManager::UnregisterPlugin(ProcessFreeBSDKernel::CreateInstance);
+}
+
+Status ProcessFreeBSDKernel::DoDestroy() { return Status(); }
+
+bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp,
+                                    bool plugin_specified_by_name) {
+  return true;
+}
+
+void ProcessFreeBSDKernel::RefreshStateAfterStop() {}
+
+bool ProcessFreeBSDKernel::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;
+    }
+
+    const Symbol *pcb_sym =
+        GetTarget().GetExecutableModule()->FindFirstSymbolWithNameAndType(
+            ConstString("dumppcb"));
+    ThreadSP thread_sp(new ThreadFreeBSDKernel(
+        *this, 1, pcb_sym ? pcb_sym->GetFileAddress() : LLDB_INVALID_ADDRESS));
+    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 ProcessFreeBSDKernel::DoLoadCore() {
+  // The core is already loaded by CreateInstance().
+  return Status();
+}
+
+size_t ProcessFreeBSDKernel::DoReadMemory(lldb::addr_t addr, void *buf,
+                                          size_t size, Status &error) {
+  ssize_t rd = fvc_read(static_cast<fvc_t *>(m_fvc), addr, buf, size);
+  if (rd < 0 || static_cast<size_t>(rd) != size) {
+    error.SetErrorStringWithFormat("Reading memory failed: %s",
+                                   fvc_geterr(static_cast<fvc_t *>(m_fvc)));
+    return rd > 0 ? rd : 0;
+  }
+  return rd;
+}
+
+DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
+  if (m_dyld_up.get() == nullptr)
+    m_dyld_up.reset(DynamicLoader::FindPlugin(
+        this, DynamicLoaderStatic::GetPluginNameStatic()));
+  return m_dyld_up.get();
+}
Index: lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
@@ -0,0 +1,19 @@
+if (NOT FBSDVMCore_FOUND)
+  message(STATUS "Skipping FreeBSDKernel plugin due to missing libfbsdvmcore")
+  return()
+endif()
+
+add_lldb_library(lldbPluginProcessFreeBSDKernel PLUGIN
+  ProcessFreeBSDKernel.cpp
+  RegisterContextFreeBSDKernel_arm64.cpp
+  RegisterContextFreeBSDKernel_i386.cpp
+  RegisterContextFreeBSDKernel_x86_64.cpp
+  ThreadFreeBSDKernel.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbTarget
+    fbsdvmcore
+  LINK_COMPONENTS
+    Support
+  )
Index: lldb/source/Plugins/Process/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Process/CMakeLists.txt
+++ lldb/source/Plugins/Process/CMakeLists.txt
@@ -18,3 +18,4 @@
 add_subdirectory(elf-core)
 add_subdirectory(mach-core)
 add_subdirectory(minidump)
+add_subdirectory(FreeBSDKernel)
Index: lldb/packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1570,7 +1570,7 @@
         return os.environ["CC"]
 
 
-    def yaml2obj(self, yaml_path, obj_path):
+    def yaml2obj(self, yaml_path, obj_path, max_size=None):
         """
         Create an object file at the given path from a yaml file.
 
@@ -1580,6 +1580,8 @@
         if not yaml2obj_bin:
             self.assertTrue(False, "No valid yaml2obj executable specified")
         command = [yaml2obj_bin, "-o=%s" % obj_path, yaml_path]
+        if max_size is not None:
+            command += ["--max-size=%d" % max_size]
         self.runBuildCommand(command)
 
     def getBuildFlags(
Index: lldb/cmake/modules/LLDBConfig.cmake
===================================================================
--- lldb/cmake/modules/LLDBConfig.cmake
+++ lldb/cmake/modules/LLDBConfig.cmake
@@ -58,6 +58,7 @@
 add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND)
 add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND)
 add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION 2.8)
+add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in LLDB" FBSDVMCore FBSDVMCORE_FOUND)
 
 option(LLDB_USE_SYSTEM_SIX "Use six.py shipped with system and do not install a copy of it" OFF)
 option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to