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