OperatingSystemPython.cpp revision b9db9d5bb01963774f28540dbe2c5a11f586ff29
1d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===//
2d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//
3d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//                     The LLVM Compiler Infrastructure
4d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//
5d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// This file is distributed under the University of Illinois Open Source
6d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// License. See LICENSE.TXT for details.
7d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//
8d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//===----------------------------------------------------------------------===//
9d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea
10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h"
11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea
12d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#ifndef LLDB_DISABLE_PYTHON
13d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
14d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "OperatingSystemPython.h"
15d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// C Includes
16d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// C++ Includes
17d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// Other libraries and framework includes
18d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/ArchSpec.h"
19d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/DataBufferHeap.h"
20155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata#include "lldb/Core/Debugger.h"
21d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/Module.h"
22d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/PluginManager.h"
2388b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton#include "lldb/Interpreter/PythonDataObjects.h"
24d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/RegisterValue.h"
25d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Core/ValueObjectVariable.h"
26155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata#include "lldb/Interpreter/CommandInterpreter.h"
27155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata#include "lldb/Interpreter/PythonDataObjects.h"
28d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Symbol/ClangNamespaceDecl.h"
29d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Symbol/ObjectFile.h"
30d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Symbol/VariableList.h"
31d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/Process.h"
32d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/StopInfo.h"
33d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/Target.h"
34d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/ThreadList.h"
35d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "lldb/Target/Thread.h"
36d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
37d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "Plugins/Process/Utility/RegisterContextMemory.h"
38d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#include "Plugins/Process/Utility/ThreadMemory.h"
39d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
40d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonusing namespace lldb;
41d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonusing namespace lldb_private;
42d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
43d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonvoid
44d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::Initialize()
45d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
46d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    PluginManager::RegisterPlugin (GetPluginNameStatic(),
47d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton                                   GetPluginDescriptionStatic(),
48d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton                                   CreateInstance);
49d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
50d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
51d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonvoid
52d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::Terminate()
53d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
54d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    PluginManager::UnregisterPlugin (CreateInstance);
55d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
56d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
57d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystem *
58d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::CreateInstance (Process *process, bool force)
59d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
60d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    // Python OperatingSystem plug-ins must be requested by name, so force must be true
612e7f313dc473b036788319690116b324cb44b765Greg Clayton    FileSpec python_os_plugin_spec (process->GetPythonOSPluginPath());
622e7f313dc473b036788319690116b324cb44b765Greg Clayton    if (python_os_plugin_spec && python_os_plugin_spec.Exists())
632e7f313dc473b036788319690116b324cb44b765Greg Clayton    {
642e7f313dc473b036788319690116b324cb44b765Greg Clayton        std::auto_ptr<OperatingSystemPython> os_ap (new OperatingSystemPython (process, python_os_plugin_spec));
652e7f313dc473b036788319690116b324cb44b765Greg Clayton        if (os_ap.get() && os_ap->IsValid())
662e7f313dc473b036788319690116b324cb44b765Greg Clayton            return os_ap.release();
672e7f313dc473b036788319690116b324cb44b765Greg Clayton    }
68d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return NULL;
69d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
70d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
71d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
72d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonconst char *
73d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginNameStatic()
74d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
75d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return "python";
76d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
77d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
78d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonconst char *
79d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginDescriptionStatic()
80d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
81d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality.";
82d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
83d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
84d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
852e7f313dc473b036788319690116b324cb44b765Greg ClaytonOperatingSystemPython::OperatingSystemPython (lldb_private::Process *process, const FileSpec &python_module_path) :
86d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    OperatingSystem (process),
87d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    m_thread_list_valobj_sp (),
88155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    m_register_info_ap (),
892e7f313dc473b036788319690116b324cb44b765Greg Clayton    m_interpreter (NULL),
902e7f313dc473b036788319690116b324cb44b765Greg Clayton    m_python_object (NULL)
91d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
92155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    if (!process)
93155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata        return;
94155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    lldb::TargetSP target_sp = process->CalculateTarget();
95155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    if (!target_sp)
96155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata        return;
97155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
98155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    if (m_interpreter)
99155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    {
1002e7f313dc473b036788319690116b324cb44b765Greg Clayton
1012e7f313dc473b036788319690116b324cb44b765Greg Clayton        std::string os_plugin_class_name (python_module_path.GetFilename().AsCString(""));
1022e7f313dc473b036788319690116b324cb44b765Greg Clayton        if (!os_plugin_class_name.empty())
10388b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        {
1042e7f313dc473b036788319690116b324cb44b765Greg Clayton            const bool init_session = false;
1052e7f313dc473b036788319690116b324cb44b765Greg Clayton            const bool allow_reload = true;
1062e7f313dc473b036788319690116b324cb44b765Greg Clayton            char python_module_path_cstr[PATH_MAX];
1072e7f313dc473b036788319690116b324cb44b765Greg Clayton            python_module_path.GetPath(python_module_path_cstr, sizeof(python_module_path_cstr));
1082e7f313dc473b036788319690116b324cb44b765Greg Clayton            Error error;
1092e7f313dc473b036788319690116b324cb44b765Greg Clayton            if (m_interpreter->LoadScriptingModule (python_module_path_cstr, allow_reload, init_session, error))
1102e7f313dc473b036788319690116b324cb44b765Greg Clayton            {
1112e7f313dc473b036788319690116b324cb44b765Greg Clayton                // Strip the ".py" extension if there is one
1122e7f313dc473b036788319690116b324cb44b765Greg Clayton                size_t py_extension_pos = os_plugin_class_name.rfind(".py");
1132e7f313dc473b036788319690116b324cb44b765Greg Clayton                if (py_extension_pos != std::string::npos)
1142e7f313dc473b036788319690116b324cb44b765Greg Clayton                    os_plugin_class_name.erase (py_extension_pos);
1152e7f313dc473b036788319690116b324cb44b765Greg Clayton                // Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn"
1162e7f313dc473b036788319690116b324cb44b765Greg Clayton                os_plugin_class_name += ".OperatingSystemPlugIn";
1172e7f313dc473b036788319690116b324cb44b765Greg Clayton                auto object_sp = m_interpreter->CreateOSPlugin(os_plugin_class_name.c_str(), process->CalculateProcess());
1182e7f313dc473b036788319690116b324cb44b765Greg Clayton                if (object_sp)
1192e7f313dc473b036788319690116b324cb44b765Greg Clayton                    m_python_object = object_sp->GetObject();
1202e7f313dc473b036788319690116b324cb44b765Greg Clayton            }
12188b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        }
122155ee91cc315888c26de1bfebd876bf35b857329Enrico Granata    }
123d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
124d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
125d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::~OperatingSystemPython ()
126d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
127d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
128d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
129d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonDynamicRegisterInfo *
130d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetDynamicRegisterInfo ()
131d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
13288b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton    if (m_register_info_ap.get() == NULL)
133d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    {
13488b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        if (!m_interpreter || !m_python_object)
13588b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton            return NULL;
136467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
137467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
138467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton        if (log)
1395f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID());
140467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
14188b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
14288b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        if (!object_sp)
14388b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton            return NULL;
14488b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
14588b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
14688b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        if (!dictionary)
14788b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton            return NULL;
14888b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton
14988b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        m_register_info_ap.reset (new DynamicRegisterInfo (dictionary));
15088b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        assert (m_register_info_ap->GetNumRegisters() > 0);
15188b980bfd735c4691b7f0771a45a78cb75033564Greg Clayton        assert (m_register_info_ap->GetNumRegisterSets() > 0);
152d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    }
153d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return m_register_info_ap.get();
154d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
155d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
156d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//------------------------------------------------------------------
157d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton// PluginInterface protocol
158d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton//------------------------------------------------------------------
159d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonconst char *
160d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginName()
161d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
162d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return "OperatingSystemPython";
163d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
164d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
165d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonconst char *
166d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetShortPluginName()
167d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
168d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return GetPluginNameStatic();
169d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
170d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
171d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonuint32_t
172d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::GetPluginVersion()
173d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
174d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return 1;
175d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
176d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
177d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonbool
178d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
179d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
1803e85b6378d312866ab25eb5623d9b8253bc498f8Enrico Granata    if (!m_interpreter || !m_python_object)
181b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea        return false;
182467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
183467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
184467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
1854a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    // First thing we have to do is get the API lock, and the run lock.  We're going to change the thread
1864a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    // content of the process, and we're going to use python, which requires the API lock to do it.
1874a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    // So get & hold that.  This is a recursive lock so we can grant it to any Python code called on the stack below us.
1884a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    Target &target = m_process->GetTarget();
1894a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    Mutex::Locker api_locker (target.GetAPIMutex());
1904a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham
191467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton    if (log)
1925f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID());
193467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
1943e85b6378d312866ab25eb5623d9b8253bc498f8Enrico Granata    auto object_sp = m_interpreter->OSPlugin_QueryForThreadsInfo(m_interpreter->MakeScriptObject(m_python_object));
1953e85b6378d312866ab25eb5623d9b8253bc498f8Enrico Granata    if (!object_sp)
196b9db9d5bb01963774f28540dbe2c5a11f586ff29Daniel Malea        return false;
197a63665a17f889d69384abc82311c671b9809419cGreg Clayton    PythonDataObject pyobj((PyObject*)object_sp->GetObject());
198b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    PythonDataArray threads_array (pyobj.GetArrayObject());
199b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    if (threads_array)
200b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    {
201b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//        const uint32_t num_old_threads = old_thread_list.GetSize(false);
202b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//        for (uint32_t i=0; i<num_old_threads; ++i)
203b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//        {
204b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//            ThreadSP old_thread_sp(old_thread_list.GetThreadAtIndex(i, false));
205b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//            if (old_thread_sp->GetID() < 0x10000)
206b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//                new_thread_list.AddThread (old_thread_sp);
207b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton//        }
208b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton
209b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        PythonDataString tid_pystr("tid");
210b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        PythonDataString name_pystr("name");
211b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        PythonDataString queue_pystr("queue");
212b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        PythonDataString state_pystr("state");
213b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        PythonDataString stop_reason_pystr("stop_reason");
21491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        PythonDataString reg_data_addr_pystr ("register_data_addr");
215b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton
216b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        const uint32_t num_threads = threads_array.GetSize();
217b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        for (uint32_t i=0; i<num_threads; ++i)
218b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        {
219b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton            PythonDataDictionary thread_dict(threads_array.GetItemAtIndex(i).GetDictionaryObject());
220b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton            if (thread_dict)
221b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton            {
22291a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID);
22391a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS);
224b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
225b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
226b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
227b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
228b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton
229b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
230b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                if (!thread_sp)
23194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                    thread_sp.reset (new ThreadMemory (*m_process,
232b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                                                       tid,
233b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                                                       name,
23491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                                                       queue,
23591a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                                                       reg_data_addr));
236b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton                new_thread_list.AddThread(thread_sp);
237b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton
238b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton            }
239b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        }
240b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    }
241b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    else
242b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    {
243b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        new_thread_list = old_thread_list;
244b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    }
245d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return new_thread_list.GetSize(false) > 0;
246d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
247d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
248d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Claytonvoid
249d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::ThreadWasSelected (Thread *thread)
250d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
251d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
252d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
253d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonRegisterContextSP
25491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg ClaytonOperatingSystemPython::CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr)
255d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
256b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    RegisterContextSP reg_ctx_sp;
2573e85b6378d312866ab25eb5623d9b8253bc498f8Enrico Granata    if (!m_interpreter || !m_python_object || !thread)
258915da3534f6024d9983e0ba94142936df8745562Filipe Cabecinhas        return RegisterContextSP();
259467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
2604a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    // First thing we have to do is get the API lock, and the run lock.  We're going to change the thread
2614a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    // content of the process, and we're going to use python, which requires the API lock to do it.
2624a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    // So get & hold that.  This is a recursive lock so we can grant it to any Python code called on the stack below us.
2634a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    Target &target = m_process->GetTarget();
2644a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham    Mutex::Locker api_locker (target.GetAPIMutex());
2654a96ab8a1d4e2222b9f6e415b97bde6b826f94a4Jim Ingham
266467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
267467e1ea328873763db41d47196b4ecd56cdde11bGreg Clayton
26891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton    if (reg_data_addr != LLDB_INVALID_ADDRESS)
269b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    {
27091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        // The registers data is in contiguous memory, just create the register
27191a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        // context using the address provided
27291a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        if (log)
2735f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", thread->GetID(), reg_data_addr);
27491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr));
27591a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton    }
27691a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton    else
27791a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton    {
27891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        // No register data address is provided, query the python plug-in to let
27991a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        // it make up the data as it sees fit
28091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        if (log)
2815f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") fetching register data from python", thread->GetID());
28291a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton
28391a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
28491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                                                                              thread->GetID());
28591a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton
28691a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        if (!object_sp)
28791a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton            return RegisterContextSP();
28891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton
28991a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
29091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton        if (reg_context_data)
291b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        {
29291a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton            DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(),
29391a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                                                      reg_context_data.GetSize()));
29491a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton            if (data_sp->GetByteSize())
295b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton            {
29691a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                RegisterContextMemory *reg_ctx_memory = new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), LLDB_INVALID_ADDRESS);
29791a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                if (reg_ctx_memory)
29891a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                {
29991a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                    reg_ctx_sp.reset(reg_ctx_memory);
30091a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                    reg_ctx_memory->SetAllRegisterData (data_sp);
30191a9f2127fa8b8e90f6ea1676d11f97f44ce22ddGreg Clayton                }
302b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton            }
303b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton        }
304b8f126a807c00e5c2d0e7faaf764c38072cd6764Greg Clayton    }
305d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return reg_ctx_sp;
306d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
307d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
308d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonStopInfoSP
309d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg ClaytonOperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread)
310d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton{
311d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    // We should have gotten the thread stop info from the dictionary of data for
312d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    // the thread in the initial call to get_thread_info(), this should have been
313d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    // cached so we can return it here
314d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
315d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton    return stop_info_sp;
316d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton}
317d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
318d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton
319d815ded12b0c9fea2c8a38cc241d3609b3fe228aGreg Clayton#endif // #ifndef LLDB_DISABLE_PYTHON
320