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/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -52,6 +52,9 @@ lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i); + const lldb_private::RegisterInfo *GetRegisterInfo( + const lldb_private::ConstString ®_name, bool case_sensitive = true) const; + const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const; uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name, @@ -77,9 +80,6 @@ typedef std::vector dwarf_opcode; typedef std::map dynamic_reg_size_map; - const lldb_private::RegisterInfo * - GetRegisterInfo(const lldb_private::ConstString ®_name) const; - void MoveFrom(DynamicRegisterInfo &&info); reg_collection m_regs; 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; } @@ -747,13 +796,10 @@ } const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo( - const lldb_private::ConstString ®_name) const { - for (auto ®_info : m_regs) { - // We can use pointer comparison since we used a ConstString to set the - // "name" member in AddRegister() - if (reg_info.name == reg_name.GetCString()) { + const lldb_private::ConstString ®_name, bool case_sensitive) const { + for (const auto ®_info : m_regs) { + if (ConstString::Equals(ConstString(reg_info.name), reg_name, case_sensitive)) return ®_info; - } } - return NULL; + return nullptr; } Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -344,7 +344,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 @@ -4525,6 +4525,58 @@ } // namespace +namespace arc { +// Adjust architecture according to ARC build configuration registers. +bool ConfigureArchitecture(ProcessGDBRemote &process, + const GDBRemoteDynamicRegisterInfo &dyn_reg_info, + ArchSpec& arch_to_use) { + // Obtain register file size from the RF_BUILD register. + static ConstString reg_name("rf_build"); + const bool case_sensitive = false; + auto rf_build_info = dyn_reg_info.GetRegisterInfo(reg_name, case_sensitive); + 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)) { + // The target is configured to use reduced register file. + arch_to_use.SetFlags(ArchSpec::eARC_rf16); + // ABI uses this information to determine how many registers it may + // use to pass arguments in a function. + process.GetTarget().SetArchitecture(arch_to_use); + } + return true; +} + +void AdjustRegisterInfo(DynamicRegisterInfo ®_info, const ArchSpec &arch) { + 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 & arch.GetFlags()) { + // In reduced mode we don't have r4-r9, r16-r25. + if (4 == dwarf_index) + // 4th register is 10th for DWARF. + dwarf_index += 6; + if (16 == dwarf_index) + // 16th register is 26th for DWARF. + dwarf_index += 10; + } + reg_num = dwarf_index; + } + ++dwarf_index; + } +} +} // namespace arc + // query the target of gdb-remote for extended target information return: // 'true' on success // 'false' on failure @@ -4646,7 +4698,16 @@ this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset); } + } + + if (llvm::Triple::arc == arch_to_use.GetMachine()) { + if (arc::ConfigureArchitecture(*this, m_register_info, arch_to_use)) + arc::AdjustRegisterInfo(m_register_info, arch_to_use); + else + // The register info is incorrect, just clear it. + m_register_info.Clear(); } + 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 @@ -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 = {