xref: /llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp (revision b3e776008bff022410508f762d0a376f8708849d)
1 //===-- OperatingSystemPython.cpp --------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_DISABLE_PYTHON
10 
11 #include "OperatingSystemPython.h"
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "llvm/ADT/Triple.h"
16 
17 #include "lldb/Core/ArchSpec.h"
18 #include "lldb/Core/DataBufferHeap.h"
19 #include "lldb/Core/Module.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/RegisterValue.h"
22 #include "lldb/Core/ValueObjectVariable.h"
23 #include "lldb/Symbol/ClangNamespaceDecl.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Symbol/VariableList.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/StopInfo.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/ThreadList.h"
30 #include "lldb/Target/Thread.h"
31 #include "Plugins/Process/Utility/DynamicRegisterInfo.h"
32 #include "Plugins/Process/Utility/RegisterContextMemory.h"
33 #include "Plugins/Process/Utility/ThreadMemory.h"
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 void
39 OperatingSystemPython::Initialize()
40 {
41     PluginManager::RegisterPlugin (GetPluginNameStatic(),
42                                    GetPluginDescriptionStatic(),
43                                    CreateInstance);
44 }
45 
46 void
47 OperatingSystemPython::Terminate()
48 {
49     PluginManager::UnregisterPlugin (CreateInstance);
50 }
51 
52 OperatingSystem *
53 OperatingSystemPython::CreateInstance (Process *process, bool force)
54 {
55     // Python OperatingSystem plug-ins must be requested by name, so force must be true
56     if (force)
57         return new OperatingSystemPython (process);
58     return NULL;
59 }
60 
61 
62 const char *
63 OperatingSystemPython::GetPluginNameStatic()
64 {
65     return "python";
66 }
67 
68 const char *
69 OperatingSystemPython::GetPluginDescriptionStatic()
70 {
71     return "Operating system plug-in that gathers OS information from a python class that implements the necessary OperatingSystem functionality.";
72 }
73 
74 
75 OperatingSystemPython::OperatingSystemPython (lldb_private::Process *process) :
76     OperatingSystem (process),
77     m_thread_list_valobj_sp (),
78     m_register_info_ap ()
79 {
80     // TODO: python: create a new python class the implements the necessary
81     // python class that will cache a SBProcess that contains the "process"
82     // argument above and implements:
83     // dict get_thread_info()
84     // dict get_register_info()
85     // Bytes get_register_context_data(SBThread thread)
86 }
87 
88 OperatingSystemPython::~OperatingSystemPython ()
89 {
90 }
91 
92 DynamicRegisterInfo *
93 OperatingSystemPython::GetDynamicRegisterInfo ()
94 {
95     // TODO: python: call get_register_info() on the python object that
96     // represents our instance of the OperatingSystem plug-in
97 
98     // Example code below shows creating a new DynamicRegisterInfo()
99     if (m_register_info_ap.get() == NULL && m_thread_list_valobj_sp)
100     {
101 //        static ConstString g_gpr_member_name("gpr");
102 //        m_register_info_ap.reset (new DynamicRegisterInfo());
103 //        ConstString empty_name;
104 //        const bool can_create = true;
105 //        AddressType addr_type;
106 //        addr_t base_addr = LLDB_INVALID_ADDRESS;
107 //        ValueObjectSP gpr_valobj_sp (m_thread_list_valobj_sp->GetChildMemberWithName(GetThreadGPRMemberName (), can_create));
108 //
109 //        if (gpr_valobj_sp->IsPointerType ())
110 //            base_addr = gpr_valobj_sp->GetPointerValue (&addr_type);
111 //        else
112 //            base_addr = gpr_valobj_sp->GetAddressOf (true, &addr_type);
113 //
114 //        ValueObjectSP child_valobj_sp;
115 //        if (gpr_valobj_sp)
116 //        {
117 //            ABI *abi = m_process->GetABI().get();
118 //            assert (abi);
119 //            uint32_t num_children = gpr_valobj_sp->GetNumChildren();
120 //
121 //            ConstString gpr_name (gpr_valobj_sp->GetName());
122 //            uint32_t reg_num = 0;
123 //            for (uint32_t i=0; i<num_children; ++i)
124 //            {
125 //                child_valobj_sp = gpr_valobj_sp->GetChildAtIndex(i, can_create);
126 //
127 //                ConstString reg_name(child_valobj_sp->GetName());
128 //                if (reg_name)
129 //                {
130 //                    const char *reg_name_cstr = reg_name.GetCString();
131 //                    while (reg_name_cstr[0] == '_')
132 //                        ++reg_name_cstr;
133 //                    if (reg_name_cstr != reg_name.GetCString())
134 //                        reg_name.SetCString (reg_name_cstr);
135 //                }
136 //
137 //                RegisterInfo reg_info;
138 //                if (abi->GetRegisterInfoByName(reg_name, reg_info))
139 //                {
140 //                    // Adjust the byte size and the offset to match the layout of registers in our struct
141 //                    reg_info.byte_size = child_valobj_sp->GetByteSize();
142 //                    reg_info.byte_offset = child_valobj_sp->GetAddressOf(true, &addr_type) - base_addr;
143 //                    reg_info.kinds[eRegisterKindLLDB] = reg_num++;
144 //                    m_register_info_ap->AddRegister (reg_info, reg_name, empty_name, gpr_name);
145 //                }
146 //                else
147 //                {
148 //                    printf ("not able to find register info for %s\n", reg_name.GetCString()); // REMOVE THIS printf before checkin!!!
149 //                }
150 //            }
151 //
152 //            m_register_info_ap->Finalize();
153 //        }
154     }
155     assert (m_register_info_ap.get());
156     return m_register_info_ap.get();
157 }
158 
159 //------------------------------------------------------------------
160 // PluginInterface protocol
161 //------------------------------------------------------------------
162 const char *
163 OperatingSystemPython::GetPluginName()
164 {
165     return "OperatingSystemPython";
166 }
167 
168 const char *
169 OperatingSystemPython::GetShortPluginName()
170 {
171     return GetPluginNameStatic();
172 }
173 
174 uint32_t
175 OperatingSystemPython::GetPluginVersion()
176 {
177     return 1;
178 }
179 
180 bool
181 OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
182 {
183     // TODO: python: call "dict get_thread_info()" on the
184     // python object that represents our instance of the OperatingSystem plug-in
185     // and parse the returned dictionary. We need to pass in the a Dictionary
186     // with the same kind of info we want back so we can reuse old threads, but
187     // only create new ones.
188 
189     // Make any constant strings once and cache the uniqued C string values
190     // so we don't have to rehash them each time through this function call
191 //    dict thread_info_dict = python.get_thread_info()
192 //    for thread_info in thread_info_dict:
193 //    {
194 //        ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
195 //        if (!thread_sp)
196 //            thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
197 //        new_thread_list.AddThread(thread_sp);
198 //    }
199     new_thread_list = old_thread_list;
200     return new_thread_list.GetSize(false) > 0;
201 }
202 
203 void
204 OperatingSystemPython::ThreadWasSelected (Thread *thread)
205 {
206 }
207 
208 RegisterContextSP
209 OperatingSystemPython::CreateRegisterContextForThread (Thread *thread)
210 {
211     // TODO: python: call "bytes get_register_context_data(SBThread thread)"
212     // and populate resulting data into thread
213     RegisterContextSP reg_ctx_sp;
214 //    bytes b = get_register_context_data(thread)
215 //    if (b)
216 //    {
217 //        reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), base_addr));
218 //        // set bytes
219 //    }
220     return reg_ctx_sp;
221 }
222 
223 StopInfoSP
224 OperatingSystemPython::CreateThreadStopReason (lldb_private::Thread *thread)
225 {
226     // We should have gotten the thread stop info from the dictionary of data for
227     // the thread in the initial call to get_thread_info(), this should have been
228     // cached so we can return it here
229     StopInfoSP stop_info_sp; //(StopInfo::CreateStopReasonWithSignal (*thread, SIGSTOP));
230     return stop_info_sp;
231 }
232 
233 
234 #endif // #ifndef LLDB_DISABLE_PYTHON
235