omjavaid updated this revision to Diff 307954. omjavaid added a comment. This update improves on last patch by adding support for register ordering in increasing order of register number even if register numbers are used randomly in target xml. Also we set offset to LLDB_INVALID_INDEX32 while initializing and if an offset is provided by remote it will be updated. However if no offset was provided an appropriate offset will be calculated incrementally by traversing a map which sorts registers in increasing order of remote register numbers.
A AArch64 test is included which places cpsr at the top of target xml description with regnum field populated. Also w registers derive their offset from corresponding x registers. All register values are checked with a provided g packet result. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D91241/new/ https://reviews.llvm.org/D91241 Files: lldb/include/lldb/Host/common/NativeRegisterContext.h lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp lldb/unittests/tools/lldb-server/tests/TestClient.cpp
Index: lldb/unittests/tools/lldb-server/tests/TestClient.cpp =================================================================== --- lldb/unittests/tools/lldb-server/tests/TestClient.cpp +++ lldb/unittests/tools/lldb-server/tests/TestClient.cpp @@ -219,6 +219,7 @@ } Error TestClient::qRegisterInfos() { + uint32_t reg_offset = 0; for (unsigned int Reg = 0;; ++Reg) { std::string Message = formatv("qRegisterInfo{0:x-}", Reg).str(); Expected<RegisterInfo> InfoOr = SendMessage<RegisterInfoParser>(Message); @@ -227,6 +228,12 @@ break; } m_register_infos.emplace_back(std::move(*InfoOr)); + + if (m_register_infos[Reg].byte_offset == LLDB_INVALID_INDEX32) + m_register_infos[Reg].byte_offset = reg_offset; + + reg_offset = + m_register_infos[Reg].byte_offset + m_register_infos[Reg].byte_size; if (m_register_infos[Reg].kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC) m_pc_register = Reg; Index: lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp =================================================================== --- lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp +++ lldb/unittests/tools/lldb-server/tests/MessageObjects.cpp @@ -171,7 +171,7 @@ Info.byte_size /= CHAR_BIT; if (!to_integer(Elements["offset"], Info.byte_offset, 10)) - return make_parsing_error("qRegisterInfo: offset"); + Info.byte_offset = LLDB_INVALID_INDEX32; Info.encoding = Args::StringToEncoding(Elements["encoding"]); if (Info.encoding == eEncodingInvalid) Index: lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py =================================================================== --- lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py +++ lldb/test/API/tools/lldb-server/registers-target-xml-reading/TestGdbRemoteTargetXmlPacket.py @@ -65,5 +65,8 @@ self.assertEqual(q_info_reg["set"], xml_info_reg.get("group")) self.assertEqual(q_info_reg["format"], xml_info_reg.get("format")) self.assertEqual(q_info_reg["bitsize"], xml_info_reg.get("bitsize")) - self.assertEqual(q_info_reg["offset"], xml_info_reg.get("offset")) + + if not self.getArchitecture() == 'aarch64': + self.assertEqual(q_info_reg["offset"], xml_info_reg.get("offset")) + self.assertEqual(q_info_reg["encoding"], xml_info_reg.get("encoding")) Index: lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py =================================================================== --- /dev/null +++ lldb/test/API/functionalities/gdb_remote_client/TestAArch64XMLRegOffsets.py @@ -0,0 +1,151 @@ +from __future__ import print_function +from textwrap import dedent +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + + +class MyResponder(MockGDBServerResponder): + def qXferRead(self, obj, annex, offset, length): + if annex == "target.xml": + return dedent("""\ + <?xml version="1.0"?> + <target version="1.0"> + <architecture>aarch64</architecture> + <feature name="org.gnu.gdb.aarch64.core"> + <reg name="cpsr" regnum="33" bitsize="32"/> + <reg name="x0" regnum="0" bitsize="64"/> + <reg name="x1" bitsize="64"/> + <reg name="x2" bitsize="64"/> + <reg name="x3" bitsize="64"/> + <reg name="x4" bitsize="64"/> + <reg name="x5" bitsize="64"/> + <reg name="x6" bitsize="64"/> + <reg name="x7" bitsize="64"/> + <reg name="x8" bitsize="64"/> + <reg name="x9" bitsize="64"/> + <reg name="x10" bitsize="64"/> + <reg name="x11" bitsize="64"/> + <reg name="x12" bitsize="64"/> + <reg name="x13" bitsize="64"/> + <reg name="x14" bitsize="64"/> + <reg name="x15" bitsize="64"/> + <reg name="x16" bitsize="64"/> + <reg name="x17" bitsize="64"/> + <reg name="x18" bitsize="64"/> + <reg name="x19" bitsize="64"/> + <reg name="x20" bitsize="64"/> + <reg name="x21" bitsize="64"/> + <reg name="x22" bitsize="64"/> + <reg name="x23" bitsize="64"/> + <reg name="x24" bitsize="64"/> + <reg name="x25" bitsize="64"/> + <reg name="x26" bitsize="64"/> + <reg name="x27" bitsize="64"/> + <reg name="x28" bitsize="64"/> + <reg name="x29" bitsize="64"/> + <reg name="x30" bitsize="64"/> + <reg name="sp" bitsize="64"/> + <reg name="pc" bitsize="64"/> + <reg name="w0" bitsize="32" value_regnums="0" invalidate_regnums="0" regnum="34"/> + <reg name="w1" bitsize="32" value_regnums="1" invalidate_regnums="1"/> + <reg name="w2" bitsize="32" value_regnums="2" invalidate_regnums="2"/> + <reg name="w3" bitsize="32" value_regnums="3" invalidate_regnums="3"/> + <reg name="w4" bitsize="32" value_regnums="4" invalidate_regnums="4"/> + <reg name="w5" bitsize="32" value_regnums="5" invalidate_regnums="5"/> + <reg name="w6" bitsize="32" value_regnums="6" invalidate_regnums="6"/> + <reg name="w7" bitsize="32" value_regnums="7" invalidate_regnums="7"/> + <reg name="w8" bitsize="32" value_regnums="8" invalidate_regnums="8"/> + <reg name="w9" bitsize="32" value_regnums="9" invalidate_regnums="9"/> + <reg name="w10" bitsize="32" value_regnums="10" invalidate_regnums="10"/> + <reg name="w11" bitsize="32" value_regnums="11" invalidate_regnums="11"/> + <reg name="w12" bitsize="32" value_regnums="12" invalidate_regnums="12"/> + <reg name="w13" bitsize="32" value_regnums="13" invalidate_regnums="13"/> + <reg name="w14" bitsize="32" value_regnums="14" invalidate_regnums="14"/> + <reg name="w15" bitsize="32" value_regnums="15" invalidate_regnums="15"/> + <reg name="w16" bitsize="32" value_regnums="16" invalidate_regnums="16"/> + <reg name="w17" bitsize="32" value_regnums="17" invalidate_regnums="17"/> + <reg name="w18" bitsize="32" value_regnums="18" invalidate_regnums="18"/> + <reg name="w19" bitsize="32" value_regnums="19" invalidate_regnums="19"/> + <reg name="w20" bitsize="32" value_regnums="20" invalidate_regnums="20"/> + <reg name="w21" bitsize="32" value_regnums="21" invalidate_regnums="21"/> + <reg name="w22" bitsize="32" value_regnums="22" invalidate_regnums="22"/> + <reg name="w23" bitsize="32" value_regnums="23" invalidate_regnums="23"/> + <reg name="w24" bitsize="32" value_regnums="24" invalidate_regnums="24"/> + <reg name="w25" bitsize="32" value_regnums="25" invalidate_regnums="25"/> + <reg name="w26" bitsize="32" value_regnums="26" invalidate_regnums="26"/> + <reg name="w27" bitsize="32" value_regnums="27" invalidate_regnums="27"/> + <reg name="w28" bitsize="32" value_regnums="28" invalidate_regnums="28"/> + </feature> + </target> + """), False + else: + return None, + + def readRegister(self, regnum): + return "E01" + + def readRegisters(self): + return "20000000000000002000000000000000f0c154bfffff00005daa985a8fea0b48f0b954bfffff0000ad13cce570150b48380000000000000070456abfffff0000a700000000000000000000000000000001010101010101010000000000000000f0c154bfffff00000f2700000000000008e355bfffff0000080e55bfffff0000281041000000000010de61bfffff00005c05000000000000f0c154bfffff000090fcffffffff00008efcffffffff00008ffcffffffff00000000000000000000001000000000000090fcffffffff000000d06cbfffff0000f0c154bfffff00000100000000000000d0b954bfffff0000e407400000000000d0b954bfffff0000e40740000000000000100000" + + +class TestAArch64XMLRegOffsets(GDBRemoteTestBase): + + @skipIfXmlSupportMissing + @skipIfRemote + @skipIfLLVMTargetMissing("AArch64") + def test_register_gpacket_offsets(self): + """ + Test that we correctly associate the register info with the eh_frame + register numbers. + """ + + target = self.createTarget("basic_eh_frame-aarch64.yaml") + self.server.responder = MyResponder() + + if self.TraceOn(): + self.runCmd("log enable gdb-remote packets") + self.addTearDownHook( + lambda: self.runCmd("log disable gdb-remote packets")) + + process = self.connect(target) + lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, + [lldb.eStateStopped]) + + registerSet = process.GetThreadAtIndex( + 0).GetFrameAtIndex(0).GetRegisters().GetValueAtIndex(0) + + reg_val_dict = { + "x0": 0x0000000000000020, "x1": 0x0000000000000020, + "x2": 0x0000ffffbf54c1f0, "x3": 0x480bea8f5a98aa5d, + "x4": 0x0000ffffbf54b9f0, "x5": 0x480b1570e5cc13ad, + "x6": 0x0000000000000038, "x7": 0x0000ffffbf6a4570, + "x8": 0x00000000000000a7, "x9": 0x0000000000000000, + "x10": 0x0101010101010101, "x11": 0x0000000000000000, + "x12": 0x0000ffffbf54c1f0, "x13": 0x000000000000270f, + "x14": 0x0000ffffbf55e308, "x15": 0x0000ffffbf550e08, + "x16": 0x0000000000411028, "x17": 0x0000ffffbf61de10, + "x18": 0x000000000000055c, "x19": 0x0000ffffbf54c1f0, + "x20": 0x0000fffffffffc90, "x21": 0x0000fffffffffc8e, + "x22": 0x0000fffffffffc8f, "x23": 0x0000000000000000, + "x24": 0x0000000000001000, "x25": 0x0000fffffffffc90, + "x26": 0x0000ffffbf6cd000, "x27": 0x0000ffffbf54c1f0, + "x28": 0x0000000000000001, "x29": 0x0000ffffbf54b9d0, + "x30": 0x00000000004007e4, "sp": 0x0000ffffbf54b9d0, + "pc": 0x00000000004007e4, "cpsr": 0x00001000, "w0": 0x00000020, + "w1": 0x00000020, "w2": 0xbf54c1f0, "w3": 0x5a98aa5d, + "w4": 0xbf54b9f0, "w5": 0xe5cc13ad, "w6": 0x00000038, + "w7": 0xbf6a4570, "w8": 0x000000a7, "w9": 0x00000000, + "w10": 0x01010101, "w11": 0x00000000, "w12": 0xbf54c1f0, + "w13": 0x0000270f, "w14": 0xbf55e308, "w15": 0xbf550e08, + "w16": 0x00411028, "w17": 0xbf61de10, "w18": 0x0000055c, + "w19": 0xbf54c1f0, "w20": 0xfffffc90, "w21": 0xfffffc8e, + "w22": 0xfffffc8f, "w23": 0x00000000, "w24": 0x00001000, + "w25": 0xfffffc90, "w26": 0xbf6cd000, "w27": 0xbf54c1f0, + "w28": 0x00000001 + } + + for reg in registerSet: + self.assertEqual(reg.GetValueAsUnsigned(), + reg_val_dict[reg.GetName()]) Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h =================================================================== --- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -391,8 +391,8 @@ bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, std::string xml_filename, - uint32_t &cur_reg_num, - uint32_t ®_offset); + uint32_t &cur_reg_remote, + uint32_t &cur_reg_local); // Query remote GDBServer for register information bool GetGDBServerRegisterInfo(ArchSpec &arch); 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 @@ -451,7 +451,7 @@ return; char packet[128]; - uint32_t reg_offset = 0; + uint32_t reg_offset = LLDB_INVALID_INDEX32; uint32_t reg_num = 0; for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse; @@ -564,7 +564,7 @@ reg_info.byte_offset = reg_offset; assert(reg_info.byte_size != 0); - reg_offset += reg_info.byte_size; + reg_offset = LLDB_INVALID_INDEX32; if (!value_regs.empty()) { value_regs.push_back(LLDB_INVALID_REGNUM); reg_info.value_regs = value_regs.data(); @@ -4276,14 +4276,14 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp, - uint32_t &cur_reg_num, uint32_t ®_offset) { + uint32_t ®_num_remote, uint32_t ®_num_local) { if (!feature_node) return false; + uint32_t reg_offset = LLDB_INVALID_INDEX32; feature_node.ForEachChildElementWithName( - "reg", - [&target_info, &dyn_reg_info, &cur_reg_num, ®_offset, - &abi_sp](const XMLNode ®_node) -> bool { + "reg", [&target_info, &dyn_reg_info, ®_num_remote, ®_num_local, + ®_offset, &abi_sp](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; ConstString reg_name; @@ -4305,8 +4305,8 @@ LLDB_INVALID_REGNUM, // eh_frame reg num LLDB_INVALID_REGNUM, // DWARF reg num LLDB_INVALID_REGNUM, // generic reg num - cur_reg_num, // process plugin reg num - cur_reg_num // native register number + reg_num_remote, // process plugin reg num + reg_num_local // native register number }, nullptr, nullptr, @@ -4433,7 +4433,7 @@ reg_info.byte_offset = reg_offset; assert(reg_info.byte_size != 0); - reg_offset += reg_info.byte_size; + reg_offset = LLDB_INVALID_INDEX32; if (!value_regs.empty()) { value_regs.push_back(LLDB_INVALID_REGNUM); reg_info.value_regs = value_regs.data(); @@ -4443,7 +4443,8 @@ reg_info.invalidate_regs = invalidate_regs.data(); } - ++cur_reg_num; + reg_num_remote = reg_info.kinds[eRegisterKindProcessPlugin] + 1; + ++reg_num_local; reg_info.name = reg_name.AsCString(); if (abi_sp) abi_sp->AugmentRegisterInfo(reg_info); @@ -4462,8 +4463,8 @@ // for nested register definition files. It returns true if it was able // to fetch and parse an xml file. bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( - ArchSpec &arch_to_use, std::string xml_filename, uint32_t &cur_reg_num, - uint32_t ®_offset) { + ArchSpec &arch_to_use, std::string xml_filename, uint32_t ®_num_remote, + uint32_t ®_num_local) { // request the target xml file std::string raw; lldb_private::Status lldberr; @@ -4567,12 +4568,12 @@ ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); for (auto &feature_node : feature_nodes) { ParseRegisters(feature_node, target_info, this->m_register_info, - abi_to_use_sp, cur_reg_num, reg_offset); + abi_to_use_sp, reg_num_remote, reg_num_local); } for (const auto &include : target_info.includes) { - GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, cur_reg_num, - reg_offset); + GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, + reg_num_remote, reg_num_local); } } } else { @@ -4592,9 +4593,10 @@ if (!m_gdb_comm.GetQXferFeaturesReadSupported()) return false; - uint32_t cur_reg_num = 0; - uint32_t reg_offset = 0; - if (GetGDBServerRegisterInfoXMLAndProcess (arch_to_use, "target.xml", cur_reg_num, reg_offset)) + uint32_t reg_num_remote = 0; + uint32_t reg_num_local = 0; + if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml", + reg_num_remote, reg_num_local)) this->m_register_info.Finalize(arch_to_use); return m_register_info.GetNumRegisters() > 0; 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 @@ -1825,8 +1825,10 @@ response.PutChar(';'); } - response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", - reg_info->byte_size * 8, reg_info->byte_offset); + response.Printf("bitsize:%" PRIu32 ";", reg_info->byte_size * 8); + + if (!reg_context.RegisterOffsetIsDynamic()) + response.Printf("offset:%" PRIu32 ";", reg_info->byte_offset); llvm::StringRef encoding = GetEncodingNameOrEmpty(*reg_info); if (!encoding.empty()) @@ -2898,10 +2900,11 @@ continue; } - 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); + response.Printf("<reg name=\"%s\" bitsize=\"%" PRIu32 "\" regnum=\"%d\" ", + reg_info->name, reg_info->byte_size * 8, reg_index); + + if (!reg_context.RegisterOffsetIsDynamic()) + response.Printf("offset=\"%" PRIu32 "\" ", reg_info->byte_offset); if (reg_info->alt_name && reg_info->alt_name[0]) response.Printf("altname=\"%s\" ", reg_info->alt_name); Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -71,6 +71,7 @@ typedef std::vector<reg_num_collection> set_reg_num_collection; typedef std::vector<lldb_private::ConstString> name_collection; typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map; + typedef std::map<uint32_t, uint32_t> reg_to_reg_map; typedef std::vector<uint8_t> dwarf_opcode; typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map; @@ -86,6 +87,7 @@ reg_to_regs_map m_value_regs_map; reg_to_regs_map m_invalidate_regs_map; dynamic_reg_size_map m_dynamic_reg_size_map; + reg_to_reg_map m_remote_to_local_regnum_map; size_t m_reg_data_byte_size = 0u; // The number of bytes required to store // all registers bool m_finalized = false; Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -422,15 +422,14 @@ m_dynamic_reg_size_map[reg_num].data(); } + m_remote_to_local_regnum_map[reg_info.kinds[eRegisterKindProcessPlugin]] = + reg_info.kinds[eRegisterKindLLDB]; m_regs.push_back(reg_info); uint32_t set = GetRegisterSetIndexByName(set_name, true); assert(set < m_sets.size()); assert(set < m_set_reg_nums.size()); assert(set < m_set_names.size()); m_set_reg_nums[set].push_back(reg_num); - size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; } void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { @@ -445,6 +444,20 @@ m_sets[set].registers = m_set_reg_nums[set].data(); } + // At this stage we manually calculate g/G packet offsets of all primary + // registers, only if target XML or qRegisterInfo packet did not send + // an offset explicitly. + uint32_t reg_offset = 0; + for (auto const ®num_pair : m_remote_to_local_regnum_map) { + if (m_regs[regnum_pair.second].byte_offset == LLDB_INVALID_INDEX32 && + m_regs[regnum_pair.second].value_regs == nullptr) { + m_regs[regnum_pair.second].byte_offset = reg_offset; + + reg_offset = m_regs[regnum_pair.second].byte_offset + + m_regs[regnum_pair.second].byte_size; + } + } + // sort and unique all value registers and make sure each is terminated with // LLDB_INVALID_REGNUM @@ -466,10 +479,24 @@ // Now update all value_regs with each register info as needed const size_t num_regs = m_regs.size(); for (size_t i = 0; i < num_regs; ++i) { - if (m_value_regs_map.find(i) != m_value_regs_map.end()) + if (m_value_regs_map.find(i) != m_value_regs_map.end()) { m_regs[i].value_regs = m_value_regs_map[i].data(); - else + // Assign a valid offset to all pseudo registers if not assigned by stub. + // Pseudo registers with value_regs list populated will share same offset + // as that of their corresponding primary register in value_regs list. + if (m_regs[i].byte_offset == LLDB_INVALID_INDEX32) { + uint32_t value_regnum = m_regs[i].value_regs[0]; + if (value_regnum != LLDB_INVALID_INDEX32) + m_regs[i].byte_offset = + GetRegisterInfoAtIndex(m_remote_to_local_regnum_map[value_regnum]) + ->byte_offset; + } + } else m_regs[i].value_regs = nullptr; + + reg_offset = m_regs[i].byte_offset + m_regs[i].byte_size; + if (m_reg_data_byte_size < reg_offset) + m_reg_data_byte_size = reg_offset; } // Expand all invalidation dependencies Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h =================================================================== --- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h +++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h @@ -44,6 +44,8 @@ void InvalidateAllRegisters() override; + bool RegisterOffsetIsDynamic() const override { return true; } + // Hardware breakpoints/watchpoint management functions uint32_t NumSupportedHardwareBreakpoints() override; 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 @@ -664,7 +664,10 @@ # Check the bare-minimum expected set of register info keys. self.assertTrue("name" in reg_info) self.assertTrue("bitsize" in reg_info) - self.assertTrue("offset" in reg_info) + + if not self.getArchitecture() == 'aarch64': + self.assertTrue("offset" in reg_info) + self.assertTrue("encoding" in reg_info) self.assertTrue("format" in reg_info) Index: lldb/include/lldb/Host/common/NativeRegisterContext.h =================================================================== --- lldb/include/lldb/Host/common/NativeRegisterContext.h +++ lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -116,6 +116,8 @@ virtual NativeThreadProtocol &GetThread() { return m_thread; } + virtual bool RegisterOffsetIsDynamic() const { return false; } + const RegisterInfo *GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx = 0);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits