diff --git a/lldb/include/lldb/Target/DynamicRegisterInfo.h b/lldb/include/lldb/Target/DynamicRegisterInfo.h --- a/lldb/include/lldb/Target/DynamicRegisterInfo.h +++ b/lldb/include/lldb/Target/DynamicRegisterInfo.h @@ -38,6 +38,7 @@ uint32_t regnum_remote = LLDB_INVALID_REGNUM; std::vector value_regs; std::vector invalidate_regs; + uint32_t value_reg_offset = 0; }; DynamicRegisterInfo() = default; @@ -101,6 +102,7 @@ typedef std::vector set_reg_num_collection; typedef std::vector name_collection; typedef std::map reg_to_regs_map; + typedef std::map reg_offset_map; llvm::Expected ByteOffsetFromSlice(uint32_t index, llvm::StringRef slice_str, @@ -122,6 +124,7 @@ name_collection m_set_names; reg_to_regs_map m_value_regs_map; reg_to_regs_map m_invalidate_regs_map; + reg_offset_map m_value_reg_offset_map; size_t m_reg_data_byte_size = 0u; // The number of bytes required to store // all registers bool m_finalized = false; diff --git a/lldb/source/Target/DynamicRegisterInfo.cpp b/lldb/source/Target/DynamicRegisterInfo.cpp --- a/lldb/source/Target/DynamicRegisterInfo.cpp +++ b/lldb/source/Target/DynamicRegisterInfo.cpp @@ -395,6 +395,10 @@ m_value_regs_map[local_regnum] = std::move(reg.value_regs); if (!reg.invalidate_regs.empty()) m_invalidate_regs_map[local_regnum] = std::move(reg.invalidate_regs); + if (reg.value_reg_offset != 0) { + assert(reg.value_regs.size() == 1); + m_value_reg_offset_map[local_regnum] = reg.value_reg_offset; + } struct RegisterInfo reg_info { reg.name.AsCString(), reg.alt_name.AsCString(), reg.byte_size, @@ -679,8 +683,12 @@ // as that of their corresponding primary register in value_regs list. if (reg.byte_offset == LLDB_INVALID_INDEX32) { uint32_t value_regnum = reg.value_regs[0]; - if (value_regnum != LLDB_INVALID_INDEX32) + if (value_regnum != LLDB_INVALID_INDEX32) { reg.byte_offset = GetRegisterInfoAtIndex(value_regnum)->byte_offset; + auto it = m_value_reg_offset_map.find(reg.kinds[eRegisterKindLLDB]); + if (it != m_value_reg_offset_map.end()) + reg.byte_offset += it->second; + } } } diff --git a/lldb/unittests/Target/DynamicRegisterInfoTest.cpp b/lldb/unittests/Target/DynamicRegisterInfoTest.cpp --- a/lldb/unittests/Target/DynamicRegisterInfoTest.cpp +++ b/lldb/unittests/Target/DynamicRegisterInfoTest.cpp @@ -203,12 +203,23 @@ }; uint32_t eax = AddTestRegister("eax", "supplementary", 4, suppl_adder, {rax}); uint32_t ax = AddTestRegister("ax", "supplementary", 2, suppl_adder, {rax}); + uint32_t ah = AddTestRegister("ah", "supplementary", 1, suppl_adder, {rax}); uint32_t al = AddTestRegister("al", "supplementary", 1, suppl_adder, {rax}); + m_regs[ah].value_reg_offset = 1; - EXPECT_IN_REGS(rax, {}, {eax, ax, al}); - EXPECT_IN_REGS(eax, {rax}, {rax, ax, al}); - EXPECT_IN_REGS(ax, {rax}, {rax, eax, al}); - EXPECT_IN_REGS(al, {rax}, {rax, eax, ax}); + EXPECT_IN_REGS(rax, {}, {eax, ax, ah, al}); + EXPECT_IN_REGS(eax, {rax}, {rax, ax, ah, al}); + EXPECT_IN_REGS(ax, {rax}, {rax, eax, ah, al}); + EXPECT_IN_REGS(ah, {rax}, {rax, eax, ax, al}); + EXPECT_IN_REGS(al, {rax}, {rax, eax, ax, ah}); + + EXPECT_EQ(m_dyninfo.SetRegisterInfo(std::move(m_regs), ArchSpec()), + m_regs.size()); + EXPECT_IN_DYNINFO(rax, 0, {}, {eax, ax, ah, al}); + EXPECT_IN_DYNINFO(eax, 0, {rax}, {rax, ax, ah, al}); + EXPECT_IN_DYNINFO(ax, 0, {rax}, {rax, eax, ah, al}); + EXPECT_IN_DYNINFO(ah, 1, {rax}, {rax, eax, ax, al}); + EXPECT_IN_DYNINFO(al, 0, {rax}, {rax, eax, ax, ah}); } TEST_F(DynamicRegisterInfoRegisterTest, SetRegisterInfo) {