diff --git a/lldb/include/lldb/Core/EmulateInstruction.h b/lldb/include/lldb/Core/EmulateInstruction.h --- a/lldb/include/lldb/Core/EmulateInstruction.h +++ b/lldb/include/lldb/Core/EmulateInstruction.h @@ -183,147 +183,222 @@ struct Context { ContextType type = eContextInvalid; + InfoType GetInfoType() const { return info.info_type; } - private: - enum InfoType info_type = eInfoTypeNoArgs; + struct ContextUnion { + private: + InfoType info_type; - public: - enum InfoType GetInfoType() const { return info_type; } - union { - struct RegisterPlusOffset { + public: + ContextUnion() : info_type(eInfoTypeNoArgs) {} + + struct RegisterPlusOffsetStruct { RegisterInfo reg; // base register int64_t signed_offset; // signed offset added to base register - } RegisterPlusOffset; + }; - struct RegisterPlusIndirectOffset { + struct RegisterPlusIndirectOffsetStruct { RegisterInfo base_reg; // base register number RegisterInfo offset_reg; // offset register kind - } RegisterPlusIndirectOffset; + }; - struct RegisterToRegisterPlusOffset { + struct RegisterToRegisterPlusOffsetStruct { RegisterInfo data_reg; // source/target register for data RegisterInfo base_reg; // base register for address calculation int64_t offset; // offset for address calculation - } RegisterToRegisterPlusOffset; + }; - struct RegisterToRegisterPlusIndirectOffset { + struct RegisterToRegisterPlusIndirectOffsetStruct { RegisterInfo base_reg; // base register for address calculation RegisterInfo offset_reg; // offset register for address calculation RegisterInfo data_reg; // source/target register for data - } RegisterToRegisterPlusIndirectOffset; + }; - struct RegisterRegisterOperands { + struct RegisterRegisterOperandsStruct { RegisterInfo operand1; // register containing first operand for binary op RegisterInfo operand2; // register containing second operand for binary op - } RegisterRegisterOperands; - - int64_t signed_offset; // signed offset by which to adjust self (for - // registers only) - - RegisterInfo reg; // plain register - - uint64_t unsigned_immediate; // unsigned immediate value - int64_t signed_immediate; // signed immediate value - - lldb::addr_t address; // direct address + }; - struct ISAAndImmediate { + struct ISAAndImmediateStruct { uint32_t isa; uint32_t unsigned_data32; // immediate data - } ISAAndImmediate; + }; - struct ISAAndImmediateSigned { + struct ISAAndImmediateSignedStruct { uint32_t isa; int32_t signed_data32; // signed immediate data - } ISAAndImmediateSigned; + }; + + ~ContextUnion() { + switch (info_type) { + case eInfoTypeRegisterPlusOffset: + RegisterPlusOffset.~RegisterPlusOffsetStruct(); + break; + case eInfoTypeRegisterPlusIndirectOffset: + RegisterPlusIndirectOffset.~RegisterPlusIndirectOffsetStruct(); + break; + case eInfoTypeRegisterToRegisterPlusOffset: + RegisterToRegisterPlusOffset.~RegisterToRegisterPlusOffsetStruct(); + break; + case eInfoTypeRegisterToRegisterPlusIndirectOffset: + RegisterToRegisterPlusIndirectOffset + .~RegisterToRegisterPlusIndirectOffsetStruct(); + break; + case eInfoTypeRegisterRegisterOperands: + RegisterRegisterOperands.~RegisterRegisterOperandsStruct(); + break; + case eInfoTypeRegister: + reg.~RegisterInfo(); + break; + case eInfoTypeISAAndImmediate: + ISAAndImmediate.~ISAAndImmediateStruct(); + break; + case eInfoTypeISAAndImmediateSigned: + ISAAndImmediateSigned.~ISAAndImmediateSignedStruct(); + break; + // The following are PODs. + case eInfoTypeAddress: + case eInfoTypeImmediate: + case eInfoTypeImmediateSigned: + case eInfoTypeOffset: + case eInfoTypeISA: + case eInfoTypeNoArgs: + break; + } + } + + union { + RegisterPlusOffsetStruct RegisterPlusOffset; + RegisterPlusIndirectOffsetStruct RegisterPlusIndirectOffset; + RegisterToRegisterPlusOffsetStruct RegisterToRegisterPlusOffset; + RegisterToRegisterPlusIndirectOffsetStruct + RegisterToRegisterPlusIndirectOffset; + RegisterRegisterOperandsStruct RegisterRegisterOperands; + int64_t signed_offset; // signed offset by which to adjust self (for + // registers only) + RegisterInfo reg; // plain register + uint64_t unsigned_immediate; // unsigned immediate value + int64_t signed_immediate; // signed immediate value + lldb::addr_t address; // direct address + ISAAndImmediateStruct ISAAndImmediate; + ISAAndImmediateSignedStruct ISAAndImmediateSigned; + uint32_t isa; + }; - uint32_t isa; + // So that Context can access info_type. + friend Context; } info; Context() = default; + // In these Set functions, anything that is non-trivial must use + // placement new. This is because operator= will interpret whatever + // uninitialised memory is in the union as the content of the object and try + // to destroy it. + void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) { - info_type = eInfoTypeRegisterPlusOffset; - info.RegisterPlusOffset.reg = base_reg; + info.~ContextUnion(); + info.info_type = eInfoTypeRegisterPlusOffset; + new (&info.RegisterPlusOffset.reg) RegisterInfo(base_reg); info.RegisterPlusOffset.signed_offset = signed_offset; } void SetRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg) { - info_type = eInfoTypeRegisterPlusIndirectOffset; - info.RegisterPlusIndirectOffset.base_reg = base_reg; - info.RegisterPlusIndirectOffset.offset_reg = offset_reg; + info.~ContextUnion(); + info.info_type = eInfoTypeRegisterPlusIndirectOffset; + new (&info.RegisterPlusIndirectOffset.base_reg) RegisterInfo(base_reg); + new (&info.RegisterPlusIndirectOffset.offset_reg) + RegisterInfo(offset_reg); } void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset) { - info_type = eInfoTypeRegisterToRegisterPlusOffset; - info.RegisterToRegisterPlusOffset.data_reg = data_reg; - info.RegisterToRegisterPlusOffset.base_reg = base_reg; + info.~ContextUnion(); + info.info_type = eInfoTypeRegisterToRegisterPlusOffset; + new (&info.RegisterToRegisterPlusOffset.data_reg) RegisterInfo(data_reg); + new (&info.RegisterToRegisterPlusOffset.base_reg) RegisterInfo(base_reg); info.RegisterToRegisterPlusOffset.offset = offset; } void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg, RegisterInfo data_reg) { - info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset; - info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg; - info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg; - info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg; + info.~ContextUnion(); + info.info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset; + new (&info.RegisterToRegisterPlusIndirectOffset.base_reg) + RegisterInfo(base_reg); + new (&info.RegisterToRegisterPlusIndirectOffset.offset_reg) + RegisterInfo(offset_reg); + new (&info.RegisterToRegisterPlusIndirectOffset.data_reg) + RegisterInfo(data_reg); } void SetRegisterRegisterOperands(RegisterInfo op1_reg, RegisterInfo op2_reg) { - info_type = eInfoTypeRegisterRegisterOperands; - info.RegisterRegisterOperands.operand1 = op1_reg; - info.RegisterRegisterOperands.operand2 = op2_reg; + info.~ContextUnion(); + info.info_type = eInfoTypeRegisterRegisterOperands; + new (&info.RegisterRegisterOperands.operand1) RegisterInfo(op1_reg); + new (&info.RegisterRegisterOperands.operand2) RegisterInfo(op2_reg); } void SetOffset(int64_t signed_offset) { - info_type = eInfoTypeOffset; + info.~ContextUnion(); + info.info_type = eInfoTypeOffset; info.signed_offset = signed_offset; } void SetRegister(RegisterInfo reg) { - info_type = eInfoTypeRegister; - info.reg = reg; + info.~ContextUnion(); + info.info_type = eInfoTypeRegister; + new (&info.reg) RegisterInfo(reg); } void SetImmediate(uint64_t immediate) { - info_type = eInfoTypeImmediate; + info.~ContextUnion(); + info.info_type = eInfoTypeImmediate; info.unsigned_immediate = immediate; } void SetImmediateSigned(int64_t signed_immediate) { - info_type = eInfoTypeImmediateSigned; + info.~ContextUnion(); + info.info_type = eInfoTypeImmediateSigned; info.signed_immediate = signed_immediate; } void SetAddress(lldb::addr_t address) { - info_type = eInfoTypeAddress; + info.~ContextUnion(); + info.info_type = eInfoTypeAddress; info.address = address; } + void SetISAAndImmediate(uint32_t isa, uint32_t data) { - info_type = eInfoTypeISAAndImmediate; + info.~ContextUnion(); + info.info_type = eInfoTypeISAAndImmediate; info.ISAAndImmediate.isa = isa; info.ISAAndImmediate.unsigned_data32 = data; } void SetISAAndImmediateSigned(uint32_t isa, int32_t data) { - info_type = eInfoTypeISAAndImmediateSigned; + info.~ContextUnion(); + info.info_type = eInfoTypeISAAndImmediateSigned; info.ISAAndImmediateSigned.isa = isa; info.ISAAndImmediateSigned.signed_data32 = data; } void SetISA(uint32_t isa) { - info_type = eInfoTypeISA; + info.~ContextUnion(); + info.info_type = eInfoTypeISA; info.isa = isa; } - void SetNoArgs() { info_type = eInfoTypeNoArgs; } + void SetNoArgs() { + info.~ContextUnion(); + info.info_type = eInfoTypeNoArgs; + } void Dump(Stream &s, EmulateInstruction *instruction) const; }; diff --git a/lldb/include/lldb/lldb-private-types.h b/lldb/include/lldb/lldb-private-types.h --- a/lldb/include/lldb/lldb-private-types.h +++ b/lldb/include/lldb/lldb-private-types.h @@ -11,10 +11,13 @@ #if defined(__cplusplus) +#include "lldb/lldb-defines.h" #include "lldb/lldb-private.h" #include "llvm/ADT/ArrayRef.h" +#include + namespace llvm { namespace sys { class DynamicLibrary; @@ -32,34 +35,46 @@ /// (optional), encoding, size in bytes and the default display format. struct RegisterInfo { /// Name of this register, can't be NULL. - const char *name; + const char *name = nullptr; /// Alternate name of this register, can be NULL. - const char *alt_name; + const char *alt_name = nullptr; /// Size in bytes of the register. - uint32_t byte_size; + uint32_t byte_size = 0; /// The byte offset in the register context data where this register's /// value is found. /// This is optional, and can be 0 if a particular RegisterContext does not /// need to address its registers by byte offset. - uint32_t byte_offset; + uint32_t byte_offset = 0; /// Encoding of the register bits. - lldb::Encoding encoding; + lldb::Encoding encoding = lldb::eEncodingInvalid; /// Default display format. - lldb::Format format; + lldb::Format format = lldb::eFormatInvalid; /// Holds all of the various register numbers for all register kinds. - uint32_t kinds[lldb::kNumRegisterKinds]; // + std::array kinds; /// List of registers (terminated with LLDB_INVALID_REGNUM). If this value is /// not null, all registers in this list will be read first, at which point /// the value for this register will be valid. For example, the value list /// for ah would be eax (x86) or rax (x64). Register numbers are /// of eRegisterKindLLDB. If multiple registers are listed, the final /// value will be the concatenation of them. - uint32_t *value_regs; + uint32_t *value_regs = nullptr; /// List of registers (terminated with LLDB_INVALID_REGNUM). If this value is /// not null, all registers in this list will be invalidated when the value of /// this register changes. For example, the invalidate list for eax would be /// rax ax, ah, and al. - uint32_t *invalidate_regs; + uint32_t *invalidate_regs = nullptr; + + RegisterInfo() { kinds.fill(LLDB_INVALID_REGNUM); } + + RegisterInfo(const char *name, const char *alt_name, uint32_t byte_size, + uint32_t byte_offset, lldb::Encoding encoding, + lldb::Format format, + std::array kinds, + uint32_t *value_regs, uint32_t *invalidate_regs) + : name(name), alt_name(alt_name), byte_size(byte_size), + byte_offset(byte_offset), encoding(encoding), format(format), + kinds(kinds), value_regs(value_regs), invalidate_regs(invalidate_regs) { + } llvm::ArrayRef data(const uint8_t *context_base) const { return llvm::ArrayRef(context_base + byte_offset, byte_size); diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp --- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -24,6 +24,7 @@ #include "Plugins/Process/Utility/ARMUtils.h" #include "Utility/ARM_DWARF_Registers.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/MathExtras.h" @@ -42,9 +43,8 @@ // ITSession implementation // -static bool GetARMDWARFRegisterInfo(unsigned reg_num, RegisterInfo ®_info) { - ::memset(®_info, 0, sizeof(RegisterInfo)); - ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); +static llvm::Optional GetARMDWARFRegisterInfo(unsigned reg_num) { + RegisterInfo reg_info; if (reg_num >= dwarf_q0 && reg_num <= dwarf_q15) { reg_info.byte_size = 16; @@ -594,9 +594,9 @@ break; default: - return false; + return llvm::None; } - return true; + return reg_info; } // A8.6.50 @@ -812,8 +812,13 @@ } } - if (reg_kind == eRegisterKindDWARF) - return GetARMDWARFRegisterInfo(reg_num, reg_info); + if (reg_kind == eRegisterKindDWARF) { + llvm::Optional info = GetARMDWARFRegisterInfo(reg_num); + if (info) + reg_info = *info; + return info.has_value(); + } + return false; } @@ -14101,7 +14106,7 @@ if (ArchVersion() >= ARMv5T) return BXWritePC(context, addr); else - return BranchWritePC((const Context)context, addr); + return BranchWritePC(context, addr); } // Dispatches to either BXWritePC or BranchWritePC based on architecture @@ -14110,7 +14115,7 @@ if (ArchVersion() >= ARMv7 && CurrentInstrSet() == eModeARM) return BXWritePC(context, addr); else - return BranchWritePC((const Context)context, addr); + return BranchWritePC(context, addr); } EmulateInstructionARM::Mode EmulateInstructionARM::CurrentInstrSet() { diff --git a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h --- a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h +++ b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h @@ -26,6 +26,7 @@ #include "lldb/Core/EmulateInstruction.h" #include "lldb/Utility/Status.h" +#include "llvm/ADT/Optional.h" class EmulateInstructionMIPS : public lldb_private::EmulateInstruction { public: @@ -203,6 +204,9 @@ const char *GetRegisterName(unsigned reg_num, bool alternate_name); + llvm::Optional + GetMIPSDWARFRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num); + private: std::unique_ptr m_disasm; std::unique_ptr m_alt_disasm; diff --git a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp --- a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -585,6 +585,56 @@ return nullptr; } +llvm::Optional +EmulateInstructionMIPS::GetMIPSDWARFRegisterInfo(RegisterKind reg_kind, + uint32_t reg_num) { + RegisterInfo reg_info; + + if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || + reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || + reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) { + reg_info.byte_size = 4; + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if ((int)reg_num >= dwarf_zero_mips && + (int)reg_num <= dwarf_f31_mips) { + reg_info.byte_size = 4; + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if ((int)reg_num >= dwarf_w0_mips && (int)reg_num <= dwarf_w31_mips) { + reg_info.byte_size = 16; + reg_info.format = eFormatVectorOfUInt8; + reg_info.encoding = eEncodingVector; + } else { + return llvm::None; + } + + reg_info.name = GetRegisterName(reg_num, false); + reg_info.alt_name = GetRegisterName(reg_num, true); + reg_info.kinds[eRegisterKindDWARF] = reg_num; + + switch (reg_num) { + case dwarf_r30_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; + break; + case dwarf_ra_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; + break; + case dwarf_sp_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; + break; + case dwarf_pc_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; + break; + case dwarf_sr_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; + break; + default: + break; + } + return reg_info; +} + bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) { @@ -616,53 +666,11 @@ } if (reg_kind == eRegisterKindDWARF) { - ::memset(®_info, 0, sizeof(RegisterInfo)); - ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); - - if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || - reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || - reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) { - reg_info.byte_size = 4; - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } else if ((int)reg_num >= dwarf_zero_mips && - (int)reg_num <= dwarf_f31_mips) { - reg_info.byte_size = 4; - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } else if ((int)reg_num >= dwarf_w0_mips && - (int)reg_num <= dwarf_w31_mips) { - reg_info.byte_size = 16; - reg_info.format = eFormatVectorOfUInt8; - reg_info.encoding = eEncodingVector; - } else { - return false; - } - - reg_info.name = GetRegisterName(reg_num, false); - reg_info.alt_name = GetRegisterName(reg_num, true); - reg_info.kinds[eRegisterKindDWARF] = reg_num; - - switch (reg_num) { - case dwarf_r30_mips: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - break; - case dwarf_ra_mips: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; - break; - case dwarf_sp_mips: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - break; - case dwarf_pc_mips: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - break; - case dwarf_sr_mips: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - break; - default: - break; - } - return true; + llvm::Optional info = + GetMIPSDWARFRegisterInfo(reg_kind, reg_num); + if (info) + reg_info = *info; + return info.has_value(); } return false; } diff --git a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h --- a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h +++ b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h @@ -12,6 +12,7 @@ #include "lldb/Core/EmulateInstruction.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/Status.h" +#include "llvm/ADT/Optional.h" namespace llvm { class MCDisassembler; @@ -168,6 +169,9 @@ const char *GetRegisterName(unsigned reg_num, bool alternate_name); + llvm::Optional + GetMIPS64DWARFRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num); + private: std::unique_ptr m_disasm; std::unique_ptr m_subtype_info; diff --git a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp --- a/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -572,6 +572,58 @@ return nullptr; } +llvm::Optional +EmulateInstructionMIPS64::GetMIPS64DWARFRegisterInfo(RegisterKind reg_kind, + uint32_t reg_num) { + RegisterInfo reg_info; + + if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 || + reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 || + reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) { + reg_info.byte_size = 4; + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if ((int)reg_num >= dwarf_zero_mips64 && + (int)reg_num <= dwarf_f31_mips64) { + reg_info.byte_size = 8; + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if ((int)reg_num >= dwarf_w0_mips64 && + (int)reg_num <= dwarf_w31_mips64) { + reg_info.byte_size = 16; + reg_info.format = eFormatVectorOfUInt8; + reg_info.encoding = eEncodingVector; + } else { + return llvm::None; + } + + reg_info.name = GetRegisterName(reg_num, false); + reg_info.alt_name = GetRegisterName(reg_num, true); + reg_info.kinds[eRegisterKindDWARF] = reg_num; + + switch (reg_num) { + case dwarf_r30_mips64: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; + break; + case dwarf_ra_mips64: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; + break; + case dwarf_sp_mips64: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; + break; + case dwarf_pc_mips64: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; + break; + case dwarf_sr_mips64: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; + break; + default: + break; + } + + return reg_info; +} + bool EmulateInstructionMIPS64::GetRegisterInfo(RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) { @@ -603,53 +655,11 @@ } if (reg_kind == eRegisterKindDWARF) { - ::memset(®_info, 0, sizeof(RegisterInfo)); - ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); - - if (reg_num == dwarf_sr_mips64 || reg_num == dwarf_fcsr_mips64 || - reg_num == dwarf_fir_mips64 || reg_num == dwarf_mcsr_mips64 || - reg_num == dwarf_mir_mips64 || reg_num == dwarf_config5_mips64) { - reg_info.byte_size = 4; - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } else if ((int)reg_num >= dwarf_zero_mips64 && - (int)reg_num <= dwarf_f31_mips64) { - reg_info.byte_size = 8; - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } else if ((int)reg_num >= dwarf_w0_mips64 && - (int)reg_num <= dwarf_w31_mips64) { - reg_info.byte_size = 16; - reg_info.format = eFormatVectorOfUInt8; - reg_info.encoding = eEncodingVector; - } else { - return false; - } - - reg_info.name = GetRegisterName(reg_num, false); - reg_info.alt_name = GetRegisterName(reg_num, true); - reg_info.kinds[eRegisterKindDWARF] = reg_num; - - switch (reg_num) { - case dwarf_r30_mips64: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - break; - case dwarf_ra_mips64: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; - break; - case dwarf_sp_mips64: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - break; - case dwarf_pc_mips64: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - break; - case dwarf_sr_mips64: - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - break; - default: - break; - } - return true; + llvm::Optional info = + GetMIPS64DWARFRegisterInfo(reg_kind, reg_num); + if (info) + reg_info = *info; + return info.has_value(); } return 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 @@ -236,7 +236,6 @@ RegisterInfo reg_info; std::vector value_regs; std::vector invalidate_regs; - memset(®_info, 0, sizeof(reg_info)); ConstString name_val; ConstString alt_name_val;