aboutsummaryrefslogtreecommitdiff
path: root/lldb/bindings/python
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/bindings/python')
-rw-r--r--lldb/bindings/python/CMakeLists.txt9
-rwxr-xr-xlldb/bindings/python/get-python-config.py8
-rw-r--r--lldb/bindings/python/python-swigsafecast.swig5
-rw-r--r--lldb/bindings/python/python-typemaps.h19
-rw-r--r--lldb/bindings/python/python-typemaps.swig71
-rw-r--r--lldb/bindings/python/python-wrapper.swig31
-rw-r--r--lldb/bindings/python/python.swig12
7 files changed, 84 insertions, 71 deletions
diff --git a/lldb/bindings/python/CMakeLists.txt b/lldb/bindings/python/CMakeLists.txt
index ef6def3..2ebcf5a 100644
--- a/lldb/bindings/python/CMakeLists.txt
+++ b/lldb/bindings/python/CMakeLists.txt
@@ -60,8 +60,10 @@ endfunction()
function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_target_dir)
# Add a Post-Build Event to copy over Python files and create the symlink to
# liblldb.so for the Python API(hardlink on Windows).
+ # Note that Swig-generated code is located one level deeper in the `native`
+ # module, in order to avoid cyclic importing.
add_custom_target(${swig_target} ALL VERBATIM
- COMMAND ${CMAKE_COMMAND} -E make_directory ${lldb_python_target_dir}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${lldb_python_target_dir}/native/
DEPENDS ${lldb_python_bindings_dir}/lldb.py
COMMENT "Python script sym-linking LLDB Python API")
@@ -75,6 +77,8 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
"${LLDB_SOURCE_DIR}/source/Interpreter/embedded_interpreter.py"
"${lldb_python_target_dir}")
+ create_python_package(${swig_target} ${lldb_python_target_dir} "native" FILES)
+
# Distribute the examples as python packages.
create_python_package(
${swig_target}
@@ -107,6 +111,7 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
"plugins"
FILES
"${LLDB_SOURCE_DIR}/examples/python/templates/parsed_cmd.py"
+ "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_frame_provider.py"
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py"
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py"
"${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py"
@@ -142,7 +147,7 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
endif()
set(LIBLLDB_SYMLINK_OUTPUT_FILE "_lldb${LLDB_PYTHON_EXT_SUFFIX}")
create_relative_symlink(${swig_target} ${LIBLLDB_SYMLINK_DEST}
- ${lldb_python_target_dir} ${LIBLLDB_SYMLINK_OUTPUT_FILE})
+ ${lldb_python_target_dir}/native/ ${LIBLLDB_SYMLINK_OUTPUT_FILE})
if (NOT WIN32)
diff --git a/lldb/bindings/python/get-python-config.py b/lldb/bindings/python/get-python-config.py
index ae84cbb..bf8cc48 100755
--- a/lldb/bindings/python/get-python-config.py
+++ b/lldb/bindings/python/get-python-config.py
@@ -18,6 +18,9 @@ def relpath_nodots(path, base):
def main():
parser = argparse.ArgumentParser(description="extract cmake variables from python")
parser.add_argument("variable_name")
+ parser.add_argument(
+ "--stable-abi", action="store_true", help="Target the Stable C ABI"
+ )
args = parser.parse_args()
if args.variable_name == "LLDB_PYTHON_RELATIVE_PATH":
# LLDB_PYTHON_RELATIVE_PATH is the relative path from lldb's prefix
@@ -68,7 +71,10 @@ def main():
print("sys.prefix:", sys.prefix, file=sys.stderr)
sys.exit(1)
elif args.variable_name == "LLDB_PYTHON_EXT_SUFFIX":
- print(sysconfig.get_config_var("EXT_SUFFIX"))
+ if args.stable_abi:
+ print(".abi3%s" % sysconfig.get_config_var("SHLIB_SUFFIX"))
+ else:
+ print(sysconfig.get_config_var("EXT_SUFFIX"))
else:
parser.error(f"unknown variable {args.variable_name}")
diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig
index 3ea24f1..a86dc44 100644
--- a/lldb/bindings/python/python-swigsafecast.swig
+++ b/lldb/bindings/python/python-swigsafecast.swig
@@ -37,6 +37,11 @@ PythonObject SWIGBridge::ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp) {
SWIGTYPE_p_lldb__SBThreadPlan);
}
+PythonObject SWIGBridge::ToSWIGWrapper(lldb::StackFrameListSP frames_sp) {
+ return ToSWIGHelper(new lldb::SBFrameList(std::move(frames_sp)),
+ SWIGTYPE_p_lldb__SBFrameList);
+}
+
PythonObject SWIGBridge::ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp) {
return ToSWIGHelper(new lldb::SBBreakpoint(std::move(breakpoint_sp)),
SWIGTYPE_p_lldb__SBBreakpoint);
diff --git a/lldb/bindings/python/python-typemaps.h b/lldb/bindings/python/python-typemaps.h
deleted file mode 100644
index 8a533e8..0000000
--- a/lldb/bindings/python/python-typemaps.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
-#define LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
-
-#include <Python.h>
-
-// Defined here instead of a .swig file because SWIG 2 doesn't support
-// explicit deleted functions.
-struct Py_buffer_RAII {
- Py_buffer buffer = {};
- Py_buffer_RAII(){};
- Py_buffer &operator=(const Py_buffer_RAII &) = delete;
- Py_buffer_RAII(const Py_buffer_RAII &) = delete;
- ~Py_buffer_RAII() {
- if (buffer.obj)
- PyBuffer_Release(&buffer);
- }
-};
-
-#endif // LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig
index 4d3a957..072e688 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -6,12 +6,6 @@ AND call SWIG_fail at the same time, because it will result in a double free.
*/
-%inline %{
-
-#include "../bindings/python/python-typemaps.h"
-
-%}
-
%typemap(in) char ** {
/* Check if is a list */
if (PythonList::Check($input)) {
@@ -634,49 +628,34 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
}
}
-// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
-// and fixed so they will not crash if PyObject_GetBuffer fails.
-// https://github.com/swig/swig/issues/1640
-//
-// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper,
-// doing it right away is not legal according to the python buffer protocol.
-
-%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
-%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
- int res;
- Py_ssize_t size = 0;
- void *buf = 0;
- res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE);
- if (res < 0) {
- PyErr_Clear();
- %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
- }
- size = view.buffer.len;
- buf = view.buffer.buf;
- $1 = ($1_ltype)buf;
- $2 = ($2_ltype)(size / sizeof($*1_type));
-}
-%enddef
-
-%define %pybuffer_binary(TYPEMAP, SIZE)
-%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
- int res;
- Py_ssize_t size = 0;
- const void *buf = 0;
- res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO);
- if (res < 0) {
- PyErr_Clear();
- %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
+
+// Typemap for SBFile::Write.
+%typemap(in) (const uint8_t *buf, size_t num_bytes) {
+ if (PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (uint8_t *)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ } else if (PythonBytes::Check($input)) {
+ PythonBytes bytes(PyRefType::Borrowed, $input);
+ $1 = (uint8_t *)bytes.GetBytes().data();
+ $2 = bytes.GetSize();
+ } else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a bytes or bytearray object");
+ SWIG_fail;
}
- size = view.buffer.len;
- buf = view.buffer.buf;
- $1 = ($1_ltype)buf;
- $2 = ($2_ltype)(size / sizeof($*1_type));
}
-%enddef
-%pybuffer_binary(const uint8_t *buf, size_t num_bytes);
-%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes);
+// Typemap for SBFile::Read.
+%typemap(in) (uint8_t *buf, size_t num_bytes) {
+ if (PythonByteArray::Check($input)) {
+ PythonByteArray bytearray(PyRefType::Borrowed, $input);
+ $1 = (uint8_t *)bytearray.GetBytes().data();
+ $2 = bytearray.GetSize();
+ } else {
+ PyErr_SetString(PyExc_ValueError, "Expecting a bytearray");
+ SWIG_fail;
+ }
+}
%typemap(in) (const char **symbol_name, uint32_t num_names) {
using namespace lldb_private;
diff --git a/lldb/bindings/python/python-wrapper.swig b/lldb/bindings/python/python-wrapper.swig
index e7acba5..0ba1521 100644
--- a/lldb/bindings/python/python-wrapper.swig
+++ b/lldb/bindings/python/python-wrapper.swig
@@ -128,8 +128,11 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallTypeScript(
PyObject *pfunc_impl = nullptr;
- if (pyfunct_wrapper && *pyfunct_wrapper &&
- PyFunction_Check(*pyfunct_wrapper)) {
+ if (pyfunct_wrapper && *pyfunct_wrapper
+#ifndef Py_LIMITED_API
+ && PyFunction_Check(*pyfunct_wrapper)
+#endif
+ ) {
pfunc_impl = (PyObject *)(*pyfunct_wrapper);
if (pfunc_impl->ob_refcnt == 1) {
Py_XDECREF(pfunc_impl);
@@ -422,6 +425,18 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *
return sb_ptr;
}
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBThread(PyObject * data) {
+ lldb::SBThread *sb_ptr = nullptr;
+
+ int valid_cast =
+ SWIG_ConvertPtr(data, (void **)&sb_ptr, SWIGTYPE_p_lldb__SBThread, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
+
void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrame(PyObject * data) {
lldb::SBFrame *sb_ptr = nullptr;
@@ -556,6 +571,18 @@ void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(PyOb
return sb_ptr;
}
+void *lldb_private::python::LLDBSWIGPython_CastPyObjectToSBFrameList(PyObject *data) {
+ lldb::SBFrameList *sb_ptr = NULL;
+
+ int valid_cast = SWIG_ConvertPtr(data, (void **)&sb_ptr,
+ SWIGTYPE_p_lldb__SBFrameList, 0);
+
+ if (valid_cast == -1)
+ return NULL;
+
+ return sb_ptr;
+}
+
bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommand(
const char *python_function_name, const char *session_dictionary_name,
lldb::DebuggerSP debugger, const char *args,
diff --git a/lldb/bindings/python/python.swig b/lldb/bindings/python/python.swig
index 4a5a39d..3d2caa6 100644
--- a/lldb/bindings/python/python.swig
+++ b/lldb/bindings/python/python.swig
@@ -50,7 +50,12 @@ Older swig versions will simply ignore this setting.
import $module
except ImportError:
# Relative import should work if we are being loaded by Python.
- from . import $module"
+ # The cpython module built by swig is pushed one level down into
+ # the native submodule, because at this point the interpreter
+ # is still constructing the lldb module itself.
+ # Simply importing anything using `from . import` constitutes
+ # a cyclic importing.
+ from .native import $module"
%enddef
// The name of the module to be created.
@@ -59,6 +64,11 @@ except ImportError:
// Parameter types will be used in the autodoc string.
%feature("autodoc", "1");
+// Include lldb-python first as it sets Py_LIMITED_API.
+%begin %{
+#include "../source/Plugins/ScriptInterpreter/Python/lldb-python.h"
+%}
+
%pythoncode%{
import uuid
import re