xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/python/py-xmethods.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /* Support for debug methods in Python.
2 
3    Copyright (C) 2013-2017 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 #include "py-ref.h"
30 
31 static const char enabled_field_name[] = "enabled";
32 static const char match_method_name[] = "match";
33 static const char get_arg_types_method_name[] = "get_arg_types";
34 static const char get_result_type_method_name[] = "get_result_type";
35 static const char matchers_attr_str[] = "xmethods";
36 
37 static PyObject *py_match_method_name = NULL;
38 static PyObject *py_get_arg_types_method_name = NULL;
39 
40 struct gdbpy_worker_data
41 {
42   PyObject *worker;
43   PyObject *this_type;
44 };
45 
46 static struct xmethod_worker *new_python_xmethod_worker (PyObject *item,
47 							 PyObject *py_obj_type);
48 
49 /* Implementation of free_xmethod_worker_data for Python.  */
50 
51 void
52 gdbpy_free_xmethod_worker_data (const struct extension_language_defn *extlang,
53 				void *data)
54 {
55   struct gdbpy_worker_data *worker_data = (struct gdbpy_worker_data *) data;
56 
57   gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
58 
59   /* We don't do much here, but we still need the GIL.  */
60   gdbpy_enter enter_py (get_current_arch (), current_language);
61 
62   Py_DECREF (worker_data->worker);
63   Py_DECREF (worker_data->this_type);
64   xfree (worker_data);
65 }
66 
67 /* Implementation of clone_xmethod_worker_data for Python.  */
68 
69 void *
70 gdbpy_clone_xmethod_worker_data (const struct extension_language_defn *extlang,
71 				 void *data)
72 {
73   struct gdbpy_worker_data *worker_data
74     = (struct gdbpy_worker_data *) data, *new_data;
75 
76   gdb_assert (worker_data->worker != NULL && worker_data->this_type != NULL);
77 
78   /* We don't do much here, but we still need the GIL.  */
79   gdbpy_enter enter_py (get_current_arch (), current_language);
80 
81   new_data = XCNEW (struct gdbpy_worker_data);
82   new_data->worker = worker_data->worker;
83   new_data->this_type = worker_data->this_type;
84   Py_INCREF (new_data->worker);
85   Py_INCREF (new_data->this_type);
86 
87   return new_data;
88 }
89 
90 /* Invoke the "match" method of the MATCHER and return a new reference
91    to the result.  Returns NULL on error.  */
92 
93 static PyObject *
94 invoke_match_method (PyObject *matcher, PyObject *py_obj_type,
95 		     const char *xmethod_name)
96 {
97   int enabled;
98 
99   gdbpy_ref<> enabled_field (PyObject_GetAttrString (matcher,
100 						     enabled_field_name));
101   if (enabled_field == NULL)
102     return NULL;
103 
104   enabled = PyObject_IsTrue (enabled_field.get ());
105   if (enabled == -1)
106     return NULL;
107   if (enabled == 0)
108     {
109       /* Return 'None' if the matcher is not enabled.  */
110       Py_RETURN_NONE;
111     }
112 
113   gdbpy_ref<> match_method (PyObject_GetAttrString (matcher,
114 						    match_method_name));
115   if (match_method == NULL)
116     return NULL;
117 
118   gdbpy_ref<> py_xmethod_name (PyString_FromString (xmethod_name));
119   if (py_xmethod_name == NULL)
120     return NULL;
121 
122   return PyObject_CallMethodObjArgs (matcher, py_match_method_name,
123 				     py_obj_type, py_xmethod_name.get (),
124 				     NULL);
125 }
126 
127 /* Implementation of get_matching_xmethod_workers for Python.  */
128 
129 enum ext_lang_rc
130 gdbpy_get_matching_xmethod_workers
131   (const struct extension_language_defn *extlang,
132    struct type *obj_type, const char *method_name,
133    xmethod_worker_vec **dm_vec)
134 {
135   struct objfile *objfile;
136   VEC (xmethod_worker_ptr) *worker_vec = NULL;
137   PyObject *py_progspace;
138 
139   gdb_assert (obj_type != NULL && method_name != NULL);
140 
141   gdbpy_enter enter_py (get_current_arch (), current_language);
142 
143   gdbpy_ref<> py_type (type_to_type_object (obj_type));
144   if (py_type == NULL)
145     {
146       gdbpy_print_stack ();
147       return EXT_LANG_RC_ERROR;
148     }
149 
150   /* Create an empty list of debug methods.  */
151   gdbpy_ref<> py_xmethod_matcher_list (PyList_New (0));
152   if (py_xmethod_matcher_list == NULL)
153     {
154       gdbpy_print_stack ();
155       return EXT_LANG_RC_ERROR;
156     }
157 
158   /* Gather debug method matchers registered with the object files.
159      This could be done differently by iterating over each objfile's matcher
160      list individually, but there's no data yet to show it's needed.  */
161   ALL_OBJFILES (objfile)
162     {
163       PyObject *py_objfile = objfile_to_objfile_object (objfile);
164 
165       if (py_objfile == NULL)
166 	{
167 	  gdbpy_print_stack ();
168 	  return EXT_LANG_RC_ERROR;
169 	}
170 
171       gdbpy_ref<> objfile_matchers (objfpy_get_xmethods (py_objfile, NULL));
172       gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
173 					   objfile_matchers.get ()));
174       if (temp == NULL)
175 	{
176 	  gdbpy_print_stack ();
177 	  return EXT_LANG_RC_ERROR;
178 	}
179 
180       py_xmethod_matcher_list = std::move (temp);
181     }
182 
183   /* Gather debug methods matchers registered with the current program
184      space.  */
185   py_progspace = pspace_to_pspace_object (current_program_space);
186   if (py_progspace != NULL)
187     {
188       gdbpy_ref<> pspace_matchers (pspy_get_xmethods (py_progspace, NULL));
189 
190       gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
191 					   pspace_matchers.get ()));
192       if (temp == NULL)
193 	{
194 	  gdbpy_print_stack ();
195 	  return EXT_LANG_RC_ERROR;
196 	}
197 
198       py_xmethod_matcher_list = std::move (temp);
199     }
200   else
201     {
202       gdbpy_print_stack ();
203       return EXT_LANG_RC_ERROR;
204     }
205 
206   /* Gather debug method matchers registered globally.  */
207   if (gdb_python_module != NULL
208       && PyObject_HasAttrString (gdb_python_module, matchers_attr_str))
209     {
210       gdbpy_ref<> gdb_matchers (PyObject_GetAttrString (gdb_python_module,
211 							matchers_attr_str));
212       if (gdb_matchers != NULL)
213 	{
214 	  gdbpy_ref<> temp (PySequence_Concat (py_xmethod_matcher_list.get (),
215 					       gdb_matchers.get ()));
216 	  if (temp == NULL)
217 	    {
218 	      gdbpy_print_stack ();
219 	      return EXT_LANG_RC_ERROR;
220 	    }
221 
222 	  py_xmethod_matcher_list = std::move (temp);
223 	}
224       else
225 	{
226 	  gdbpy_print_stack ();
227 	  return EXT_LANG_RC_ERROR;
228 	}
229     }
230 
231   gdbpy_ref<> list_iter (PyObject_GetIter (py_xmethod_matcher_list.get ()));
232   if (list_iter == NULL)
233     {
234       gdbpy_print_stack ();
235       return EXT_LANG_RC_ERROR;
236     }
237   while (true)
238     {
239       gdbpy_ref<> matcher (PyIter_Next (list_iter.get ()));
240       if (matcher == NULL)
241 	{
242 	  if (PyErr_Occurred ())
243 	    {
244 	      gdbpy_print_stack ();
245 	      return EXT_LANG_RC_ERROR;
246 	    }
247 	  break;
248 	}
249 
250       gdbpy_ref<> match_result (invoke_match_method (matcher.get (),
251 						     py_type.get (),
252 						     method_name));
253 
254       if (match_result == NULL)
255 	{
256 	  gdbpy_print_stack ();
257 	  return EXT_LANG_RC_ERROR;
258 	}
259       if (match_result == Py_None)
260 	; /* This means there was no match.  */
261       else if (PySequence_Check (match_result.get ()))
262 	{
263 	  gdbpy_ref<> iter (PyObject_GetIter (match_result.get ()));
264 
265 	  if (iter == NULL)
266 	    {
267 	      gdbpy_print_stack ();
268 	      return EXT_LANG_RC_ERROR;
269 	    }
270 	  while (true)
271 	    {
272 	      struct xmethod_worker *worker;
273 
274 	      gdbpy_ref<> py_worker (PyIter_Next (iter.get ()));
275 	      if (py_worker == NULL)
276 		{
277 		  if (PyErr_Occurred ())
278 		    {
279 		      gdbpy_print_stack ();
280 		      return EXT_LANG_RC_ERROR;
281 		    }
282 		  break;
283 		}
284 
285 	      worker = new_python_xmethod_worker (py_worker.get (),
286 						  py_type.get ());
287 	      VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
288 	    }
289 	}
290       else
291 	{
292 	  struct xmethod_worker *worker;
293 
294 	  worker = new_python_xmethod_worker (match_result.get (),
295 					      py_type.get ());
296 	  VEC_safe_push (xmethod_worker_ptr, worker_vec, worker);
297 	}
298     }
299 
300   *dm_vec = worker_vec;
301 
302   return EXT_LANG_RC_OK;
303 }
304 
305 /* Implementation of get_xmethod_arg_types for Python.  */
306 
307 enum ext_lang_rc
308 gdbpy_get_xmethod_arg_types (const struct extension_language_defn *extlang,
309 			     struct xmethod_worker *worker,
310 			     int *nargs, struct type ***arg_types)
311 {
312   /* The gdbpy_enter object needs to be placed first, so that it's the last to
313      be destroyed.  */
314   gdbpy_enter enter_py (get_current_arch (), current_language);
315   struct gdbpy_worker_data *worker_data
316     = (struct gdbpy_worker_data *) worker->data;
317   PyObject *py_worker = worker_data->worker;
318   struct type *obj_type;
319   int i = 1, arg_count;
320   gdbpy_ref<> list_iter;
321 
322   /* Set nargs to -1 so that any premature return from this function returns
323      an invalid/unusable number of arg types.  */
324   *nargs = -1;
325 
326   gdbpy_ref<> get_arg_types_method
327     (PyObject_GetAttrString (py_worker, get_arg_types_method_name));
328   if (get_arg_types_method == NULL)
329     {
330       gdbpy_print_stack ();
331       return EXT_LANG_RC_ERROR;
332     }
333 
334   gdbpy_ref<> py_argtype_list
335     (PyObject_CallMethodObjArgs (py_worker, py_get_arg_types_method_name,
336 				 NULL));
337   if (py_argtype_list == NULL)
338     {
339       gdbpy_print_stack ();
340       return EXT_LANG_RC_ERROR;
341     }
342 
343   if (py_argtype_list == Py_None)
344     arg_count = 0;
345   else if (PySequence_Check (py_argtype_list.get ()))
346     {
347       arg_count = PySequence_Size (py_argtype_list.get ());
348       if (arg_count == -1)
349 	{
350 	  gdbpy_print_stack ();
351 	  return EXT_LANG_RC_ERROR;
352 	}
353 
354       list_iter.reset (PyObject_GetIter (py_argtype_list.get ()));
355       if (list_iter == NULL)
356 	{
357 	  gdbpy_print_stack ();
358 	  return EXT_LANG_RC_ERROR;
359 	}
360     }
361   else
362     arg_count = 1;
363 
364   /* Include the 'this' argument in the size.  */
365   gdb::unique_xmalloc_ptr<struct type *> type_array
366     (XCNEWVEC (struct type *, arg_count + 1));
367   i = 1;
368   if (list_iter != NULL)
369     {
370       while (true)
371 	{
372 	  gdbpy_ref<> item (PyIter_Next (list_iter.get ()));
373 	  if (item == NULL)
374 	    {
375 	      if (PyErr_Occurred ())
376 		{
377 		  gdbpy_print_stack ();
378 		  return EXT_LANG_RC_ERROR;
379 		}
380 	      break;
381 	    }
382 
383 	  struct type *arg_type = type_object_to_type (item.get ());
384 	  if (arg_type == NULL)
385 	    {
386 	      PyErr_SetString (PyExc_TypeError,
387 			       _("Arg type returned by the get_arg_types "
388 				 "method of a debug method worker object is "
389 				 "not a gdb.Type object."));
390 	      return EXT_LANG_RC_ERROR;
391 	    }
392 
393 	  (type_array.get ())[i] = arg_type;
394 	  i++;
395 	}
396     }
397   else if (arg_count == 1)
398     {
399       /* py_argtype_list is not actually a list but a single gdb.Type
400 	 object.  */
401       struct type *arg_type = type_object_to_type (py_argtype_list.get ());
402 
403       if (arg_type == NULL)
404 	{
405 	  PyErr_SetString (PyExc_TypeError,
406 			   _("Arg type returned by the get_arg_types method "
407 			     "of an xmethod worker object is not a gdb.Type "
408 			     "object."));
409 	  return EXT_LANG_RC_ERROR;
410 	}
411       else
412 	{
413 	  (type_array.get ())[i] = arg_type;
414 	  i++;
415 	}
416     }
417 
418   /* Add the type of 'this' as the first argument.  The 'this' pointer should
419      be a 'const' value.  Hence, create a 'const' variant of the 'this' pointer
420      type.  */
421   obj_type = type_object_to_type (worker_data->this_type);
422   (type_array.get ())[0] = make_cv_type (1, 0, lookup_pointer_type (obj_type),
423 					 NULL);
424   *nargs = i;
425   *arg_types = type_array.release ();
426 
427   return EXT_LANG_RC_OK;
428 }
429 
430 /* Implementation of get_xmethod_result_type for Python.  */
431 
432 enum ext_lang_rc
433 gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
434 			       struct xmethod_worker *worker,
435 			       struct value *obj,
436 			       struct value **args, int nargs,
437 			       struct type **result_type_ptr)
438 {
439   struct gdbpy_worker_data *worker_data
440     = (struct gdbpy_worker_data *) worker->data;
441   PyObject *py_worker = worker_data->worker;
442   struct type *obj_type, *this_type;
443   int i;
444 
445   gdbpy_enter enter_py (get_current_arch (), current_language);
446 
447   /* First see if there is a get_result_type method.
448      If not this could be an old xmethod (pre 7.9.1).  */
449   gdbpy_ref<> get_result_type_method
450     (PyObject_GetAttrString (py_worker, get_result_type_method_name));
451   if (get_result_type_method == NULL)
452     {
453       PyErr_Clear ();
454       *result_type_ptr = NULL;
455       return EXT_LANG_RC_OK;
456     }
457 
458   obj_type = check_typedef (value_type (obj));
459   this_type = check_typedef (type_object_to_type (worker_data->this_type));
460   if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
461     {
462       struct type *this_ptr = lookup_pointer_type (this_type);
463 
464       if (!types_equal (obj_type, this_ptr))
465 	obj = value_cast (this_ptr, obj);
466     }
467   else if (TYPE_IS_REFERENCE (obj_type))
468     {
469       struct type *this_ref
470         = lookup_reference_type (this_type, TYPE_CODE (obj_type));
471 
472       if (!types_equal (obj_type, this_ref))
473 	obj = value_cast (this_ref, obj);
474     }
475   else
476     {
477       if (!types_equal (obj_type, this_type))
478 	obj = value_cast (this_type, obj);
479     }
480   gdbpy_ref<> py_value_obj (value_to_value_object (obj));
481   if (py_value_obj == NULL)
482     {
483       gdbpy_print_stack ();
484       return EXT_LANG_RC_ERROR;
485     }
486 
487   gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
488   if (py_arg_tuple == NULL)
489     {
490       gdbpy_print_stack ();
491       return EXT_LANG_RC_ERROR;
492     }
493 
494   /* PyTuple_SET_ITEM steals the reference of the element, hence the
495      release.  */
496   PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
497 
498   for (i = 0; i < nargs; i++)
499     {
500       PyObject *py_value_arg = value_to_value_object (args[i]);
501 
502       if (py_value_arg == NULL)
503 	{
504 	  gdbpy_print_stack ();
505 	  return EXT_LANG_RC_ERROR;
506 	}
507       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
508     }
509 
510   gdbpy_ref<> py_result_type
511     (PyObject_CallObject (get_result_type_method.get (), py_arg_tuple.get ()));
512   if (py_result_type == NULL)
513     {
514       gdbpy_print_stack ();
515       return EXT_LANG_RC_ERROR;
516     }
517 
518   *result_type_ptr = type_object_to_type (py_result_type.get ());
519   if (*result_type_ptr == NULL)
520     {
521       PyErr_SetString (PyExc_TypeError,
522 		       _("Type returned by the get_result_type method of an"
523 			 " xmethod worker object is not a gdb.Type object."));
524       gdbpy_print_stack ();
525       return EXT_LANG_RC_ERROR;
526     }
527 
528   return EXT_LANG_RC_OK;
529 }
530 
531 /* Implementation of invoke_xmethod for Python.  */
532 
533 struct value *
534 gdbpy_invoke_xmethod (const struct extension_language_defn *extlang,
535 		      struct xmethod_worker *worker,
536 		      struct value *obj, struct value **args, int nargs)
537 {
538   int i;
539   struct type *obj_type, *this_type;
540   struct value *res = NULL;
541   struct gdbpy_worker_data *worker_data
542     = (struct gdbpy_worker_data *) worker->data;
543   PyObject *xmethod_worker = worker_data->worker;
544 
545   gdbpy_enter enter_py (get_current_arch (), current_language);
546 
547   obj_type = check_typedef (value_type (obj));
548   this_type = check_typedef (type_object_to_type (worker_data->this_type));
549   if (TYPE_CODE (obj_type) == TYPE_CODE_PTR)
550     {
551       struct type *this_ptr = lookup_pointer_type (this_type);
552 
553       if (!types_equal (obj_type, this_ptr))
554 	obj = value_cast (this_ptr, obj);
555     }
556   else if (TYPE_IS_REFERENCE (obj_type))
557     {
558       struct type *this_ref
559 	= lookup_reference_type (this_type, TYPE_CODE (obj_type));
560 
561       if (!types_equal (obj_type, this_ref))
562 	obj = value_cast (this_ref, obj);
563     }
564   else
565     {
566       if (!types_equal (obj_type, this_type))
567 	obj = value_cast (this_type, obj);
568     }
569   gdbpy_ref<> py_value_obj (value_to_value_object (obj));
570   if (py_value_obj == NULL)
571     {
572       gdbpy_print_stack ();
573       error (_("Error while executing Python code."));
574     }
575 
576   gdbpy_ref<> py_arg_tuple (PyTuple_New (nargs + 1));
577   if (py_arg_tuple == NULL)
578     {
579       gdbpy_print_stack ();
580       error (_("Error while executing Python code."));
581     }
582 
583   /* PyTuple_SET_ITEM steals the reference of the element, hence the
584      release.  */
585   PyTuple_SET_ITEM (py_arg_tuple.get (), 0, py_value_obj.release ());
586 
587   for (i = 0; i < nargs; i++)
588     {
589       PyObject *py_value_arg = value_to_value_object (args[i]);
590 
591       if (py_value_arg == NULL)
592 	{
593 	  gdbpy_print_stack ();
594 	  error (_("Error while executing Python code."));
595 	}
596 
597       PyTuple_SET_ITEM (py_arg_tuple.get (), i + 1, py_value_arg);
598     }
599 
600   gdbpy_ref<> py_result (PyObject_CallObject (xmethod_worker,
601 					      py_arg_tuple.get ()));
602   if (py_result == NULL)
603     {
604       gdbpy_print_stack ();
605       error (_("Error while executing Python code."));
606     }
607 
608   if (py_result != Py_None)
609     {
610       res = convert_value_from_python (py_result.get ());
611       if (res == NULL)
612 	{
613 	  gdbpy_print_stack ();
614 	  error (_("Error while executing Python code."));
615 	}
616     }
617   else
618     {
619       res = allocate_value (lookup_typename (python_language, python_gdbarch,
620 					     "void", NULL, 0));
621     }
622 
623   return res;
624 }
625 
626 /* Creates a new Python xmethod_worker object.
627    The new object has data of type 'struct gdbpy_worker_data' composed
628    with the components PY_WORKER and THIS_TYPE.  */
629 
630 static struct xmethod_worker *
631 new_python_xmethod_worker (PyObject *py_worker, PyObject *this_type)
632 {
633   struct gdbpy_worker_data *data;
634 
635   gdb_assert (py_worker != NULL && this_type != NULL);
636 
637   data = XCNEW (struct gdbpy_worker_data);
638   data->worker = py_worker;
639   data->this_type = this_type;
640   Py_INCREF (py_worker);
641   Py_INCREF (this_type);
642 
643   return new_xmethod_worker (&extension_language_python, data);
644 }
645 
646 int
647 gdbpy_initialize_xmethods (void)
648 {
649   py_match_method_name = PyString_FromString (match_method_name);
650   if (py_match_method_name == NULL)
651     return -1;
652 
653   py_get_arg_types_method_name
654     = PyString_FromString (get_arg_types_method_name);
655   if (py_get_arg_types_method_name == NULL)
656     return -1;
657 
658   return 1;
659 }
660