]> Git Repo - binutils.git/blob - gdb/python/py-xmethods.c
Update copyright year range in all GDB files.
[binutils.git] / gdb / python / py-xmethods.c
1 /* Support for debug methods in Python.
2
3    Copyright (C) 2013-2020 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "extension-priv.h"
23 #include "objfiles.h"
24 #include "value.h"
25 #include "language.h"
26
27 #include "python.h"
28 #include "python-internal.h"
29
30 static const char enabled_field_name[] = "enabled";
31 static const char match_method_name[] = "match";
32 static const char get_arg_types_method_name[] = "get_arg_types";
33 static const char get_result_type_method_name[] = "get_result_type";
34 static const char matchers_attr_str[] = "xmethods";
35
36 static PyObject *py_match_method_name = NULL;
37 static PyObject *py_get_arg_types_method_name = NULL;
38
39 struct python_xmethod_worker : xmethod_worker
40 {
41   python_xmethod_worker (PyObject *worker, PyObject *this_type);
42   ~python_xmethod_worker ();
43
44   DISABLE_COPY_AND_ASSIGN (python_xmethod_worker);
45
46   /* Implementation of xmethod_worker::invoke for Python.  */
47
48   value *invoke (value *obj, gdb::array_view<value *> args) override;
49
50   /* Implementation of xmethod_worker::do_get_arg_types for Python.  */
51
52   ext_lang_rc do_get_arg_types (std::vector<type *> *type_args) override;
53
54   /* Implementation of xmethod_worker::do_get_result_type for Python.
55
56      For backward compatibility with 7.9, which did not support getting the
57      result type, if the get_result_type operation is not provided by WORKER
58      then EXT_LANG_RC_OK is returned and NULL is returned in *RESULT_TYPE.  */
59
60   ext_lang_rc do_get_result_type (value *obj, gdb::array_view<value *> args,
61                                   type **result_type_ptr) override;
62
63 private:
64
65   PyObject *m_py_worker;
66   PyObject *m_this_type;
67 };
68
69 python_xmethod_worker::~python_xmethod_worker ()
70 {
71   /* We don't do much here, but we still need the GIL.  */
72   gdbpy_enter enter_py (get_current_arch (), current_language);
73
74   Py_DECREF (m_py_worker);
75   Py_DECREF (m_this_type);
76 }
77
78 /* Invoke the "match" method of the MATCHER and return a new reference
79    to the result.  Returns NULL on error.  */
80
81 static PyObject *
82 invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
83                      const char *xmethod_name)
84 {
85   int enabled;
86
87   gdbpy_ref<> enabled_field (PyObject_GetAttrString (matcher,
88                                                      enabled_field_name));
89   if (enabled_field == NULL)
90     return NULL;
91
92   enabled = PyObject_IsTrue (enabled_field.get ());
93   if (enabled == -1)
94     return NULL;
95   if (enabled == 0)
96     {
97       /* Return 'None' if the matcher is not enabled.  */
98       Py_RETURN_NONE;
99     }
100
101   gdbpy_ref<> match_method (PyObject_GetAttrString (matcher,
102                                                     match_method_name));
103   if (match_method == NULL)
104     return NULL;
105
106   gdbpy_ref<> py_xmethod_name (PyString_FromString (xmethod_name));
107   if (py_xmethod_name == NULL)
108     return NULL;
109
110   return PyObject_CallMethodObjArgs (matcher, py_match_method_name,
111                                      py_obj_type, py_xmethod_name.get (),
112                                      NULL);
113 }
114
115 /* Implementation of get_matching_xmethod_workers for Python.  */
116
117 enum ext_lang_rc
118 gdbpy_get_matching_xmethod_workers
119   (const struct extension_language_defn *extlang,
120    struct type *obj_type, const char *method_name,
121    std::vector<xmethod_worker_up> *dm_vec)
122 {
123   gdb_assert (obj_type != NULL && method_name != NULL);
124
125   gdbpy_enter enter_py (get_current_arch (), current_language);
126
127   gdbpy_ref<> py_type (type_to_type_object (obj_type));
128   if (py_type == NULL)
129     {
130       gdbpy_print_stack ();
131       return EXT_LANG_RC_ERROR;
132     }
133
134   /* Create an empty list of debug methods.  */
135   gdbpy_ref<> py_xmethod_matcher_list (PyList_New (0));
136   if (py_xmethod_matcher_list == NULL)
137     {
138       gdbpy_print_stack ();
139       return EXT_LANG_RC_ERROR;
140     }
141
142   /* Gather debug method matchers registered with the object files.
143      This could be done differently by iterating over each objfile's matcher
144      list individually, but there's no data yet to show it's needed.  */
145   for (objfile *objfile : current_program_space->objfiles ())
146     {
147       gdbpy_ref<> py_objfile = objfile_to_objfile_object (objfile);
148
149       if (py_objfile == NULL)
150         {
151           gdbpy_print_stack ();
152           return EXT_LANG_RC_ERROR;
153         }
154
155       gdbpy_ref<> objfile_matchers (objfpy_get_xmethods (py_objfile.get (),
156                                                          NULL));
157       gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
158                                            objfile_matchers.get ()));
159       if (temp == NULL)
160         {
161           gdbpy_print_stack ();
162           return EXT_LANG_RC_ERROR;
163         }
164
165       py_xmethod_matcher_list = std::move (temp);
166     }
167
168   /* Gather debug methods matchers registered with the current program
169      space.  */
170   gdbpy_ref<> py_progspace = pspace_to_pspace_object (current_program_space);
171   if (py_progspace != NULL)
172     {
173       gdbpy_ref<> pspace_matchers (pspy_get_xmethods (py_progspace.get (),
174                                                       NULL));
175
176       gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
177                                            pspace_matchers.get ()));
178       if (temp == NULL)
179         {
180           gdbpy_print_stack ();
181           return EXT_LANG_RC_ERROR;
182         }
183
184       py_xmethod_matcher_list = std::move (temp);
185     }
186   else
187     {
188       gdbpy_print_stack ();
189       return EXT_LANG_RC_ERROR;
190     }
191
192   /* Gather debug method matchers registered globally.  */
193   if (gdb_python_module != NULL
194       && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
195     {
196       gdbpy_ref<> gdb_matchers (PyObject_GetAttrString (gdb_python_module,
197                                                         matchers_attr_str));
198       if (gdb_matchers != NULL)
199         {
200           gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
201                                                gdb_matchers.get ()));
202           if (temp == NULL)
203             {
204               gdbpy_print_stack ();
205               return EXT_LANG_RC_ERROR;
206             }
207
208           py_xmethod_matcher_list = std::move (temp);
209         }
210       else
211         {
212           gdbpy_print_stack ();
213           return EXT_LANG_RC_ERROR;
214         }
215     }
216
217   gdbpy_ref<> list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
218   if (list_iter == NULL)
219     {
220       gdbpy_print_stack ();
221       return EXT_LANG_RC_ERROR;
222     }
223   while (true)
224     {
225       gdbpy_ref<> matcher (PyIter_Next (list_iter.get ()));
226       if (matcher == NULL)
227         {
228           if (PyErr_Occurred ())
229             {
230               gdbpy_print_stack ();
231               return EXT_LANG_RC_ERROR;
232             }
233           break;
234         }
235
236       gdbpy_ref<> match_result (invoke_match_method (matcher.get (),
237                                                      py_type.get (),
238                                                      method_name));
239
240       if (match_result == NULL)
241         {
242           gdbpy_print_stack ();
243           return EXT_LANG_RC_ERROR;
244         }
245       if (match_result == Py_None)
246         ; /* This means there was no match.  */
247       else if (PySequence_Check (match_result.get ()))
248         {
249           gdbpy_ref<> iter (PyObject_GetIter (match_result.get ()));
250
251           if (iter == NULL)
252             {
253               gdbpy_print_stack ();
254               return EXT_LANG_RC_ERROR;
255             }
256           while (true)
257             {
258               struct xmethod_worker *worker;
259
260               gdbpy_ref<> py_worker (PyIter_Next (iter.get ()));
261               if (py_worker == NULL)
262                 {
263                   if (PyErr_Occurred ())
264                     {
265                       gdbpy_print_stack ();
266                       return EXT_LANG_RC_ERROR;
267                     }
268                   break;
269                 }
270
271               worker = new python_xmethod_worker (py_worker.get (),
272                                                   py_type.get ());
273
274               dm_vec->emplace_back (worker);
275             }
276         }
277       else
278         {
279           struct xmethod_worker *worker;
280
281           worker = new python_xmethod_worker (match_result.get (),
282                                               py_type.get ());
283           dm_vec->emplace_back (worker);
284         }
285     }
286
287   return EXT_LANG_RC_OK;
288 }
289
290 /* See declaration.  */
291
292 ext_lang_rc
293 python_xmethod_worker::do_get_arg_types (std::vector<type *> *arg_types)
294 {
295   /* The gdbpy_enter object needs to be placed first, so that it's the last to
296      be destroyed.  */
297   gdbpy_enter enter_py (get_current_arch (), current_language);
298   struct type *obj_type;
299   int i = 1, arg_count;
300   gdbpy_ref<> list_iter;
301
302   gdbpy_ref<> get_arg_types_method
303     (PyObject_GetAttrString (m_py_worker, get_arg_types_method_name));
304   if (get_arg_types_method == NULL)
305     {
306       gdbpy_print_stack ();
307       return EXT_LANG_RC_ERROR;
308     }
309
310   gdbpy_ref<> py_argtype_list
311     (PyObject_CallMethodObjArgs (m_py_worker, py_get_arg_types_method_name,
312                                  NULL));
313   if (py_argtype_list == NULL)
314     {
315       gdbpy_print_stack ();
316       return EXT_LANG_RC_ERROR;
317     }
318
319   if (py_argtype_list == Py_None)
320     arg_count = 0;
321   else if (PySequence_Check (py_argtype_list.get ()))
322     {
323       arg_count = PySequence_Size (py_argtype_list.get ());
324       if (arg_count == -1)
325         {
326           gdbpy_print_stack ();
327           return EXT_LANG_RC_ERROR;
328         }
329
330       list_iter.reset (PyObject_GetIter (py_argtype_list.get ()));
331       if (list_iter == NULL)
332         {
333           gdbpy_print_stack ();
334           return EXT_LANG_RC_ERROR;
335         }
336     }
337   else
338     arg_count = 1;
339
340   /* Include the 'this' argument in the size.  */
341   arg_types->resize (arg_count + 1);
342   i = 1;
343   if (list_iter != NULL)
344     {
345       while (true)
346         {
347           gdbpy_ref<> item (PyIter_Next (list_iter.get ()));
348           if (item == NULL)
349             {
350               if (PyErr_Occurred ())
351                 {
352                   gdbpy_print_stack ();
353                   return EXT_LANG_RC_ERROR;
354                 }
355               break;
356             }
357
358           struct type *arg_type = type_object_to_type (item.get ());
359           if (arg_type == NULL)
360             {
361               PyErr_SetString (PyExc_TypeError,
362                                _("Arg type returned by the get_arg_types "
363                                  "method of a debug method worker object is "
364                                  "not a gdb.Type object."));
365               return EXT_LANG_RC_ERROR;
366             }
367
368           (*arg_types)[i] = arg_type;
369           i++;
370         }
371     }
372   else if (arg_count == 1)
373     {
374       /* py_argtype_list is not actually a list but a single gdb.Type
375          object.  */
376       struct type *arg_type = type_object_to_type (py_argtype_list.get ());
377
378       if (arg_type == NULL)
379         {
380           PyErr_SetString (PyExc_TypeError,
381                            _("Arg type returned by the get_arg_types method "
382                              "of an xmethod worker object is not a gdb.Type "
383                              "object."));
384           return EXT_LANG_RC_ERROR;
385         }
386       else
387         {
388           (*arg_types)[i] = arg_type;
389           i++;
390         }
391     }
392
393   /* Add the type of 'this' as the first argument.  The 'this' pointer should
394      be a 'const' value.  Hence, create a 'const' variant of the 'this' pointer
395      type.  */
396   obj_type = type_object_to_type (m_this_type);
397   (*arg_types)[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
398                                   NULL);
399
400   return EXT_LANG_RC_OK;
401 }
402
403 /* See declaration.  */
404
405 ext_lang_rc
406 python_xmethod_worker::do_get_result_type (value *obj,
407                                            gdb::array_view<value *> args,
408                                            type **result_type_ptr)
409 {
410   struct type *obj_type, *this_type;
411   int i;
412
413   gdbpy_enter enter_py (get_current_arch (), current_language);
414
415   /* First see if there is a get_result_type method.
416      If not this could be an old xmethod (pre 7.9.1).  */
417   gdbpy_ref<> get_result_type_method
418     (PyObject_GetAttrString (m_py_worker, get_result_type_method_name));
419   if (get_result_type_method == NULL)
420     {
421       PyErr_Clear ();
422       *result_type_ptr = NULL;
423       return EXT_LANG_RC_OK;
424     }
425
426   obj_type = check_typedef (value_type (obj));
427   this_type = check_typedef (type_object_to_type (m_this_type));
428   if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
429     {
430       struct type *this_ptr = lookup_pointer_type (this_type);
431
432       if (!types_equal (obj_type, this_ptr))
433         obj = value_cast (this_ptr, obj);
434     }
435   else if (TYPE_IS_REFERENCE (obj_type))
436     {
437       struct type *this_ref
438         = lookup_reference_type (this_type, TYPE_CODE (obj_type));
439
440       if (!types_equal (obj_type, this_ref))
441         obj = value_cast (this_ref, obj);
442     }
443   else
444     {
445       if (!types_equal (obj_type, this_type))
446         obj = value_cast (this_type, obj);
447     }
448   gdbpy_ref<> py_value_obj (value_to_value_object (obj));
449   if (py_value_obj == NULL)
450     {
451       gdbpy_print_stack ();
452       return EXT_LANG_RC_ERROR;
453     }
454
455   gdbpy_ref<> py_arg_tuple (PyTuple_New (args.size () + 1));
456   if (py_arg_tuple == NULL)
457     {
458       gdbpy_print_stack ();
459       return EXT_LANG_RC_ERROR;
460     }
461
462   /* PyTuple_SET_ITEM steals the reference of the element, hence the
463      release.  */
464   PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
465
466   for (i = 0; i < args.size (); i++)
467     {
468       PyObject *py_value_arg = value_to_value_object (args[i]);
469
470       if (py_value_arg == NULL)
471         {
472           gdbpy_print_stack ();
473           return EXT_LANG_RC_ERROR;
474         }
475       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
476     }
477
478   gdbpy_ref<> py_result_type
479     (PyObject_CallObject (get_result_type_method.get (), py_arg_tuple.get ()));
480   if (py_result_type == NULL)
481     {
482       gdbpy_print_stack ();
483       return EXT_LANG_RC_ERROR;
484     }
485
486   *result_type_ptr = type_object_to_type (py_result_type.get ());
487   if (*result_type_ptr == NULL)
488     {
489       PyErr_SetString (PyExc_TypeError,
490                        _("Type returned by the get_result_type method of an"
491                          " xmethod worker object is not a gdb.Type object."));
492       gdbpy_print_stack ();
493       return EXT_LANG_RC_ERROR;
494     }
495
496   return EXT_LANG_RC_OK;
497 }
498
499 /* See declaration.  */
500
501 struct value *
502 python_xmethod_worker::invoke (struct value *obj,
503                                gdb::array_view<value *> args)
504 {
505   gdbpy_enter enter_py (get_current_arch (), current_language);
506
507   int i;
508   struct type *obj_type, *this_type;
509   struct value *res = NULL;
510
511   obj_type = check_typedef (value_type (obj));
512   this_type = check_typedef (type_object_to_type (m_this_type));
513   if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
514     {
515       struct type *this_ptr = lookup_pointer_type (this_type);
516
517       if (!types_equal (obj_type, this_ptr))
518         obj = value_cast (this_ptr, obj);
519     }
520   else if (TYPE_IS_REFERENCE (obj_type))
521     {
522       struct type *this_ref
523         = lookup_reference_type (this_type, TYPE_CODE (obj_type));
524
525       if (!types_equal (obj_type, this_ref))
526         obj = value_cast (this_ref, obj);
527     }
528   else
529     {
530       if (!types_equal (obj_type, this_type))
531         obj = value_cast (this_type, obj);
532     }
533   gdbpy_ref<> py_value_obj (value_to_value_object (obj));
534   if (py_value_obj == NULL)
535     {
536       gdbpy_print_stack ();
537       error (_("Error while executing Python code."));
538     }
539
540   gdbpy_ref<> py_arg_tuple (PyTuple_New (args.size () + 1));
541   if (py_arg_tuple == NULL)
542     {
543       gdbpy_print_stack ();
544       error (_("Error while executing Python code."));
545     }
546
547   /* PyTuple_SET_ITEM steals the reference of the element, hence the
548      release.  */
549   PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
550
551   for (i = 0; i < args.size (); i++)
552     {
553       PyObject *py_value_arg = value_to_value_object (args[i]);
554
555       if (py_value_arg == NULL)
556         {
557           gdbpy_print_stack ();
558           error (_("Error while executing Python code."));
559         }
560
561       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
562     }
563
564   gdbpy_ref<> py_result (PyObject_CallObject (m_py_worker,
565                                               py_arg_tuple.get ()));
566   if (py_result == NULL)
567     {
568       gdbpy_print_stack ();
569       error (_("Error while executing Python code."));
570     }
571
572   if (py_result != Py_None)
573     {
574       res = convert_value_from_python (py_result.get ());
575       if (res == NULL)
576         {
577           gdbpy_print_stack ();
578           error (_("Error while executing Python code."));
579         }
580     }
581   else
582     {
583       res = allocate_value (lookup_typename (python_language,
584                                              "void", NULL, 0));
585     }
586
587   return res;
588 }
589
590 python_xmethod_worker::python_xmethod_worker (PyObject *py_worker,
591                                                PyObject *this_type)
592 : xmethod_worker (&extension_language_python),
593   m_py_worker (py_worker), m_this_type (this_type)
594 {
595   gdb_assert (m_py_worker != NULL && m_this_type != NULL);
596
597   Py_INCREF (py_worker);
598   Py_INCREF (this_type);
599 }
600
601 int
602 gdbpy_initialize_xmethods (void)
603 {
604   py_match_method_name = PyString_FromString (match_method_name);
605   if (py_match_method_name == NULL)
606     return -1;
607
608   py_get_arg_types_method_name
609     = PyString_FromString (get_arg_types_method_name);
610   if (py_get_arg_types_method_name == NULL)
611     return -1;
612
613   return 1;
614 }
This page took 0.059324 seconds and 4 git commands to generate.