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