tatyana-krasnukha created this revision.
tatyana-krasnukha added reviewers: clayborg, jasonmolenda.
tatyana-krasnukha added a project: LLDB.
Herald added subscribers: lldb-commits, mgorny.
Add ARC architecture (bare-metal) that can be debugged through an RSP-server.
Repository:
rLLDB LLDB
https://reviews.llvm.org/D55718
Files:
include/lldb/Core/Architecture.h
include/lldb/Utility/ArchSpec.h
source/API/SystemInitializerFull.cpp
source/Plugins/Architecture/Arc/ArchitectureArc.cpp
source/Plugins/Architecture/Arc/ArchitectureArc.h
source/Plugins/Architecture/Arc/CMakeLists.txt
source/Plugins/Architecture/CMakeLists.txt
source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
source/Target/Platform.cpp
source/Target/Target.cpp
source/Target/Thread.cpp
source/Utility/ArchSpec.cpp
Index: source/Utility/ArchSpec.cpp
===================================================================
--- source/Utility/ArchSpec.cpp
+++ source/Utility/ArchSpec.cpp
@@ -221,7 +221,8 @@
{eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba4,
"kalimba4"},
{eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba5,
- "kalimba5"}};
+ "kalimba5"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"}};
// Ensure that we have an entry in the g_core_definitions for each core. If you
// comment out an entry above, you will need to comment out the corresponding
@@ -458,7 +459,9 @@
{ArchSpec::eCore_kalimba4, llvm::ELF::EM_CSR_KALIMBA,
llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu}, // KALIMBA
{ArchSpec::eCore_kalimba5, llvm::ELF::EM_CSR_KALIMBA,
- llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu} // KALIMBA
+ llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu}, // KALIMBA
+ {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu } // ARC
};
static const ArchDefinition g_elf_arch_def = {
Index: source/Target/Thread.cpp
===================================================================
--- source/Target/Thread.cpp
+++ source/Target/Thread.cpp
@@ -2058,6 +2058,7 @@
switch (machine) {
case llvm::Triple::x86_64:
case llvm::Triple::x86:
+ case llvm::Triple::arc:
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::thumb:
Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -67,11 +67,11 @@
Target::Arch::Arch(const ArchSpec &spec)
: m_spec(spec),
- m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}
+ m_plugin_up(PluginManager::CreateArchitectureInstance(m_spec)) {}
const Target::Arch& Target::Arch::operator=(const ArchSpec &spec) {
m_spec = spec;
- m_plugin_up = PluginManager::CreateArchitectureInstance(spec);
+ m_plugin_up = PluginManager::CreateArchitectureInstance(m_spec);
return *this;
}
@@ -1527,7 +1527,7 @@
os_changed, os_ver_changed, env_changed);
if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
- replace_local_arch = false;
+ replace_local_arch = arch_spec.GetFlags() != m_arch.GetSpec().GetFlags();
}
}
}
Index: source/Target/Platform.cpp
===================================================================
--- source/Target/Platform.cpp
+++ source/Target/Platform.cpp
@@ -1869,6 +1869,12 @@
size_t trap_opcode_size = 0;
switch (arch.GetMachine()) {
+ case llvm::Triple::arc: {
+ static const uint8_t g_hex_opcode[] = { 0xff, 0x7f };
+ trap_opcode = g_hex_opcode;
+ trap_opcode_size = sizeof(g_hex_opcode);
+ } break;
+
case llvm::Triple::aarch64: {
static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
trap_opcode = g_aarch64_opcode;
Index: source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
===================================================================
--- source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -622,6 +622,55 @@
}
break;
+ case llvm::Triple::arc:
+ {
+ for (auto ® : m_regs) {
+ if (strcmp(reg.name, "pc") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ else if ((strcmp(reg.name, "fp") == 0) ||
+ (strcmp(reg.name, "r27") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+ else if ((strcmp(reg.name, "sp") == 0) ||
+ (strcmp(reg.name, "r28") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+ else if ((strcmp(reg.name, "blink") == 0) ||
+ (strcmp(reg.name, "r31") == 0))
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+ else if (strcmp(reg.name, "status32") == 0)
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+
+ switch (reg.kinds[eRegisterKindDWARF]) {
+ case 0:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG1;
+ break;
+ case 1:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG2;
+ break;
+ case 2:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG3;
+ break;
+ case 3:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG4;
+ break;
+ case 4:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG5;
+ break;
+ case 5:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG6;
+ break;
+ case 6:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG7;
+ break;
+ case 7:
+ reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG8;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+
default:
break;
}
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -4523,6 +4523,38 @@
return true;
}
+bool ConfigureArchitecture(ProcessGDBRemote &process,
+ const GDBRemoteDynamicRegisterInfo &dyn_reg_info,
+ ArchSpec& arch_to_use) {
+ static llvm::StringRef reg_name("rf_build");
+ const RegisterInfo *rf_build_info = nullptr;
+
+ const auto reg_count = dyn_reg_info.GetNumRegisters();
+ // At least 16 first registers are not BCRs.
+ decltype(reg_count) skip_gpr = 16u;
+ for (auto reg_num = skip_gpr; reg_num < reg_count; ++reg_num) {
+ const auto reg_info = dyn_reg_info.GetRegisterInfoAtIndex(reg_num);
+ if (reg_name.equals_lower(reg_info->name)) {
+ rf_build_info = reg_info;
+ break;
+ }
+ }
+
+ if(nullptr == rf_build_info)
+ return false;
+
+ const auto tid = LLDB_INVALID_THREAD_ID; // BCRs are not context-dependent.
+ // Cannot use GDBRemoteRegisterContext here, it is not created yet.
+ DataBufferSP buffer_sp = process.GetGDBRemote().ReadRegister(tid,
+ rf_build_info->kinds[eRegisterKindProcessPlugin]);
+ if (!buffer_sp || buffer_sp->GetByteSize() < rf_build_info->byte_size)
+ return false;
+
+ if (0 != (buffer_sp->GetData()[1] & ArchSpec::eARC_rf16))
+ arch_to_use.SetFlags(ArchSpec::eARC_rf16);
+ return true;
+}
+
} // namespace
// query the target of gdb-remote for extended target information return:
@@ -4646,7 +4678,18 @@
this->m_register_info, abi_to_use_sp, cur_reg_num,
reg_offset);
}
+ }
+
+ if (llvm::Triple::arc == arch_to_use.GetMachine()) {
+ if (!ConfigureArchitecture(*this, m_register_info, arch_to_use))
+ return false;
+ GetTarget().SetArchitecture(arch_to_use);
}
+
+ auto arch_plugin = GetTarget().GetArchitecturePlugin();
+ if (arch_plugin)
+ arch_plugin->AdjustRegisterInfo(m_register_info);
+
this->m_register_info.Finalize(arch_to_use);
}
}
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -350,7 +350,7 @@
// not, we assume no limit
// build the qSupported packet
- std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
+ std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
StreamString packet;
packet.PutCString("qSupported");
for (uint32_t i = 0; i < features.size(); ++i) {
Index: source/Plugins/Architecture/CMakeLists.txt
===================================================================
--- source/Plugins/Architecture/CMakeLists.txt
+++ source/Plugins/Architecture/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(Arc)
add_subdirectory(Arm)
add_subdirectory(Mips)
add_subdirectory(PPC64)
Index: source/Plugins/Architecture/Arc/CMakeLists.txt
===================================================================
--- source/Plugins/Architecture/Arc/CMakeLists.txt
+++ source/Plugins/Architecture/Arc/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_lldb_library(lldbPluginArchitectureArc PLUGIN
+ ArchitectureArc.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbTarget
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+ )
Index: source/Plugins/Architecture/Arc/ArchitectureArc.h
===================================================================
--- source/Plugins/Architecture/Arc/ArchitectureArc.h
+++ source/Plugins/Architecture/Arc/ArchitectureArc.h
@@ -0,0 +1,47 @@
+//===-- ArchitectureArc.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGIN_ARCHITECTURE_ARC_H
+#define LLDB_PLUGIN_ARCHITECTURE_ARC_H
+
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitectureArc : public Architecture {
+public:
+ static ConstString GetPluginNameStatic();
+ static void Initialize();
+ static void Terminate();
+
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ void OverrideStopInfo(Thread &thread) const override {}
+
+ lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr,
+ Target &) const override;
+
+ lldb::addr_t GetCallableLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class) const override;
+
+ lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class) const override;
+
+ void AdjustRegisterInfo(DynamicRegisterInfo ®_info) const override;
+
+private:
+ static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+ ArchitectureArc(const ArchSpec &arch);
+ const ArchSpec &m_arch;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGIN_ARCHITECTURE_ARC_H
Index: source/Plugins/Architecture/Arc/ArchitectureArc.cpp
===================================================================
--- source/Plugins/Architecture/Arc/ArchitectureArc.cpp
+++ source/Plugins/Architecture/Arc/ArchitectureArc.cpp
@@ -0,0 +1,93 @@
+//===-- ArchitectureArc.cpp -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Architecture/Arc/ArchitectureArc.h"
+#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/ArchSpec.h"
+
+#include "llvm/Support/MathExtras.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+ConstString ArchitectureArc::GetPluginNameStatic() {
+ return ConstString("arc");
+}
+
+void ArchitectureArc::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "ARC-specific algorithms",
+ &ArchitectureArc::Create);
+}
+
+void ArchitectureArc::Terminate() {
+ PluginManager::UnregisterPlugin(&ArchitectureArc::Create);
+}
+
+std::unique_ptr<Architecture> ArchitectureArc::Create(const ArchSpec &arch) {
+ if (arch.GetMachine() != llvm::Triple::arc)
+ return nullptr;
+ return std::unique_ptr<Architecture>(new ArchitectureArc(arch));
+}
+
+ArchitectureArc::ArchitectureArc(const ArchSpec &arch)
+ : m_arch(arch) {}
+
+ConstString ArchitectureArc::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t ArchitectureArc::GetPluginVersion() { return 1; }
+
+addr_t ArchitectureArc::GetCallableLoadAddress(addr_t code_addr,
+ AddressClass addr_class) const {
+ switch (addr_class) {
+ case AddressClass::eData:
+ case AddressClass::eDebug:
+ return LLDB_INVALID_ADDRESS;
+ default: break;
+ }
+
+ return llvm::alignDown(code_addr, m_arch.GetAddressByteSize());
+}
+
+addr_t ArchitectureArc::GetOpcodeLoadAddress(addr_t opcode_addr,
+ AddressClass addr_class) const {
+ switch (addr_class) {
+ case AddressClass::eData:
+ case AddressClass::eDebug:
+ return LLDB_INVALID_ADDRESS;
+ default: break;
+ }
+
+ return llvm::alignDown(opcode_addr, m_arch.GetMinimumOpcodeByteSize());
+}
+
+lldb::addr_t ArchitectureArc::GetBreakableLoadAddress(lldb::addr_t addr,
+ Target &) const {
+ // TODO: handle instructions with delay-slots as Mips does.
+ return GetOpcodeLoadAddress(addr, AddressClass::eUnknown);
+}
+
+void ArchitectureArc::AdjustRegisterInfo(DynamicRegisterInfo ®_info) const {
+ auto reg_count = reg_info.GetNumRegisters();
+ decltype(reg_count) dwarf_index = 0;
+ for (decltype(reg_count) i = 0; i < reg_count; ++i) {
+ auto ® = *reg_info.GetRegisterInfoAtIndex(i);
+ auto ®_num = reg.kinds[eRegisterKindDWARF];
+ if (LLDB_INVALID_REGNUM == reg_num) {
+ if (ArchSpec::eARC_rf16 & m_arch.GetFlags()) {
+ if (4 == dwarf_index)
+ dwarf_index += 6;
+ if (16 == dwarf_index)
+ dwarf_index += 10;
+ }
+ reg_num = dwarf_index;
+ }
+ ++dwarf_index;
+ }
+}
Index: source/API/SystemInitializerFull.cpp
===================================================================
--- source/API/SystemInitializerFull.cpp
+++ source/API/SystemInitializerFull.cpp
@@ -39,6 +39,7 @@
#include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
#include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
+#include "Plugins/Architecture/Arc/ArchitectureArc.h"
#include "Plugins/Architecture/Arm/ArchitectureArm.h"
#include "Plugins/Architecture/Mips/ArchitectureMips.h"
#include "Plugins/Architecture/PPC64/ArchitecturePPC64.h"
@@ -326,6 +327,7 @@
ABISysV_mips64::Initialize();
ABISysV_s390x::Initialize();
+ ArchitectureArc::Initialize();
ArchitectureArm::Initialize();
ArchitectureMips::Initialize();
ArchitecturePPC64::Initialize();
@@ -442,6 +444,7 @@
ClangASTContext::Terminate();
+ ArchitectureArc::Terminate();
ArchitectureArm::Terminate();
ArchitectureMips::Terminate();
ArchitecturePPC64::Terminate();
Index: include/lldb/Utility/ArchSpec.h
===================================================================
--- include/lldb/Utility/ArchSpec.h
+++ include/lldb/Utility/ArchSpec.h
@@ -88,6 +88,9 @@
eMIPS_ABI_FP_mask = 0x00700000
};
+ // ARC configuration flags
+ enum ARCflags { eARC_rf32 = 0 /*0b00*/, eARC_rf16 = 2 /*0b10*/ };
+
// ARM specific e_flags
enum ARMeflags {
eARM_abi_soft_float = 0x00000200,
@@ -190,6 +193,8 @@
eCore_kalimba4,
eCore_kalimba5,
+ eCore_arc, // little endian ARC
+
kNumCores,
kCore_invalid,
Index: include/lldb/Core/Architecture.h
===================================================================
--- include/lldb/Core/Architecture.h
+++ include/lldb/Core/Architecture.h
@@ -12,7 +12,10 @@
#include "lldb/Core/PluginInterface.h"
+class DynamicRegisterInfo;
+
namespace lldb_private {
+class ArchSpec;
class Architecture : public PluginInterface {
public:
@@ -112,6 +115,8 @@
return addr;
}
+ virtual void AdjustRegisterInfo(DynamicRegisterInfo ®_info) const {}
+
private:
Architecture(const Architecture &) = delete;
void operator=(const Architecture &) = delete;
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits