Index: include/lldb/Host/common/NativeRegisterContext.h =================================================================== --- include/lldb/Host/common/NativeRegisterContext.h +++ include/lldb/Host/common/NativeRegisterContext.h @@ -87,6 +87,9 @@ virtual bool ClearHardwareBreakpoint (uint32_t hw_idx); + virtual size_t + GetDwarfOpcodeLength (const uint32_t i) const; + virtual uint32_t NumSupportedHardwareWatchpoints (); Index: include/lldb/Host/common/NativeRegisterContextRegisterInfo.h =================================================================== --- include/lldb/Host/common/NativeRegisterContextRegisterInfo.h +++ include/lldb/Host/common/NativeRegisterContextRegisterInfo.h @@ -37,6 +37,9 @@ const RegisterInfo * GetRegisterInfoAtIndex (uint32_t reg_index) const override; + size_t + GetDwarfOpcodeLength (const uint32_t i) const override; + const RegisterInfoInterface& GetRegisterInfoInterface () const; Index: include/lldb/Target/RegisterContext.h =================================================================== --- include/lldb/Target/RegisterContext.h +++ include/lldb/Target/RegisterContext.h @@ -46,6 +46,12 @@ virtual const RegisterInfo * GetRegisterInfoAtIndex (size_t reg) = 0; + // Detect the register size dynamically. + uint32_t + UpdateDynamicRegisterSize (const lldb_private::ArchSpec &arch, + RegisterInfo* reg_info, + size_t opcode_len); + virtual size_t GetRegisterSetCount () = 0; Index: include/lldb/lldb-private-types.h =================================================================== --- include/lldb/lldb-private-types.h +++ include/lldb/lldb-private-types.h @@ -54,6 +54,8 @@ // 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. + const uint8_t *dynamic_size_dwarf_expr_bytes; // A DWARF expression that when evaluated gives + // the byte size of this register. }; //---------------------------------------------------------------------- Index: source/Host/common/NativeRegisterContext.cpp =================================================================== --- source/Host/common/NativeRegisterContext.cpp +++ source/Host/common/NativeRegisterContext.cpp @@ -270,6 +270,12 @@ return 0; } +size_t +NativeRegisterContext::GetDwarfOpcodeLength (const uint32_t i) const +{ + return 0; +} + uint32_t NativeRegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) { Index: source/Host/common/NativeRegisterContextRegisterInfo.cpp =================================================================== --- source/Host/common/NativeRegisterContextRegisterInfo.cpp +++ source/Host/common/NativeRegisterContextRegisterInfo.cpp @@ -48,3 +48,11 @@ { return *m_register_info_interface_up; } + +size_t +NativeRegisterContextRegisterInfo::GetDwarfOpcodeLength (const uint32_t i) const +{ + const RegisterInfoInterface& reg_info_interface = GetRegisterInfoInterface (); + return reg_info_interface.GetDwarfOpcodeLength (i); +} + Index: source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -39,7 +39,8 @@ AddRegister (lldb_private::RegisterInfo ®_info, lldb_private::ConstString ®_name, lldb_private::ConstString ®_alt_name, - lldb_private::ConstString &set_name); + lldb_private::ConstString &set_name, + uint32_t dwarf_expr_bytes_len = 0); void Finalize (const lldb_private::ArchSpec &arch); @@ -53,9 +54,16 @@ size_t GetRegisterDataByteSize() const; + // Get length of the Dwarf Opcode + size_t + GetDwarfOpcodeLength (uint32_t i); + const lldb_private::RegisterInfo * GetRegisterInfoAtIndex (uint32_t i) const; + lldb_private::RegisterInfo * + GetRegisterInfoAtIndex (uint32_t i); + const lldb_private::RegisterSet * GetRegisterSet (uint32_t i) const; @@ -81,6 +89,8 @@ typedef std::vector set_reg_num_collection; typedef std::vector name_collection; typedef std::map reg_to_regs_map; + typedef std::vector dwarf_opcode; + typedef std::map dynamic_reg_size_map; lldb_private::RegisterInfo * GetRegisterInfo (const lldb_private::ConstString ®_name); @@ -91,6 +101,7 @@ name_collection m_set_names; 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; size_t m_reg_data_byte_size; // The number of bytes required to store all registers bool m_finalized; }; Index: source/Plugins/Process/Utility/DynamicRegisterInfo.cpp =================================================================== --- source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -19,7 +19,7 @@ #include "lldb/Core/StructuredData.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/StringConvert.h" - +#include "lldb/Utility/StringExtractor.h" using namespace lldb; using namespace lldb_private; @@ -30,6 +30,7 @@ m_set_names (), m_value_regs_map (), m_invalidate_regs_map (), + m_dynamic_reg_size_map (), m_reg_data_byte_size (0), m_finalized (false) { @@ -43,6 +44,7 @@ m_set_names (), m_value_regs_map (), m_invalidate_regs_map (), + m_dynamic_reg_size_map (), m_reg_data_byte_size (0), m_finalized (false) { @@ -292,6 +294,31 @@ reg_info.byte_size = bitsize / 8; + std::string dwarf_opcode_string; + if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes", dwarf_opcode_string)) + { + uint8_t *dwarf_opcode_ptr = NULL; + uint32_t dwarf_expr_bytes_len = dwarf_opcode_string.length () / 2; + uint32_t j; + StringExtractor name_extractor; + dwarf_opcode_ptr = new uint8_t[dwarf_expr_bytes_len]; + if (dwarf_opcode_ptr) + { + // Swap "dwarf_opcode_string" over into "name_extractor" + name_extractor.GetStringRef ().swap (dwarf_opcode_string); + uint32_t ret_val = name_extractor.GetHexBytesAvail (dwarf_opcode_ptr, dwarf_expr_bytes_len); + assert(ret_val == dwarf_expr_bytes_len); + for (j = 0; j < dwarf_expr_bytes_len; ++j) + m_dynamic_reg_size_map[i].push_back(dwarf_opcode_ptr[j]); + + delete[] dwarf_opcode_ptr; + + // Update the actual location + reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data (); + } + else + reg_info.dynamic_size_dwarf_expr_bytes = NULL; + } std::string format_str; if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) { @@ -394,12 +421,18 @@ return m_regs.size(); } +size_t +DynamicRegisterInfo::GetDwarfOpcodeLength (uint32_t i) +{ + return m_dynamic_reg_size_map[i].size(); +} void DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, ConstString ®_name, ConstString ®_alt_name, - ConstString &set_name) + ConstString &set_name, + uint32_t dwarf_expr_bytes_len) { assert(!m_finalized); const uint32_t reg_num = m_regs.size(); @@ -417,6 +450,14 @@ for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); } + if (reg_info.dynamic_size_dwarf_expr_bytes) + { + for (i = 0; i < dwarf_expr_bytes_len; ++i) + m_dynamic_reg_size_map[reg_num].push_back(reg_info.dynamic_size_dwarf_expr_bytes[i]); + + // Update the actual location + reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[reg_num].data (); + } m_regs.push_back (reg_info); uint32_t set = GetRegisterSetIndexByName (set_name, true); assert (set < m_sets.size()); @@ -641,6 +682,14 @@ return NULL; } +RegisterInfo * +DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) +{ + if (i < m_regs.size()) + return &m_regs[i]; + return NULL; +} + const RegisterSet * DynamicRegisterInfo::GetRegisterSet (uint32_t i) const { @@ -688,6 +737,7 @@ m_set_names.clear(); m_value_regs_map.clear(); m_invalidate_regs_map.clear(); + m_dynamic_reg_size_map.clear(); m_reg_data_byte_size = 0; m_finalized = false; } Index: source/Plugins/Process/Utility/RegisterContextLinux_mips.h =================================================================== --- source/Plugins/Process/Utility/RegisterContextLinux_mips.h +++ source/Plugins/Process/Utility/RegisterContextLinux_mips.h @@ -31,6 +31,9 @@ uint32_t GetUserRegisterCount () const override; + size_t + GetDwarfOpcodeLength (const uint32_t i) const override; + private: uint32_t m_user_register_count; }; Index: source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp =================================================================== --- source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp +++ source/Plugins/Process/Utility/RegisterContextLinux_mips.cpp @@ -69,6 +69,19 @@ return static_cast (sizeof (g_register_infos_mips) / sizeof (g_register_infos_mips [0])); } +size_t +RegisterContextLinux_mips::GetDwarfOpcodeLength (const uint32_t i) const +{ + if (i < GetRegisterCount ()) + { + const RegisterInfo *reg_info = GetRegisterInfo() + i; + + if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) + return sizeof(dwarf_opcode_mips); + } + return 0; +} + uint32_t RegisterContextLinux_mips::GetUserRegisterCount () const { Index: source/Plugins/Process/Utility/RegisterContextLinux_mips64.h =================================================================== --- source/Plugins/Process/Utility/RegisterContextLinux_mips64.h +++ source/Plugins/Process/Utility/RegisterContextLinux_mips64.h @@ -33,6 +33,9 @@ uint32_t GetUserRegisterCount () const override; + size_t + GetDwarfOpcodeLength (const uint32_t i) const override; + private: const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; Index: source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp =================================================================== --- source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp +++ source/Plugins/Process/Utility/RegisterContextLinux_mips64.cpp @@ -121,6 +121,19 @@ return m_register_info_count; } +size_t +RegisterContextLinux_mips64::GetDwarfOpcodeLength (const uint32_t i) const +{ + if (i < GetRegisterCount ()) + { + const RegisterInfo *reg_info = GetRegisterInfo() + i; + + if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) + return sizeof(dwarf_opcode_mips64); + } + return 0; +} + uint32_t RegisterContextLinux_mips64::GetUserRegisterCount () const { Index: source/Plugins/Process/Utility/RegisterInfoInterface.h =================================================================== --- source/Plugins/Process/Utility/RegisterInfoInterface.h +++ source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -48,6 +48,12 @@ return GetRegisterCount(); } + virtual size_t + GetDwarfOpcodeLength (const uint32_t i) const + { + return 0; + } + const lldb_private::ArchSpec& GetTargetArchitecture() const { return m_target_arch; } Index: source/Plugins/Process/Utility/RegisterInfos_mips.h =================================================================== --- source/Plugins/Process/Utility/RegisterInfos_mips.h +++ source/Plugins/Process/Utility/RegisterInfos_mips.h @@ -13,7 +13,7 @@ // C++ Includes // Other libraries and framework includes #include "llvm/Support/Compiler.h" - +#include "lldb/Core/dwarf.h" // Project includes #ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT @@ -36,23 +36,29 @@ // Note that the size and offset will be updated by platform-specific classes. #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((GPR_linux_mips*)NULL)->reg) / 2, GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips }, NULL, NULL, NULL} + +const uint8_t dwarf_opcode_mips [] = { + llvm::dwarf::DW_OP_regx, dwarf_sr_mips, llvm::dwarf::DW_OP_lit1, + llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and, + llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr + }; #define DEFINE_FPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingIEEE754, \ - eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL } + eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL, dwarf_opcode_mips} #define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((FPR_linux_mips*)NULL)->reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips }, NULL, NULL, NULL} #define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \ - eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL } + eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL} #define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips }, NULL, NULL, NULL} // RegisterKind: EH_Frame, DWARF, Generic, Procss Plugin, LLDB Index: source/Plugins/Process/Utility/RegisterInfos_mips64.h =================================================================== --- source/Plugins/Process/Utility/RegisterInfos_mips64.h +++ source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -13,7 +13,7 @@ // C++ Includes // Other libraries and framework includes #include "llvm/Support/Compiler.h" - +#include "lldb/Core/dwarf.h" // Project includes #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT @@ -44,32 +44,39 @@ #ifdef LINUX_MIPS64 #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((GPR_linux_mips*)0)->reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL} #else #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((GPR_freebsd_mips*)0)->reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL} #endif #define DEFINE_GPR_INFO(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((GPR_linux_mips*)0)->reg) / 2, GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL, NULL} + +const uint8_t dwarf_opcode_mips64 [] = { + llvm::dwarf::DW_OP_regx, dwarf_sr_mips64, llvm::dwarf::DW_OP_lit1, + llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shl, llvm::dwarf::DW_OP_and, + llvm::dwarf::DW_OP_lit26, llvm::dwarf::DW_OP_shr + }; + #define DEFINE_FPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((FPR_linux_mips*)0)->reg), FPR_OFFSET(reg), eEncodingIEEE754, \ - eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL } + eFormatFloat, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL, dwarf_opcode_mips64} #define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((FPR_linux_mips*)0)->reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, fpr_##reg##_mips64 }, NULL, NULL, NULL} #define DEFINE_MSA(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingVector, \ - eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL } + eFormatVectorOfUInt8, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL} #define DEFINE_MSA_INFO(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((MSA_linux_mips*)0)->reg), MSA_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, msa_##reg##_mips64 }, NULL, NULL, NULL} static RegisterInfo g_register_infos_mips64[] = Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -1634,6 +1634,14 @@ response.PutChar (';'); } + if (reg_info->dynamic_size_dwarf_expr_bytes) + { + const size_t dwarf_opcode_len = reg_context_sp->GetDwarfOpcodeLength (reg_index); + response.PutCString("dynamic_size_dwarf_expr_bytes:"); + for(uint32_t i = 0; i < dwarf_opcode_len; ++i) + response.PutHex8 (reg_info->dynamic_size_dwarf_expr_bytes[i]); + response.PutChar(';'); + } return SendPacketNoLock(response.GetData(), response.GetSize()); } @@ -1829,7 +1837,10 @@ return SendErrorResponse (0x47); } - if (reg_size != reg_info->byte_size) + // The dwarf expression are evaluate on LLDB side + // which may cause register size to change + // Hence the reg_size may not be same as reg_info->bytes_size + if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes)) { return SendIllFormedResponse (packet, "P packet register size is incorrect"); } Index: source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -89,7 +89,16 @@ const RegisterInfo * GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg) { - return m_reg_info.GetRegisterInfoAtIndex (reg); + RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg); + + if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) + { + const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); + size_t opcode_len = m_reg_info.GetDwarfOpcodeLength (reg); + uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info, opcode_len); + reg_info->byte_size = reg_size; + } + return reg_info; } size_t Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -539,6 +539,8 @@ ConstString set_name; std::vector value_regs; std::vector invalidate_regs; + uint8_t *dwarf_opcode_bytes = NULL; + uint32_t dwarf_expr_bytes_len; RegisterInfo reg_info = { NULL, // Name NULL, // Alt name 0, // byte size @@ -553,6 +555,7 @@ reg_num // native register number }, NULL, + NULL, NULL }; @@ -638,6 +641,25 @@ { SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16); } + else if (name.compare("dynamic_size_dwarf_expr_bytes") == 0) + { + dwarf_expr_bytes_len = value.length () / 2; + assert(dwarf_expr_bytes_len > 0); + dwarf_opcode_bytes = new uint8_t[dwarf_expr_bytes_len]; + StringExtractor name_extractor; + + if (dwarf_opcode_bytes) + { + // Swap "value" over into "name_extractor" + name_extractor.GetStringRef().swap(value); + uint32_t ret_val = name_extractor.GetHexBytesAvail (dwarf_opcode_bytes, dwarf_expr_bytes_len); + assert (dwarf_expr_bytes_len == ret_val); + + // Right now the dynamic_size_dwarf_expr_bytes is pointing to a temporary location + // the actual location will be updated in DynamicRegisterInfo class + reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes; + } + } } reg_info.byte_offset = reg_offset; @@ -661,7 +683,11 @@ AugmentRegisterInfoViaABI (reg_info, reg_name, abi_to_use); - m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name); + m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name, dwarf_expr_bytes_len); + + // Free the allocated memory + if (dwarf_opcode_bytes) + delete[] dwarf_opcode_bytes; } else { @@ -4373,6 +4399,8 @@ ConstString set_name; std::vector value_regs; std::vector invalidate_regs; + uint8_t *dwarf_opcode_bytes = NULL; + uint32_t dwarf_expr_bytes_len; bool encoding_set = false; bool format_set = false; RegisterInfo reg_info = { NULL, // Name @@ -4389,10 +4417,11 @@ cur_reg_num // native register number }, NULL, + NULL, NULL }; - reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, ®_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, ®_info, &cur_reg_num, ®_offset](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { + reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, ®_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, ®_info, &cur_reg_num, ®_offset, &dwarf_expr_bytes_len, &dwarf_opcode_bytes](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { if (name == "name") { reg_name.SetString(value); @@ -4480,6 +4509,25 @@ { SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0); } + else if (name == "dynamic_size_dwarf_expr_bytes") + { + StringExtractor name_extractor; + std::string opcode_string = value.str(); + dwarf_expr_bytes_len = opcode_string.length() / 2; + assert(dwarf_expr_bytes_len > 0); + dwarf_opcode_bytes = new uint8_t[dwarf_expr_bytes_len]; + + if (dwarf_opcode_bytes) + { + name_extractor.GetStringRef().swap(opcode_string); + uint32_t ret_val = name_extractor.GetHexBytesAvail (dwarf_opcode_bytes, dwarf_expr_bytes_len); + assert(dwarf_expr_bytes_len == ret_val); + + // Right now the dynamic_size_dwarf_expr_bytes point to temporary location + // the actual location will be updated in DynamicRegisterInfo + reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes; + } + } else { printf("unhandled attribute %s = %s\n", name.data(), value.data()); @@ -4527,7 +4575,11 @@ ++cur_reg_num; AugmentRegisterInfoViaABI (reg_info, reg_name, abi_sp); - dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name); + dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name, dwarf_expr_bytes_len); + + //Free allocated memory + if (dwarf_opcode_bytes) + delete[] dwarf_opcode_bytes; return true; // Keep iterating through all "reg" elements }); Index: source/Target/RegisterContext.cpp =================================================================== --- source/Target/RegisterContext.cpp +++ source/Target/RegisterContext.cpp @@ -21,7 +21,9 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Target.h" - +#include "lldb/Core/Module.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Core/Value.h" using namespace lldb; using namespace lldb_private; @@ -76,6 +78,46 @@ return nullptr; } +uint32_t +RegisterContext::UpdateDynamicRegisterSize (const lldb_private::ArchSpec &arch, + RegisterInfo* reg_info, + size_t opcode_len) +{ + ExecutionContext exe_ctx (CalculateThread()); + + // In MIPS, the floating point registers size is depends on FR bit of SR register. + // if SR.FR == 1 then all floating point registers are 64 bits. + // else they are all 32 bits. + + int expr_result; + uint32_t addr_size = arch.GetAddressByteSize (); + const uint8_t* opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes; + + DataExtractor dwarf_data (opcode_ptr, opcode_len, + arch.GetByteOrder (), addr_size); + ModuleSP opcode_ctx; + DWARFExpression dwarf_expr (opcode_ctx, dwarf_data, nullptr, 0, opcode_len); + Value result; + Error error; + const lldb::offset_t offset = 0; + if(dwarf_expr.Evaluate (&exe_ctx, nullptr, nullptr, this, opcode_ctx, dwarf_data, nullptr, + offset, opcode_len, eRegisterKindDWARF, nullptr, nullptr, result, &error)) + { + expr_result = result.GetScalar().SInt(-1); + switch (expr_result) + { + case 0: return 4; + case 1: return 8; + default: return reg_info->byte_size; + } + } + else + { + printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString()); + return reg_info->byte_size; + } +} + const RegisterInfo * RegisterContext::GetRegisterInfo (lldb::RegisterKind kind, uint32_t num) {