Index: lldb/include/lldb/Host/common/NativeRegisterContext.h =================================================================== --- lldb/include/lldb/Host/common/NativeRegisterContext.h +++ lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -16,6 +16,8 @@ class NativeThreadProtocol; +enum class ExpeditedRegs { Minimal, Full }; + class NativeRegisterContext : public std::enable_shared_from_this { public: @@ -114,6 +116,9 @@ virtual NativeThreadProtocol &GetThread() { return m_thread; } + virtual std::vector + GetExpeditedRegisters(ExpeditedRegs expType) const; + const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx = 0); Index: lldb/source/Host/common/NativeRegisterContext.cpp =================================================================== --- lldb/source/Host/common/NativeRegisterContext.cpp +++ lldb/source/Host/common/NativeRegisterContext.cpp @@ -420,3 +420,33 @@ return LLDB_INVALID_REGNUM; } + +std::vector +NativeRegisterContext::GetExpeditedRegisters(ExpeditedRegs expType) const { + if (expType == ExpeditedRegs::Minimal) { + // Expedite only a minimum set of important generic registers. + static const uint32_t k_expedited_registers[] = { + LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, + LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM}; + + std::vector expedited_reg_nums; + for (const uint32_t *generic_reg_p = k_expedited_registers; + *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) { + uint32_t reg_num = ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, *generic_reg_p); + if (reg_num == LLDB_INVALID_REGNUM) + continue; // Target does not support the given register. + else + expedited_reg_nums.push_back(reg_num); + } + + return expedited_reg_nums; + } + + if (GetRegisterSetCount() > 0 && expType == ExpeditedRegs::Full) + return std::vector(GetRegisterSet(0)->registers, + GetRegisterSet(0)->registers + + GetRegisterSet(0)->num_registers); + + return std::vector(); +} Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -504,30 +504,16 @@ json::Object register_object; #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET - // Expedite all registers in the first register set (i.e. should be GPRs) - // that are not contained in other registers. - const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0); - if (!reg_set_p) - return llvm::make_error("failed to get registers", - llvm::inconvertibleErrorCode()); - for (const uint32_t *reg_num_p = reg_set_p->registers; - *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { - uint32_t reg_num = *reg_num_p; + const auto expedited_regs = + reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); #else - // Expedite only a couple of registers until we figure out why sending - // registers is expensive. - static const uint32_t k_expedited_registers[] = { - LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, - LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM}; - - for (const uint32_t *generic_reg_p = k_expedited_registers; - *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) { - uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber( - eRegisterKindGeneric, *generic_reg_p); - if (reg_num == LLDB_INVALID_REGNUM) - continue; // Target does not support the given register. + const auto expedited_regs = + reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Minimal); #endif - + if (expedited_regs.empty()) + return llvm::make_error("failed to get registers", + llvm::inconvertibleErrorCode()); + for (auto ®_num : expedited_regs) { const RegisterInfo *const reg_info_p = reg_ctx.GetRegisterInfoAtIndex(reg_num); if (reg_info_p == nullptr) { @@ -806,35 +792,19 @@ // Grab the register context. NativeRegisterContext& reg_ctx = thread->GetRegisterContext(); - // Expedite all registers in the first register set (i.e. should be GPRs) - // that are not contained in other registers. - const RegisterSet *reg_set_p; - if (reg_ctx.GetRegisterSetCount() > 0 && - ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) { - LLDB_LOGF(log, - "GDBRemoteCommunicationServerLLGS::%s expediting registers " - "from set '%s' (registers set count: %zu)", - __FUNCTION__, reg_set_p->name ? reg_set_p->name : "", - reg_set_p->num_registers); + const auto expedited_regs = + reg_ctx.GetExpeditedRegisters(ExpeditedRegs::Full); - for (const uint32_t *reg_num_p = reg_set_p->registers; - *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { + if (!expedited_regs.empty()) { + for (auto ®_num : expedited_regs) { const RegisterInfo *const reg_info_p = - reg_ctx.GetRegisterInfoAtIndex(*reg_num_p); - if (reg_info_p == nullptr) { - LLDB_LOGF(log, - "GDBRemoteCommunicationServerLLGS::%s failed to get " - "register info for register set '%s', register index " - "%" PRIu32, - __FUNCTION__, - reg_set_p->name ? reg_set_p->name : "", - *reg_num_p); - } else if (reg_info_p->value_regs == nullptr) { - // Only expediate registers that are not contained in other registers. + reg_ctx.GetRegisterInfoAtIndex(reg_num); + // Only expediate registers that are not contained in other registers. + if (reg_info_p != nullptr && reg_info_p->value_regs == nullptr) { RegisterValue reg_value; Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); if (error.Success()) { - response.Printf("%.02x:", *reg_num_p); + response.Printf("%.02x:", reg_num); WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, ®_value, lldb::eByteOrderBig); response.PutChar(';'); @@ -844,7 +814,7 @@ "register '%s' index %" PRIu32 ": %s", __FUNCTION__, reg_info_p->name ? reg_info_p->name : "", - *reg_num_p, error.AsCString()); + reg_num, error.AsCString()); } } }