py-inferior.c revision 1.10 1 1.1 christos /* Python interface to inferiors.
2 1.1 christos
3 1.10 christos Copyright (C) 2009-2023 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "defs.h"
21 1.10 christos #include "auto-load.h"
22 1.1 christos #include "gdbcore.h"
23 1.1 christos #include "gdbthread.h"
24 1.1 christos #include "inferior.h"
25 1.1 christos #include "objfiles.h"
26 1.8 christos #include "observable.h"
27 1.1 christos #include "python-internal.h"
28 1.1 christos #include "arch-utils.h"
29 1.1 christos #include "language.h"
30 1.9 christos #include "gdbsupport/gdb_signals.h"
31 1.1 christos #include "py-event.h"
32 1.1 christos #include "py-stopevent.h"
33 1.10 christos #include <unordered_map>
34 1.1 christos
35 1.10 christos using thread_map_t
36 1.10 christos = std::unordered_map<thread_info *, gdbpy_ref<thread_object>>;
37 1.1 christos
38 1.8 christos struct inferior_object
39 1.1 christos {
40 1.1 christos PyObject_HEAD
41 1.1 christos
42 1.1 christos /* The inferior we represent. */
43 1.1 christos struct inferior *inferior;
44 1.1 christos
45 1.10 christos /* thread_object instances under this inferior. This owns a
46 1.1 christos reference to each object it contains. */
47 1.10 christos thread_map_t *threads;
48 1.8 christos };
49 1.1 christos
50 1.5 christos extern PyTypeObject inferior_object_type
51 1.1 christos CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
52 1.1 christos
53 1.10 christos /* Deleter to clean up when an inferior is removed. */
54 1.10 christos struct infpy_deleter
55 1.10 christos {
56 1.10 christos void operator() (inferior_object *obj)
57 1.10 christos {
58 1.10 christos if (!gdb_python_initialized)
59 1.10 christos return;
60 1.1 christos
61 1.10 christos gdbpy_enter enter_py;
62 1.10 christos gdbpy_ref<inferior_object> inf_obj (obj);
63 1.10 christos
64 1.10 christos inf_obj->inferior = NULL;
65 1.1 christos
66 1.10 christos delete inf_obj->threads;
67 1.10 christos }
68 1.10 christos };
69 1.1 christos
70 1.10 christos static const registry<inferior>::key<inferior_object, infpy_deleter>
71 1.10 christos infpy_inf_data_key;
72 1.1 christos
73 1.1 christos /* Require that INFERIOR be a valid inferior ID. */
74 1.1 christos #define INFPY_REQUIRE_VALID(Inferior) \
75 1.1 christos do { \
76 1.1 christos if (!Inferior->inferior) \
77 1.1 christos { \
78 1.1 christos PyErr_SetString (PyExc_RuntimeError, \
79 1.1 christos _("Inferior no longer exists.")); \
80 1.1 christos return NULL; \
81 1.1 christos } \
82 1.1 christos } while (0)
83 1.1 christos
84 1.1 christos static void
85 1.10 christos python_on_normal_stop (struct bpstat *bs, int print_frame)
86 1.1 christos {
87 1.1 christos enum gdb_signal stop_signal;
88 1.1 christos
89 1.1 christos if (!gdb_python_initialized)
90 1.1 christos return;
91 1.1 christos
92 1.8 christos if (inferior_ptid == null_ptid)
93 1.8 christos return;
94 1.1 christos
95 1.10 christos stop_signal = inferior_thread ()->stop_signal ();
96 1.1 christos
97 1.10 christos gdbpy_enter enter_py;
98 1.1 christos
99 1.1 christos if (emit_stop_event (bs, stop_signal) < 0)
100 1.1 christos gdbpy_print_stack ();
101 1.1 christos }
102 1.1 christos
103 1.1 christos static void
104 1.1 christos python_on_resume (ptid_t ptid)
105 1.1 christos {
106 1.1 christos if (!gdb_python_initialized)
107 1.1 christos return;
108 1.1 christos
109 1.10 christos gdbpy_enter enter_py (target_gdbarch ());
110 1.1 christos
111 1.1 christos if (emit_continue_event (ptid) < 0)
112 1.1 christos gdbpy_print_stack ();
113 1.1 christos }
114 1.1 christos
115 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
116 1.3 christos when an inferior function call is about to be made. */
117 1.3 christos
118 1.3 christos static void
119 1.3 christos python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
120 1.3 christos {
121 1.10 christos gdbpy_enter enter_py (target_gdbarch ());
122 1.3 christos
123 1.3 christos if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
124 1.3 christos gdbpy_print_stack ();
125 1.3 christos }
126 1.3 christos
127 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
128 1.3 christos when an inferior function call has completed. */
129 1.3 christos
130 1.3 christos static void
131 1.3 christos python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
132 1.3 christos {
133 1.10 christos gdbpy_enter enter_py (target_gdbarch ());
134 1.3 christos
135 1.3 christos if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
136 1.3 christos gdbpy_print_stack ();
137 1.3 christos }
138 1.3 christos
139 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
140 1.3 christos when a part of memory has been modified by user action (eg via a
141 1.3 christos 'set' command). */
142 1.3 christos
143 1.3 christos static void
144 1.3 christos python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
145 1.3 christos {
146 1.10 christos gdbpy_enter enter_py (target_gdbarch ());
147 1.3 christos
148 1.3 christos if (emit_memory_changed_event (addr, len) < 0)
149 1.3 christos gdbpy_print_stack ();
150 1.3 christos }
151 1.3 christos
152 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
153 1.3 christos when a register has been modified by user action (eg via a 'set'
154 1.3 christos command). */
155 1.3 christos
156 1.3 christos static void
157 1.10 christos python_on_register_change (frame_info_ptr frame, int regnum)
158 1.3 christos {
159 1.10 christos gdbpy_enter enter_py (target_gdbarch ());
160 1.3 christos
161 1.3 christos if (emit_register_changed_event (frame, regnum) < 0)
162 1.3 christos gdbpy_print_stack ();
163 1.3 christos }
164 1.3 christos
165 1.1 christos static void
166 1.1 christos python_inferior_exit (struct inferior *inf)
167 1.1 christos {
168 1.1 christos const LONGEST *exit_code = NULL;
169 1.1 christos
170 1.1 christos if (!gdb_python_initialized)
171 1.1 christos return;
172 1.1 christos
173 1.10 christos gdbpy_enter enter_py (target_gdbarch ());
174 1.1 christos
175 1.1 christos if (inf->has_exit_code)
176 1.1 christos exit_code = &inf->exit_code;
177 1.1 christos
178 1.1 christos if (emit_exited_event (exit_code, inf) < 0)
179 1.1 christos gdbpy_print_stack ();
180 1.1 christos }
181 1.1 christos
182 1.1 christos /* Callback used to notify Python listeners about new objfiles loaded in the
183 1.3 christos inferior. OBJFILE may be NULL which means that the objfile list has been
184 1.3 christos cleared (emptied). */
185 1.1 christos
186 1.1 christos static void
187 1.1 christos python_new_objfile (struct objfile *objfile)
188 1.1 christos {
189 1.1 christos if (!gdb_python_initialized)
190 1.1 christos return;
191 1.1 christos
192 1.7 christos gdbpy_enter enter_py (objfile != NULL
193 1.9 christos ? objfile->arch ()
194 1.10 christos : target_gdbarch ());
195 1.1 christos
196 1.3 christos if (objfile == NULL)
197 1.3 christos {
198 1.3 christos if (emit_clear_objfiles_event () < 0)
199 1.3 christos gdbpy_print_stack ();
200 1.3 christos }
201 1.3 christos else
202 1.3 christos {
203 1.3 christos if (emit_new_objfile_event (objfile) < 0)
204 1.3 christos gdbpy_print_stack ();
205 1.3 christos }
206 1.1 christos }
207 1.1 christos
208 1.10 christos /* Emit a Python event when an objfile is about to be removed. */
209 1.10 christos
210 1.10 christos static void
211 1.10 christos python_free_objfile (struct objfile *objfile)
212 1.10 christos {
213 1.10 christos if (!gdb_python_initialized)
214 1.10 christos return;
215 1.10 christos
216 1.10 christos gdbpy_enter enter_py (objfile->arch ());
217 1.10 christos
218 1.10 christos if (emit_free_objfile_event (objfile) < 0)
219 1.10 christos gdbpy_print_stack ();
220 1.10 christos }
221 1.10 christos
222 1.1 christos /* Return a reference to the Python object of type Inferior
223 1.1 christos representing INFERIOR. If the object has already been created,
224 1.1 christos return it and increment the reference count, otherwise, create it.
225 1.1 christos Return NULL on failure. */
226 1.8 christos
227 1.8 christos gdbpy_ref<inferior_object>
228 1.1 christos inferior_to_inferior_object (struct inferior *inferior)
229 1.1 christos {
230 1.1 christos inferior_object *inf_obj;
231 1.1 christos
232 1.10 christos inf_obj = infpy_inf_data_key.get (inferior);
233 1.1 christos if (!inf_obj)
234 1.1 christos {
235 1.1 christos inf_obj = PyObject_New (inferior_object, &inferior_object_type);
236 1.1 christos if (!inf_obj)
237 1.8 christos return NULL;
238 1.1 christos
239 1.1 christos inf_obj->inferior = inferior;
240 1.10 christos inf_obj->threads = new thread_map_t ();
241 1.1 christos
242 1.7 christos /* PyObject_New initializes the new object with a refcount of 1. This
243 1.7 christos counts for the reference we are keeping in the inferior data. */
244 1.10 christos infpy_inf_data_key.set (inferior, inf_obj);
245 1.1 christos }
246 1.7 christos
247 1.7 christos /* We are returning a new reference. */
248 1.8 christos gdb_assert (inf_obj != nullptr);
249 1.8 christos return gdbpy_ref<inferior_object>::new_reference (inf_obj);
250 1.8 christos }
251 1.1 christos
252 1.8 christos /* Called when a new inferior is created. Notifies any Python event
253 1.8 christos listeners. */
254 1.8 christos static void
255 1.8 christos python_new_inferior (struct inferior *inf)
256 1.8 christos {
257 1.8 christos if (!gdb_python_initialized)
258 1.8 christos return;
259 1.1 christos
260 1.10 christos gdbpy_enter enter_py;
261 1.1 christos
262 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
263 1.8 christos return;
264 1.1 christos
265 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
266 1.8 christos if (inf_obj == NULL)
267 1.8 christos {
268 1.8 christos gdbpy_print_stack ();
269 1.8 christos return;
270 1.8 christos }
271 1.1 christos
272 1.8 christos gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
273 1.8 christos if (event == NULL
274 1.8 christos || evpy_add_attribute (event.get (), "inferior",
275 1.8 christos (PyObject *) inf_obj.get ()) < 0
276 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
277 1.8 christos gdbpy_print_stack ();
278 1.1 christos }
279 1.1 christos
280 1.8 christos /* Called when an inferior is removed. Notifies any Python event
281 1.8 christos listeners. */
282 1.8 christos static void
283 1.8 christos python_inferior_deleted (struct inferior *inf)
284 1.1 christos {
285 1.8 christos if (!gdb_python_initialized)
286 1.8 christos return;
287 1.1 christos
288 1.10 christos gdbpy_enter enter_py;
289 1.8 christos
290 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
291 1.8 christos return;
292 1.8 christos
293 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
294 1.8 christos if (inf_obj == NULL)
295 1.8 christos {
296 1.8 christos gdbpy_print_stack ();
297 1.8 christos return;
298 1.8 christos }
299 1.8 christos
300 1.8 christos gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
301 1.8 christos if (event == NULL
302 1.8 christos || evpy_add_attribute (event.get (), "inferior",
303 1.8 christos (PyObject *) inf_obj.get ()) < 0
304 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
305 1.8 christos gdbpy_print_stack ();
306 1.8 christos }
307 1.1 christos
308 1.8 christos gdbpy_ref<>
309 1.8 christos thread_to_thread_object (thread_info *thr)
310 1.8 christos {
311 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
312 1.7 christos if (inf_obj == NULL)
313 1.1 christos return NULL;
314 1.1 christos
315 1.10 christos auto thread_it = inf_obj->threads->find (thr);
316 1.10 christos if (thread_it != inf_obj->threads->end ())
317 1.10 christos return gdbpy_ref<>::new_reference
318 1.10 christos ((PyObject *) (thread_it->second.get ()));
319 1.1 christos
320 1.8 christos PyErr_SetString (PyExc_SystemError,
321 1.8 christos _("could not find gdb thread object"));
322 1.1 christos return NULL;
323 1.1 christos }
324 1.1 christos
325 1.1 christos static void
326 1.1 christos add_thread_object (struct thread_info *tp)
327 1.1 christos {
328 1.1 christos inferior_object *inf_obj;
329 1.1 christos
330 1.1 christos if (!gdb_python_initialized)
331 1.1 christos return;
332 1.1 christos
333 1.10 christos gdbpy_enter enter_py;
334 1.1 christos
335 1.9 christos gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
336 1.9 christos if (thread_obj == NULL)
337 1.1 christos {
338 1.1 christos gdbpy_print_stack ();
339 1.1 christos return;
340 1.1 christos }
341 1.1 christos
342 1.1 christos inf_obj = (inferior_object *) thread_obj->inf_obj;
343 1.1 christos
344 1.10 christos auto ins_result = inf_obj->threads->emplace
345 1.10 christos (thread_map_t::value_type (tp, std::move (thread_obj)));
346 1.1 christos
347 1.10 christos if (!ins_result.second)
348 1.10 christos return;
349 1.8 christos
350 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.new_thread))
351 1.8 christos return;
352 1.8 christos
353 1.10 christos gdbpy_ref<> event = create_thread_event_object
354 1.10 christos (&new_thread_event_object_type,
355 1.10 christos (PyObject *) ins_result.first->second.get ());
356 1.10 christos
357 1.8 christos if (event == NULL
358 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
359 1.8 christos gdbpy_print_stack ();
360 1.1 christos }
361 1.1 christos
362 1.1 christos static void
363 1.1 christos delete_thread_object (struct thread_info *tp, int ignore)
364 1.1 christos {
365 1.1 christos if (!gdb_python_initialized)
366 1.1 christos return;
367 1.1 christos
368 1.10 christos gdbpy_enter enter_py;
369 1.1 christos
370 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
371 1.7 christos if (inf_obj == NULL)
372 1.7 christos return;
373 1.1 christos
374 1.10 christos auto it = inf_obj->threads->find (tp);
375 1.10 christos if (it != inf_obj->threads->end ())
376 1.10 christos {
377 1.10 christos /* Some python code can still hold a reference to the thread_object
378 1.10 christos instance. Make sure to remove the link to the associated
379 1.10 christos thread_info object as it will be freed soon. This makes the python
380 1.10 christos object invalid (i.e. gdb.InfThread.is_valid returns False). */
381 1.10 christos it->second->thread = nullptr;
382 1.10 christos inf_obj->threads->erase (it);
383 1.10 christos }
384 1.1 christos }
385 1.1 christos
386 1.1 christos static PyObject *
387 1.1 christos infpy_threads (PyObject *self, PyObject *args)
388 1.1 christos {
389 1.10 christos int i = 0;
390 1.1 christos inferior_object *inf_obj = (inferior_object *) self;
391 1.1 christos PyObject *tuple;
392 1.1 christos
393 1.1 christos INFPY_REQUIRE_VALID (inf_obj);
394 1.1 christos
395 1.9 christos try
396 1.5 christos {
397 1.5 christos update_thread_list ();
398 1.5 christos }
399 1.9 christos catch (const gdb_exception &except)
400 1.5 christos {
401 1.5 christos GDB_PY_HANDLE_EXCEPTION (except);
402 1.5 christos }
403 1.1 christos
404 1.10 christos tuple = PyTuple_New (inf_obj->threads->size ());
405 1.1 christos if (!tuple)
406 1.1 christos return NULL;
407 1.1 christos
408 1.10 christos for (const thread_map_t::value_type &entry : *inf_obj->threads)
409 1.1 christos {
410 1.10 christos PyObject *thr = (PyObject *) entry.second.get ();
411 1.9 christos Py_INCREF (thr);
412 1.9 christos PyTuple_SET_ITEM (tuple, i, thr);
413 1.10 christos i = i + 1;
414 1.1 christos }
415 1.1 christos
416 1.1 christos return tuple;
417 1.1 christos }
418 1.1 christos
419 1.1 christos static PyObject *
420 1.1 christos infpy_get_num (PyObject *self, void *closure)
421 1.1 christos {
422 1.1 christos inferior_object *inf = (inferior_object *) self;
423 1.1 christos
424 1.1 christos INFPY_REQUIRE_VALID (inf);
425 1.1 christos
426 1.10 christos return gdb_py_object_from_longest (inf->inferior->num).release ();
427 1.10 christos }
428 1.10 christos
429 1.10 christos /* Return the gdb.TargetConnection object for this inferior, or None if a
430 1.10 christos connection does not exist. */
431 1.10 christos
432 1.10 christos static PyObject *
433 1.10 christos infpy_get_connection (PyObject *self, void *closure)
434 1.10 christos {
435 1.10 christos inferior_object *inf = (inferior_object *) self;
436 1.10 christos
437 1.10 christos INFPY_REQUIRE_VALID (inf);
438 1.10 christos
439 1.10 christos process_stratum_target *target = inf->inferior->process_target ();
440 1.10 christos return target_to_connection_object (target).release ();
441 1.10 christos }
442 1.10 christos
443 1.10 christos /* Return the connection number of the given inferior, or None if a
444 1.10 christos connection does not exist. */
445 1.10 christos
446 1.10 christos static PyObject *
447 1.10 christos infpy_get_connection_num (PyObject *self, void *closure)
448 1.10 christos {
449 1.10 christos inferior_object *inf = (inferior_object *) self;
450 1.10 christos
451 1.10 christos INFPY_REQUIRE_VALID (inf);
452 1.10 christos
453 1.10 christos process_stratum_target *target = inf->inferior->process_target ();
454 1.10 christos if (target == nullptr)
455 1.10 christos Py_RETURN_NONE;
456 1.10 christos
457 1.10 christos return gdb_py_object_from_longest (target->connection_number).release ();
458 1.1 christos }
459 1.1 christos
460 1.1 christos static PyObject *
461 1.1 christos infpy_get_pid (PyObject *self, void *closure)
462 1.1 christos {
463 1.1 christos inferior_object *inf = (inferior_object *) self;
464 1.1 christos
465 1.1 christos INFPY_REQUIRE_VALID (inf);
466 1.1 christos
467 1.10 christos return gdb_py_object_from_longest (inf->inferior->pid).release ();
468 1.1 christos }
469 1.1 christos
470 1.1 christos static PyObject *
471 1.1 christos infpy_get_was_attached (PyObject *self, void *closure)
472 1.1 christos {
473 1.1 christos inferior_object *inf = (inferior_object *) self;
474 1.1 christos
475 1.1 christos INFPY_REQUIRE_VALID (inf);
476 1.1 christos if (inf->inferior->attach_flag)
477 1.1 christos Py_RETURN_TRUE;
478 1.1 christos Py_RETURN_FALSE;
479 1.1 christos }
480 1.1 christos
481 1.8 christos /* Getter of gdb.Inferior.progspace. */
482 1.8 christos
483 1.8 christos static PyObject *
484 1.8 christos infpy_get_progspace (PyObject *self, void *closure)
485 1.8 christos {
486 1.8 christos inferior_object *inf = (inferior_object *) self;
487 1.8 christos
488 1.8 christos INFPY_REQUIRE_VALID (inf);
489 1.8 christos
490 1.8 christos program_space *pspace = inf->inferior->pspace;
491 1.8 christos gdb_assert (pspace != nullptr);
492 1.8 christos
493 1.8 christos return pspace_to_pspace_object (pspace).release ();
494 1.8 christos }
495 1.8 christos
496 1.1 christos /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
497 1.1 christos Returns a tuple of all inferiors. */
498 1.1 christos PyObject *
499 1.1 christos gdbpy_inferiors (PyObject *unused, PyObject *unused2)
500 1.1 christos {
501 1.7 christos gdbpy_ref<> list (PyList_New (0));
502 1.7 christos if (list == NULL)
503 1.7 christos return NULL;
504 1.1 christos
505 1.9 christos for (inferior *inf : all_inferiors ())
506 1.9 christos {
507 1.9 christos gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
508 1.9 christos
509 1.9 christos if (inferior == NULL)
510 1.9 christos continue;
511 1.9 christos
512 1.9 christos if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
513 1.9 christos return NULL;
514 1.9 christos }
515 1.1 christos
516 1.7 christos return PyList_AsTuple (list.get ());
517 1.1 christos }
518 1.1 christos
519 1.1 christos /* Membuf and memory manipulation. */
520 1.1 christos
521 1.1 christos /* Implementation of Inferior.read_memory (address, length).
522 1.1 christos Returns a Python buffer object with LENGTH bytes of the inferior's
523 1.1 christos memory at ADDRESS. Both arguments are integers. Returns NULL on error,
524 1.1 christos with a python exception set. */
525 1.1 christos static PyObject *
526 1.1 christos infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
527 1.1 christos {
528 1.1 christos CORE_ADDR addr, length;
529 1.8 christos gdb::unique_xmalloc_ptr<gdb_byte> buffer;
530 1.10 christos PyObject *addr_obj, *length_obj;
531 1.7 christos static const char *keywords[] = { "address", "length", NULL };
532 1.1 christos
533 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
534 1.7 christos &addr_obj, &length_obj))
535 1.1 christos return NULL;
536 1.1 christos
537 1.1 christos if (get_addr_from_python (addr_obj, &addr) < 0
538 1.1 christos || get_addr_from_python (length_obj, &length) < 0)
539 1.1 christos return NULL;
540 1.1 christos
541 1.9 christos try
542 1.1 christos {
543 1.8 christos buffer.reset ((gdb_byte *) xmalloc (length));
544 1.1 christos
545 1.8 christos read_memory (addr, buffer.get (), length);
546 1.1 christos }
547 1.9 christos catch (const gdb_exception &except)
548 1.1 christos {
549 1.1 christos GDB_PY_HANDLE_EXCEPTION (except);
550 1.1 christos }
551 1.1 christos
552 1.1 christos
553 1.10 christos return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
554 1.1 christos }
555 1.1 christos
556 1.1 christos /* Implementation of Inferior.write_memory (address, buffer [, length]).
557 1.1 christos Writes the contents of BUFFER (a Python object supporting the read
558 1.1 christos buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
559 1.1 christos bytes from BUFFER, or its entire contents if the argument is not
560 1.1 christos provided. The function returns nothing. Returns NULL on error, with
561 1.1 christos a python exception set. */
562 1.1 christos static PyObject *
563 1.1 christos infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
564 1.1 christos {
565 1.9 christos struct gdb_exception except;
566 1.1 christos Py_ssize_t buf_len;
567 1.6 christos const gdb_byte *buffer;
568 1.1 christos CORE_ADDR addr, length;
569 1.1 christos PyObject *addr_obj, *length_obj = NULL;
570 1.7 christos static const char *keywords[] = { "address", "buffer", "length", NULL };
571 1.1 christos Py_buffer pybuf;
572 1.1 christos
573 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
574 1.7 christos &addr_obj, &pybuf, &length_obj))
575 1.1 christos return NULL;
576 1.1 christos
577 1.9 christos Py_buffer_up buffer_up (&pybuf);
578 1.6 christos buffer = (const gdb_byte *) pybuf.buf;
579 1.1 christos buf_len = pybuf.len;
580 1.1 christos
581 1.1 christos if (get_addr_from_python (addr_obj, &addr) < 0)
582 1.9 christos return nullptr;
583 1.1 christos
584 1.1 christos if (!length_obj)
585 1.1 christos length = buf_len;
586 1.1 christos else if (get_addr_from_python (length_obj, &length) < 0)
587 1.9 christos return nullptr;
588 1.1 christos
589 1.9 christos try
590 1.1 christos {
591 1.6 christos write_memory_with_notification (addr, buffer, length);
592 1.1 christos }
593 1.9 christos catch (gdb_exception &ex)
594 1.5 christos {
595 1.9 christos except = std::move (ex);
596 1.5 christos }
597 1.5 christos
598 1.1 christos GDB_PY_HANDLE_EXCEPTION (except);
599 1.1 christos
600 1.1 christos Py_RETURN_NONE;
601 1.1 christos }
602 1.1 christos
603 1.1 christos /* Implementation of
604 1.1 christos gdb.search_memory (address, length, pattern). ADDRESS is the
605 1.1 christos address to start the search. LENGTH specifies the scope of the
606 1.1 christos search from ADDRESS. PATTERN is the pattern to search for (and
607 1.1 christos must be a Python object supporting the buffer protocol).
608 1.1 christos Returns a Python Long object holding the address where the pattern
609 1.1 christos was located, or if the pattern was not found, returns None. Returns NULL
610 1.1 christos on error, with a python exception set. */
611 1.1 christos static PyObject *
612 1.1 christos infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
613 1.1 christos {
614 1.9 christos struct gdb_exception except;
615 1.1 christos CORE_ADDR start_addr, length;
616 1.7 christos static const char *keywords[] = { "address", "length", "pattern", NULL };
617 1.1 christos PyObject *start_addr_obj, *length_obj;
618 1.1 christos Py_ssize_t pattern_size;
619 1.6 christos const gdb_byte *buffer;
620 1.1 christos CORE_ADDR found_addr;
621 1.1 christos int found = 0;
622 1.1 christos Py_buffer pybuf;
623 1.1 christos
624 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
625 1.7 christos &start_addr_obj, &length_obj,
626 1.7 christos &pybuf))
627 1.1 christos return NULL;
628 1.1 christos
629 1.9 christos Py_buffer_up buffer_up (&pybuf);
630 1.6 christos buffer = (const gdb_byte *) pybuf.buf;
631 1.1 christos pattern_size = pybuf.len;
632 1.1 christos
633 1.1 christos if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
634 1.9 christos return nullptr;
635 1.1 christos
636 1.1 christos if (get_addr_from_python (length_obj, &length) < 0)
637 1.9 christos return nullptr;
638 1.1 christos
639 1.1 christos if (!length)
640 1.1 christos {
641 1.1 christos PyErr_SetString (PyExc_ValueError,
642 1.1 christos _("Search range is empty."));
643 1.9 christos return nullptr;
644 1.1 christos }
645 1.1 christos /* Watch for overflows. */
646 1.1 christos else if (length > CORE_ADDR_MAX
647 1.1 christos || (start_addr + length - 1) < start_addr)
648 1.1 christos {
649 1.1 christos PyErr_SetString (PyExc_ValueError,
650 1.1 christos _("The search range is too large."));
651 1.9 christos return nullptr;
652 1.1 christos }
653 1.1 christos
654 1.9 christos try
655 1.1 christos {
656 1.1 christos found = target_search_memory (start_addr, length,
657 1.1 christos buffer, pattern_size,
658 1.1 christos &found_addr);
659 1.1 christos }
660 1.9 christos catch (gdb_exception &ex)
661 1.5 christos {
662 1.9 christos except = std::move (ex);
663 1.5 christos }
664 1.5 christos
665 1.1 christos GDB_PY_HANDLE_EXCEPTION (except);
666 1.1 christos
667 1.1 christos if (found)
668 1.9 christos return gdb_py_object_from_ulongest (found_addr).release ();
669 1.1 christos else
670 1.1 christos Py_RETURN_NONE;
671 1.1 christos }
672 1.1 christos
673 1.1 christos /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
674 1.1 christos Returns True if this inferior object still exists in GDB. */
675 1.1 christos
676 1.1 christos static PyObject *
677 1.1 christos infpy_is_valid (PyObject *self, PyObject *args)
678 1.1 christos {
679 1.1 christos inferior_object *inf = (inferior_object *) self;
680 1.1 christos
681 1.1 christos if (! inf->inferior)
682 1.1 christos Py_RETURN_FALSE;
683 1.1 christos
684 1.1 christos Py_RETURN_TRUE;
685 1.1 christos }
686 1.1 christos
687 1.9 christos /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
688 1.10 christos -> gdb.InferiorThread. */
689 1.8 christos
690 1.8 christos static PyObject *
691 1.8 christos infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
692 1.8 christos {
693 1.8 christos PyObject *handle_obj;
694 1.8 christos inferior_object *inf_obj = (inferior_object *) self;
695 1.9 christos static const char *keywords[] = { "handle", NULL };
696 1.8 christos
697 1.8 christos INFPY_REQUIRE_VALID (inf_obj);
698 1.8 christos
699 1.8 christos if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
700 1.8 christos return NULL;
701 1.8 christos
702 1.9 christos const gdb_byte *bytes;
703 1.9 christos size_t bytes_len;
704 1.9 christos Py_buffer_up buffer_up;
705 1.9 christos Py_buffer py_buf;
706 1.9 christos
707 1.9 christos if (PyObject_CheckBuffer (handle_obj)
708 1.9 christos && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
709 1.9 christos {
710 1.9 christos buffer_up.reset (&py_buf);
711 1.9 christos bytes = (const gdb_byte *) py_buf.buf;
712 1.9 christos bytes_len = py_buf.len;
713 1.9 christos }
714 1.9 christos else if (gdbpy_is_value_object (handle_obj))
715 1.9 christos {
716 1.9 christos struct value *val = value_object_to_value (handle_obj);
717 1.10 christos bytes = value_contents_all (val).data ();
718 1.10 christos bytes_len = value_type (val)->length ();
719 1.9 christos }
720 1.9 christos else
721 1.8 christos {
722 1.8 christos PyErr_SetString (PyExc_TypeError,
723 1.9 christos _("Argument 'handle' must be a thread handle object."));
724 1.8 christos
725 1.8 christos return NULL;
726 1.8 christos }
727 1.8 christos
728 1.9 christos try
729 1.8 christos {
730 1.8 christos struct thread_info *thread_info;
731 1.8 christos
732 1.9 christos thread_info = find_thread_by_handle
733 1.10 christos (gdb::array_view<const gdb_byte> (bytes, bytes_len),
734 1.9 christos inf_obj->inferior);
735 1.8 christos if (thread_info != NULL)
736 1.8 christos return thread_to_thread_object (thread_info).release ();
737 1.8 christos }
738 1.9 christos catch (const gdb_exception &except)
739 1.8 christos {
740 1.8 christos GDB_PY_HANDLE_EXCEPTION (except);
741 1.8 christos }
742 1.8 christos
743 1.8 christos Py_RETURN_NONE;
744 1.8 christos }
745 1.8 christos
746 1.8 christos /* Implementation of gdb.Inferior.architecture. */
747 1.8 christos
748 1.8 christos static PyObject *
749 1.8 christos infpy_architecture (PyObject *self, PyObject *args)
750 1.8 christos {
751 1.8 christos inferior_object *inf = (inferior_object *) self;
752 1.8 christos
753 1.8 christos INFPY_REQUIRE_VALID (inf);
754 1.8 christos
755 1.8 christos return gdbarch_to_arch_object (inf->inferior->gdbarch);
756 1.8 christos }
757 1.8 christos
758 1.8 christos /* Implement repr() for gdb.Inferior. */
759 1.8 christos
760 1.8 christos static PyObject *
761 1.8 christos infpy_repr (PyObject *obj)
762 1.8 christos {
763 1.8 christos inferior_object *self = (inferior_object *) obj;
764 1.8 christos inferior *inf = self->inferior;
765 1.8 christos
766 1.8 christos if (inf == nullptr)
767 1.10 christos return PyUnicode_FromString ("<gdb.Inferior (invalid)>");
768 1.8 christos
769 1.10 christos return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
770 1.10 christos inf->num, inf->pid);
771 1.8 christos }
772 1.8 christos
773 1.8 christos
774 1.1 christos static void
775 1.1 christos infpy_dealloc (PyObject *obj)
776 1.1 christos {
777 1.1 christos inferior_object *inf_obj = (inferior_object *) obj;
778 1.1 christos
779 1.10 christos /* The inferior itself holds a reference to this Python object, which
780 1.10 christos will keep the reference count of this object above zero until GDB
781 1.10 christos deletes the inferior and py_free_inferior is called.
782 1.10 christos
783 1.10 christos Once py_free_inferior has been called then the link between this
784 1.10 christos Python object and the inferior is set to nullptr, and then the
785 1.10 christos reference count on this Python object is decremented.
786 1.10 christos
787 1.10 christos The result of all this is that the link between this Python object and
788 1.10 christos the inferior should always have been set to nullptr before this
789 1.10 christos function is called. */
790 1.10 christos gdb_assert (inf_obj->inferior == nullptr);
791 1.1 christos
792 1.9 christos Py_TYPE (obj)->tp_free (obj);
793 1.1 christos }
794 1.1 christos
795 1.1 christos /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
796 1.1 christos Returns the current inferior object. */
797 1.1 christos
798 1.1 christos PyObject *
799 1.1 christos gdbpy_selected_inferior (PyObject *self, PyObject *args)
800 1.1 christos {
801 1.8 christos return ((PyObject *)
802 1.8 christos inferior_to_inferior_object (current_inferior ()).release ());
803 1.1 christos }
804 1.1 christos
805 1.1 christos int
806 1.1 christos gdbpy_initialize_inferior (void)
807 1.1 christos {
808 1.1 christos if (PyType_Ready (&inferior_object_type) < 0)
809 1.1 christos return -1;
810 1.1 christos
811 1.1 christos if (gdb_pymodule_addobject (gdb_module, "Inferior",
812 1.1 christos (PyObject *) &inferior_object_type) < 0)
813 1.1 christos return -1;
814 1.1 christos
815 1.10 christos gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
816 1.10 christos gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
817 1.10 christos gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
818 1.10 christos gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
819 1.10 christos gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
820 1.10 christos "py-inferior");
821 1.10 christos gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
822 1.10 christos "py-inferior");
823 1.10 christos gdb::observers::memory_changed.attach (python_on_memory_change,
824 1.10 christos "py-inferior");
825 1.10 christos gdb::observers::register_changed.attach (python_on_register_change,
826 1.10 christos "py-inferior");
827 1.10 christos gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
828 1.10 christos /* Need to run after auto-load's new_objfile observer, so that
829 1.10 christos auto-loaded pretty-printers are available. */
830 1.10 christos gdb::observers::new_objfile.attach
831 1.10 christos (python_new_objfile, "py-inferior",
832 1.10 christos { &auto_load_new_objfile_observer_token });
833 1.10 christos gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior");
834 1.10 christos gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
835 1.10 christos gdb::observers::inferior_removed.attach (python_inferior_deleted,
836 1.10 christos "py-inferior");
837 1.1 christos
838 1.10 christos return 0;
839 1.1 christos }
840 1.1 christos
841 1.7 christos static gdb_PyGetSetDef inferior_object_getset[] =
842 1.1 christos {
843 1.1 christos { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
844 1.10 christos { "connection", infpy_get_connection, NULL,
845 1.10 christos "The gdb.TargetConnection for this inferior.", NULL },
846 1.10 christos { "connection_num", infpy_get_connection_num, NULL,
847 1.10 christos "ID of inferior's connection, as assigned by GDB.", NULL },
848 1.1 christos { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
849 1.1 christos NULL },
850 1.1 christos { "was_attached", infpy_get_was_attached, NULL,
851 1.1 christos "True if the inferior was created using 'attach'.", NULL },
852 1.8 christos { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
853 1.1 christos { NULL }
854 1.1 christos };
855 1.1 christos
856 1.1 christos static PyMethodDef inferior_object_methods[] =
857 1.1 christos {
858 1.1 christos { "is_valid", infpy_is_valid, METH_NOARGS,
859 1.1 christos "is_valid () -> Boolean.\n\
860 1.1 christos Return true if this inferior is valid, false if not." },
861 1.1 christos { "threads", infpy_threads, METH_NOARGS,
862 1.1 christos "Return all the threads of this inferior." },
863 1.1 christos { "read_memory", (PyCFunction) infpy_read_memory,
864 1.1 christos METH_VARARGS | METH_KEYWORDS,
865 1.1 christos "read_memory (address, length) -> buffer\n\
866 1.1 christos Return a buffer object for reading from the inferior's memory." },
867 1.1 christos { "write_memory", (PyCFunction) infpy_write_memory,
868 1.1 christos METH_VARARGS | METH_KEYWORDS,
869 1.1 christos "write_memory (address, buffer [, length])\n\
870 1.1 christos Write the given buffer object to the inferior's memory." },
871 1.1 christos { "search_memory", (PyCFunction) infpy_search_memory,
872 1.1 christos METH_VARARGS | METH_KEYWORDS,
873 1.1 christos "search_memory (address, length, pattern) -> long\n\
874 1.1 christos Return a long with the address of a match, or None." },
875 1.9 christos /* thread_from_thread_handle is deprecated. */
876 1.8 christos { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
877 1.8 christos METH_VARARGS | METH_KEYWORDS,
878 1.8 christos "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
879 1.9 christos Return thread object corresponding to thread handle.\n\
880 1.9 christos This method is deprecated - use thread_from_handle instead." },
881 1.9 christos { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
882 1.9 christos METH_VARARGS | METH_KEYWORDS,
883 1.9 christos "thread_from_handle (handle) -> gdb.InferiorThread.\n\
884 1.8 christos Return thread object corresponding to thread handle." },
885 1.8 christos { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
886 1.8 christos "architecture () -> gdb.Architecture\n\
887 1.8 christos Return architecture of this inferior." },
888 1.1 christos { NULL }
889 1.1 christos };
890 1.1 christos
891 1.5 christos PyTypeObject inferior_object_type =
892 1.1 christos {
893 1.1 christos PyVarObject_HEAD_INIT (NULL, 0)
894 1.1 christos "gdb.Inferior", /* tp_name */
895 1.1 christos sizeof (inferior_object), /* tp_basicsize */
896 1.1 christos 0, /* tp_itemsize */
897 1.1 christos infpy_dealloc, /* tp_dealloc */
898 1.1 christos 0, /* tp_print */
899 1.1 christos 0, /* tp_getattr */
900 1.1 christos 0, /* tp_setattr */
901 1.1 christos 0, /* tp_compare */
902 1.8 christos infpy_repr, /* tp_repr */
903 1.1 christos 0, /* tp_as_number */
904 1.1 christos 0, /* tp_as_sequence */
905 1.1 christos 0, /* tp_as_mapping */
906 1.1 christos 0, /* tp_hash */
907 1.1 christos 0, /* tp_call */
908 1.1 christos 0, /* tp_str */
909 1.1 christos 0, /* tp_getattro */
910 1.1 christos 0, /* tp_setattro */
911 1.1 christos 0, /* tp_as_buffer */
912 1.10 christos Py_TPFLAGS_DEFAULT, /* tp_flags */
913 1.1 christos "GDB inferior object", /* tp_doc */
914 1.1 christos 0, /* tp_traverse */
915 1.1 christos 0, /* tp_clear */
916 1.1 christos 0, /* tp_richcompare */
917 1.1 christos 0, /* tp_weaklistoffset */
918 1.1 christos 0, /* tp_iter */
919 1.1 christos 0, /* tp_iternext */
920 1.1 christos inferior_object_methods, /* tp_methods */
921 1.1 christos 0, /* tp_members */
922 1.1 christos inferior_object_getset, /* tp_getset */
923 1.1 christos 0, /* tp_base */
924 1.1 christos 0, /* tp_dict */
925 1.1 christos 0, /* tp_descr_get */
926 1.1 christos 0, /* tp_descr_set */
927 1.1 christos 0, /* tp_dictoffset */
928 1.1 christos 0, /* tp_init */
929 1.1 christos 0 /* tp_alloc */
930 1.1 christos };
931