Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / python / py-inferior.c
1 /* Python interface to inferiors.
2
3 Copyright (C) 2009-2022 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 "auto-load.h"
22 #include "gdbcore.h"
23 #include "gdbthread.h"
24 #include "inferior.h"
25 #include "objfiles.h"
26 #include "observable.h"
27 #include "python-internal.h"
28 #include "arch-utils.h"
29 #include "language.h"
30 #include "gdbsupport/gdb_signals.h"
31 #include "py-event.h"
32 #include "py-stopevent.h"
33
34 struct threadlist_entry
35 {
36 threadlist_entry (gdbpy_ref<thread_object> &&ref)
37 : thread_obj (std::move (ref))
38 {
39 }
40
41 gdbpy_ref<thread_object> thread_obj;
42 struct threadlist_entry *next;
43 };
44
45 struct inferior_object
46 {
47 PyObject_HEAD
48
49 /* The inferior we represent. */
50 struct inferior *inferior;
51
52 /* thread_object instances under this inferior. This list owns a
53 reference to each object it contains. */
54 struct threadlist_entry *threads;
55
56 /* Number of threads in the list. */
57 int nthreads;
58 };
59
60 extern PyTypeObject inferior_object_type
61 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
62
63 static const struct inferior_data *infpy_inf_data_key;
64
65 struct membuf_object {
66 PyObject_HEAD
67 void *buffer;
68
69 /* These are kept just for mbpy_str. */
70 CORE_ADDR addr;
71 CORE_ADDR length;
72 };
73
74 extern PyTypeObject membuf_object_type
75 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
76
77 /* Require that INFERIOR be a valid inferior ID. */
78 #define INFPY_REQUIRE_VALID(Inferior) \
79 do { \
80 if (!Inferior->inferior) \
81 { \
82 PyErr_SetString (PyExc_RuntimeError, \
83 _("Inferior no longer exists.")); \
84 return NULL; \
85 } \
86 } while (0)
87
88 static void
89 python_on_normal_stop (struct bpstats *bs, int print_frame)
90 {
91 enum gdb_signal stop_signal;
92
93 if (!gdb_python_initialized)
94 return;
95
96 if (inferior_ptid == null_ptid)
97 return;
98
99 stop_signal = inferior_thread ()->suspend.stop_signal;
100
101 gdbpy_enter enter_py (get_current_arch (), current_language);
102
103 if (emit_stop_event (bs, stop_signal) < 0)
104 gdbpy_print_stack ();
105 }
106
107 static void
108 python_on_resume (ptid_t ptid)
109 {
110 if (!gdb_python_initialized)
111 return;
112
113 gdbpy_enter enter_py (target_gdbarch (), current_language);
114
115 if (emit_continue_event (ptid) < 0)
116 gdbpy_print_stack ();
117 }
118
119 /* Callback, registered as an observer, that notifies Python listeners
120 when an inferior function call is about to be made. */
121
122 static void
123 python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
124 {
125 gdbpy_enter enter_py (target_gdbarch (), current_language);
126
127 if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
128 gdbpy_print_stack ();
129 }
130
131 /* Callback, registered as an observer, that notifies Python listeners
132 when an inferior function call has completed. */
133
134 static void
135 python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
136 {
137 gdbpy_enter enter_py (target_gdbarch (), current_language);
138
139 if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
140 gdbpy_print_stack ();
141 }
142
143 /* Callback, registered as an observer, that notifies Python listeners
144 when a part of memory has been modified by user action (eg via a
145 'set' command). */
146
147 static void
148 python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
149 {
150 gdbpy_enter enter_py (target_gdbarch (), current_language);
151
152 if (emit_memory_changed_event (addr, len) < 0)
153 gdbpy_print_stack ();
154 }
155
156 /* Callback, registered as an observer, that notifies Python listeners
157 when a register has been modified by user action (eg via a 'set'
158 command). */
159
160 static void
161 python_on_register_change (struct frame_info *frame, int regnum)
162 {
163 gdbpy_enter enter_py (target_gdbarch (), current_language);
164
165 if (emit_register_changed_event (frame, regnum) < 0)
166 gdbpy_print_stack ();
167 }
168
169 static void
170 python_inferior_exit (struct inferior *inf)
171 {
172 const LONGEST *exit_code = NULL;
173
174 if (!gdb_python_initialized)
175 return;
176
177 gdbpy_enter enter_py (target_gdbarch (), current_language);
178
179 if (inf->has_exit_code)
180 exit_code = &inf->exit_code;
181
182 if (emit_exited_event (exit_code, inf) < 0)
183 gdbpy_print_stack ();
184 }
185
186 /* Callback used to notify Python listeners about new objfiles loaded in the
187 inferior. OBJFILE may be NULL which means that the objfile list has been
188 cleared (emptied). */
189
190 static void
191 python_new_objfile (struct objfile *objfile)
192 {
193 if (!gdb_python_initialized)
194 return;
195
196 gdbpy_enter enter_py (objfile != NULL
197 ? objfile->arch ()
198 : target_gdbarch (),
199 current_language);
200
201 if (objfile == NULL)
202 {
203 if (emit_clear_objfiles_event () < 0)
204 gdbpy_print_stack ();
205 }
206 else
207 {
208 if (emit_new_objfile_event (objfile) < 0)
209 gdbpy_print_stack ();
210 }
211 }
212
213 /* Return a reference to the Python object of type Inferior
214 representing INFERIOR. If the object has already been created,
215 return it and increment the reference count, otherwise, create it.
216 Return NULL on failure. */
217
218 gdbpy_ref<inferior_object>
219 inferior_to_inferior_object (struct inferior *inferior)
220 {
221 inferior_object *inf_obj;
222
223 inf_obj = (inferior_object *) inferior_data (inferior, infpy_inf_data_key);
224 if (!inf_obj)
225 {
226 inf_obj = PyObject_New (inferior_object, &inferior_object_type);
227 if (!inf_obj)
228 return NULL;
229
230 inf_obj->inferior = inferior;
231 inf_obj->threads = NULL;
232 inf_obj->nthreads = 0;
233
234 /* PyObject_New initializes the new object with a refcount of 1. This
235 counts for the reference we are keeping in the inferior data. */
236 set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
237 }
238
239 /* We are returning a new reference. */
240 gdb_assert (inf_obj != nullptr);
241 return gdbpy_ref<inferior_object>::new_reference (inf_obj);
242 }
243
244 /* Called when a new inferior is created. Notifies any Python event
245 listeners. */
246 static void
247 python_new_inferior (struct inferior *inf)
248 {
249 if (!gdb_python_initialized)
250 return;
251
252 gdbpy_enter enter_py (python_gdbarch, python_language);
253
254 if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
255 return;
256
257 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
258 if (inf_obj == NULL)
259 {
260 gdbpy_print_stack ();
261 return;
262 }
263
264 gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
265 if (event == NULL
266 || evpy_add_attribute (event.get (), "inferior",
267 (PyObject *) inf_obj.get ()) < 0
268 || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
269 gdbpy_print_stack ();
270 }
271
272 /* Called when an inferior is removed. Notifies any Python event
273 listeners. */
274 static void
275 python_inferior_deleted (struct inferior *inf)
276 {
277 if (!gdb_python_initialized)
278 return;
279
280 gdbpy_enter enter_py (python_gdbarch, python_language);
281
282 if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
283 return;
284
285 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
286 if (inf_obj == NULL)
287 {
288 gdbpy_print_stack ();
289 return;
290 }
291
292 gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
293 if (event == NULL
294 || evpy_add_attribute (event.get (), "inferior",
295 (PyObject *) inf_obj.get ()) < 0
296 || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
297 gdbpy_print_stack ();
298 }
299
300 gdbpy_ref<>
301 thread_to_thread_object (thread_info *thr)
302 {
303 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
304 if (inf_obj == NULL)
305 return NULL;
306
307 for (threadlist_entry *thread = inf_obj->threads;
308 thread != NULL;
309 thread = thread->next)
310 if (thread->thread_obj->thread == thr)
311 return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ());
312
313 PyErr_SetString (PyExc_SystemError,
314 _("could not find gdb thread object"));
315 return NULL;
316 }
317
318 static void
319 add_thread_object (struct thread_info *tp)
320 {
321 inferior_object *inf_obj;
322 struct threadlist_entry *entry;
323
324 if (!gdb_python_initialized)
325 return;
326
327 gdbpy_enter enter_py (python_gdbarch, python_language);
328
329 gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
330 if (thread_obj == NULL)
331 {
332 gdbpy_print_stack ();
333 return;
334 }
335
336 inf_obj = (inferior_object *) thread_obj->inf_obj;
337
338 entry = new threadlist_entry (std::move (thread_obj));
339 entry->next = inf_obj->threads;
340
341 inf_obj->threads = entry;
342 inf_obj->nthreads++;
343
344 if (evregpy_no_listeners_p (gdb_py_events.new_thread))
345 return;
346
347 gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type,
348 (PyObject *) inf_obj);
349 if (event == NULL
350 || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
351 gdbpy_print_stack ();
352 }
353
354 static void
355 delete_thread_object (struct thread_info *tp, int ignore)
356 {
357 struct threadlist_entry **entry, *tmp;
358
359 if (!gdb_python_initialized)
360 return;
361
362 gdbpy_enter enter_py (python_gdbarch, python_language);
363
364 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
365 if (inf_obj == NULL)
366 return;
367
368 /* Find thread entry in its inferior's thread_list. */
369 for (entry = &inf_obj->threads; *entry != NULL; entry =
370 &(*entry)->next)
371 if ((*entry)->thread_obj->thread == tp)
372 break;
373
374 if (!*entry)
375 return;
376
377 tmp = *entry;
378 tmp->thread_obj->thread = NULL;
379
380 *entry = (*entry)->next;
381 inf_obj->nthreads--;
382
383 delete tmp;
384 }
385
386 static PyObject *
387 infpy_threads (PyObject *self, PyObject *args)
388 {
389 int i;
390 struct threadlist_entry *entry;
391 inferior_object *inf_obj = (inferior_object *) self;
392 PyObject *tuple;
393
394 INFPY_REQUIRE_VALID (inf_obj);
395
396 try
397 {
398 update_thread_list ();
399 }
400 catch (const gdb_exception &except)
401 {
402 GDB_PY_HANDLE_EXCEPTION (except);
403 }
404
405 tuple = PyTuple_New (inf_obj->nthreads);
406 if (!tuple)
407 return NULL;
408
409 for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
410 i++, entry = entry->next)
411 {
412 PyObject *thr = (PyObject *) entry->thread_obj.get ();
413 Py_INCREF (thr);
414 PyTuple_SET_ITEM (tuple, i, thr);
415 }
416
417 return tuple;
418 }
419
420 static PyObject *
421 infpy_get_num (PyObject *self, void *closure)
422 {
423 inferior_object *inf = (inferior_object *) self;
424
425 INFPY_REQUIRE_VALID (inf);
426
427 return gdb_py_object_from_longest (inf->inferior->num).release ();
428 }
429
430 /* Return the connection number of the given inferior, or None if a
431 connection does not exist. */
432
433 static PyObject *
434 infpy_get_connection_num (PyObject *self, void *closure)
435 {
436 inferior_object *inf = (inferior_object *) self;
437
438 INFPY_REQUIRE_VALID (inf);
439
440 process_stratum_target *target = inf->inferior->process_target ();
441 if (target == nullptr)
442 Py_RETURN_NONE;
443
444 return gdb_py_object_from_longest (target->connection_number).release ();
445 }
446
447 static PyObject *
448 infpy_get_pid (PyObject *self, void *closure)
449 {
450 inferior_object *inf = (inferior_object *) self;
451
452 INFPY_REQUIRE_VALID (inf);
453
454 return gdb_py_object_from_longest (inf->inferior->pid).release ();
455 }
456
457 static PyObject *
458 infpy_get_was_attached (PyObject *self, void *closure)
459 {
460 inferior_object *inf = (inferior_object *) self;
461
462 INFPY_REQUIRE_VALID (inf);
463 if (inf->inferior->attach_flag)
464 Py_RETURN_TRUE;
465 Py_RETURN_FALSE;
466 }
467
468 /* Getter of gdb.Inferior.progspace. */
469
470 static PyObject *
471 infpy_get_progspace (PyObject *self, void *closure)
472 {
473 inferior_object *inf = (inferior_object *) self;
474
475 INFPY_REQUIRE_VALID (inf);
476
477 program_space *pspace = inf->inferior->pspace;
478 gdb_assert (pspace != nullptr);
479
480 return pspace_to_pspace_object (pspace).release ();
481 }
482
483 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
484 Returns a tuple of all inferiors. */
485 PyObject *
486 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
487 {
488 gdbpy_ref<> list (PyList_New (0));
489 if (list == NULL)
490 return NULL;
491
492 for (inferior *inf : all_inferiors ())
493 {
494 gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
495
496 if (inferior == NULL)
497 continue;
498
499 if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
500 return NULL;
501 }
502
503 return PyList_AsTuple (list.get ());
504 }
505
506 /* Membuf and memory manipulation. */
507
508 /* Implementation of Inferior.read_memory (address, length).
509 Returns a Python buffer object with LENGTH bytes of the inferior's
510 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
511 with a python exception set. */
512 static PyObject *
513 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
514 {
515 CORE_ADDR addr, length;
516 gdb::unique_xmalloc_ptr<gdb_byte> buffer;
517 PyObject *addr_obj, *length_obj, *result;
518 static const char *keywords[] = { "address", "length", NULL };
519
520 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
521 &addr_obj, &length_obj))
522 return NULL;
523
524 if (get_addr_from_python (addr_obj, &addr) < 0
525 || get_addr_from_python (length_obj, &length) < 0)
526 return NULL;
527
528 try
529 {
530 buffer.reset ((gdb_byte *) xmalloc (length));
531
532 read_memory (addr, buffer.get (), length);
533 }
534 catch (const gdb_exception &except)
535 {
536 GDB_PY_HANDLE_EXCEPTION (except);
537 }
538
539 gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
540 &membuf_object_type));
541 if (membuf_obj == NULL)
542 return NULL;
543
544 membuf_obj->buffer = buffer.release ();
545 membuf_obj->addr = addr;
546 membuf_obj->length = length;
547
548 #ifdef IS_PY3K
549 result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
550 #else
551 result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0,
552 Py_END_OF_BUFFER);
553 #endif
554
555 return result;
556 }
557
558 /* Implementation of Inferior.write_memory (address, buffer [, length]).
559 Writes the contents of BUFFER (a Python object supporting the read
560 buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
561 bytes from BUFFER, or its entire contents if the argument is not
562 provided. The function returns nothing. Returns NULL on error, with
563 a python exception set. */
564 static PyObject *
565 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
566 {
567 struct gdb_exception except;
568 Py_ssize_t buf_len;
569 const gdb_byte *buffer;
570 CORE_ADDR addr, length;
571 PyObject *addr_obj, *length_obj = NULL;
572 static const char *keywords[] = { "address", "buffer", "length", NULL };
573 Py_buffer pybuf;
574
575 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
576 &addr_obj, &pybuf, &length_obj))
577 return NULL;
578
579 Py_buffer_up buffer_up (&pybuf);
580 buffer = (const gdb_byte *) pybuf.buf;
581 buf_len = pybuf.len;
582
583 if (get_addr_from_python (addr_obj, &addr) < 0)
584 return nullptr;
585
586 if (!length_obj)
587 length = buf_len;
588 else if (get_addr_from_python (length_obj, &length) < 0)
589 return nullptr;
590
591 try
592 {
593 write_memory_with_notification (addr, buffer, length);
594 }
595 catch (gdb_exception &ex)
596 {
597 except = std::move (ex);
598 }
599
600 GDB_PY_HANDLE_EXCEPTION (except);
601
602 Py_RETURN_NONE;
603 }
604
605 /* Destructor of Membuf objects. */
606 static void
607 mbpy_dealloc (PyObject *self)
608 {
609 xfree (((membuf_object *) self)->buffer);
610 Py_TYPE (self)->tp_free (self);
611 }
612
613 /* Return a description of the Membuf object. */
614 static PyObject *
615 mbpy_str (PyObject *self)
616 {
617 membuf_object *membuf_obj = (membuf_object *) self;
618
619 return PyString_FromFormat (_("Memory buffer for address %s, \
620 which is %s bytes long."),
621 paddress (python_gdbarch, membuf_obj->addr),
622 pulongest (membuf_obj->length));
623 }
624
625 #ifdef IS_PY3K
626
627 static int
628 get_buffer (PyObject *self, Py_buffer *buf, int flags)
629 {
630 membuf_object *membuf_obj = (membuf_object *) self;
631 int ret;
632
633 ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
634 membuf_obj->length, 0,
635 PyBUF_CONTIG);
636
637 /* Despite the documentation saying this field is a "const char *",
638 in Python 3.4 at least, it's really a "char *". */
639 buf->format = (char *) "c";
640
641 return ret;
642 }
643
644 #else
645
646 static Py_ssize_t
647 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
648 {
649 membuf_object *membuf_obj = (membuf_object *) self;
650
651 if (segment)
652 {
653 PyErr_SetString (PyExc_SystemError,
654 _("The memory buffer supports only one segment."));
655 return -1;
656 }
657
658 *ptrptr = membuf_obj->buffer;
659
660 return membuf_obj->length;
661 }
662
663 static Py_ssize_t
664 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
665 {
666 return get_read_buffer (self, segment, ptrptr);
667 }
668
669 static Py_ssize_t
670 get_seg_count (PyObject *self, Py_ssize_t *lenp)
671 {
672 if (lenp)
673 *lenp = ((membuf_object *) self)->length;
674
675 return 1;
676 }
677
678 static Py_ssize_t
679 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
680 {
681 void *ptr = NULL;
682 Py_ssize_t ret;
683
684 ret = get_read_buffer (self, segment, &ptr);
685 *ptrptr = (char *) ptr;
686
687 return ret;
688 }
689
690 #endif /* IS_PY3K */
691
692 /* Implementation of
693 gdb.search_memory (address, length, pattern). ADDRESS is the
694 address to start the search. LENGTH specifies the scope of the
695 search from ADDRESS. PATTERN is the pattern to search for (and
696 must be a Python object supporting the buffer protocol).
697 Returns a Python Long object holding the address where the pattern
698 was located, or if the pattern was not found, returns None. Returns NULL
699 on error, with a python exception set. */
700 static PyObject *
701 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
702 {
703 struct gdb_exception except;
704 CORE_ADDR start_addr, length;
705 static const char *keywords[] = { "address", "length", "pattern", NULL };
706 PyObject *start_addr_obj, *length_obj;
707 Py_ssize_t pattern_size;
708 const gdb_byte *buffer;
709 CORE_ADDR found_addr;
710 int found = 0;
711 Py_buffer pybuf;
712
713 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
714 &start_addr_obj, &length_obj,
715 &pybuf))
716 return NULL;
717
718 Py_buffer_up buffer_up (&pybuf);
719 buffer = (const gdb_byte *) pybuf.buf;
720 pattern_size = pybuf.len;
721
722 if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
723 return nullptr;
724
725 if (get_addr_from_python (length_obj, &length) < 0)
726 return nullptr;
727
728 if (!length)
729 {
730 PyErr_SetString (PyExc_ValueError,
731 _("Search range is empty."));
732 return nullptr;
733 }
734 /* Watch for overflows. */
735 else if (length > CORE_ADDR_MAX
736 || (start_addr + length - 1) < start_addr)
737 {
738 PyErr_SetString (PyExc_ValueError,
739 _("The search range is too large."));
740 return nullptr;
741 }
742
743 try
744 {
745 found = target_search_memory (start_addr, length,
746 buffer, pattern_size,
747 &found_addr);
748 }
749 catch (gdb_exception &ex)
750 {
751 except = std::move (ex);
752 }
753
754 GDB_PY_HANDLE_EXCEPTION (except);
755
756 if (found)
757 return gdb_py_object_from_ulongest (found_addr).release ();
758 else
759 Py_RETURN_NONE;
760 }
761
762 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
763 Returns True if this inferior object still exists in GDB. */
764
765 static PyObject *
766 infpy_is_valid (PyObject *self, PyObject *args)
767 {
768 inferior_object *inf = (inferior_object *) self;
769
770 if (! inf->inferior)
771 Py_RETURN_FALSE;
772
773 Py_RETURN_TRUE;
774 }
775
776 /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
777 -> gdb.InferiorThread. */
778
779 static PyObject *
780 infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
781 {
782 PyObject *handle_obj;
783 inferior_object *inf_obj = (inferior_object *) self;
784 static const char *keywords[] = { "handle", NULL };
785
786 INFPY_REQUIRE_VALID (inf_obj);
787
788 if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
789 return NULL;
790
791 const gdb_byte *bytes;
792 size_t bytes_len;
793 Py_buffer_up buffer_up;
794 Py_buffer py_buf;
795
796 if (PyObject_CheckBuffer (handle_obj)
797 && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
798 {
799 buffer_up.reset (&py_buf);
800 bytes = (const gdb_byte *) py_buf.buf;
801 bytes_len = py_buf.len;
802 }
803 else if (gdbpy_is_value_object (handle_obj))
804 {
805 struct value *val = value_object_to_value (handle_obj);
806 bytes = value_contents_all (val);
807 bytes_len = TYPE_LENGTH (value_type (val));
808 }
809 else
810 {
811 PyErr_SetString (PyExc_TypeError,
812 _("Argument 'handle' must be a thread handle object."));
813
814 return NULL;
815 }
816
817 try
818 {
819 struct thread_info *thread_info;
820
821 thread_info = find_thread_by_handle
822 (gdb::array_view<const gdb_byte> (bytes, bytes_len),
823 inf_obj->inferior);
824 if (thread_info != NULL)
825 return thread_to_thread_object (thread_info).release ();
826 }
827 catch (const gdb_exception &except)
828 {
829 GDB_PY_HANDLE_EXCEPTION (except);
830 }
831
832 Py_RETURN_NONE;
833 }
834
835 /* Implementation of gdb.Inferior.architecture. */
836
837 static PyObject *
838 infpy_architecture (PyObject *self, PyObject *args)
839 {
840 inferior_object *inf = (inferior_object *) self;
841
842 INFPY_REQUIRE_VALID (inf);
843
844 return gdbarch_to_arch_object (inf->inferior->gdbarch);
845 }
846
847 /* Implement repr() for gdb.Inferior. */
848
849 static PyObject *
850 infpy_repr (PyObject *obj)
851 {
852 inferior_object *self = (inferior_object *) obj;
853 inferior *inf = self->inferior;
854
855 if (inf == nullptr)
856 return PyString_FromString ("<gdb.Inferior (invalid)>");
857
858 return PyString_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
859 inf->num, inf->pid);
860 }
861
862
863 static void
864 infpy_dealloc (PyObject *obj)
865 {
866 inferior_object *inf_obj = (inferior_object *) obj;
867 struct inferior *inf = inf_obj->inferior;
868
869 if (! inf)
870 return;
871
872 set_inferior_data (inf, infpy_inf_data_key, NULL);
873 Py_TYPE (obj)->tp_free (obj);
874 }
875
876 /* Clear the INFERIOR pointer in an Inferior object and clear the
877 thread list. */
878 static void
879 py_free_inferior (struct inferior *inf, void *datum)
880 {
881 struct threadlist_entry *th_entry, *th_tmp;
882
883 if (!gdb_python_initialized)
884 return;
885
886 gdbpy_enter enter_py (python_gdbarch, python_language);
887 gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
888
889 inf_obj->inferior = NULL;
890
891 /* Deallocate threads list. */
892 for (th_entry = inf_obj->threads; th_entry != NULL;)
893 {
894 th_tmp = th_entry;
895 th_entry = th_entry->next;
896 delete th_tmp;
897 }
898
899 inf_obj->nthreads = 0;
900 }
901
902 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
903 Returns the current inferior object. */
904
905 PyObject *
906 gdbpy_selected_inferior (PyObject *self, PyObject *args)
907 {
908 return ((PyObject *)
909 inferior_to_inferior_object (current_inferior ()).release ());
910 }
911
912 void _initialize_py_inferior ();
913 void
914 _initialize_py_inferior ()
915 {
916 infpy_inf_data_key =
917 register_inferior_data_with_cleanup (NULL, py_free_inferior);
918 }
919
920 int
921 gdbpy_initialize_inferior (void)
922 {
923 if (PyType_Ready (&inferior_object_type) < 0)
924 return -1;
925
926 if (gdb_pymodule_addobject (gdb_module, "Inferior",
927 (PyObject *) &inferior_object_type) < 0)
928 return -1;
929
930 gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
931 gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
932 gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
933 gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
934 gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
935 "py-inferior");
936 gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
937 "py-inferior");
938 gdb::observers::memory_changed.attach (python_on_memory_change,
939 "py-inferior");
940 gdb::observers::register_changed.attach (python_on_register_change,
941 "py-inferior");
942 gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
943 /* Need to run after auto-load's new_objfile observer, so that
944 auto-loaded pretty-printers are available. */
945 gdb::observers::new_objfile.attach
946 (python_new_objfile, "py-inferior",
947 { &auto_load_new_objfile_observer_token });
948 gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
949 gdb::observers::inferior_removed.attach (python_inferior_deleted,
950 "py-inferior");
951
952 membuf_object_type.tp_new = PyType_GenericNew;
953 if (PyType_Ready (&membuf_object_type) < 0)
954 return -1;
955
956 return gdb_pymodule_addobject (gdb_module, "Membuf",
957 (PyObject *) &membuf_object_type);
958 }
959
960 static gdb_PyGetSetDef inferior_object_getset[] =
961 {
962 { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
963 { "connection_num", infpy_get_connection_num, NULL,
964 "ID of inferior's connection, as assigned by GDB.", NULL },
965 { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
966 NULL },
967 { "was_attached", infpy_get_was_attached, NULL,
968 "True if the inferior was created using 'attach'.", NULL },
969 { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
970 { NULL }
971 };
972
973 static PyMethodDef inferior_object_methods[] =
974 {
975 { "is_valid", infpy_is_valid, METH_NOARGS,
976 "is_valid () -> Boolean.\n\
977 Return true if this inferior is valid, false if not." },
978 { "threads", infpy_threads, METH_NOARGS,
979 "Return all the threads of this inferior." },
980 { "read_memory", (PyCFunction) infpy_read_memory,
981 METH_VARARGS | METH_KEYWORDS,
982 "read_memory (address, length) -> buffer\n\
983 Return a buffer object for reading from the inferior's memory." },
984 { "write_memory", (PyCFunction) infpy_write_memory,
985 METH_VARARGS | METH_KEYWORDS,
986 "write_memory (address, buffer [, length])\n\
987 Write the given buffer object to the inferior's memory." },
988 { "search_memory", (PyCFunction) infpy_search_memory,
989 METH_VARARGS | METH_KEYWORDS,
990 "search_memory (address, length, pattern) -> long\n\
991 Return a long with the address of a match, or None." },
992 /* thread_from_thread_handle is deprecated. */
993 { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
994 METH_VARARGS | METH_KEYWORDS,
995 "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
996 Return thread object corresponding to thread handle.\n\
997 This method is deprecated - use thread_from_handle instead." },
998 { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
999 METH_VARARGS | METH_KEYWORDS,
1000 "thread_from_handle (handle) -> gdb.InferiorThread.\n\
1001 Return thread object corresponding to thread handle." },
1002 { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
1003 "architecture () -> gdb.Architecture\n\
1004 Return architecture of this inferior." },
1005 { NULL }
1006 };
1007
1008 PyTypeObject inferior_object_type =
1009 {
1010 PyVarObject_HEAD_INIT (NULL, 0)
1011 "gdb.Inferior", /* tp_name */
1012 sizeof (inferior_object), /* tp_basicsize */
1013 0, /* tp_itemsize */
1014 infpy_dealloc, /* tp_dealloc */
1015 0, /* tp_print */
1016 0, /* tp_getattr */
1017 0, /* tp_setattr */
1018 0, /* tp_compare */
1019 infpy_repr, /* tp_repr */
1020 0, /* tp_as_number */
1021 0, /* tp_as_sequence */
1022 0, /* tp_as_mapping */
1023 0, /* tp_hash */
1024 0, /* tp_call */
1025 0, /* tp_str */
1026 0, /* tp_getattro */
1027 0, /* tp_setattro */
1028 0, /* tp_as_buffer */
1029 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */
1030 "GDB inferior object", /* tp_doc */
1031 0, /* tp_traverse */
1032 0, /* tp_clear */
1033 0, /* tp_richcompare */
1034 0, /* tp_weaklistoffset */
1035 0, /* tp_iter */
1036 0, /* tp_iternext */
1037 inferior_object_methods, /* tp_methods */
1038 0, /* tp_members */
1039 inferior_object_getset, /* tp_getset */
1040 0, /* tp_base */
1041 0, /* tp_dict */
1042 0, /* tp_descr_get */
1043 0, /* tp_descr_set */
1044 0, /* tp_dictoffset */
1045 0, /* tp_init */
1046 0 /* tp_alloc */
1047 };
1048
1049 #ifdef IS_PY3K
1050
1051 static PyBufferProcs buffer_procs =
1052 {
1053 get_buffer
1054 };
1055
1056 #else
1057
1058 static PyBufferProcs buffer_procs = {
1059 get_read_buffer,
1060 get_write_buffer,
1061 get_seg_count,
1062 get_char_buffer
1063 };
1064 #endif /* IS_PY3K */
1065
1066 PyTypeObject membuf_object_type = {
1067 PyVarObject_HEAD_INIT (NULL, 0)
1068 "gdb.Membuf", /*tp_name*/
1069 sizeof (membuf_object), /*tp_basicsize*/
1070 0, /*tp_itemsize*/
1071 mbpy_dealloc, /*tp_dealloc*/
1072 0, /*tp_print*/
1073 0, /*tp_getattr*/
1074 0, /*tp_setattr*/
1075 0, /*tp_compare*/
1076 0, /*tp_repr*/
1077 0, /*tp_as_number*/
1078 0, /*tp_as_sequence*/
1079 0, /*tp_as_mapping*/
1080 0, /*tp_hash */
1081 0, /*tp_call*/
1082 mbpy_str, /*tp_str*/
1083 0, /*tp_getattro*/
1084 0, /*tp_setattro*/
1085 &buffer_procs, /*tp_as_buffer*/
1086 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1087 "GDB memory buffer object", /*tp_doc*/
1088 0, /* tp_traverse */
1089 0, /* tp_clear */
1090 0, /* tp_richcompare */
1091 0, /* tp_weaklistoffset */
1092 0, /* tp_iter */
1093 0, /* tp_iternext */
1094 0, /* tp_methods */
1095 0, /* tp_members */
1096 0, /* tp_getset */
1097 0, /* tp_base */
1098 0, /* tp_dict */
1099 0, /* tp_descr_get */
1100 0, /* tp_descr_set */
1101 0, /* tp_dictoffset */
1102 0, /* tp_init */
1103 0, /* tp_alloc */
1104 };
This page took 0.053336 seconds and 4 git commands to generate.