1 Star 0 Fork 15

SEmmmer/lldb

forked from src-openEuler/lldb 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0004-apply-patch-for-ABISysV.patch 16.00 KB
一键复制 编辑 原始数据 按行查看 历史
SEmmmer 提交于 2022-05-26 00:09 +08:00 . initial riscv64 support
From 2b6263505b796be99113a97eeaa46a697e4236e1 Mon Sep 17 00:00:00 2001
From: SEmmmer <yjhdandan@163.com>
Date: Thu, 9 Jun 2022 22:13:10 +0800
Subject: [PATCH 2/4] apply patch for ABISysV
---
lldb/include/lldb/Utility/ArchSpec.h | 7 +
lldb/source/Plugins/ABI/CMakeLists.txt | 2 +-
.../Plugins/ABI/RISCV/ABISysV_riscv.cpp | 243 ++++++++++++++++++
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h | 119 +++++++++
lldb/source/Plugins/ABI/RISCV/CMakeLists.txt | 10 +
.../Disassembler/LLVMC/DisassemblerLLVMC.cpp | 5 +
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 12 +
lldb/source/Target/Platform.cpp | 14 +
8 files changed, 411 insertions(+), 1 deletion(-)
create mode 100644 lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
create mode 100644 lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
create mode 100644 lldb/source/Plugins/ABI/RISCV/CMakeLists.txt
diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h
index fdfe6ac..b52f3a9 100644
--- a/lldb/include/lldb/Utility/ArchSpec.h
+++ b/lldb/include/lldb/Utility/ArchSpec.h
@@ -98,6 +98,13 @@ public:
eRISCVSubType_riscv64,
};
+ /// RISC-V specific flags
+ enum RISCVflags {
+ eRISCV_arch_c = 0x00000001, /// ISA C extension (compressed instructions)
+ eRISCV_abi_f = 0x00000010, /// Single-precision hard-float ABI
+ eRISCV_abi_d = 0x00000020 /// Double-precision hard-float ABI
+ };
+
enum Core {
eCore_arm_generic,
eCore_arm_armv4,
diff --git a/lldb/source/Plugins/ABI/CMakeLists.txt b/lldb/source/Plugins/ABI/CMakeLists.txt
index d7cc39b..7589303 100644
--- a/lldb/source/Plugins/ABI/CMakeLists.txt
+++ b/lldb/source/Plugins/ABI/CMakeLists.txt
@@ -1,4 +1,4 @@
-foreach(target AArch64 ARM ARC Hexagon Mips PowerPC SystemZ X86)
+foreach(target AArch64 ARM ARC Hexagon Mips PowerPC RISCV SystemZ X86)
if (${target} IN_LIST LLVM_TARGETS_TO_BUILD)
add_subdirectory(${target})
endif()
diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
new file mode 100644
index 0000000..601b61a
--- /dev/null
+++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
@@ -0,0 +1,243 @@
+//===-- ABISysV_riscv.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 "ABISysV_riscv.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Core/ValueObjectRegister.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE(ABISysV_riscv)
+
+enum riscv_dwarf_regnums {
+ dwarf_x0 = 0,
+ dwarf_x1,
+ dwarf_x2,
+ dwarf_x3,
+ dwarf_x4,
+ dwarf_x5,
+ dwarf_x6,
+ dwarf_x7,
+ dwarf_x8,
+ dwarf_x9,
+ dwarf_x10,
+ dwarf_x11,
+ dwarf_x12,
+ dwarf_x13,
+ dwarf_x14,
+ dwarf_x15,
+ dwarf_x16,
+ dwarf_x17,
+ dwarf_x18,
+ dwarf_x19,
+ dwarf_x20,
+ dwarf_x21,
+ dwarf_x22,
+ dwarf_x23,
+ dwarf_x24,
+ dwarf_x25,
+ dwarf_x26,
+ dwarf_x27,
+ dwarf_x28,
+ dwarf_x29,
+ dwarf_x30,
+ dwarf_x31,
+ dwarf_f0 = 32,
+ dwarf_f1,
+ dwarf_f2,
+ dwarf_f3,
+ dwarf_f4,
+ dwarf_f5,
+ dwarf_f6,
+ dwarf_f7,
+ dwarf_f8,
+ dwarf_f9,
+ dwarf_f10,
+ dwarf_f11,
+ dwarf_f12,
+ dwarf_f13,
+ dwarf_f14,
+ dwarf_f15,
+ dwarf_f16,
+ dwarf_f17,
+ dwarf_f18,
+ dwarf_f19,
+ dwarf_f20,
+ dwarf_f21,
+ dwarf_f22,
+ dwarf_f23,
+ dwarf_f24,
+ dwarf_f25,
+ dwarf_f26,
+ dwarf_f27,
+ dwarf_f28,
+ dwarf_f29,
+ dwarf_f30,
+ dwarf_f31
+};
+
+bool ABISysV_riscv::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindGeneric);
+
+ uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ uint32_t ra_reg_num = LLDB_REGNUM_GENERIC_RA;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Define CFA as the stack pointer
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+
+ // Previous frames pc is in ra
+ row->SetRegisterLocationToRegister(pc_reg_num, ra_reg_num, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("riscv function-entry unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ return true;
+}
+
+bool ABISysV_riscv::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ unwind_plan.SetRegisterKind(eRegisterKindGeneric);
+
+ uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
+ uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
+ uint32_t ra_reg_num = LLDB_REGNUM_GENERIC_RA;
+
+ UnwindPlan::RowSP row(new UnwindPlan::Row);
+
+ // Define the CFA as the current stack pointer.
+ row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
+ row->SetOffset(0);
+
+ // The previous frames pc is stored in ra.
+ row->SetRegisterLocationToRegister(pc_reg_num, ra_reg_num, true);
+
+ unwind_plan.AppendRow(row);
+ unwind_plan.SetSourceName("riscv default unwind plan");
+ unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ return true;
+}
+
+bool ABISysV_riscv::RegisterIsVolatile(
+ const lldb_private::RegisterInfo *reg_info) {
+ return !RegisterIsCalleeSaved(reg_info);
+}
+
+// See "Register Convention" in the RISC-V psABI documentation, which is
+// maintained at https://github.com/riscv/riscv-elf-psabi-doc
+bool ABISysV_riscv::RegisterIsCalleeSaved(
+ const lldb_private::RegisterInfo *reg_info) {
+ if (!reg_info)
+ return false;
+
+ bool IsCalleeSaved =
+ llvm::StringSwitch<bool>(reg_info->name)
+ .Cases("x1", "x2", "x8", "x9", "x18", "x19", "x20", "x21", true)
+ .Cases("x22", "x23", "x24", "x25", "x26", "x27", true)
+ .Cases("f8", "f9", "f18", "f19", "f20", "f21", IsHardFloatProcess())
+ .Cases("f22", "f23", "f24", "f25", "f26", "f27", IsHardFloatProcess())
+ .Default(false);
+ return IsCalleeSaved;
+}
+
+std::pair<uint32_t, uint32_t>
+ABISysV_riscv::GetEHAndDWARFNums(llvm::StringRef name) {
+ if (name == "ra")
+ return {LLDB_INVALID_REGNUM, riscv_dwarf_regnums::dwarf_x1};
+ if (name == "sp")
+ return {LLDB_INVALID_REGNUM, riscv_dwarf_regnums::dwarf_x2};
+ if (name == "fp")
+ return {LLDB_INVALID_REGNUM, riscv_dwarf_regnums::dwarf_x8};
+ return MCBasedABI::GetEHAndDWARFNums(name);
+}
+
+uint32_t ABISysV_riscv::GetGenericNum(llvm::StringRef name) {
+ return llvm::StringSwitch<uint32_t>(name)
+ .Case("pc", LLDB_REGNUM_GENERIC_PC)
+ .Case("ra", LLDB_REGNUM_GENERIC_RA)
+ .Case("sp", LLDB_REGNUM_GENERIC_SP)
+ .Case("fp", LLDB_REGNUM_GENERIC_FP)
+ .Case("a0", LLDB_REGNUM_GENERIC_ARG1)
+ .Case("a1", LLDB_REGNUM_GENERIC_ARG2)
+ .Case("a2", LLDB_REGNUM_GENERIC_ARG3)
+ .Case("a3", LLDB_REGNUM_GENERIC_ARG4)
+ .Case("a4", LLDB_REGNUM_GENERIC_ARG5)
+ .Case("a5", LLDB_REGNUM_GENERIC_ARG6)
+ .Case("a6", LLDB_REGNUM_GENERIC_ARG7)
+ .Case("a7", LLDB_REGNUM_GENERIC_ARG8)
+ .Default(LLDB_INVALID_REGNUM);
+}
+
+bool ABISysV_riscv::IsHardFloatProcess() const {
+ bool is_hardfloat = false;
+ ProcessSP process_sp(GetProcessSP());
+ if (process_sp) {
+ const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
+ if (arch.GetFlags() & ArchSpec::eRISCV_abi_f ||
+ arch.GetFlags() & ArchSpec::eRISCV_abi_d)
+ is_hardfloat = true;
+ }
+ return is_hardfloat;
+}
+
+ABISP
+ABISysV_riscv::CreateInstance(lldb::ProcessSP process_sp,
+ const ArchSpec &arch) {
+ if (arch.GetTriple().getArch() == llvm::Triple::riscv32 ||
+ arch.GetTriple().getArch() == llvm::Triple::riscv64) {
+ return ABISP(
+ new ABISysV_riscv(std::move(process_sp), MakeMCRegisterInfo(arch),
+ arch.GetTriple().getArch() == llvm::Triple::riscv64));
+ }
+ return ABISP();
+}
+
+void ABISysV_riscv::Initialize() {
+ PluginManager::RegisterPlugin(
+ GetPluginNameStatic(), "System V ABI for riscv targets", CreateInstance);
+}
+
+void ABISysV_riscv::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+// PluginInterface protocol
+
+lldb_private::ConstString ABISysV_riscv::GetPluginNameStatic() {
+ static ConstString g_name("sysv-riscv");
+ return g_name;
+}
+
+lldb_private::ConstString ABISysV_riscv::GetPluginName() {
+ return GetPluginNameStatic();
+}
diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
new file mode 100644
index 0000000..6136851
--- /dev/null
+++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.h
@@ -0,0 +1,119 @@
+//===-- ABISysV_riscv.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 liblldb_ABISysV_riscv_h_
+#define liblldb_ABISysV_riscv_h_
+
+#include "lldb/Target/ABI.h"
+#include "lldb/lldb-private.h"
+
+class ABISysV_riscv : public lldb_private::MCBasedABI {
+ bool isRV64;
+
+public:
+ ~ABISysV_riscv() override = default;
+
+ size_t GetRedZoneSize() const override { return 0; }
+
+ bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp,
+ lldb::addr_t functionAddress,
+ lldb::addr_t returnAddress,
+ llvm::ArrayRef<lldb::addr_t> args) const override {
+ // TODO: Implement
+ return false;
+ }
+
+ bool GetArgumentValues(lldb_private::Thread &thread,
+ lldb_private::ValueList &values) const override {
+ // TODO: Implement
+ return false;
+ }
+
+ lldb_private::Status
+ SetReturnValueObject(lldb::StackFrameSP &frame_sp,
+ lldb::ValueObjectSP &new_value) override {
+ // TODO: Implement
+ lldb_private::Status error;
+ error.SetErrorString("Not yet implemented");
+ return error;
+ }
+
+ lldb::ValueObjectSP
+ GetReturnValueObjectImpl(lldb_private::Thread &thread,
+ lldb_private::CompilerType &type) const override {
+ // TODO: Implement
+ lldb::ValueObjectSP return_valobj;
+ return return_valobj;
+ }
+
+ bool
+ CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override;
+
+ bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override;
+
+ bool CallFrameAddressIsValid(lldb::addr_t cfa) override {
+ // Assume any address except zero is valid
+ if (cfa == 0)
+ return false;
+ return true;
+ }
+
+ bool CodeAddressIsValid(lldb::addr_t pc) override {
+ // Ensure addresses are smaller than XLEN bits wide. Calls can use the least
+ // significant bit to store auxiliary information, so no strict check is
+ // done for alignment.
+ if (!isRV64)
+ return (pc <= UINT32_MAX);
+ return (pc <= UINT64_MAX);
+ }
+
+ lldb::addr_t FixCodeAddress(lldb::addr_t pc) override {
+ // Since the least significant bit of a code address can be used to store
+ // auxiliary information, that bit must be zeroed in any addresses.
+ return pc & ~(lldb::addr_t)1;
+ }
+
+ // Static Functions
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp,
+ const lldb_private::ArchSpec &arch);
+
+ // PluginInterface protocol
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ lldb_private::ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+protected:
+ bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info);
+
+ std::pair<uint32_t, uint32_t>
+ GetEHAndDWARFNums(llvm::StringRef name) override;
+
+ uint32_t GetGenericNum(llvm::StringRef reg) override;
+
+ bool IsHardFloatProcess() const;
+
+private:
+ ABISysV_riscv(lldb::ProcessSP process_sp,
+ std::unique_ptr<llvm::MCRegisterInfo> info_up, bool _isRV64)
+ : lldb_private::MCBasedABI(std::move(process_sp), std::move(info_up)),
+ isRV64(_isRV64) {
+ // Call CreateInstance instead.
+ }
+};
+
+#endif // liblldb_ABISysV_riscv_h_
diff --git a/lldb/source/Plugins/ABI/RISCV/CMakeLists.txt b/lldb/source/Plugins/ABI/RISCV/CMakeLists.txt
new file mode 100644
index 0000000..c60608c
--- /dev/null
+++ b/lldb/source/Plugins/ABI/RISCV/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_lldb_library(lldbPluginABISysV_riscv PLUGIN
+ ABISysV_riscv.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbTarget
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
index 8a2d323..40f004b 100644
--- a/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
+++ b/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
@@ -1146,6 +1146,11 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
cpu = "apple-latest";
}
+ // For RISC-V, enable all standard extensions so these can be disassembled.
+ if (triple.getArch() == llvm::Triple::riscv32 ||
+ triple.getArch() == llvm::Triple::riscv64)
+ features_str += "+a,+c,+d,+f,+m";
+
// We use m_disasm_up.get() to tell whether we are valid or not, so if this
// isn't good for some reason, we won't be valid and FindPlugin will fail and
// we won't get used.
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index cad9ce2..15ed776 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1376,6 +1376,18 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
}
+ if (arch_spec.GetMachine() == llvm::Triple::riscv32 ||
+ arch_spec.GetMachine() == llvm::Triple::riscv64) {
+ if (header.e_flags & llvm::ELF::EF_RISCV_RVC)
+ arch_spec.SetFlags(ArchSpec::eRISCV_arch_c);
+ if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI) ==
+ llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)
+ arch_spec.SetFlags(ArchSpec::eRISCV_abi_f);
+ if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI) ==
+ llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)
+ arch_spec.SetFlags(ArchSpec::eRISCV_abi_d);
+ }
+
// If there are no section headers we are done.
if (header.e_shnum == 0)
return 0;
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index a77ecdd..3a4f0c3 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -1970,6 +1970,20 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target,
trap_opcode_size = sizeof(g_i386_opcode);
} break;
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64: {
+ static const uint8_t g_riscv_c_opcode[] = {0x02, 0x90}; // c_ebreak
+ static const uint8_t g_riscv_opcode[] = {0x73, 0x00, 0x10, 0x00}; // ebreak
+ if (arch.GetFlags() & ArchSpec::eRISCV_arch_c) {
+ trap_opcode = g_riscv_c_opcode;
+ trap_opcode_size = sizeof(g_riscv_c_opcode);
+ } else {
+ trap_opcode = g_riscv_opcode;
+ trap_opcode_size = sizeof(g_riscv_opcode);
+ }
+ break;
+ }
+
default:
return 0;
}
--
2.30.2
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/emmmer/lldb.git
git@gitee.com:emmmer/lldb.git
emmmer
lldb
lldb
master

搜索帮助