summaryrefslogtreecommitdiffstats
path: root/lldb/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/scripts')
-rw-r--r--lldb/scripts/Python/python-swigsafecast.swig14
-rw-r--r--lldb/scripts/Python/python-wrapper.swig95
-rw-r--r--lldb/scripts/interface/SBBreakpoint.i4
-rw-r--r--lldb/scripts/interface/SBStructuredData.i2
-rw-r--r--lldb/scripts/interface/SBTarget.i68
5 files changed, 183 insertions, 0 deletions
diff --git a/lldb/scripts/Python/python-swigsafecast.swig b/lldb/scripts/Python/python-swigsafecast.swig
index ffd7546323a..57ae00c067d 100644
--- a/lldb/scripts/Python/python-swigsafecast.swig
+++ b/lldb/scripts/Python/python-swigsafecast.swig
@@ -147,3 +147,17 @@ SBTypeToSWIGWrapper (lldb::SBTypeSummaryOptions* summary_options_sb)
{
return SWIG_NewPointerObj((void *) summary_options_sb, SWIGTYPE_p_lldb__SBTypeSummaryOptions, 0);
}
+
+template <>
+PyObject*
+SBTypeToSWIGWrapper (lldb::SBStructuredData* structured_data_sb)
+{
+ return SWIG_NewPointerObj((void *) structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData, 0);
+}
+
+template <>
+PyObject*
+SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb)
+{
+ return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0);
+}
diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig
index 96b8dda80f8..1679d895e4a 100644
--- a/lldb/scripts/Python/python-wrapper.swig
+++ b/lldb/scripts/Python/python-wrapper.swig
@@ -333,6 +333,101 @@ LLDBSWIGPythonCallThreadPlan
return false;
}
+SWIGEXPORT void *
+LLDBSwigPythonCreateScriptedBreakpointResolver
+(
+ const char *python_class_name,
+ const char *session_dictionary_name,
+ lldb_private::StructuredDataImpl *args_impl,
+ lldb::BreakpointSP &breakpoint_sp
+)
+{
+ using namespace lldb_private;
+
+ if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
+ Py_RETURN_NONE;
+
+ PyErr_Cleaner py_err_cleaner(true);
+
+ auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name);
+ auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict);
+
+ if (!pfunc.IsAllocated())
+ return nullptr;
+
+ lldb::SBBreakpoint *bkpt_value = new lldb::SBBreakpoint(breakpoint_sp);
+
+ PythonObject bkpt_arg(PyRefType::Owned, SBTypeToSWIGWrapper(bkpt_value));
+
+ lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl);
+ PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value));
+
+ PythonObject result = pfunc(bkpt_arg, args_arg, dict);
+ // FIXME: At this point we should check that the class we found supports all the methods
+ // that we need.
+
+ if (result.IsAllocated())
+ {
+ // Check that __callback__ is defined:
+ auto callback_func = result.ResolveName<PythonCallable>("__callback__");
+ if (callback_func.IsAllocated())
+ return result.release();
+ else
+ result.release();
+ }
+ Py_RETURN_NONE;
+}
+
+SWIGEXPORT unsigned int
+LLDBSwigPythonCallBreakpointResolver
+(
+ void *implementor,
+ const char *method_name,
+ lldb_private::SymbolContext *sym_ctx
+)
+{
+ using namespace lldb_private;
+
+ PyErr_Cleaner py_err_cleaner(false);
+ PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
+ auto pfunc = self.ResolveName<PythonCallable>(method_name);
+
+ if (!pfunc.IsAllocated())
+ return 0;
+
+ PythonObject result;
+ if (sym_ctx != nullptr) {
+ lldb::SBSymbolContext sb_sym_ctx(sym_ctx);
+ PythonObject sym_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_sym_ctx));
+ result = pfunc(sym_ctx_arg);
+ } else
+ result = pfunc();
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ return 0;
+ }
+
+ // The callback will return a bool, but we're need to also return ints
+ // so we're squirrelling the bool through as an int... And if you return
+ // nothing, we'll continue.
+ if (strcmp(method_name, "__callback__") == 0) {
+ if (result.get() == Py_False)
+ return 0;
+ else
+ return 1;
+ }
+
+ PythonInteger int_result = result.AsType<PythonInteger>();
+ if (!int_result.IsAllocated())
+ return 0;
+
+ unsigned int ret_val = int_result.GetInteger();
+
+ return ret_val;
+}
+
// wrapper that calls an optional instance member of an object taking no arguments
static PyObject*
LLDBSwigPython_CallOptionalMember
diff --git a/lldb/scripts/interface/SBBreakpoint.i b/lldb/scripts/interface/SBBreakpoint.i
index 525797ad91f..b810682d10f 100644
--- a/lldb/scripts/interface/SBBreakpoint.i
+++ b/lldb/scripts/interface/SBBreakpoint.i
@@ -226,6 +226,10 @@ public:
bool
GetDescription(lldb::SBStream &description, bool include_locations);
+ // Can only be called from a ScriptedBreakpointResolver...
+ SBError
+ AddLocation(SBAddress &address);
+
bool
operator == (const lldb::SBBreakpoint& rhs);
diff --git a/lldb/scripts/interface/SBStructuredData.i b/lldb/scripts/interface/SBStructuredData.i
index 4e54cdd7b40..d30179c4d48 100644
--- a/lldb/scripts/interface/SBStructuredData.i
+++ b/lldb/scripts/interface/SBStructuredData.i
@@ -38,6 +38,8 @@ namespace lldb {
size_t GetSize() const;
+ bool GetKeys(lldb::SBStringList &keys) const;
+
lldb::SBStructuredData GetValueForKey(const char *key) const;
lldb::SBStructuredData GetItemAtIndex(size_t idx) const;
diff --git a/lldb/scripts/interface/SBTarget.i b/lldb/scripts/interface/SBTarget.i
index 993c374080c..1743b4d0858 100644
--- a/lldb/scripts/interface/SBTarget.i
+++ b/lldb/scripts/interface/SBTarget.i
@@ -731,6 +731,74 @@ public:
lldb::SBBreakpoint
BreakpointCreateBySBAddress (SBAddress &sb_address);
+
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Create a breakpoint using a scripted resolver.
+ ///
+ /// @param[in] class_name
+ /// This is the name of the class that implements a scripted resolver.
+ /// The class should have the following signature:
+ /// class Resolver:
+ /// def __init__(self, bkpt, extra_args):
+ /// # bkpt - the breakpoint for which this is the resolver. When
+ /// # the resolver finds an interesting address, call AddLocation
+ /// # on this breakpoint to add it.
+ /// #
+ /// # extra_args - an SBStructuredData that can be used to
+ /// # parametrize this instance. Same as the extra_args passed
+ /// # to BreakpointCreateFromScript.
+ ///
+ /// def __get_depth__ (self):
+ /// # This is optional, but if defined, you should return the
+ /// # depth at which you want the callback to be called. The
+ /// # available options are:
+ /// # lldb.eSearchDepthModule
+ /// # lldb.eSearchDepthCompUnit
+ /// # The default if you don't implement this method is
+ /// # eSearchDepthModule.
+ ///
+ /// def __callback__(self, sym_ctx):
+ /// # sym_ctx - an SBSymbolContext that is the cursor in the
+ /// # search through the program to resolve breakpoints.
+ /// # The sym_ctx will be filled out to the depth requested in
+ /// # __get_depth__.
+ /// # Look in this sym_ctx for new breakpoint locations,
+ /// # and if found use bkpt.AddLocation to add them.
+ /// # Note, you will only get called for modules/compile_units that
+ /// # pass the SearchFilter provided by the module_list & file_list
+ /// # passed into BreakpointCreateFromScript.
+ ///
+ /// def get_short_help(self):
+ /// # Optional, but if implemented return a short string that will
+ /// # be printed at the beginning of the break list output for the
+ /// # breakpoint.
+ ///
+ /// @param[in] extra_args
+ /// This is an SBStructuredData object that will get passed to the
+ /// constructor of the class in class_name. You can use this to
+ /// reuse the same class, parametrizing it with entries from this
+ /// dictionary.
+ ///
+ /// @param module_list
+ /// If this is non-empty, this will be used as the module filter in the
+ /// SearchFilter created for this breakpoint.
+ ///
+ /// @param file_list
+ /// If this is non-empty, this will be used as the comp unit filter in the
+ /// SearchFilter created for this breakpoint.
+ ///
+ /// @return
+ /// An SBBreakpoint that will set locations based on the logic in the
+ /// resolver's search callback.
+ //------------------------------------------------------------------
+ ") BreakpointCreateFromScript;
+ lldb::SBBreakpoint BreakpointCreateFromScript(
+ const char *class_name,
+ SBStructuredData &extra_args,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &file_list,
+ bool request_hardware = false);
uint32_t
GetNumBreakpoints () const;
OpenPOWER on IntegriCloud