Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / python / py-inferior.c
CommitLineData
595939de
PM
1/* Python interface to inferiors.
2
88b9d363 3 Copyright (C) 2009-2022 Free Software Foundation, Inc.
595939de
PM
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"
2c473def 21#include "auto-load.h"
595939de
PM
22#include "gdbcore.h"
23#include "gdbthread.h"
24#include "inferior.h"
20c168b5 25#include "objfiles.h"
76727919 26#include "observable.h"
595939de
PM
27#include "python-internal.h"
28#include "arch-utils.h"
29#include "language.h"
268a13a5 30#include "gdbsupport/gdb_signals.h"
505500db
SW
31#include "py-event.h"
32#include "py-stopevent.h"
595939de 33
05b08ac1
TT
34struct 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;
595939de
PM
42 struct threadlist_entry *next;
43};
44
00431a78 45struct inferior_object
595939de
PM
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;
00431a78 58};
595939de 59
e36122e9 60extern PyTypeObject inferior_object_type
62eec1a5 61 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
595939de
PM
62
63static const struct inferior_data *infpy_inf_data_key;
64
f99b5177 65struct membuf_object {
595939de
PM
66 PyObject_HEAD
67 void *buffer;
68
69 /* These are kept just for mbpy_str. */
70 CORE_ADDR addr;
71 CORE_ADDR length;
f99b5177 72};
595939de 73
e36122e9 74extern PyTypeObject membuf_object_type
62eec1a5 75 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
595939de
PM
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
505500db
SW
88static void
89python_on_normal_stop (struct bpstats *bs, int print_frame)
90{
2ea28649 91 enum gdb_signal stop_signal;
505500db 92
0646da15
TT
93 if (!gdb_python_initialized)
94 return;
95
151bb4a5
PA
96 if (inferior_ptid == null_ptid)
97 return;
505500db
SW
98
99 stop_signal = inferior_thread ()->suspend.stop_signal;
100
07bc7329 101 gdbpy_enter enter_py (get_current_arch (), current_language);
505500db
SW
102
103 if (emit_stop_event (bs, stop_signal) < 0)
104 gdbpy_print_stack ();
505500db
SW
105}
106
107static void
108python_on_resume (ptid_t ptid)
109{
0646da15
TT
110 if (!gdb_python_initialized)
111 return;
112
07bc7329 113 gdbpy_enter enter_py (target_gdbarch (), current_language);
505500db
SW
114
115 if (emit_continue_event (ptid) < 0)
116 gdbpy_print_stack ();
505500db
SW
117}
118
162078c8
NB
119/* Callback, registered as an observer, that notifies Python listeners
120 when an inferior function call is about to be made. */
121
122static void
123python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
124{
07bc7329 125 gdbpy_enter enter_py (target_gdbarch (), current_language);
162078c8
NB
126
127 if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
128 gdbpy_print_stack ();
162078c8
NB
129}
130
131/* Callback, registered as an observer, that notifies Python listeners
132 when an inferior function call has completed. */
133
134static void
135python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
136{
07bc7329 137 gdbpy_enter enter_py (target_gdbarch (), current_language);
162078c8
NB
138
139 if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
140 gdbpy_print_stack ();
162078c8
NB
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
147static void
148python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
149{
07bc7329 150 gdbpy_enter enter_py (target_gdbarch (), current_language);
162078c8
NB
151
152 if (emit_memory_changed_event (addr, len) < 0)
153 gdbpy_print_stack ();
162078c8
NB
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
160static void
161python_on_register_change (struct frame_info *frame, int regnum)
162{
07bc7329 163 gdbpy_enter enter_py (target_gdbarch (), current_language);
162078c8
NB
164
165 if (emit_register_changed_event (frame, regnum) < 0)
166 gdbpy_print_stack ();
162078c8
NB
167}
168
505500db
SW
169static void
170python_inferior_exit (struct inferior *inf)
171{
8cf64490 172 const LONGEST *exit_code = NULL;
505500db 173
0646da15
TT
174 if (!gdb_python_initialized)
175 return;
176
07bc7329 177 gdbpy_enter enter_py (target_gdbarch (), current_language);
505500db 178
8cf64490
TT
179 if (inf->has_exit_code)
180 exit_code = &inf->exit_code;
505500db 181
cb6be26b 182 if (emit_exited_event (exit_code, inf) < 0)
505500db 183 gdbpy_print_stack ();
505500db
SW
184}
185
20c168b5 186/* Callback used to notify Python listeners about new objfiles loaded in the
4ffbba72
DE
187 inferior. OBJFILE may be NULL which means that the objfile list has been
188 cleared (emptied). */
20c168b5
KP
189
190static void
191python_new_objfile (struct objfile *objfile)
192{
0646da15
TT
193 if (!gdb_python_initialized)
194 return;
195
07bc7329 196 gdbpy_enter enter_py (objfile != NULL
08feed99 197 ? objfile->arch ()
07bc7329
TT
198 : target_gdbarch (),
199 current_language);
20c168b5 200
4ffbba72
DE
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 }
20c168b5
KP
211}
212
754eadd1 213/* Return a reference to the Python object of type Inferior
595939de 214 representing INFERIOR. If the object has already been created,
754eadd1
PM
215 return it and increment the reference count, otherwise, create it.
216 Return NULL on failure. */
00431a78 217
61fd3e73 218gdbpy_ref<inferior_object>
595939de
PM
219inferior_to_inferior_object (struct inferior *inferior)
220{
221 inferior_object *inf_obj;
222
19ba03f4 223 inf_obj = (inferior_object *) inferior_data (inferior, infpy_inf_data_key);
595939de
PM
224 if (!inf_obj)
225 {
595939de
PM
226 inf_obj = PyObject_New (inferior_object, &inferior_object_type);
227 if (!inf_obj)
61fd3e73 228 return NULL;
595939de
PM
229
230 inf_obj->inferior = inferior;
231 inf_obj->threads = NULL;
232 inf_obj->nthreads = 0;
233
72bc1d24
SM
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. */
595939de 236 set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
595939de 237 }
72bc1d24
SM
238
239 /* We are returning a new reference. */
61fd3e73
TT
240 gdb_assert (inf_obj != nullptr);
241 return gdbpy_ref<inferior_object>::new_reference (inf_obj);
595939de
PM
242}
243
7c96f8c1
TT
244/* Called when a new inferior is created. Notifies any Python event
245 listeners. */
246static void
247python_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
61fd3e73 257 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
7c96f8c1
TT
258 if (inf_obj == NULL)
259 {
260 gdbpy_print_stack ();
261 return;
262 }
263
d98fc15b 264 gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
7c96f8c1 265 if (event == NULL
00431a78
PA
266 || evpy_add_attribute (event.get (), "inferior",
267 (PyObject *) inf_obj.get ()) < 0
7c96f8c1
TT
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. */
274static void
275python_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
61fd3e73 285 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
7c96f8c1
TT
286 if (inf_obj == NULL)
287 {
288 gdbpy_print_stack ();
289 return;
290 }
291
d98fc15b 292 gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
7c96f8c1 293 if (event == NULL
00431a78
PA
294 || evpy_add_attribute (event.get (), "inferior",
295 (PyObject *) inf_obj.get ()) < 0
7c96f8c1
TT
296 || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
297 gdbpy_print_stack ();
298}
299
db1337cc 300gdbpy_ref<>
00431a78 301thread_to_thread_object (thread_info *thr)
595939de 302{
61fd3e73 303 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
9205649a 304 if (inf_obj == NULL)
754eadd1
PM
305 return NULL;
306
00431a78
PA
307 for (threadlist_entry *thread = inf_obj->threads;
308 thread != NULL;
754eadd1 309 thread = thread->next)
00431a78 310 if (thread->thread_obj->thread == thr)
05b08ac1 311 return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ());
595939de 312
4a137fec
TT
313 PyErr_SetString (PyExc_SystemError,
314 _("could not find gdb thread object"));
595939de
PM
315 return NULL;
316}
317
318static void
319add_thread_object (struct thread_info *tp)
320{
595939de
PM
321 inferior_object *inf_obj;
322 struct threadlist_entry *entry;
323
0646da15
TT
324 if (!gdb_python_initialized)
325 return;
326
07bc7329 327 gdbpy_enter enter_py (python_gdbarch, python_language);
595939de 328
05b08ac1
TT
329 gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
330 if (thread_obj == NULL)
595939de
PM
331 {
332 gdbpy_print_stack ();
595939de
PM
333 return;
334 }
335
336 inf_obj = (inferior_object *) thread_obj->inf_obj;
337
05b08ac1 338 entry = new threadlist_entry (std::move (thread_obj));
595939de
PM
339 entry->next = inf_obj->threads;
340
341 inf_obj->threads = entry;
342 inf_obj->nthreads++;
7c96f8c1
TT
343
344 if (evregpy_no_listeners_p (gdb_py_events.new_thread))
345 return;
346
d98fc15b 347 gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type,
72ee03ff 348 (PyObject *) inf_obj);
7c96f8c1
TT
349 if (event == NULL
350 || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
351 gdbpy_print_stack ();
595939de
PM
352}
353
354static void
355delete_thread_object (struct thread_info *tp, int ignore)
356{
595939de 357 struct threadlist_entry **entry, *tmp;
256458bc 358
0646da15
TT
359 if (!gdb_python_initialized)
360 return;
361
07bc7329 362 gdbpy_enter enter_py (python_gdbarch, python_language);
595939de 363
61fd3e73 364 gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
88b6faea 365 if (inf_obj == NULL)
07bc7329 366 return;
595939de
PM
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)
88b6faea 375 return;
595939de 376
595939de
PM
377 tmp = *entry;
378 tmp->thread_obj->thread = NULL;
379
380 *entry = (*entry)->next;
381 inf_obj->nthreads--;
382
05b08ac1 383 delete tmp;
595939de
PM
384}
385
386static PyObject *
387infpy_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
a70b8144 396 try
492d29ea
PA
397 {
398 update_thread_list ();
399 }
230d2906 400 catch (const gdb_exception &except)
492d29ea
PA
401 {
402 GDB_PY_HANDLE_EXCEPTION (except);
403 }
f66713d2 404
595939de
PM
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 {
05b08ac1
TT
412 PyObject *thr = (PyObject *) entry->thread_obj.get ();
413 Py_INCREF (thr);
414 PyTuple_SET_ITEM (tuple, i, thr);
595939de
PM
415 }
416
417 return tuple;
418}
419
420static PyObject *
421infpy_get_num (PyObject *self, void *closure)
422{
423 inferior_object *inf = (inferior_object *) self;
424
425 INFPY_REQUIRE_VALID (inf);
426
062534d4 427 return gdb_py_object_from_longest (inf->inferior->num).release ();
595939de
PM
428}
429
55789354
TBA
430/* Return the connection number of the given inferior, or None if a
431 connection does not exist. */
432
433static PyObject *
434infpy_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
8b9c48b2 444 return gdb_py_object_from_longest (target->connection_number).release ();
55789354
TBA
445}
446
595939de
PM
447static PyObject *
448infpy_get_pid (PyObject *self, void *closure)
449{
450 inferior_object *inf = (inferior_object *) self;
451
452 INFPY_REQUIRE_VALID (inf);
453
062534d4 454 return gdb_py_object_from_longest (inf->inferior->pid).release ();
595939de
PM
455}
456
457static PyObject *
458infpy_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
a40bf0c2
SM
468/* Getter of gdb.Inferior.progspace. */
469
470static PyObject *
471infpy_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
3c7aa307 480 return pspace_to_pspace_object (pspace).release ();
a40bf0c2
SM
481}
482
595939de
PM
483/* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
484 Returns a tuple of all inferiors. */
485PyObject *
486gdbpy_inferiors (PyObject *unused, PyObject *unused2)
487{
7780f186 488 gdbpy_ref<> list (PyList_New (0));
f59fe7f8 489 if (list == NULL)
595939de
PM
490 return NULL;
491
d9bc85b6
SM
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 }
27ca1a5b 502
f59fe7f8 503 return PyList_AsTuple (list.get ());
595939de
PM
504}
505
506/* Membuf and memory manipulation. */
507
2678e2af 508/* Implementation of Inferior.read_memory (address, length).
595939de 509 Returns a Python buffer object with LENGTH bytes of the inferior's
8dc78533
JK
510 memory at ADDRESS. Both arguments are integers. Returns NULL on error,
511 with a python exception set. */
595939de
PM
512static PyObject *
513infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
514{
595939de 515 CORE_ADDR addr, length;
075c55e0 516 gdb::unique_xmalloc_ptr<gdb_byte> buffer;
cc0265cd 517 PyObject *addr_obj, *length_obj, *result;
2adadf51 518 static const char *keywords[] = { "address", "length", NULL };
595939de 519
2adadf51
PA
520 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
521 &addr_obj, &length_obj))
595939de
PM
522 return NULL;
523
b86af38a
TT
524 if (get_addr_from_python (addr_obj, &addr) < 0
525 || get_addr_from_python (length_obj, &length) < 0)
526 return NULL;
527
a70b8144 528 try
595939de 529 {
075c55e0 530 buffer.reset ((gdb_byte *) xmalloc (length));
595939de 531
075c55e0 532 read_memory (addr, buffer.get (), length);
595939de 533 }
230d2906 534 catch (const gdb_exception &except)
595939de 535 {
595939de
PM
536 GDB_PY_HANDLE_EXCEPTION (except);
537 }
538
88b6faea
TT
539 gdbpy_ref<membuf_object> membuf_obj (PyObject_New (membuf_object,
540 &membuf_object_type));
595939de 541 if (membuf_obj == NULL)
075c55e0 542 return NULL;
595939de 543
075c55e0 544 membuf_obj->buffer = buffer.release ();
595939de
PM
545 membuf_obj->addr = addr;
546 membuf_obj->length = length;
547
9a27f2c6 548#ifdef IS_PY3K
88b6faea 549 result = PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
9a27f2c6 550#else
88b6faea 551 result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj.get (), 0,
cc0265cd 552 Py_END_OF_BUFFER);
9a27f2c6 553#endif
9a27f2c6 554
cc0265cd 555 return result;
595939de
PM
556}
557
2678e2af 558/* Implementation of Inferior.write_memory (address, buffer [, length]).
595939de
PM
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
8dc78533
JK
562 provided. The function returns nothing. Returns NULL on error, with
563 a python exception set. */
595939de
PM
564static PyObject *
565infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
566{
cc06b668 567 struct gdb_exception except;
ddd49eee 568 Py_ssize_t buf_len;
7c543f7b 569 const gdb_byte *buffer;
595939de
PM
570 CORE_ADDR addr, length;
571 PyObject *addr_obj, *length_obj = NULL;
2adadf51 572 static const char *keywords[] = { "address", "buffer", "length", NULL };
9a27f2c6 573 Py_buffer pybuf;
595939de 574
2adadf51
PA
575 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
576 &addr_obj, &pybuf, &length_obj))
9a27f2c6 577 return NULL;
595939de 578
6ca62222 579 Py_buffer_up buffer_up (&pybuf);
7c543f7b 580 buffer = (const gdb_byte *) pybuf.buf;
9a27f2c6 581 buf_len = pybuf.len;
595939de 582
b86af38a 583 if (get_addr_from_python (addr_obj, &addr) < 0)
6ca62222 584 return nullptr;
b86af38a
TT
585
586 if (!length_obj)
587 length = buf_len;
588 else if (get_addr_from_python (length_obj, &length) < 0)
6ca62222 589 return nullptr;
b86af38a 590
a70b8144 591 try
595939de 592 {
7c543f7b 593 write_memory_with_notification (addr, buffer, length);
595939de 594 }
94aeb44b 595 catch (gdb_exception &ex)
492d29ea 596 {
94aeb44b 597 except = std::move (ex);
492d29ea 598 }
492d29ea 599
595939de
PM
600 GDB_PY_HANDLE_EXCEPTION (except);
601
595939de
PM
602 Py_RETURN_NONE;
603}
604
605/* Destructor of Membuf objects. */
606static void
607mbpy_dealloc (PyObject *self)
608{
609 xfree (((membuf_object *) self)->buffer);
9a27f2c6 610 Py_TYPE (self)->tp_free (self);
595939de
PM
611}
612
613/* Return a description of the Membuf object. */
614static PyObject *
615mbpy_str (PyObject *self)
616{
617 membuf_object *membuf_obj = (membuf_object *) self;
618
619 return PyString_FromFormat (_("Memory buffer for address %s, \
620which is %s bytes long."),
621 paddress (python_gdbarch, membuf_obj->addr),
622 pulongest (membuf_obj->length));
623}
624
9a27f2c6
PK
625#ifdef IS_PY3K
626
627static int
628get_buffer (PyObject *self, Py_buffer *buf, int flags)
629{
630 membuf_object *membuf_obj = (membuf_object *) self;
631 int ret;
256458bc 632
9a27f2c6 633 ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
256458bc 634 membuf_obj->length, 0,
9a27f2c6 635 PyBUF_CONTIG);
a121b7c1
PA
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";
9a27f2c6
PK
640
641 return ret;
642}
643
644#else
645
595939de
PM
646static Py_ssize_t
647get_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
663static Py_ssize_t
664get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
665{
666 return get_read_buffer (self, segment, ptrptr);
667}
668
669static Py_ssize_t
670get_seg_count (PyObject *self, Py_ssize_t *lenp)
671{
672 if (lenp)
673 *lenp = ((membuf_object *) self)->length;
674
675 return 1;
676}
677
678static Py_ssize_t
679get_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
9a27f2c6
PK
690#endif /* IS_PY3K */
691
595939de
PM
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
8dc78533
JK
698 was located, or if the pattern was not found, returns None. Returns NULL
699 on error, with a python exception set. */
595939de
PM
700static PyObject *
701infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
702{
cc06b668 703 struct gdb_exception except;
595939de 704 CORE_ADDR start_addr, length;
2adadf51 705 static const char *keywords[] = { "address", "length", "pattern", NULL };
9a27f2c6 706 PyObject *start_addr_obj, *length_obj;
595939de 707 Py_ssize_t pattern_size;
7c543f7b 708 const gdb_byte *buffer;
595939de
PM
709 CORE_ADDR found_addr;
710 int found = 0;
9a27f2c6 711 Py_buffer pybuf;
595939de 712
2adadf51
PA
713 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
714 &start_addr_obj, &length_obj,
715 &pybuf))
9a27f2c6
PK
716 return NULL;
717
6ca62222 718 Py_buffer_up buffer_up (&pybuf);
7c543f7b 719 buffer = (const gdb_byte *) pybuf.buf;
9a27f2c6 720 pattern_size = pybuf.len;
595939de 721
b86af38a 722 if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
6ca62222 723 return nullptr;
256458bc 724
b86af38a 725 if (get_addr_from_python (length_obj, &length) < 0)
6ca62222 726 return nullptr;
9a27f2c6 727
b86af38a
TT
728 if (!length)
729 {
730 PyErr_SetString (PyExc_ValueError,
731 _("Search range is empty."));
6ca62222 732 return nullptr;
b86af38a
TT
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."));
6ca62222 740 return nullptr;
595939de 741 }
595939de 742
a70b8144 743 try
595939de
PM
744 {
745 found = target_search_memory (start_addr, length,
746 buffer, pattern_size,
747 &found_addr);
748 }
94aeb44b 749 catch (gdb_exception &ex)
492d29ea 750 {
94aeb44b 751 except = std::move (ex);
492d29ea 752 }
492d29ea 753
b86af38a 754 GDB_PY_HANDLE_EXCEPTION (except);
9a27f2c6 755
595939de 756 if (found)
b017825f 757 return gdb_py_object_from_ulongest (found_addr).release ();
595939de
PM
758 else
759 Py_RETURN_NONE;
760}
761
29703da4
PM
762/* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
763 Returns True if this inferior object still exists in GDB. */
764
765static PyObject *
766infpy_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
2b0c8b01 776/* Implementation of gdb.Inferior.thread_from_handle (self, handle)
dda83cd7 777 -> gdb.InferiorThread. */
fbbe5337 778
7d221512 779static PyObject *
fbbe5337
KB
780infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
781{
db1337cc 782 PyObject *handle_obj;
fbbe5337 783 inferior_object *inf_obj = (inferior_object *) self;
2b0c8b01 784 static const char *keywords[] = { "handle", NULL };
fbbe5337
KB
785
786 INFPY_REQUIRE_VALID (inf_obj);
787
788 if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
789 return NULL;
790
50a82723
KB
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
fbbe5337
KB
810 {
811 PyErr_SetString (PyExc_TypeError,
2b0c8b01 812 _("Argument 'handle' must be a thread handle object."));
fbbe5337
KB
813
814 return NULL;
815 }
db1337cc 816
a70b8144 817 try
db1337cc
TT
818 {
819 struct thread_info *thread_info;
db1337cc 820
50a82723 821 thread_info = find_thread_by_handle
dda83cd7 822 (gdb::array_view<const gdb_byte> (bytes, bytes_len),
50a82723 823 inf_obj->inferior);
db1337cc 824 if (thread_info != NULL)
4a137fec 825 return thread_to_thread_object (thread_info).release ();
db1337cc 826 }
230d2906 827 catch (const gdb_exception &except)
fbbe5337 828 {
db1337cc 829 GDB_PY_HANDLE_EXCEPTION (except);
fbbe5337
KB
830 }
831
4a137fec 832 Py_RETURN_NONE;
fbbe5337
KB
833}
834
add5ded5
TT
835/* Implementation of gdb.Inferior.architecture. */
836
837static PyObject *
838infpy_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
1256af7d
SM
847/* Implement repr() for gdb.Inferior. */
848
849static PyObject *
850infpy_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
fbbe5337 862
754eadd1
PM
863static void
864infpy_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);
2e953aca 873 Py_TYPE (obj)->tp_free (obj);
754eadd1 874}
595939de
PM
875
876/* Clear the INFERIOR pointer in an Inferior object and clear the
877 thread list. */
878static void
879py_free_inferior (struct inferior *inf, void *datum)
880{
595939de
PM
881 struct threadlist_entry *th_entry, *th_tmp;
882
0646da15
TT
883 if (!gdb_python_initialized)
884 return;
885
07bc7329 886 gdbpy_enter enter_py (python_gdbarch, python_language);
05b08ac1 887 gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
595939de
PM
888
889 inf_obj->inferior = NULL;
890
891 /* Deallocate threads list. */
892 for (th_entry = inf_obj->threads; th_entry != NULL;)
893 {
595939de
PM
894 th_tmp = th_entry;
895 th_entry = th_entry->next;
05b08ac1 896 delete th_tmp;
595939de
PM
897 }
898
899 inf_obj->nthreads = 0;
595939de
PM
900}
901
2aa48337
KP
902/* Implementation of gdb.selected_inferior() -> gdb.Inferior.
903 Returns the current inferior object. */
904
905PyObject *
906gdbpy_selected_inferior (PyObject *self, PyObject *args)
907{
61fd3e73
TT
908 return ((PyObject *)
909 inferior_to_inferior_object (current_inferior ()).release ());
2aa48337
KP
910}
911
8e3685bf
AB
912void _initialize_py_inferior ();
913void
914_initialize_py_inferior ()
915{
916 infpy_inf_data_key =
917 register_inferior_data_with_cleanup (NULL, py_free_inferior);
918}
919
999633ed 920int
595939de
PM
921gdbpy_initialize_inferior (void)
922{
923 if (PyType_Ready (&inferior_object_type) < 0)
999633ed 924 return -1;
595939de 925
aa36459a
TT
926 if (gdb_pymodule_addobject (gdb_module, "Inferior",
927 (PyObject *) &inferior_object_type) < 0)
999633ed 928 return -1;
595939de 929
c90e7d63
SM
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");
2c473def
MW
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 });
c90e7d63
SM
948 gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
949 gdb::observers::inferior_removed.attach (python_inferior_deleted,
950 "py-inferior");
595939de 951
6a1b1664 952 membuf_object_type.tp_new = PyType_GenericNew;
595939de 953 if (PyType_Ready (&membuf_object_type) < 0)
999633ed 954 return -1;
595939de 955
8833fbf0
TT
956 return gdb_pymodule_addobject (gdb_module, "Membuf",
957 (PyObject *) &membuf_object_type);
595939de
PM
958}
959
0d1f4ceb 960static gdb_PyGetSetDef inferior_object_getset[] =
595939de
PM
961{
962 { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
55789354
TBA
963 { "connection_num", infpy_get_connection_num, NULL,
964 "ID of inferior's connection, as assigned by GDB.", NULL },
595939de
PM
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 },
a40bf0c2 969 { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
595939de
PM
970 { NULL }
971};
972
973static PyMethodDef inferior_object_methods[] =
974{
29703da4
PM
975 { "is_valid", infpy_is_valid, METH_NOARGS,
976 "is_valid () -> Boolean.\n\
977Return true if this inferior is valid, false if not." },
595939de
PM
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\
983Return 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\
987Write 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\
991Return a long with the address of a match, or None." },
2b0c8b01 992 /* thread_from_thread_handle is deprecated. */
fbbe5337
KB
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\
2b0c8b01
KB
996Return thread object corresponding to thread handle.\n\
997This 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\
fbbe5337 1001Return thread object corresponding to thread handle." },
add5ded5
TT
1002 { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
1003 "architecture () -> gdb.Architecture\n\
1004Return architecture of this inferior." },
595939de
PM
1005 { NULL }
1006};
1007
e36122e9 1008PyTypeObject inferior_object_type =
595939de 1009{
9a27f2c6 1010 PyVarObject_HEAD_INIT (NULL, 0)
595939de
PM
1011 "gdb.Inferior", /* tp_name */
1012 sizeof (inferior_object), /* tp_basicsize */
1013 0, /* tp_itemsize */
754eadd1 1014 infpy_dealloc, /* tp_dealloc */
595939de
PM
1015 0, /* tp_print */
1016 0, /* tp_getattr */
1017 0, /* tp_setattr */
1018 0, /* tp_compare */
1256af7d 1019 infpy_repr, /* tp_repr */
595939de
PM
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
9a27f2c6
PK
1049#ifdef IS_PY3K
1050
1051static PyBufferProcs buffer_procs =
1052{
1053 get_buffer
1054};
1055
1056#else
1057
595939de
PM
1058static PyBufferProcs buffer_procs = {
1059 get_read_buffer,
1060 get_write_buffer,
1061 get_seg_count,
6c28e44a 1062 get_char_buffer
595939de 1063};
9a27f2c6 1064#endif /* IS_PY3K */
595939de 1065
e36122e9 1066PyTypeObject membuf_object_type = {
9a27f2c6 1067 PyVarObject_HEAD_INIT (NULL, 0)
595939de
PM
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 */
595939de 1104};
This page took 1.715041 seconds and 4 git commands to generate.