diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 411db05da462f5..8b85c7805f5bdb 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -442,28 +442,6 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { m_sets[set].registers = m_set_reg_nums[set].data(); } - // We are going to create a map between remote (eRegisterKindProcessPlugin) - // and local (eRegisterKindLLDB) register numbers. This map will give us - // remote register numbers in increasing order for offset calculation. - std::map remote_to_local_regnum_map; - for (const auto ® : m_regs) - remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] = - reg.kinds[eRegisterKindLLDB]; - - // 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 : 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 @@ -485,24 +463,10 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { // 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(); - // 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(remote_to_local_regnum_map[value_regnum]) - ->byte_offset; - } - } else + 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 @@ -648,6 +612,55 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { break; } } + + // At this stage call ConfigureOffsets to calculate register offsets for + // targets supporting dynamic offset calculation. It also calculates + // total byte size of register data. + ConfigureOffsets(); +} + +void DynamicRegisterInfo::ConfigureOffsets() { + // We are going to create a map between remote (eRegisterKindProcessPlugin) + // and local (eRegisterKindLLDB) register numbers. This map will give us + // remote register numbers in increasing order for offset calculation. + std::map remote_to_local_regnum_map; + for (const auto ® : m_regs) + remote_to_local_regnum_map[reg.kinds[eRegisterKindProcessPlugin]] = + reg.kinds[eRegisterKindLLDB]; + + // 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 : 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; + } + } + + // Now update all value_regs with each register info as needed + for (auto ® : m_regs) { + if (reg.value_regs != nullptr) { + // 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 (reg.byte_offset == LLDB_INVALID_INDEX32) { + uint32_t value_regnum = reg.value_regs[0]; + if (value_regnum != LLDB_INVALID_INDEX32) + reg.byte_offset = + GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum]) + ->byte_offset; + } + } + + reg_offset = reg.byte_offset + reg.byte_size; + if (m_reg_data_byte_size < reg_offset) + m_reg_data_byte_size = reg_offset; + } } bool DynamicRegisterInfo::IsReconfigurable() { return m_is_reconfigurable; } diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index 0938b472c4cee0..31d040e2e137db 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -82,6 +82,8 @@ class DynamicRegisterInfo { void MoveFrom(DynamicRegisterInfo &&info); + void ConfigureOffsets(); + reg_collection m_regs; set_collection m_sets; set_reg_num_collection m_set_reg_nums;