diff options
| author | Zachary Turner <zturner@google.com> | 2015-03-17 20:04:04 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2015-03-17 20:04:04 +0000 |
| commit | 0641ca1a2dc2d4923ee702651aab2a9704d563b5 (patch) | |
| tree | 702d70f8895c939cf047fbd1d31f9909faa4d85a /lldb/source/Plugins | |
| parent | c888dd0cb8b6cc3f1f33674189aea59d0938f2b4 (diff) | |
| download | bcm5719-llvm-0641ca1a2dc2d4923ee702651aab2a9704d563b5.tar.gz bcm5719-llvm-0641ca1a2dc2d4923ee702651aab2a9704d563b5.zip | |
Remove ScriptInterpreterObject.
This removes ScriptInterpreterObject from the codebase completely.
Places that used to rely on ScriptInterpreterObject now use
StructuredData::Object and its derived classes. To support this,
a new type of StructuredData object is introduced, called
StructuredData::Generic, which stores a void*. Internally within
the python library, StructuredPythonObject subclasses this
StructuredData::Generic class so that it can addref and decref
the python object on construction and destruction.
Additionally, all of the classes in PythonDataObjects.h such
as PythonList, PythonDictionary, etc now provide a method to
create an instance of the corresponding StructuredData type. For
example, there is PythonDictionary::CreateStructuredDictionary.
To eliminate dependencies on PythonDataObjects for external
callers, all ScriptInterpreter methods now return only
StructuredData classes
The rest of the changes in this CL are focused on fixing up
users of PythonDataObjects classes to use the new StructuredData
classes.
llvm-svn: 232534
Diffstat (limited to 'lldb/source/Plugins')
6 files changed, 367 insertions, 427 deletions
diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index 7ca337e797d..e85020a965c 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -22,9 +22,10 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/PythonDataObjects.h" +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/VariableList.h" @@ -116,8 +117,9 @@ OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, co os_plugin_class_name.erase (py_extension_pos); // Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn" os_plugin_class_name += ".OperatingSystemPlugIn"; - ScriptInterpreterObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess()); - if (object_sp && object_sp->GetObject()) + StructuredData::ObjectSP object_sp = + m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess()); + if (object_sp && object_sp->IsValid()) m_python_object_sp = object_sp; } } @@ -139,12 +141,12 @@ OperatingSystemPython::GetDynamicRegisterInfo () if (log) log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID()); - - PythonDictionary dictionary(m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp)); + + StructuredData::DictionarySP dictionary = m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp); if (!dictionary) return NULL; - - m_register_info_ap.reset (new DynamicRegisterInfo (dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder())); + + m_register_info_ap.reset(new DynamicRegisterInfo(*dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder())); assert (m_register_info_ap->GetNumRegisters() > 0); assert (m_register_info_ap->GetNumRegisterSets() > 0); } @@ -189,8 +191,8 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, // lldb_private::Process subclass, no memory threads will be in this list. auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive - PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp)); - + StructuredData::ArraySP threads_list = m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp); + const uint32_t num_cores = core_thread_list.GetSize(false); // Make a map so we can keep track of which cores were used from the @@ -202,22 +204,19 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, if (log) { StreamString strm; - threads_list.Dump(strm); + threads_list->Dump(strm); log->Printf("threads_list = %s", strm.GetString().c_str()); } - uint32_t i; - const uint32_t num_threads = threads_list.GetSize(); - if (num_threads > 0) + + const uint32_t num_threads = threads_list->GetSize(); + for (uint32_t i = 0; i < num_threads; ++i) { - for (i=0; i<num_threads; ++i) + StructuredData::ObjectSP thread_dict_obj = threads_list->GetItemAtIndex(i); + if (auto thread_dict = thread_dict_obj->GetAsDictionary()) { - PythonDictionary thread_dict(threads_list.GetItemAtIndex(i)); - if (thread_dict) - { - ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, core_thread_list, old_thread_list, core_used_map, NULL)); - if (thread_sp) - new_thread_list.AddThread(thread_sp); - } + ThreadSP thread_sp(CreateThreadFromThreadInfo(*thread_dict, core_thread_list, old_thread_list, core_used_map, NULL)); + if (thread_sp) + new_thread_list.AddThread(thread_sp); } } } @@ -239,79 +238,63 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, } ThreadSP -OperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict, - ThreadList &core_thread_list, - ThreadList &old_thread_list, - std::vector<bool> &core_used_map, - bool *did_create_ptr) +OperatingSystemPython::CreateThreadFromThreadInfo(StructuredData::Dictionary &thread_dict, ThreadList &core_thread_list, + ThreadList &old_thread_list, std::vector<bool> &core_used_map, bool *did_create_ptr) { ThreadSP thread_sp; - if (thread_dict) + tid_t tid = LLDB_INVALID_THREAD_ID; + if (!thread_dict.GetValueForKeyAsInteger("tid", tid)) + return ThreadSP(); + + uint32_t core_number; + addr_t reg_data_addr; + std::string name; + std::string queue; + + thread_dict.GetValueForKeyAsInteger("core", core_number, UINT32_MAX); + thread_dict.GetValueForKeyAsInteger("register_data_addr", reg_data_addr, LLDB_INVALID_ADDRESS); + thread_dict.GetValueForKeyAsString("name", name); + thread_dict.GetValueForKeyAsString("queue", queue); + + // See if a thread already exists for "tid" + thread_sp = old_thread_list.FindThreadByID(tid, false); + if (thread_sp) { - PythonString tid_pystr("tid"); - const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID); - if (tid != LLDB_INVALID_THREAD_ID) + // A thread already does exist for "tid", make sure it was an operating system + // plug-in generated thread. + if (!IsOperatingSystemPluginThread(thread_sp)) { - PythonString core_pystr("core"); - PythonString name_pystr("name"); - PythonString queue_pystr("queue"); - //PythonString state_pystr("state"); - //PythonString stop_reason_pystr("stop_reason"); - PythonString reg_data_addr_pystr ("register_data_addr"); - - const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX); - const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS); - const char *name = thread_dict.GetItemForKeyAsString (name_pystr); - const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr); - //const char *state = thread_dict.GetItemForKeyAsString (state_pystr); - //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr); - - // See if a thread already exists for "tid" - thread_sp = old_thread_list.FindThreadByID (tid, false); - if (thread_sp) - { - // A thread already does exist for "tid", make sure it was an operating system - // plug-in generated thread. - if (!IsOperatingSystemPluginThread(thread_sp)) - { - // We have thread ID overlap between the protocol threads and the - // operating system threads, clear the thread so we create an - // operating system thread for this. - thread_sp.reset(); - } - } - - if (!thread_sp) + // We have thread ID overlap between the protocol threads and the + // operating system threads, clear the thread so we create an + // operating system thread for this. + thread_sp.reset(); + } + } + + if (!thread_sp) + { + if (did_create_ptr) + *did_create_ptr = true; + thread_sp.reset(new ThreadMemory(*m_process, tid, name.c_str(), queue.c_str(), reg_data_addr)); + } + + if (core_number < core_thread_list.GetSize(false)) + { + ThreadSP core_thread_sp(core_thread_list.GetThreadAtIndex(core_number, false)); + if (core_thread_sp) + { + // Keep track of which cores were set as the backing thread for memory threads... + if (core_number < core_used_map.size()) + core_used_map[core_number] = true; + + ThreadSP backing_core_thread_sp(core_thread_sp->GetBackingThread()); + if (backing_core_thread_sp) { - if (did_create_ptr) - *did_create_ptr = true; - thread_sp.reset (new ThreadMemory (*m_process, - tid, - name, - queue, - reg_data_addr)); - + thread_sp->SetBackingThread(backing_core_thread_sp); } - - if (core_number < core_thread_list.GetSize(false)) + else { - ThreadSP core_thread_sp (core_thread_list.GetThreadAtIndex(core_number, false)); - if (core_thread_sp) - { - // Keep track of which cores were set as the backing thread for memory threads... - if (core_number < core_used_map.size()) - core_used_map[core_number] = true; - - ThreadSP backing_core_thread_sp (core_thread_sp->GetBackingThread()); - if (backing_core_thread_sp) - { - thread_sp->SetBackingThread(backing_core_thread_sp); - } - else - { - thread_sp->SetBackingThread(core_thread_sp); - } - } + thread_sp->SetBackingThread(core_thread_sp); } } } @@ -364,11 +347,11 @@ OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t re thread->GetID(), thread->GetProtocolID()); - PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID())); + StructuredData::StringSP reg_context_data = m_interpreter->OSPlugin_RegisterContextData(m_python_object_sp, thread->GetID()); if (reg_context_data) { - DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(), - reg_context_data.GetSize())); + std::string value = reg_context_data->GetValue(); + DataBufferSP data_sp(new DataBufferHeap(value.c_str(), value.length())); if (data_sp->GetByteSize()) { RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS); @@ -417,14 +400,14 @@ OperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context) Mutex::Locker api_locker (target.GetAPIMutex()); auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive - PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context)); + StructuredData::DictionarySP thread_info_dict = m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context); std::vector<bool> core_used_map; if (thread_info_dict) { ThreadList core_threads(m_process); ThreadList &thread_list = m_process->GetThreadList(); bool did_create = false; - ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, core_used_map, &did_create)); + ThreadSP thread_sp(CreateThreadFromThreadInfo(*thread_info_dict, core_threads, thread_list, core_used_map, &did_create)); if (did_create) thread_list.AddThread(thread_sp); return thread_sp; diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h index 3b7dd264dc6..e29bf8054f6 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -14,11 +14,16 @@ // C Includes // C++ Includes // Other libraries and framework includes -#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Target/OperatingSystem.h" class DynamicRegisterInfo; +namespace lldb_private +{ +class ScriptInterpreter; +} + class OperatingSystemPython : public lldb_private::OperatingSystem { public: @@ -86,15 +91,12 @@ protected: bool IsValid() const { - return m_python_object_sp && m_python_object_sp->GetObject() != NULL; + return m_python_object_sp && m_python_object_sp->IsValid(); } - - lldb::ThreadSP - CreateThreadFromThreadInfo (lldb_private::PythonDictionary &thread_dict, - lldb_private::ThreadList &core_thread_list, - lldb_private::ThreadList &old_thread_list, - std::vector<bool> &core_used_map, - bool *did_create_ptr); + + lldb::ThreadSP CreateThreadFromThreadInfo(lldb_private::StructuredData::Dictionary &thread_dict, + lldb_private::ThreadList &core_thread_list, lldb_private::ThreadList &old_thread_list, + std::vector<bool> &core_used_map, bool *did_create_ptr); DynamicRegisterInfo * GetDynamicRegisterInfo (); @@ -102,8 +104,7 @@ protected: lldb::ValueObjectSP m_thread_list_valobj_sp; std::unique_ptr<DynamicRegisterInfo> m_register_info_ap; lldb_private::ScriptInterpreter *m_interpreter; - lldb::ScriptInterpreterObjectSP m_python_object_sp; - + lldb_private::StructuredData::ObjectSP m_python_object_sp; }; #endif // #ifndef liblldb_OperatingSystemPython_h_ diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 25a195e11a0..0e9b540b7cf 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -18,12 +18,9 @@ #include "lldb/Host/StringConvert.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredData.h" #include "lldb/DataFormatters/FormatManager.h" -#ifndef LLDB_DISABLE_PYTHON -#include "lldb/Interpreter/PythonDataObjects.h" -#endif - using namespace lldb; using namespace lldb_private; @@ -39,15 +36,15 @@ DynamicRegisterInfo::DynamicRegisterInfo () : { } -DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) : - m_regs (), - m_sets (), - m_set_reg_nums (), - m_set_names (), - m_value_regs_map (), - m_invalidate_regs_map (), - m_reg_data_byte_size (0), - m_finalized (false) +DynamicRegisterInfo::DynamicRegisterInfo(const StructuredData::Dictionary &dict, ByteOrder byte_order) + : m_regs() + , m_sets() + , m_set_reg_nums() + , m_set_names() + , m_value_regs_map() + , m_invalidate_regs_map() + , m_reg_data_byte_size(0) + , m_finalized(false) { SetRegisterInfo (dict, byte_order); } @@ -56,23 +53,20 @@ DynamicRegisterInfo::~DynamicRegisterInfo () { } - size_t -DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict, - ByteOrder byte_order) +DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, ByteOrder byte_order) { assert(!m_finalized); -#ifndef LLDB_DISABLE_PYTHON - PythonList sets (dict.GetItemForKey("sets")); - if (sets) + StructuredData::Array *sets = nullptr; + if (dict.GetValueForKeyAsArray("sets", sets)) { - const uint32_t num_sets = sets.GetSize(); + const uint32_t num_sets = sets->GetSize(); for (uint32_t i=0; i<num_sets; ++i) { - PythonString py_set_name(sets.GetItemAtIndex(i)); + std::string set_name_str; ConstString set_name; - if (py_set_name) - set_name.SetCString(py_set_name.GetString()); + if (sets->GetItemAtIndexAsString(i, set_name_str)) + set_name.SetCString(set_name_str.c_str()); if (set_name) { RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; @@ -87,346 +81,310 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict } 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 dwarf_pystr("dwarf"); - PythonString generic_pystr("generic"); - PythonString slice_pystr("slice"); - PythonString composite_pystr("composite"); - PythonString invalidate_regs_pystr("invalidate-regs"); - + StructuredData::Array *regs = nullptr; + if (!dict.GetValueForKeyAsArray("registers", regs)) + return 0; + + const uint32_t num_regs = regs->GetSize(); // typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap; // InvalidateNameMap invalidate_map; - for (uint32_t i=0; i<num_regs; ++i) + for (uint32_t i = 0; i < num_regs; ++i) + { + StructuredData::Dictionary *reg_info_dict = nullptr; + if (!regs->GetItemAtIndexAsDictionary(i, reg_info_dict)) { - 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; - std::vector<uint32_t> value_regs; - std::vector<uint32_t> invalidate_regs; - memset(®_info, 0, sizeof(reg_info)); - - reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); - if (reg_info.name == NULL) - { - Clear(); - printf("error: registers must have valid names\n"); - reg_info_dict.Dump(); - 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); + Clear(); + printf("error: items in the 'registers' array must be dictionaries\n"); + regs->DumpToStdout(); + return 0; + } + + // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, + // 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, + RegisterInfo reg_info; + std::vector<uint32_t> value_regs; + std::vector<uint32_t> invalidate_regs; + memset(®_info, 0, sizeof(reg_info)); + + ConstString name_val; + ConstString alt_name_val; + if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) + { + Clear(); + printf("error: registers must have valid names and offsets\n"); + reg_info_dict->DumpToStdout(); + return 0; + } + reg_info.name = name_val.GetCString(); + reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr); + reg_info.alt_name = alt_name_val.GetCString(); - if (reg_info.byte_offset == UINT32_MAX) + reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX); + + if (reg_info.byte_offset == UINT32_MAX) + { + // No offset for this register, see if the register has a value expression + // which indicates this register is part of another register. Value expressions + // are things like "rax[31:0]" which state that the current register's value + // is in a concrete register "rax" in bits 31:0. If there is a value expression + // we can calculate the offset + bool success = false; + std::string slice_str; + if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) + { + // Slices use the following format: + // REGNAME[MSBIT:LSBIT] + // REGNAME - name of the register to grab a slice of + // MSBIT - the most significant bit at which the current register value starts at + // LSBIT - the least significant bit at which the current register value ends at + static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); + RegularExpression::Match regex_match(3); + if (g_bitfield_regex.Execute(slice_str.c_str(), ®ex_match)) { - // No offset for this register, see if the register has a value expression - // which indicates this register is part of another register. Value expressions - // are things like "rax[31:0]" which state that the current register's value - // is in a concrete register "rax" in bits 31:0. If there is a value expression - // we can calculate the offset - bool success = false; - const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr); - if (slice_cstr) + llvm::StringRef reg_name_str; + std::string msbit_str; + std::string lsbit_str; + if (regex_match.GetMatchAtIndex(slice_str.c_str(), 1, reg_name_str) && + regex_match.GetMatchAtIndex(slice_str.c_str(), 2, msbit_str) && + regex_match.GetMatchAtIndex(slice_str.c_str(), 3, lsbit_str)) { - // Slices use the following format: - // REGNAME[MSBIT:LSBIT] - // REGNAME - name of the register to grab a slice of - // MSBIT - the most significant bit at which the current register value starts at - // LSBIT - the least significant bit at which the current register value ends at - static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); - RegularExpression::Match regex_match(3); - if (g_bitfield_regex.Execute(slice_cstr, ®ex_match)) + const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); + const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); + if (msbit != UINT32_MAX && lsbit != UINT32_MAX) { - llvm::StringRef reg_name_str; - std::string msbit_str; - std::string lsbit_str; - if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) && - regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) && - regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str)) + if (msbit > lsbit) { - const uint32_t msbit = StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); - const uint32_t lsbit = StringConvert::ToUInt32(lsbit_str.c_str(), UINT32_MAX); - if (msbit != UINT32_MAX && lsbit != UINT32_MAX) + const uint32_t msbyte = msbit / 8; + const uint32_t lsbyte = lsbit / 8; + + ConstString containing_reg_name(reg_name_str); + + RegisterInfo *containing_reg_info = GetRegisterInfo(containing_reg_name); + if (containing_reg_info) { - if (msbit > lsbit) + const uint32_t max_bit = containing_reg_info->byte_size * 8; + if (msbit < max_bit && lsbit < max_bit) { - const uint32_t msbyte = msbit / 8; - const uint32_t lsbyte = lsbit / 8; + m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); - ConstString containing_reg_name(reg_name_str); - - RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name); - if (containing_reg_info) + if (byte_order == eByteOrderLittle) + { + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; + } + else if (byte_order == eByteOrderBig) { - const uint32_t max_bit = containing_reg_info->byte_size * 8; - if (msbit < max_bit && lsbit < max_bit) - { - m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); - m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); - - if (byte_order == eByteOrderLittle) - { - success = true; - reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; - } - else if (byte_order == eByteOrderBig) - { - success = true; - reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; - } - else - { - assert(!"Invalid byte order"); - } - } - else - { - if (msbit > max_bit) - printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit); - else - printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit); - } + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; } else { - printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); + assert(!"Invalid byte order"); } } else { - printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); + if (msbit > max_bit) + printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, + max_bit); + else + printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, + max_bit); } } else { - printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); + printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); } } else { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); - + printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); } } else { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to match against register bitfield regex\n"); + printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); } } else { - PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr)); - if (composite_reg_list) + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); + } + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to match against register bitfield regex\n"); + } + } + else + { + StructuredData::Array *composite_reg_list = nullptr; + if (reg_info_dict->GetValueForKeyAsArray("composite", composite_reg_list)) + { + const size_t num_composite_regs = composite_reg_list->GetSize(); + if (num_composite_regs > 0) + { + uint32_t composite_offset = UINT32_MAX; + for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; ++composite_idx) { - const size_t num_composite_regs = composite_reg_list.GetSize(); - if (num_composite_regs > 0) + ConstString composite_reg_name; + if (composite_reg_list->GetItemAtIndexAsString(composite_idx, composite_reg_name, nullptr)) { - uint32_t composite_offset = UINT32_MAX; - for (uint32_t composite_idx=0; composite_idx<num_composite_regs; ++composite_idx) - { - PythonString composite_reg_name_pystr(composite_reg_list.GetItemAtIndex(composite_idx)); - if (composite_reg_name_pystr) - { - ConstString composite_reg_name(composite_reg_name_pystr.GetString()); - if (composite_reg_name) - { - RegisterInfo *composite_reg_info = GetRegisterInfo (composite_reg_name); - if (composite_reg_info) - { - if (composite_offset > composite_reg_info->byte_offset) - composite_offset = composite_reg_info->byte_offset; - m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); - m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); - m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); - } - else - { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); - } - } - else - { - printf("error: 'composite' key contained an empty string\n"); - } - } - else - { - printf("error: 'composite' list value wasn't a python string\n"); - } - } - if (composite_offset != UINT32_MAX) + RegisterInfo *composite_reg_info = GetRegisterInfo(composite_reg_name); + if (composite_reg_info) { - reg_info.byte_offset = composite_offset; - success = m_value_regs_map.find(i) != m_value_regs_map.end(); + composite_offset = std::min(composite_offset, composite_reg_info->byte_offset); + m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); } else { - printf("error: 'composite' registers must specify at least one real register\n"); + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); } } else { - printf("error: 'composite' list was empty\n"); + printf("error: 'composite' list value wasn't a python string\n"); } } + if (composite_offset != UINT32_MAX) + { + reg_info.byte_offset = composite_offset; + success = m_value_regs_map.find(i) != m_value_regs_map.end(); + } + else + { + printf("error: 'composite' registers must specify at least one real register\n"); + } } - - - if (!success) + else { - Clear(); - reg_info_dict.Dump(); - return 0; + printf("error: 'composite' list was empty\n"); } } - const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); - if (bitsize == 0) - { - Clear(); - printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n"); - reg_info_dict.Dump(); - return 0; - } + } - reg_info.byte_size = bitsize / 8; - - const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); - if (format_cstr) - { - if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) - { - Clear(); - printf("error: invalid 'format' value in register dictionary\n"); - reg_info_dict.Dump(); - 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); + if (!success) + { + Clear(); + reg_info_dict->DumpToStdout(); + return 0; + } + } - const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); - if (static_cast<size_t>(set) >= m_sets.size()) - { - Clear(); - printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set); - reg_info_dict.Dump(); - return 0; - } + int64_t bitsize = 0; + if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) + { + Clear(); + printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n"); + reg_info_dict->DumpToStdout(); + return 0; + } - // Fill in the register numbers - reg_info.kinds[lldb::eRegisterKindLLDB] = i; - 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); - 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); + reg_info.byte_size = bitsize / 8; + + std::string format_str; + if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) + { + if (Args::StringToFormat(format_str.c_str(), reg_info.format, NULL).Fail()) + { + Clear(); + printf("error: invalid 'format' value in register dictionary\n"); + reg_info_dict->DumpToStdout(); + return 0; + } + } + else + { + reg_info_dict->GetValueForKeyAsInteger("format", reg_info.format, eFormatHex); + } + + std::string encoding_str; + if (reg_info_dict->GetValueForKeyAsString("encoding", encoding_str)) + reg_info.encoding = Args::StringToEncoding(encoding_str.c_str(), eEncodingUint); + else + reg_info_dict->GetValueForKeyAsInteger("encoding", reg_info.encoding, eEncodingUint); - // Check if this register invalidates any other register values when it is modified - PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr)); - if (invalidate_reg_list) + size_t set = 0; + if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) || set >= m_sets.size()) + { + Clear(); + printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set); + reg_info_dict->DumpToStdout(); + return 0; + } + + // Fill in the register numbers + reg_info.kinds[lldb::eRegisterKindLLDB] = i; + reg_info.kinds[lldb::eRegisterKindGDB] = i; + reg_info_dict->GetValueForKeyAsInteger("gcc", reg_info.kinds[lldb::eRegisterKindGCC], LLDB_INVALID_REGNUM); + reg_info_dict->GetValueForKeyAsInteger("dwarf", reg_info.kinds[lldb::eRegisterKindDWARF], LLDB_INVALID_REGNUM); + std::string generic_str; + if (reg_info_dict->GetValueForKeyAsString("generic", generic_str)) + reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister(generic_str.c_str()); + else + reg_info_dict->GetValueForKeyAsInteger("generic", reg_info.kinds[lldb::eRegisterKindGeneric], LLDB_INVALID_REGNUM); + + // Check if this register invalidates any other register values when it is modified + StructuredData::Array *invalidate_reg_list = nullptr; + if (reg_info_dict->GetValueForKeyAsArray("invalidate-regs", invalidate_reg_list)) + { + const size_t num_regs = invalidate_reg_list->GetSize(); + if (num_regs > 0) + { + for (uint32_t idx = 0; idx < num_regs; ++idx) { - const size_t num_regs = invalidate_reg_list.GetSize(); - if (num_regs > 0) + ConstString invalidate_reg_name; + uint64_t invalidate_reg_num; + if (invalidate_reg_list->GetItemAtIndexAsString(idx, invalidate_reg_name)) { - for (uint32_t idx=0; idx<num_regs; ++idx) + RegisterInfo *invalidate_reg_info = GetRegisterInfo(invalidate_reg_name); + if (invalidate_reg_info) { - PythonObject invalidate_reg_object (invalidate_reg_list.GetItemAtIndex(idx)); - PythonString invalidate_reg_name_pystr(invalidate_reg_object); - if (invalidate_reg_name_pystr) - { - ConstString invalidate_reg_name(invalidate_reg_name_pystr.GetString()); - if (invalidate_reg_name) - { - RegisterInfo *invalidate_reg_info = GetRegisterInfo (invalidate_reg_name); - if (invalidate_reg_info) - { - m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); - } - else - { - // TODO: print error invalid slice string that doesn't follow the format - printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name); - } - } - else - { - printf("error: 'invalidate-regs' list value was an empty string\n"); - } - } - else - { - PythonInteger invalidate_reg_num(invalidate_reg_object); - - if (invalidate_reg_num) - { - const int64_t r = invalidate_reg_num.GetInteger(); - if (r != static_cast<int64_t>(UINT64_MAX)) - m_invalidate_regs_map[i].push_back(r); - else - printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); - } - else - { - printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); - } - } + m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", + invalidate_reg_name.GetCString(), reg_info.name); } } + else if (invalidate_reg_list->GetItemAtIndexAsInteger(idx, invalidate_reg_num)) + { + if (invalidate_reg_num != UINT64_MAX) + m_invalidate_regs_map[i].push_back(invalidate_reg_num); + else + printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); + } else { - printf("error: 'invalidate-regs' contained an empty list\n"); + printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); } } - - // Calculate the register offset - 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(); - printf("error: items in the 'registers' array must be dictionaries\n"); - regs.Dump(); - return 0; + printf("error: 'invalidate-regs' contained an empty list\n"); } } - Finalize (); + + // Calculate the register offset + 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); } -#endif + Finalize(); return m_regs.size(); } diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index a41c77e49f9..128d8987397 100644 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -19,21 +19,19 @@ // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/StructuredData.h" class DynamicRegisterInfo { public: DynamicRegisterInfo (); - DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, - lldb::ByteOrder byte_order); - + DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, lldb::ByteOrder byte_order); + virtual ~DynamicRegisterInfo (); - size_t - SetRegisterInfo (const lldb_private::PythonDictionary &dict, - lldb::ByteOrder byte_order); + size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, lldb::ByteOrder byte_order); void AddRegister (lldb_private::RegisterInfo ®_info, diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 365180a1097..7a00949fa6d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -52,9 +52,6 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" -#ifndef LLDB_DISABLE_PYTHON -#include "lldb/Interpreter/PythonDataObjects.h" -#endif #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" @@ -337,41 +334,47 @@ ProcessGDBRemote::GetPluginVersion() bool ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec) { -#ifndef LLDB_DISABLE_PYTHON ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); Error error; - lldb::ScriptInterpreterObjectSP module_object_sp (interpreter->LoadPluginModule(target_definition_fspec, error)); + StructuredData::ObjectSP 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); + StructuredData::DictionarySP target_definition_sp( + interpreter->GetDynamicSettings(module_object_sp, &GetTarget(), "gdb-server-target-definition", error)); - if (target_dict) + if (target_definition_sp) { - PythonDictionary host_info_dict (target_dict.GetItemForKey("host-info")); - if (host_info_dict) + StructuredData::ObjectSP target_object(target_definition_sp->GetValueForKey("host-info")); + if (target_object) { - ArchSpec host_arch (host_info_dict.GetItemForKeyAsString(PythonString("triple"))); - - if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) + if (auto host_info_dict = target_object->GetAsDictionary()) { - GetTarget().SetArchitecture(host_arch); + StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple"); + if (auto triple_string_value = triple_value->GetAsString()) + { + std::string triple_string = triple_string_value->GetValue(); + ArchSpec host_arch(triple_string.c_str()); + if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) + { + GetTarget().SetArchitecture(host_arch); + } + } } - } - m_breakpoint_pc_offset = target_dict.GetItemForKeyAsInteger("breakpoint-pc-offset", 0); + m_breakpoint_pc_offset = 0; + StructuredData::ObjectSP breakpoint_pc_offset_value = target_definition_sp->GetValueForKey("breakpoint-pc-offset"); + if (breakpoint_pc_offset_value) + { + if (auto breakpoint_pc_int_value = breakpoint_pc_offset_value->GetAsInteger()) + m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue(); + } - if (m_register_info.SetRegisterInfo (target_dict, GetTarget().GetArchitecture().GetByteOrder()) > 0) + if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture().GetByteOrder()) > 0) { return true; } } } -#endif return false; } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index e0c460a202d..bf12d1ae5ee 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -303,9 +303,6 @@ protected: bool ParsePythonTargetDefinition(const lldb_private::FileSpec &target_definition_fspec); - - bool - ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array); const lldb::DataBufferSP GetAuxvData() override; |

