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