diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index b8129c9..69dae05 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/StreamString.h" +#include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Utils.h" // Project includes @@ -696,6 +697,137 @@ GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, ui return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); } +size_t +GDBRemoteDynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict) +{ +#ifndef LLDB_DISABLE_PYTHON + PythonList sets (dict.GetItemForKey("sets")); + if (sets) + { + const uint32_t num_sets = sets.GetSize(); + for (uint32_t i=0; i<num_sets; ++i) + { + PythonString py_set_name(sets.GetItemAtIndex(i)); + ConstString set_name; + if (py_set_name) + set_name.SetCString(py_set_name.GetString()); + if (set_name) + { + RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; + m_sets.push_back (new_set); + } + else + { + Clear(); + return 0; + } + } + m_set_reg_nums.resize(m_sets.size()); + } + PythonList regs (dict.GetItemForKey("registers")); + if (regs) + { + const uint32_t num_regs = regs.GetSize(); + PythonString name_pystr("name"); + PythonString altname_pystr("alt-name"); + PythonString bitsize_pystr("bitsize"); + PythonString offset_pystr("offset"); + PythonString encoding_pystr("encoding"); + PythonString format_pystr("format"); + PythonString set_pystr("set"); + PythonString gcc_pystr("gcc"); + PythonString gdb_pystr("gdb"); + PythonString dwarf_pystr("dwarf"); + PythonString generic_pystr("generic"); + for (uint32_t i=0; i<num_regs; ++i) + { + PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); + if (reg_info_dict) + { + // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, + RegisterInfo reg_info; + bzero (®_info, sizeof(reg_info)); + + reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); + if (reg_info.name == NULL) + { + Clear(); + return 0; + } + + reg_info.alt_name = ConstString (reg_info_dict.GetItemForKeyAsString(altname_pystr)).GetCString(); + + reg_info.byte_offset = reg_info_dict.GetItemForKeyAsInteger(offset_pystr, UINT32_MAX); + + if (reg_info.byte_offset == UINT32_MAX) + { + Clear(); + return 0; + } + reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8; + + if (reg_info.byte_size == 0) + { + Clear(); + return 0; + } + + const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); + if (format_cstr) + { + if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) + { + Clear(); + return 0; + } + } + else + { + reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex); + } + + const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); + if (encoding_cstr) + reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); + else + reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint); + + const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); + if (set >= m_sets.size()) + { + Clear(); + return 0; + } + + reg_info.kinds[lldb::eRegisterKindLLDB] = i; + reg_info.kinds[lldb::eRegisterKindGDB] = reg_info_dict.GetItemForKeyAsInteger(gdb_pystr , LLDB_INVALID_REGNUM); + reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr , LLDB_INVALID_REGNUM); + reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr , LLDB_INVALID_REGNUM); + const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr); + if (generic_cstr) + reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); + else + reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); + const 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; + + m_regs.push_back (reg_info); + m_set_reg_nums[set].push_back(i); + + } + else + { + Clear(); + return 0; + } + } + Finalize (); + } +#endif + return 0; +} + void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) { |