1*be691f3bSpatrick //===-- ScriptedProcessPythonInterface.cpp --------------------------------===// 2*be691f3bSpatrick // 3*be691f3bSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*be691f3bSpatrick // See https://llvm.org/LICENSE.txt for license information. 5*be691f3bSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*be691f3bSpatrick // 7*be691f3bSpatrick //===----------------------------------------------------------------------===// 8*be691f3bSpatrick 9*be691f3bSpatrick #include "lldb/Host/Config.h" 10*be691f3bSpatrick #include "lldb/lldb-enumerations.h" 11*be691f3bSpatrick 12*be691f3bSpatrick #if LLDB_ENABLE_PYTHON 13*be691f3bSpatrick 14*be691f3bSpatrick // LLDB Python header must be included first 15*be691f3bSpatrick #include "lldb-python.h" 16*be691f3bSpatrick 17*be691f3bSpatrick #include "SWIGPythonBridge.h" 18*be691f3bSpatrick #include "ScriptInterpreterPythonImpl.h" 19*be691f3bSpatrick #include "ScriptedProcessPythonInterface.h" 20*be691f3bSpatrick 21*be691f3bSpatrick using namespace lldb; 22*be691f3bSpatrick using namespace lldb_private; 23*be691f3bSpatrick using namespace lldb_private::python; 24*be691f3bSpatrick using Locker = ScriptInterpreterPythonImpl::Locker; 25*be691f3bSpatrick 26*be691f3bSpatrick StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( 27*be691f3bSpatrick const llvm::StringRef class_name, lldb::TargetSP target_sp, 28*be691f3bSpatrick StructuredData::DictionarySP args_sp) { 29*be691f3bSpatrick if (class_name.empty()) 30*be691f3bSpatrick return {}; 31*be691f3bSpatrick 32*be691f3bSpatrick std::string error_string; 33*be691f3bSpatrick StructuredDataImpl *args_impl = nullptr; 34*be691f3bSpatrick if (args_sp) { 35*be691f3bSpatrick args_impl = new StructuredDataImpl(); 36*be691f3bSpatrick args_impl->SetObjectSP(args_sp); 37*be691f3bSpatrick } 38*be691f3bSpatrick 39*be691f3bSpatrick void *ret_val; 40*be691f3bSpatrick 41*be691f3bSpatrick { 42*be691f3bSpatrick 43*be691f3bSpatrick Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 44*be691f3bSpatrick Locker::FreeLock); 45*be691f3bSpatrick 46*be691f3bSpatrick ret_val = LLDBSwigPythonCreateScriptedProcess( 47*be691f3bSpatrick class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, 48*be691f3bSpatrick args_impl, error_string); 49*be691f3bSpatrick } 50*be691f3bSpatrick 51*be691f3bSpatrick m_object_instance_sp = 52*be691f3bSpatrick StructuredData::GenericSP(new StructuredPythonObject(ret_val)); 53*be691f3bSpatrick 54*be691f3bSpatrick return m_object_instance_sp; 55*be691f3bSpatrick } 56*be691f3bSpatrick 57*be691f3bSpatrick Status ScriptedProcessPythonInterface::Launch() { 58*be691f3bSpatrick return GetStatusFromMethod("launch"); 59*be691f3bSpatrick } 60*be691f3bSpatrick 61*be691f3bSpatrick Status ScriptedProcessPythonInterface::Resume() { 62*be691f3bSpatrick return GetStatusFromMethod("resume"); 63*be691f3bSpatrick } 64*be691f3bSpatrick 65*be691f3bSpatrick bool ScriptedProcessPythonInterface::ShouldStop() { 66*be691f3bSpatrick llvm::Optional<unsigned long long> should_stop = 67*be691f3bSpatrick GetGenericInteger("should_stop"); 68*be691f3bSpatrick 69*be691f3bSpatrick if (!should_stop) 70*be691f3bSpatrick return false; 71*be691f3bSpatrick 72*be691f3bSpatrick return static_cast<bool>(*should_stop); 73*be691f3bSpatrick } 74*be691f3bSpatrick 75*be691f3bSpatrick Status ScriptedProcessPythonInterface::Stop() { 76*be691f3bSpatrick return GetStatusFromMethod("stop"); 77*be691f3bSpatrick } 78*be691f3bSpatrick 79*be691f3bSpatrick Status ScriptedProcessPythonInterface::GetStatusFromMethod( 80*be691f3bSpatrick llvm::StringRef method_name) { 81*be691f3bSpatrick Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 82*be691f3bSpatrick Locker::FreeLock); 83*be691f3bSpatrick 84*be691f3bSpatrick if (!m_object_instance_sp) 85*be691f3bSpatrick return Status("Python object ill-formed."); 86*be691f3bSpatrick 87*be691f3bSpatrick if (!m_object_instance_sp) 88*be691f3bSpatrick return Status("Cannot convert Python object to StructuredData::Generic."); 89*be691f3bSpatrick PythonObject implementor(PyRefType::Borrowed, 90*be691f3bSpatrick (PyObject *)m_object_instance_sp->GetValue()); 91*be691f3bSpatrick 92*be691f3bSpatrick if (!implementor.IsAllocated()) 93*be691f3bSpatrick return Status("Python implementor not allocated."); 94*be691f3bSpatrick 95*be691f3bSpatrick PythonObject pmeth( 96*be691f3bSpatrick PyRefType::Owned, 97*be691f3bSpatrick PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); 98*be691f3bSpatrick 99*be691f3bSpatrick if (PyErr_Occurred()) 100*be691f3bSpatrick PyErr_Clear(); 101*be691f3bSpatrick 102*be691f3bSpatrick if (!pmeth.IsAllocated()) 103*be691f3bSpatrick return Status("Python method not allocated."); 104*be691f3bSpatrick 105*be691f3bSpatrick if (PyCallable_Check(pmeth.get()) == 0) { 106*be691f3bSpatrick if (PyErr_Occurred()) 107*be691f3bSpatrick PyErr_Clear(); 108*be691f3bSpatrick return Status("Python method not callable."); 109*be691f3bSpatrick } 110*be691f3bSpatrick 111*be691f3bSpatrick if (PyErr_Occurred()) 112*be691f3bSpatrick PyErr_Clear(); 113*be691f3bSpatrick 114*be691f3bSpatrick PythonObject py_return(PyRefType::Owned, 115*be691f3bSpatrick PyObject_CallMethod(implementor.get(), 116*be691f3bSpatrick method_name.str().c_str(), 117*be691f3bSpatrick nullptr)); 118*be691f3bSpatrick 119*be691f3bSpatrick if (PyErr_Occurred()) { 120*be691f3bSpatrick PyErr_Print(); 121*be691f3bSpatrick PyErr_Clear(); 122*be691f3bSpatrick return Status("Python method could not be called."); 123*be691f3bSpatrick } 124*be691f3bSpatrick 125*be691f3bSpatrick if (PyObject *py_ret_ptr = py_return.get()) { 126*be691f3bSpatrick lldb::SBError *sb_error = 127*be691f3bSpatrick (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr); 128*be691f3bSpatrick 129*be691f3bSpatrick if (!sb_error) 130*be691f3bSpatrick return Status("Couldn't cast lldb::SBError to lldb::Status."); 131*be691f3bSpatrick 132*be691f3bSpatrick Status status = m_interpreter.GetStatusFromSBError(*sb_error); 133*be691f3bSpatrick 134*be691f3bSpatrick if (status.Fail()) 135*be691f3bSpatrick return Status("error: %s", status.AsCString()); 136*be691f3bSpatrick 137*be691f3bSpatrick return status; 138*be691f3bSpatrick } 139*be691f3bSpatrick 140*be691f3bSpatrick return Status("Returned object is null."); 141*be691f3bSpatrick } 142*be691f3bSpatrick 143*be691f3bSpatrick llvm::Optional<unsigned long long> 144*be691f3bSpatrick ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) { 145*be691f3bSpatrick Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 146*be691f3bSpatrick Locker::FreeLock); 147*be691f3bSpatrick 148*be691f3bSpatrick if (!m_object_instance_sp) 149*be691f3bSpatrick return llvm::None; 150*be691f3bSpatrick 151*be691f3bSpatrick if (!m_object_instance_sp) 152*be691f3bSpatrick return llvm::None; 153*be691f3bSpatrick PythonObject implementor(PyRefType::Borrowed, 154*be691f3bSpatrick (PyObject *)m_object_instance_sp->GetValue()); 155*be691f3bSpatrick 156*be691f3bSpatrick if (!implementor.IsAllocated()) 157*be691f3bSpatrick return llvm::None; 158*be691f3bSpatrick 159*be691f3bSpatrick PythonObject pmeth( 160*be691f3bSpatrick PyRefType::Owned, 161*be691f3bSpatrick PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); 162*be691f3bSpatrick 163*be691f3bSpatrick if (PyErr_Occurred()) 164*be691f3bSpatrick PyErr_Clear(); 165*be691f3bSpatrick 166*be691f3bSpatrick if (!pmeth.IsAllocated()) 167*be691f3bSpatrick return llvm::None; 168*be691f3bSpatrick 169*be691f3bSpatrick if (PyCallable_Check(pmeth.get()) == 0) { 170*be691f3bSpatrick if (PyErr_Occurred()) 171*be691f3bSpatrick PyErr_Clear(); 172*be691f3bSpatrick return llvm::None; 173*be691f3bSpatrick } 174*be691f3bSpatrick 175*be691f3bSpatrick if (PyErr_Occurred()) 176*be691f3bSpatrick PyErr_Clear(); 177*be691f3bSpatrick 178*be691f3bSpatrick PythonObject py_return(PyRefType::Owned, 179*be691f3bSpatrick PyObject_CallMethod(implementor.get(), 180*be691f3bSpatrick method_name.str().c_str(), 181*be691f3bSpatrick nullptr)); 182*be691f3bSpatrick 183*be691f3bSpatrick if (PyErr_Occurred()) { 184*be691f3bSpatrick PyErr_Print(); 185*be691f3bSpatrick PyErr_Clear(); 186*be691f3bSpatrick } 187*be691f3bSpatrick 188*be691f3bSpatrick if (!py_return.get()) 189*be691f3bSpatrick return llvm::None; 190*be691f3bSpatrick 191*be691f3bSpatrick llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong(); 192*be691f3bSpatrick // FIXME: Handle error. 193*be691f3bSpatrick if (!size) 194*be691f3bSpatrick return llvm::None; 195*be691f3bSpatrick 196*be691f3bSpatrick return *size; 197*be691f3bSpatrick } 198*be691f3bSpatrick 199*be691f3bSpatrick lldb::MemoryRegionInfoSP 200*be691f3bSpatrick ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( 201*be691f3bSpatrick lldb::addr_t address) { 202*be691f3bSpatrick // TODO: Implement 203*be691f3bSpatrick return nullptr; 204*be691f3bSpatrick } 205*be691f3bSpatrick 206*be691f3bSpatrick StructuredData::DictionarySP 207*be691f3bSpatrick ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { 208*be691f3bSpatrick // TODO: Implement 209*be691f3bSpatrick return nullptr; 210*be691f3bSpatrick } 211*be691f3bSpatrick 212*be691f3bSpatrick StructuredData::DictionarySP 213*be691f3bSpatrick ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { 214*be691f3bSpatrick // TODO: Implement 215*be691f3bSpatrick return nullptr; 216*be691f3bSpatrick } 217*be691f3bSpatrick 218*be691f3bSpatrick lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( 219*be691f3bSpatrick lldb::addr_t address, size_t size, Status &error) { 220*be691f3bSpatrick Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, 221*be691f3bSpatrick Locker::FreeLock); 222*be691f3bSpatrick 223*be691f3bSpatrick auto error_with_message = [&error](llvm::StringRef message) { 224*be691f3bSpatrick error.SetErrorString(message); 225*be691f3bSpatrick return nullptr; 226*be691f3bSpatrick }; 227*be691f3bSpatrick 228*be691f3bSpatrick static char callee_name[] = "read_memory_at_address"; 229*be691f3bSpatrick std::string param_format = GetPythonValueFormatString(address); 230*be691f3bSpatrick param_format += GetPythonValueFormatString(size); 231*be691f3bSpatrick 232*be691f3bSpatrick if (!m_object_instance_sp) 233*be691f3bSpatrick return error_with_message("Python object ill-formed."); 234*be691f3bSpatrick 235*be691f3bSpatrick if (!m_object_instance_sp) 236*be691f3bSpatrick return error_with_message("Python method not callable."); 237*be691f3bSpatrick 238*be691f3bSpatrick PythonObject implementor(PyRefType::Borrowed, 239*be691f3bSpatrick (PyObject *)m_object_instance_sp->GetValue()); 240*be691f3bSpatrick 241*be691f3bSpatrick if (!implementor.IsAllocated()) 242*be691f3bSpatrick return error_with_message("Python implementor not allocated."); 243*be691f3bSpatrick 244*be691f3bSpatrick PythonObject pmeth(PyRefType::Owned, 245*be691f3bSpatrick PyObject_GetAttrString(implementor.get(), callee_name)); 246*be691f3bSpatrick 247*be691f3bSpatrick if (PyErr_Occurred()) 248*be691f3bSpatrick PyErr_Clear(); 249*be691f3bSpatrick 250*be691f3bSpatrick if (!pmeth.IsAllocated()) 251*be691f3bSpatrick return error_with_message("Python method not allocated."); 252*be691f3bSpatrick 253*be691f3bSpatrick if (PyCallable_Check(pmeth.get()) == 0) { 254*be691f3bSpatrick if (PyErr_Occurred()) 255*be691f3bSpatrick PyErr_Clear(); 256*be691f3bSpatrick return error_with_message("Python method not callable."); 257*be691f3bSpatrick } 258*be691f3bSpatrick 259*be691f3bSpatrick if (PyErr_Occurred()) 260*be691f3bSpatrick PyErr_Clear(); 261*be691f3bSpatrick 262*be691f3bSpatrick PythonObject py_return(PyRefType::Owned, 263*be691f3bSpatrick PyObject_CallMethod(implementor.get(), callee_name, 264*be691f3bSpatrick param_format.c_str(), address, 265*be691f3bSpatrick size)); 266*be691f3bSpatrick 267*be691f3bSpatrick if (PyErr_Occurred()) { 268*be691f3bSpatrick PyErr_Print(); 269*be691f3bSpatrick PyErr_Clear(); 270*be691f3bSpatrick return error_with_message("Python method could not be called."); 271*be691f3bSpatrick } 272*be691f3bSpatrick 273*be691f3bSpatrick if (PyObject *py_ret_ptr = py_return.get()) { 274*be691f3bSpatrick lldb::SBData *sb_data = 275*be691f3bSpatrick (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr); 276*be691f3bSpatrick 277*be691f3bSpatrick if (!sb_data) 278*be691f3bSpatrick return error_with_message( 279*be691f3bSpatrick "Couldn't cast lldb::SBData to lldb::DataExtractor."); 280*be691f3bSpatrick 281*be691f3bSpatrick return m_interpreter.GetDataExtractorFromSBData(*sb_data); 282*be691f3bSpatrick } 283*be691f3bSpatrick 284*be691f3bSpatrick return error_with_message("Returned object is null."); 285*be691f3bSpatrick } 286*be691f3bSpatrick 287*be691f3bSpatrick StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { 288*be691f3bSpatrick // TODO: Implement 289*be691f3bSpatrick return nullptr; 290*be691f3bSpatrick } 291*be691f3bSpatrick 292*be691f3bSpatrick lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { 293*be691f3bSpatrick llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id"); 294*be691f3bSpatrick return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid; 295*be691f3bSpatrick } 296*be691f3bSpatrick 297*be691f3bSpatrick bool ScriptedProcessPythonInterface::IsAlive() { 298*be691f3bSpatrick llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive"); 299*be691f3bSpatrick 300*be691f3bSpatrick if (!is_alive) 301*be691f3bSpatrick return false; 302*be691f3bSpatrick 303*be691f3bSpatrick return static_cast<bool>(*is_alive); 304*be691f3bSpatrick } 305*be691f3bSpatrick 306*be691f3bSpatrick #endif 307