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