omjavaid created this revision. omjavaid added reviewers: labath, jankratochvil. Herald added subscribers: danielkiss, kristof.beyls. Herald added a reviewer: rengolin.
Native register descriptions in LLDB specify lldb register numbers in value_regs and invalidate_regs lists. These register numbers may not match with Process gdb-remote register numbers which are generated through native process by counting all registers in its register sets. It was coincidentally not causing any problems as we never came across a native target with dynamically changing register sets and register numbers generated by counter matched with LLDB native register numbers. This came up while testing target AArch64 SVE which can choose register sets based on underlying hardware. This patch fixes this behavior and tries to send lldb register number as extra information in registerinfo and targetxml packets. This patch also updates Read/Write RegisterBytes function of process gdb-remote to look for LLDB register numbers if they are available. I have tested this on arm, aarch64, x86_64. https://reviews.llvm.org/D77043 Files: lldb/docs/lldb-gdb-remote.txt lldb/include/lldb/Host/common/NativeRegisterContext.h lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -553,6 +553,10 @@ } else if (name.equals("generic")) { reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value); + } else if (name.equals("regnum")) { + if (value.getAsInteger(0, + reg_info.kinds[eRegisterKindProcessPlugin])) + reg_info.kinds[eRegisterKindProcessPlugin] = reg_num; } else if (name.equals("container-regs")) { SplitCommaSeparatedRegisterNumberString(value, value_regs, 16); } else if (name.equals("invalidate-regs")) { Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp =================================================================== --- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -242,11 +242,15 @@ // Index of the primordial register. bool success = true; for (uint32_t idx = 0; success; ++idx) { - const uint32_t prim_reg = reg_info->value_regs[idx]; + uint32_t prim_reg = reg_info->value_regs[idx]; if (prim_reg == LLDB_INVALID_REGNUM) break; // We have a valid primordial register as our constituent. Grab the // corresponding register info. + uint32_t regnum = ConvertRegisterKindToRegisterNumber( + eRegisterKindProcessPlugin, prim_reg); + if (regnum != LLDB_INVALID_REGNUM) + prim_reg = regnum; const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); if (prim_reg_info == nullptr) success = false; @@ -375,11 +379,15 @@ // Invalidate this composite register first. for (uint32_t idx = 0; success; ++idx) { - const uint32_t reg = reg_info->value_regs[idx]; + uint32_t reg = reg_info->value_regs[idx]; if (reg == LLDB_INVALID_REGNUM) break; // We have a valid primordial register as our constituent. Grab the // corresponding register info. + uint32_t lldb_regnum = ConvertRegisterKindToRegisterNumber( + eRegisterKindProcessPlugin, reg); + if (lldb_regnum != LLDB_INVALID_REGNUM) + reg = lldb_regnum; const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); if (value_reg_info == nullptr) success = false; @@ -397,6 +405,10 @@ for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; reg != LLDB_INVALID_REGNUM; reg = reg_info->invalidate_regs[++idx]) { + uint32_t lldb_regnum = ConvertRegisterKindToRegisterNumber( + eRegisterKindProcessPlugin, reg); + if (lldb_regnum != LLDB_INVALID_REGNUM) + reg = lldb_regnum; SetRegisterIsValid(reg, false); } } 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 @@ -1772,7 +1772,9 @@ if (reg_index >= reg_context.GetUserRegisterCount()) return SendErrorResponse(69); - const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); + uint32_t native_reg_index = reg_context.GetNativeRegisterIndex(reg_index); + const RegisterInfo *reg_info = + reg_context.GetRegisterInfoAtIndex(native_reg_index); if (!reg_info) return SendErrorResponse(69); @@ -1801,7 +1803,7 @@ response << "format:" << format << ';'; const char *const register_set_name = - reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); + reg_context.GetRegisterSetNameForRegisterAtIndex(native_reg_index); if (register_set_name) response << "set:" << register_set_name << ';'; @@ -1818,6 +1820,10 @@ if (!kind_generic.empty()) response << "generic:" << kind_generic << ';'; + if (reg_info->kinds[RegisterKind::eRegisterKindLLDB] != LLDB_INVALID_REGNUM) + response.Printf("regnum:%" PRIu32 ";", + reg_info->kinds[RegisterKind::eRegisterKindLLDB]); + if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) { response.PutCString("container-regs:"); CollectRegNums(reg_info->value_regs, response, true); @@ -1903,7 +1909,9 @@ std::vector<uint8_t> regs_buffer; for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount(); ++reg_num) { - const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num); + uint32_t native_reg_num = reg_ctx.GetNativeRegisterIndex(reg_num); + const RegisterInfo *reg_info = + reg_ctx.GetRegisterInfoAtIndex(native_reg_num); if (reg_info == nullptr) { LLDB_LOG(log, "failed to get register info for register index {0}", @@ -1966,11 +1974,11 @@ // Return the end of registers response if we've iterated one past the end of // the register set. - if (reg_index >= reg_context.GetUserRegisterCount()) { + if (reg_index >= reg_context.GetRegisterCount()) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed, requested " "register %" PRIu32 " beyond register count %" PRIu32, - __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); + __FUNCTION__, reg_index, reg_context.GetRegisterCount()); return SendErrorResponse(0x15); } @@ -2066,11 +2074,11 @@ // Return the end of registers response if we've iterated one past the end of // the register set. - if (reg_index >= reg_context.GetUserRegisterCount()) { + if (reg_index >= reg_context.GetRegisterCount()) { LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s failed, requested " "register %" PRIu32 " beyond register count %" PRIu32, - __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); + __FUNCTION__, reg_index, reg_context.GetRegisterCount()); return SendErrorResponse(0x47); } @@ -2763,8 +2771,9 @@ const int registers_count = reg_context.GetUserRegisterCount(); for (int reg_index = 0; reg_index < registers_count; reg_index++) { + uint32_t native_reg_index = reg_context.GetNativeRegisterIndex(reg_index); const RegisterInfo *reg_info = - reg_context.GetRegisterInfoAtIndex(reg_index); + reg_context.GetRegisterInfoAtIndex(native_reg_index); if (!reg_info) { LLDB_LOGF(log, @@ -2773,10 +2782,14 @@ continue; } + uint32_t regnum = native_reg_index; + if (reg_info->kinds[RegisterKind::eRegisterKindLLDB] != LLDB_INVALID_REGNUM) + regnum = reg_info->kinds[RegisterKind::eRegisterKindLLDB]; + response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" offset=\"%" PRIu32 "\" regnum=\"%d\" ", reg_info->name, reg_info->byte_size * 8, - reg_info->byte_offset, reg_index); + reg_info->byte_offset, regnum); if (reg_info->alt_name && reg_info->alt_name[0]) response.Printf("altname=\"%s\" ", reg_info->alt_name); @@ -2790,7 +2803,7 @@ response << "format=\"" << format << "\" "; const char *const register_set_name = - reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); + reg_context.GetRegisterSetNameForRegisterAtIndex(native_reg_index); if (register_set_name) response << "group=\"" << register_set_name << "\" "; Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h @@ -29,6 +29,8 @@ uint32_t GetUserRegisterCount() const override; + uint32_t GetNativeRegisterIndex(uint32_t reg_index) const override; + const RegisterInfo *GetRegisterInfoAtIndex(uint32_t reg_index) const override; const RegisterInfoInterface &GetRegisterInfoInterface() const; Index: lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp +++ lldb/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp @@ -28,6 +28,11 @@ return m_register_info_interface_up->GetUserRegisterCount(); } +uint32_t NativeRegisterContextRegisterInfo::GetNativeRegisterIndex( + uint32_t reg_index) const { + return reg_index; +} + const RegisterInfo *NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex( uint32_t reg_index) const { if (reg_index <= GetRegisterCount()) Index: lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py =================================================================== --- lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -752,6 +752,7 @@ "ehframe", "dwarf", "generic", + "regnum", "container-regs", "invalidate-regs", "dynamic_size_dwarf_expr_bytes", Index: lldb/include/lldb/Host/common/NativeRegisterContext.h =================================================================== --- lldb/include/lldb/Host/common/NativeRegisterContext.h +++ lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -35,6 +35,8 @@ virtual uint32_t GetUserRegisterCount() const = 0; + virtual uint32_t GetNativeRegisterIndex(uint32_t reg_index) const = 0; + virtual const RegisterInfo *GetRegisterInfoAtIndex(uint32_t reg) const = 0; const char *GetRegisterSetNameForRegisterAtIndex(uint32_t reg_index) const; Index: lldb/docs/lldb-gdb-remote.txt =================================================================== --- lldb/docs/lldb-gdb-remote.txt +++ lldb/docs/lldb-gdb-remote.txt @@ -597,6 +597,8 @@ vector-float32 vector-uint128 +regnum Optional register number assigned by native process or remote stub. + set The register set name as a string that this register belongs to. gcc The GCC compiler registers number for this register (used for
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits