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; 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: 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: 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 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 ArchitectureArc::Create(const ArchSpec &arch) { + if (arch.GetMachine() != llvm::Triple::arc) + return nullptr; + return std::unique_ptr(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/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/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/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/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 features = {"xmlRegisters=i386,arm,mips"}; + std::vector features = {"xmlRegisters=i386,arm,mips,arc"}; StreamString packet; packet.PutCString("qSupported"); for (uint32_t i = 0; i < features.size(); ++i) { 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/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/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/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/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 = {