forked from OSchip/llvm-project
Revert "[lldb] Introduce a FreeBSDKernel plugin for vmcores"
This reverts commit aedb328a4d
.
I have failed to make the new tests conditional to the presence
of libfbsdvmcore.
This commit is contained in:
parent
7598ac5ec5
commit
76c876e7e6
|
@ -58,7 +58,6 @@ add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in LLD
|
|||
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)
|
||||
|
|
|
@ -1570,7 +1570,7 @@ class Base(unittest2.TestCase):
|
|||
return os.environ["CC"]
|
||||
|
||||
|
||||
def yaml2obj(self, yaml_path, obj_path, max_size=None):
|
||||
def yaml2obj(self, yaml_path, obj_path):
|
||||
"""
|
||||
Create an object file at the given path from a yaml file.
|
||||
|
||||
|
@ -1580,8 +1580,6 @@ class Base(unittest2.TestCase):
|
|||
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(
|
||||
|
|
|
@ -18,4 +18,3 @@ add_subdirectory(Utility)
|
|||
add_subdirectory(elf-core)
|
||||
add_subdirectory(mach-core)
|
||||
add_subdirectory(minidump)
|
||||
add_subdirectory(FreeBSDKernel)
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
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
|
||||
)
|
|
@ -1,126 +0,0 @@
|
|||
//===-- 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();
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
//===-- 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
|
|
@ -1,110 +0,0 @@
|
|||
//===-- 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:
|
||||
static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
|
||||
"nonconsecutive arm64 register numbers");
|
||||
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;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//===-- 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
|
|
@ -1,83 +0,0 @@
|
|||
//===-- 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;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//===-- 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
|
|
@ -1,88 +0,0 @@
|
|||
//===-- 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;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//===-- 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
|
|
@ -1,85 +0,0 @@
|
|||
//===-- 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; }
|
|
@ -1,36 +0,0 @@
|
|||
//===-- 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
|
|
@ -1,153 +0,0 @@
|
|||
import bz2
|
||||
import shutil
|
||||
import struct
|
||||
|
||||
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
|
||||
|
||||
def do_test(self, kernel_yaml, vmcore_bz2, bt_expected, regs_expected,
|
||||
hz_value=100):
|
||||
target = self.make_target(kernel_yaml)
|
||||
vmcore_file = self.make_vmcore(vmcore_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 = %d" % hz_value])
|
||||
|
||||
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),
|
||||
struct.pack("<I", hz_value))
|
||||
|
||||
# test backtrace
|
||||
self.assertEqual(
|
||||
[process.GetThreadAtIndex(0).GetFrameAtIndex(i).addr
|
||||
.GetLoadAddress(target) for i in range(len(bt_expected))],
|
||||
bt_expected)
|
||||
|
||||
# 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, regs_expected)
|
||||
|
||||
self.dbg.DeleteTarget(target)
|
||||
|
||||
def test_amd64_full_vmcore(self):
|
||||
self.do_test("kernel-amd64.yaml", "vmcore-amd64-full.bz2",
|
||||
[0xffffffff80c09ade, 0xffffffff80c09916,
|
||||
0xffffffff80c09d90, 0xffffffff80c09b93,
|
||||
0xffffffff80c57d91, 0xffffffff80c19e71,
|
||||
0xffffffff80c192bc, 0xffffffff80c19933,
|
||||
0xffffffff80c1977f, 0xffffffff8108ba8c,
|
||||
0xffffffff810620ce],
|
||||
{"rbx": "0x0000000000000000",
|
||||
"rbp": "0xfffffe0085cb2760",
|
||||
"rsp": "0xfffffe0085cb2748",
|
||||
"r12": "0xfffffe0045a6c300",
|
||||
"r13": "0xfffff800033693a8",
|
||||
"r14": "0x0000000000000000",
|
||||
"r15": "0xfffff80003369380",
|
||||
"rip": "0xffffffff80c09ade",
|
||||
})
|
||||
|
||||
def test_amd64_minidump(self):
|
||||
self.do_test("kernel-amd64.yaml", "vmcore-amd64-minidump.bz2",
|
||||
[0xffffffff80c09ade, 0xffffffff80c09916,
|
||||
0xffffffff80c09d90, 0xffffffff80c09b93,
|
||||
0xffffffff80c57d91, 0xffffffff80c19e71,
|
||||
0xffffffff80c192bc, 0xffffffff80c19933,
|
||||
0xffffffff80c1977f, 0xffffffff8108ba8c,
|
||||
0xffffffff810620ce],
|
||||
{"rbx": "0x0000000000000000",
|
||||
"rbp": "0xfffffe00798c4760",
|
||||
"rsp": "0xfffffe00798c4748",
|
||||
"r12": "0xfffffe0045b11c00",
|
||||
"r13": "0xfffff800033693a8",
|
||||
"r14": "0x0000000000000000",
|
||||
"r15": "0xfffff80003369380",
|
||||
"rip": "0xffffffff80c09ade",
|
||||
})
|
||||
|
||||
def test_arm64_minidump(self):
|
||||
self.do_test("kernel-arm64.yaml", "vmcore-arm64-minidump.bz2",
|
||||
[0xffff0000004b6e78], # TODO: fix unwinding
|
||||
{"x0": "0x0000000000000000",
|
||||
"x1": "0x0000000000000000",
|
||||
"x2": "0x0000000000000000",
|
||||
"x3": "0x0000000000000000",
|
||||
"x4": "0x0000000000000000",
|
||||
"x5": "0x0000000000000000",
|
||||
"x6": "0x0000000000000000",
|
||||
"x7": "0x0000000000000000",
|
||||
"x8": "0xffffa00001548700",
|
||||
"x9": "0x0000000000000000",
|
||||
"x10": "0xffffa00000e04580",
|
||||
"x11": "0x0000000000000000",
|
||||
"x12": "0x000000000008950a",
|
||||
"x13": "0x0000000000089500",
|
||||
"x14": "0x0000000000000039",
|
||||
"x15": "0x0000000000000000",
|
||||
"x16": "0x00000000ffffffd8",
|
||||
"x17": "0x0000000000000000",
|
||||
"x18": "0xffff000000e6d380",
|
||||
"x19": "0xffff000000af9000",
|
||||
"x20": "0xffff000000b82000",
|
||||
"x21": "0xffffa00000319da8",
|
||||
"x22": "0xffff000000b84000",
|
||||
"x23": "0xffff000000b84000",
|
||||
"x24": "0xffff000000b55000",
|
||||
"x25": "0x0000000000000000",
|
||||
"x26": "0x0000000000040800",
|
||||
"x27": "0x0000000000000000",
|
||||
"x28": "0x00000000002019ca",
|
||||
"fp": "0xffff0000d58f23b0",
|
||||
"sp": "0xffff0000d58f23b0",
|
||||
"pc": "0xffff0000004b6e78",
|
||||
},
|
||||
hz_value=1000)
|
||||
|
||||
def test_i386_minidump(self):
|
||||
self.do_test("kernel-i386.yaml", "vmcore-i386-minidump.bz2",
|
||||
[0x010025c5, 0x01002410, 0x010027d5, 0x01002644,
|
||||
0x01049a2f, 0x01011077, 0x01010780, 0x01010c7a,
|
||||
0x01010ab2, 0x013e9e2d, 0xffc033f9],
|
||||
{"ebp": "0x151968e4",
|
||||
"esp": "0x151968d8",
|
||||
"esi": "0x0c77aa80",
|
||||
"edi": "0x03f0dc80",
|
||||
"eip": "0x010025c5",
|
||||
})
|
|
@ -1,38 +0,0 @@
|
|||
--- !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
|
|
@ -1,30 +0,0 @@
|
|||
--- !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
|
|
@ -1,38 +0,0 @@
|
|||
--- !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
|
|
@ -1,36 +0,0 @@
|
|||
How to create vmcores for tests
|
||||
===============================
|
||||
|
||||
1. Boot a FreeBSD VM with as little memory as possible and create a core dump
|
||||
per `FreeBSD Handbook Kernel Debugging Chapter`_. Note that you may need to
|
||||
reboot with more memory after the kernel panic as otherwise savecore(8) may
|
||||
fail.
|
||||
|
||||
For instance, I was able to boot FreeBSD and qemu-system-x86_64 with 128 MiB
|
||||
RAM but had to increase it to 256 MiB for the boot after kernel panic.
|
||||
|
||||
2. Transfer the kernel image (``/boot/kernel/kernel``) and vmcore
|
||||
(``/var/crash/vmcore.latest``) from the VM.
|
||||
|
||||
3. Patch libfbsdvmcore using ``libfbsdvmcore-print-offsets.patch`` and build
|
||||
LLDB against the patched library.
|
||||
|
||||
4. Do a test run of ``test.script`` in LLDB against the kernel + vmcore::
|
||||
|
||||
lldb -b -s test.script --core /path/to/core /path/to/kernel
|
||||
|
||||
If everything works fine, the LLDB output should be interspersed with
|
||||
``%RD`` lines.
|
||||
|
||||
5. Use the ``copy-sparse.py`` tool to create a sparse version of the vmcore::
|
||||
|
||||
lldb -b -s test.script --core /path/to/core /path/to/kernel |
|
||||
grep '^% RD' | python copy-sparse.py /path/to/core vmcore.sparse
|
||||
|
||||
6. Compress the sparse vmcore file using ``bzip2``::
|
||||
|
||||
bzip2 -9 vmcore.sparse
|
||||
|
||||
|
||||
.. _FreeBSD Handbook Kernel Debugging Chapter:
|
||||
https://docs.freebsd.org/en/books/developers-handbook/kerneldebug/
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
argp = argparse.ArgumentParser()
|
||||
argp.add_argument('infile', type=argparse.FileType('rb'),
|
||||
help='Input vmcore file')
|
||||
argp.add_argument('outfile', type=argparse.FileType('wb'),
|
||||
help='Output vmcore file')
|
||||
args = argp.parse_args()
|
||||
|
||||
inf = args.infile
|
||||
outf = args.outfile
|
||||
line_re = re.compile(r"^% RD: (\d+) (\d+)")
|
||||
|
||||
# copy the first chunk that usually includes ELF headers
|
||||
# (not output by patched libfbsdvmcore since libelf reads this)
|
||||
outf.write(inf.read(1024))
|
||||
|
||||
for l in sys.stdin:
|
||||
m = line_re.match(l)
|
||||
offset, size = [int(x) for x in m.groups()]
|
||||
|
||||
inf.seek(offset)
|
||||
outf.seek(offset)
|
||||
outf.write(inf.read(size))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -1,166 +0,0 @@
|
|||
diff --git a/lib/fvc.c b/lib/fvc.c
|
||||
index e6b96c1..4033f78 100644
|
||||
--- a/lib/fvc.c
|
||||
+++ b/lib/fvc.c
|
||||
@@ -297,6 +297,7 @@ fvc_read(fvc_t *kd, fvc_addr_t kva, void *buf, size_t len)
|
||||
_fvc_syserr(kd, kd->program, "fvc_read");
|
||||
break;
|
||||
}
|
||||
+ printf("%% RD: %zu %d\n", pa, cc);
|
||||
/*
|
||||
* If ka_kvatop returns a bogus value or our core file is
|
||||
* truncated, we might wind up seeking beyond the end of the
|
||||
@@ -331,3 +332,8 @@ fvc_kerndisp(fvc_t *kd)
|
||||
|
||||
return (kd->arch->ka_kerndisp(kd));
|
||||
}
|
||||
+
|
||||
+ssize_t xpread(int fd, void *buf, size_t count, off_t offset) {
|
||||
+ printf("%% RD: %zu %zu\n", offset, count);
|
||||
+ return pread(fd, buf, count, offset);
|
||||
+}
|
||||
diff --git a/lib/fvc.h b/lib/fvc.h
|
||||
index 8680079..ff1e0f0 100644
|
||||
--- a/lib/fvc.h
|
||||
+++ b/lib/fvc.h
|
||||
@@ -54,6 +54,8 @@ typedef unsigned char fvc_vm_prot_t;
|
||||
#define FVC_VM_PROT_WRITE ((fvc_vm_prot_t) 0x02)
|
||||
#define FVC_VM_PROT_EXECUTE ((fvc_vm_prot_t) 0x04)
|
||||
|
||||
+ssize_t xpread(int fd, void *buf, size_t count, off_t offset);
|
||||
+
|
||||
struct fvc_page {
|
||||
unsigned int kp_version;
|
||||
fvc_addr_t kp_paddr;
|
||||
diff --git a/lib/fvc_amd64.c b/lib/fvc_amd64.c
|
||||
index 4d27998..69f1807 100644
|
||||
--- a/lib/fvc_amd64.c
|
||||
+++ b/lib/fvc_amd64.c
|
||||
@@ -205,7 +205,7 @@ _amd64_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
|
||||
_fvc_err(kd, kd->program, "_amd64_vatop: pdpe_pa not found");
|
||||
goto invalid;
|
||||
}
|
||||
- if (pread(kd->pmfd, &pdpe, sizeof(pdpe), ofs) != sizeof(pdpe)) {
|
||||
+ if (xpread(kd->pmfd, &pdpe, sizeof(pdpe), ofs) != sizeof(pdpe)) {
|
||||
_fvc_syserr(kd, kd->program, "_amd64_vatop: read pdpe");
|
||||
goto invalid;
|
||||
}
|
||||
@@ -237,7 +237,7 @@ _amd64_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
|
||||
_fvc_syserr(kd, kd->program, "_amd64_vatop: pde_pa not found");
|
||||
goto invalid;
|
||||
}
|
||||
- if (pread(kd->pmfd, &pde, sizeof(pde), ofs) != sizeof(pde)) {
|
||||
+ if (xpread(kd->pmfd, &pde, sizeof(pde), ofs) != sizeof(pde)) {
|
||||
_fvc_syserr(kd, kd->program, "_amd64_vatop: read pde");
|
||||
goto invalid;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ _amd64_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
|
||||
_fvc_err(kd, kd->program, "_amd64_vatop: pte_pa not found");
|
||||
goto invalid;
|
||||
}
|
||||
- if (pread(kd->pmfd, &pte, sizeof(pte), ofs) != sizeof(pte)) {
|
||||
+ if (xpread(kd->pmfd, &pte, sizeof(pte), ofs) != sizeof(pte)) {
|
||||
_fvc_syserr(kd, kd->program, "_amd64_vatop: read");
|
||||
goto invalid;
|
||||
}
|
||||
diff --git a/lib/fvc_minidump_aarch64.c b/lib/fvc_minidump_aarch64.c
|
||||
index 4b8477a..a1c5b42 100644
|
||||
--- a/lib/fvc_minidump_aarch64.c
|
||||
+++ b/lib/fvc_minidump_aarch64.c
|
||||
@@ -86,7 +86,7 @@ _aarch64_minidump_initvtop(fvc_t *kd)
|
||||
return (-1);
|
||||
}
|
||||
kd->vmst = vmst;
|
||||
- if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
|
||||
+ if (xpread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
|
||||
sizeof(vmst->hdr)) {
|
||||
_fvc_err(kd, kd->program, "cannot read dump header");
|
||||
return (-1);
|
||||
diff --git a/lib/fvc_minidump_amd64.c b/lib/fvc_minidump_amd64.c
|
||||
index 93e8238..0d2237f 100644
|
||||
--- a/lib/fvc_minidump_amd64.c
|
||||
+++ b/lib/fvc_minidump_amd64.c
|
||||
@@ -126,7 +126,7 @@ _amd64_minidump_initvtop(fvc_t *kd)
|
||||
return (-1);
|
||||
}
|
||||
kd->vmst = vmst;
|
||||
- if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
|
||||
+ if (xpread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
|
||||
sizeof(vmst->hdr)) {
|
||||
_fvc_err(kd, kd->program, "cannot read dump header");
|
||||
return (-1);
|
||||
@@ -269,7 +269,7 @@ _amd64_minidump_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
|
||||
(uintmax_t)a);
|
||||
goto invalid;
|
||||
}
|
||||
- if (pread(kd->pmfd, &pt, AMD64_PAGE_SIZE, ofs) !=
|
||||
+ if (xpread(kd->pmfd, &pt, AMD64_PAGE_SIZE, ofs) !=
|
||||
AMD64_PAGE_SIZE) {
|
||||
_fvc_err(kd, kd->program,
|
||||
"cannot read page table entry for %ju",
|
||||
diff --git a/lib/fvc_minidump_i386.c b/lib/fvc_minidump_i386.c
|
||||
index 61cc3db..b3ab955 100644
|
||||
--- a/lib/fvc_minidump_i386.c
|
||||
+++ b/lib/fvc_minidump_i386.c
|
||||
@@ -94,7 +94,7 @@ _i386_minidump_initvtop(fvc_t *kd)
|
||||
return (-1);
|
||||
}
|
||||
kd->vmst = vmst;
|
||||
- if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
|
||||
+ if (xpread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
|
||||
sizeof(vmst->hdr)) {
|
||||
_fvc_err(kd, kd->program, "cannot read dump header");
|
||||
return (-1);
|
||||
diff --git a/lib/fvc_private.c b/lib/fvc_private.c
|
||||
index 0069a54..fc798fe 100644
|
||||
--- a/lib/fvc_private.c
|
||||
+++ b/lib/fvc_private.c
|
||||
@@ -130,7 +130,7 @@ _fvc_is_minidump(fvc_t *kd)
|
||||
{
|
||||
char minihdr[8];
|
||||
|
||||
- if (pread(kd->pmfd, &minihdr, 8, 0) == 8 &&
|
||||
+ if (xpread(kd->pmfd, &minihdr, 8, 0) == 8 &&
|
||||
memcmp(&minihdr, "minidump", 8) == 0)
|
||||
return (1);
|
||||
return (0);
|
||||
@@ -256,6 +256,7 @@ _fvc_pmap_get(fvc_t *kd, u_long idx, size_t len)
|
||||
|
||||
if ((off_t)off >= kd->pt_sparse_off)
|
||||
return (NULL);
|
||||
+ printf("%% RD: %zu %zu\n", kd->page_map_off+off, len);
|
||||
return (void *)((uintptr_t)kd->page_map + off);
|
||||
}
|
||||
|
||||
@@ -270,8 +271,13 @@ _fvc_map_get(fvc_t *kd, u_long pa, unsigned int page_size)
|
||||
return NULL;
|
||||
|
||||
addr = (uintptr_t)kd->page_map + off;
|
||||
- if (off >= kd->pt_sparse_off)
|
||||
+ if (off >= kd->pt_sparse_off) {
|
||||
+
|
||||
addr = (uintptr_t)kd->sparse_map + (off - kd->pt_sparse_off);
|
||||
+ printf("%% RD: %zu %u\n", off, page_size);
|
||||
+ }
|
||||
+ else
|
||||
+ printf("%% RD: %zu %u\n", kd->page_map_off+off, page_size);
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
@@ -289,6 +295,7 @@ _fvc_pt_init(fvc_t *kd, size_t dump_avail_size, off_t dump_avail_off,
|
||||
if (dump_avail_size > 0) {
|
||||
kd->dump_avail = mmap(NULL, kd->dump_avail_size, PROT_READ,
|
||||
MAP_PRIVATE, kd->pmfd, dump_avail_off);
|
||||
+ printf("%% RD: %zu %zu\n", dump_avail_off, dump_avail_size);
|
||||
} else {
|
||||
/*
|
||||
* Older version minidumps don't provide dump_avail[],
|
||||
@@ -309,7 +316,7 @@ _fvc_pt_init(fvc_t *kd, size_t dump_avail_size, off_t dump_avail_off,
|
||||
map_len);
|
||||
return (-1);
|
||||
}
|
||||
- rd = pread(kd->pmfd, kd->pt_map, map_len, map_off);
|
||||
+ rd = xpread(kd->pmfd, kd->pt_map, map_len, map_off);
|
||||
if (rd < 0 || rd != (ssize_t)map_len) {
|
||||
_fvc_err(kd, kd->program, "cannot read %zu bytes for bitmap",
|
||||
map_len);
|
|
@ -1,5 +0,0 @@
|
|||
thread list
|
||||
register read pc
|
||||
bt
|
||||
p *(int*)&hz
|
||||
memory read &hz
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue