diff options
Diffstat (limited to 'lldb/source/Plugins')
6 files changed, 207 insertions, 11 deletions
diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 0c95d66cef9..5caba5c4ccd 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -114,13 +114,14 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict Clear(); return 0; } - reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8; - - if (reg_info.byte_size == 0) + const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); + if (bitsize == 0) { Clear(); return 0; } + + reg_info.byte_size = bitsize / 8; const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); if (format_cstr) @@ -132,13 +133,15 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict } } else - reg_info.format = eFormatHex; - + { + 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 = eEncodingUint; + 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()) @@ -151,7 +154,11 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict reg_info.kinds[lldb::eRegisterKindGDB] = i; 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); - reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (reg_info_dict.GetItemForKeyAsString(generic_pystr)); + 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; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 5e871d3a81b..7761b166d1c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2341,7 +2341,9 @@ GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtracto assert (packet_len < (int)sizeof(packet)); if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) { - if (response.IsNormalResponse()) + if (response.IsUnsupportedResponse()) + m_supports_qThreadStopInfo = false; + else if (response.IsNormalResponse()) return true; else return false; @@ -2351,8 +2353,6 @@ GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtracto m_supports_qThreadStopInfo = false; } } -// if (SetCurrentThread (tid)) -// return GetStopReply (response); return false; } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index b8129c97cdb..69dae055bb8 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) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 3110ddf8edf..319813f4005 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -171,6 +171,9 @@ public: void HardcodeARMRegisters(bool from_scratch); + size_t + SetRegisterInfo (const lldb_private::PythonDictionary &dict); + protected: //------------------------------------------------------------------ // Classes that inherit from GDBRemoteRegisterContext can see and modify these diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index ad06724add8..e44d7a355f3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -49,6 +49,7 @@ #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/PythonDataObjects.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" @@ -97,12 +98,14 @@ namespace { g_properties[] = { { "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, NULL, "Specify the default packet timeout in seconds." }, + { "target-definition-file" , OptionValue::eTypeFileSpec , true, 0 , NULL, NULL, "The file that provides the description for remote target registers." }, { NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL } }; enum { - ePropertyPacketTimeout + ePropertyPacketTimeout, + ePropertyTargetDefinitionFile }; class PluginProperties : public Properties @@ -133,6 +136,12 @@ namespace { const uint32_t idx = ePropertyPacketTimeout; return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value); } + FileSpec + GetTargetDefinitionFile () const + { + const uint32_t idx = ePropertyTargetDefinitionFile; + return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx); + } }; typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP; @@ -308,6 +317,33 @@ ProcessGDBRemote::GetPluginVersion() return 1; } +bool +ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec) +{ + ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); + Error error; + lldb::ScriptInterpreterObjectSP module_object_sp (interpreter->LoadPluginModule(target_definition_fspec, error)); + if (module_object_sp) + { + lldb::ScriptInterpreterObjectSP target_definition_sp (interpreter->GetDynamicSettings(module_object_sp, + &GetTarget(), + "gdb-server-target-definition", + error)); + + PythonDictionary target_dict(target_definition_sp); + + if (target_dict) + { + if (m_register_info.SetRegisterInfo (target_dict) > 0) + { + return true; + } + } + } + return false; +} + + void ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) { @@ -483,6 +519,18 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) } } + if (reg_num == 0) + { + FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile (); + + // See if we can get register definitions from a python file + if (ParsePythonTargetDefinition (target_definition_fspec)) + { + m_register_info.Finalize (); + return; + } + } + // We didn't get anything if the accumulated reg_num is zero. See if we are // debugging ARM and fill with a hard coded register set until we can get an // updated debugserver down on the devices. diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index c8bd42bdfab..ef79d776b50 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -291,6 +291,12 @@ protected: void SetLastStopPacket (const StringExtractorGDBRemote &response); + bool + ParsePythonTargetDefinition(const lldb_private::FileSpec &target_definition_fspec); + + bool + ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array); + //------------------------------------------------------------------ /// Broadcaster event bits definitions. //------------------------------------------------------------------ |