]> Git Repo - binutils.git/blob - gdb/python/py-inferior.c
2011-10-27 Phil Muldoon <[email protected]>
[binutils.git] / gdb / python / py-inferior.c
1 /* Python interface to inferiors.
2
3    Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "exceptions.h"
22 #include "gdbcore.h"
23 #include "gdbthread.h"
24 #include "inferior.h"
25 #include "objfiles.h"
26 #include "observer.h"
27 #include "python-internal.h"
28 #include "arch-utils.h"
29 #include "language.h"
30 #include "gdb_signals.h"
31 #include "py-event.h"
32 #include "py-stopevent.h"
33
34 struct threadlist_entry {
35   thread_object *thread_obj;
36   struct threadlist_entry *next;
37 };
38
39 typedef struct
40 {
41   PyObject_HEAD
42
43   /* The inferior we represent.  */
44   struct inferior *inferior;
45
46   /* thread_object instances under this inferior.  This list owns a
47      reference to each object it contains.  */
48   struct threadlist_entry *threads;
49
50   /* Number of threads in the list.  */
51   int nthreads;
52 } inferior_object;
53
54 static PyTypeObject inferior_object_type;
55
56 static const struct inferior_data *infpy_inf_data_key;
57
58 typedef struct {
59   PyObject_HEAD
60   void *buffer;
61
62   /* These are kept just for mbpy_str.  */
63   CORE_ADDR addr;
64   CORE_ADDR length;
65 } membuf_object;
66
67 static PyTypeObject membuf_object_type;
68
69 /* Require that INFERIOR be a valid inferior ID.  */
70 #define INFPY_REQUIRE_VALID(Inferior)                           \
71   do {                                                          \
72     if (!Inferior->inferior)                                    \
73       {                                                         \
74         PyErr_SetString (PyExc_RuntimeError,                    \
75                          _("Inferior no longer exists."));      \
76         return NULL;                                            \
77       }                                                         \
78   } while (0)
79
80 static void
81 python_on_normal_stop (struct bpstats *bs, int print_frame)
82 {
83   struct cleanup *cleanup;
84   enum target_signal stop_signal;
85
86   if (!find_thread_ptid (inferior_ptid))
87       return;
88
89   stop_signal = inferior_thread ()->suspend.stop_signal;
90
91   cleanup = ensure_python_env (get_current_arch (), current_language);
92
93   if (emit_stop_event (bs, stop_signal) < 0)
94     gdbpy_print_stack ();
95
96   do_cleanups (cleanup);
97 }
98
99 static void
100 python_on_resume (ptid_t ptid)
101 {
102   struct cleanup *cleanup;
103
104   cleanup = ensure_python_env (target_gdbarch, current_language);
105
106   if (emit_continue_event (ptid) < 0)
107     gdbpy_print_stack ();
108
109   do_cleanups (cleanup);
110 }
111
112 static void
113 python_inferior_exit (struct inferior *inf)
114 {
115   struct cleanup *cleanup;
116   const LONGEST *exit_code = NULL;
117
118   cleanup = ensure_python_env (target_gdbarch, current_language);
119
120   if (inf->has_exit_code)
121     exit_code = &inf->exit_code;
122
123   if (emit_exited_event (exit_code, inf) < 0)
124     gdbpy_print_stack ();
125
126   do_cleanups (cleanup);
127 }
128
129 /* Callback used to notify Python listeners about new objfiles loaded in the
130    inferior.  */
131
132 static void
133 python_new_objfile (struct objfile *objfile)
134 {
135   struct cleanup *cleanup;
136
137   if (objfile == NULL)
138     return;
139
140   cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
141
142   if (emit_new_objfile_event (objfile) < 0)
143     gdbpy_print_stack ();
144
145   do_cleanups (cleanup);
146 }
147
148 /* Return a reference to the Python object of type Inferior
149    representing INFERIOR.  If the object has already been created,
150    return it and increment the reference count,  otherwise, create it.
151    Return NULL on failure.  */
152 PyObject *
153 inferior_to_inferior_object (struct inferior *inferior)
154 {
155   inferior_object *inf_obj;
156
157   inf_obj = inferior_data (inferior, infpy_inf_data_key);
158   if (!inf_obj)
159     {
160       struct cleanup *cleanup;
161       cleanup = ensure_python_env (python_gdbarch, python_language);
162
163       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
164       if (!inf_obj)
165         {
166           do_cleanups (cleanup);
167           return NULL;
168         }
169
170       inf_obj->inferior = inferior;
171       inf_obj->threads = NULL;
172       inf_obj->nthreads = 0;
173
174       set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
175
176       do_cleanups (cleanup);
177     }
178   else
179     Py_INCREF ((PyObject *)inf_obj);
180
181   return (PyObject *) inf_obj;
182 }
183
184 /* Finds the Python Inferior object for the given PID.  Returns a
185    reference, or NULL if PID does not match any inferior object. */
186
187 PyObject *
188 find_inferior_object (int pid)
189 {
190   struct inflist_entry *p;
191   struct inferior *inf = find_inferior_pid (pid);
192
193   if (inf)
194     return inferior_to_inferior_object (inf);
195
196   return NULL;
197 }
198
199 thread_object *
200 find_thread_object (ptid_t ptid)
201 {
202   int pid;
203   struct threadlist_entry *thread;
204   PyObject *inf_obj;
205   thread_object *found = NULL;
206
207   pid = PIDGET (ptid);
208   if (pid == 0)
209     return NULL;
210
211   inf_obj = find_inferior_object (pid);
212
213   if (! inf_obj)
214     return NULL;
215
216   for (thread = ((inferior_object *)inf_obj)->threads; thread;
217        thread = thread->next)
218     if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
219       {
220         found = thread->thread_obj;
221         break;
222       }
223
224   Py_DECREF (inf_obj);
225
226   if (found)
227     return found;
228
229   return NULL;
230 }
231
232 static void
233 add_thread_object (struct thread_info *tp)
234 {
235   struct cleanup *cleanup;
236   thread_object *thread_obj;
237   inferior_object *inf_obj;
238   struct threadlist_entry *entry;
239
240   cleanup = ensure_python_env (python_gdbarch, python_language);
241
242   thread_obj = create_thread_object (tp);
243   if (!thread_obj)
244     {
245       gdbpy_print_stack ();
246       do_cleanups (cleanup);
247       return;
248     }
249
250   inf_obj = (inferior_object *) thread_obj->inf_obj;
251
252   entry = xmalloc (sizeof (struct threadlist_entry));
253   entry->thread_obj = thread_obj;
254   entry->next = inf_obj->threads;
255
256   inf_obj->threads = entry;
257   inf_obj->nthreads++;
258
259   do_cleanups (cleanup);
260 }
261
262 static void
263 delete_thread_object (struct thread_info *tp, int ignore)
264 {
265   struct cleanup *cleanup;
266   inferior_object *inf_obj;
267   thread_object *thread_obj;
268   struct threadlist_entry **entry, *tmp;
269
270   inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
271   if (!inf_obj)
272     return;
273
274   /* Find thread entry in its inferior's thread_list.  */
275   for (entry = &inf_obj->threads; *entry != NULL; entry =
276          &(*entry)->next)
277     if ((*entry)->thread_obj->thread == tp)
278       break;
279
280   if (!*entry)
281     {
282       Py_DECREF (inf_obj);
283       return;
284     }
285
286   cleanup = ensure_python_env (python_gdbarch, python_language);
287
288   tmp = *entry;
289   tmp->thread_obj->thread = NULL;
290
291   *entry = (*entry)->next;
292   inf_obj->nthreads--;
293
294   Py_DECREF (tmp->thread_obj);
295   Py_DECREF (inf_obj);
296   xfree (tmp);
297
298   do_cleanups (cleanup);
299 }
300
301 static PyObject *
302 infpy_threads (PyObject *self, PyObject *args)
303 {
304   int i;
305   struct threadlist_entry *entry;
306   inferior_object *inf_obj = (inferior_object *) self;
307   PyObject *tuple;
308
309   INFPY_REQUIRE_VALID (inf_obj);
310
311   tuple = PyTuple_New (inf_obj->nthreads);
312   if (!tuple)
313     return NULL;
314
315   for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
316        i++, entry = entry->next)
317     {
318       Py_INCREF (entry->thread_obj);
319       PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj);
320     }
321
322   return tuple;
323 }
324
325 static PyObject *
326 infpy_get_num (PyObject *self, void *closure)
327 {
328   inferior_object *inf = (inferior_object *) self;
329
330   INFPY_REQUIRE_VALID (inf);
331
332   return PyLong_FromLong (inf->inferior->num);
333 }
334
335 static PyObject *
336 infpy_get_pid (PyObject *self, void *closure)
337 {
338   inferior_object *inf = (inferior_object *) self;
339
340   INFPY_REQUIRE_VALID (inf);
341
342   return PyLong_FromLong (inf->inferior->pid);
343 }
344
345 static PyObject *
346 infpy_get_was_attached (PyObject *self, void *closure)
347 {
348   inferior_object *inf = (inferior_object *) self;
349
350   INFPY_REQUIRE_VALID (inf);
351   if (inf->inferior->attach_flag)
352     Py_RETURN_TRUE;
353   Py_RETURN_FALSE;
354 }
355
356 static int
357 build_inferior_list (struct inferior *inf, void *arg)
358 {
359   PyObject *list = arg;
360   PyObject *inferior = inferior_to_inferior_object (inf);
361   int success = 0;
362
363   if (! inferior)
364     return 0;
365
366   success = PyList_Append (list, inferior);
367   Py_DECREF (inferior);
368
369   if (success)
370     return 1;
371
372   return 0;
373 }
374
375 /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
376    Returns a tuple of all inferiors.  */
377 PyObject *
378 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
379 {
380   PyObject *list, *tuple;
381
382   list = PyList_New (0);
383   if (!list)
384     return NULL;
385
386   if (iterate_over_inferiors (build_inferior_list, list))
387     {
388       Py_DECREF (list);
389       return NULL;
390     }
391
392   tuple = PyList_AsTuple (list);
393   Py_DECREF (list);
394
395   return tuple;
396 }
397
398 /* Membuf and memory manipulation.  */
399
400 /* Implementation of gdb.read_memory (address, length).
401    Returns a Python buffer object with LENGTH bytes of the inferior's
402    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
403    with a python exception set.  */
404 static PyObject *
405 infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
406 {
407   int error = 0;
408   CORE_ADDR addr, length;
409   void *buffer = NULL;
410   membuf_object *membuf_obj;
411   PyObject *addr_obj, *length_obj;
412   struct cleanup *cleanups;
413   volatile struct gdb_exception except;
414   static char *keywords[] = { "address", "length", NULL };
415
416   if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
417                                      &addr_obj, &length_obj))
418     return NULL;
419
420   cleanups = make_cleanup (null_cleanup, NULL);
421
422   TRY_CATCH (except, RETURN_MASK_ALL)
423     {
424       if (!get_addr_from_python (addr_obj, &addr)
425           || !get_addr_from_python (length_obj, &length))
426         {
427           error = 1;
428           break;
429         }
430
431       buffer = xmalloc (length);
432       make_cleanup (xfree, buffer);
433
434       read_memory (addr, buffer, length);
435     }
436   if (except.reason < 0)
437     {
438       do_cleanups (cleanups);
439       GDB_PY_HANDLE_EXCEPTION (except);
440     }
441
442   if (error)
443     {
444       do_cleanups (cleanups);
445       return NULL;
446     }
447
448   membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
449   if (membuf_obj == NULL)
450     {
451       PyErr_SetString (PyExc_MemoryError,
452                        _("Could not allocate memory buffer object."));
453       do_cleanups (cleanups);
454       return NULL;
455     }
456
457   discard_cleanups (cleanups);
458
459   membuf_obj->buffer = buffer;
460   membuf_obj->addr = addr;
461   membuf_obj->length = length;
462
463   return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
464                                        Py_END_OF_BUFFER);
465 }
466
467 /* Implementation of gdb.write_memory (address, buffer [, length]).
468    Writes the contents of BUFFER (a Python object supporting the read
469    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
470    bytes from BUFFER, or its entire contents if the argument is not
471    provided.  The function returns nothing.  Returns NULL on error, with
472    a python exception set.  */
473 static PyObject *
474 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
475 {
476   Py_ssize_t buf_len;
477   int error = 0;
478   const char *buffer;
479   CORE_ADDR addr, length;
480   PyObject *addr_obj, *length_obj = NULL;
481   volatile struct gdb_exception except;
482   static char *keywords[] = { "address", "buffer", "length", NULL };
483
484
485   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords,
486                                      &addr_obj, &buffer, &buf_len,
487                                      &length_obj))
488     return NULL;
489
490   TRY_CATCH (except, RETURN_MASK_ALL)
491     {
492       if (!get_addr_from_python (addr_obj, &addr))
493         {
494           error = 1;
495           break;
496         }
497
498       if (!length_obj)
499         length = buf_len;
500       else if (!get_addr_from_python (length_obj, &length))
501         {
502           error = 1;
503           break;
504         }
505       write_memory (addr, buffer, length);
506     }
507   GDB_PY_HANDLE_EXCEPTION (except);
508
509   if (error)
510     return NULL;
511
512   Py_RETURN_NONE;
513 }
514
515 /* Destructor of Membuf objects.  */
516 static void
517 mbpy_dealloc (PyObject *self)
518 {
519   xfree (((membuf_object *) self)->buffer);
520   self->ob_type->tp_free (self);
521 }
522
523 /* Return a description of the Membuf object.  */
524 static PyObject *
525 mbpy_str (PyObject *self)
526 {
527   membuf_object *membuf_obj = (membuf_object *) self;
528
529   return PyString_FromFormat (_("Memory buffer for address %s, \
530 which is %s bytes long."),
531                               paddress (python_gdbarch, membuf_obj->addr),
532                               pulongest (membuf_obj->length));
533 }
534
535 static Py_ssize_t
536 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
537 {
538   membuf_object *membuf_obj = (membuf_object *) self;
539
540   if (segment)
541     {
542       PyErr_SetString (PyExc_SystemError,
543                        _("The memory buffer supports only one segment."));
544       return -1;
545     }
546
547   *ptrptr = membuf_obj->buffer;
548
549   return membuf_obj->length;
550 }
551
552 static Py_ssize_t
553 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
554 {
555   return get_read_buffer (self, segment, ptrptr);
556 }
557
558 static Py_ssize_t
559 get_seg_count (PyObject *self, Py_ssize_t *lenp)
560 {
561   if (lenp)
562     *lenp = ((membuf_object *) self)->length;
563
564   return 1;
565 }
566
567 static Py_ssize_t
568 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
569 {
570   void *ptr = NULL;
571   Py_ssize_t ret;
572
573   ret = get_read_buffer (self, segment, &ptr);
574   *ptrptr = (char *) ptr;
575
576   return ret;
577 }
578
579 /* Implementation of
580    gdb.search_memory (address, length, pattern).  ADDRESS is the
581    address to start the search.  LENGTH specifies the scope of the
582    search from ADDRESS.  PATTERN is the pattern to search for (and
583    must be a Python object supporting the buffer protocol).
584    Returns a Python Long object holding the address where the pattern
585    was located, or if the pattern was not found, returns None.  Returns NULL
586    on error, with a python exception set.  */
587 static PyObject *
588 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
589 {
590   CORE_ADDR start_addr, length;
591   static char *keywords[] = { "address", "length", "pattern", NULL };
592   PyObject *pattern, *start_addr_obj, *length_obj;
593   volatile struct gdb_exception except;
594   Py_ssize_t pattern_size;
595   const void *buffer;
596   CORE_ADDR found_addr;
597   int found = 0;
598
599   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
600                                      &start_addr_obj, &length_obj,
601                                      &pattern))
602     return NULL;
603
604   if (get_addr_from_python (start_addr_obj, &start_addr)
605       && get_addr_from_python (length_obj, &length))
606     {
607       if (!length)
608         {
609           PyErr_SetString (PyExc_ValueError,
610                            _("Search range is empty."));
611           return NULL;
612         }
613       /* Watch for overflows.  */
614       else if (length > CORE_ADDR_MAX
615                || (start_addr + length - 1) < start_addr)
616         {
617           PyErr_SetString (PyExc_ValueError,
618                            _("The search range is too large."));
619
620           return NULL;
621         }
622     }
623   else
624     return NULL;
625
626   if (!PyObject_CheckReadBuffer (pattern))
627     {
628       PyErr_SetString (PyExc_RuntimeError,
629                        _("The pattern is not a Python buffer."));
630
631       return NULL;
632     }
633
634   if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1)
635     return NULL;
636
637   TRY_CATCH (except, RETURN_MASK_ALL)
638     {
639       found = target_search_memory (start_addr, length,
640                                     buffer, pattern_size,
641                                     &found_addr);
642     }
643   GDB_PY_HANDLE_EXCEPTION (except);
644
645   if (found)
646     return PyLong_FromLong (found_addr);
647   else
648     Py_RETURN_NONE;
649 }
650
651 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
652    Returns True if this inferior object still exists in GDB.  */
653
654 static PyObject *
655 infpy_is_valid (PyObject *self, PyObject *args)
656 {
657   inferior_object *inf = (inferior_object *) self;
658
659   if (! inf->inferior)
660     Py_RETURN_FALSE;
661
662   Py_RETURN_TRUE;
663 }
664
665 static void
666 infpy_dealloc (PyObject *obj)
667 {
668   inferior_object *inf_obj = (inferior_object *) obj;
669   struct inferior *inf = inf_obj->inferior;
670
671   if (! inf)
672     return;
673
674   set_inferior_data (inf, infpy_inf_data_key, NULL);
675 }
676
677 /* Clear the INFERIOR pointer in an Inferior object and clear the
678    thread list.  */
679 static void
680 py_free_inferior (struct inferior *inf, void *datum)
681 {
682
683   struct cleanup *cleanup;
684   inferior_object *inf_obj = datum;
685   struct threadlist_entry *th_entry, *th_tmp;
686
687   cleanup = ensure_python_env (python_gdbarch, python_language);
688
689   inf_obj->inferior = NULL;
690
691   /* Deallocate threads list.  */
692   for (th_entry = inf_obj->threads; th_entry != NULL;)
693     {
694       Py_DECREF (th_entry->thread_obj);
695
696       th_tmp = th_entry;
697       th_entry = th_entry->next;
698       xfree (th_tmp);
699     }
700
701   inf_obj->nthreads = 0;
702
703   Py_DECREF ((PyObject *) inf_obj);
704   do_cleanups (cleanup);
705 }
706
707 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
708    Returns the current inferior object.  */
709
710 PyObject *
711 gdbpy_selected_inferior (PyObject *self, PyObject *args)
712 {
713   PyObject *inf_obj;
714
715   inf_obj = inferior_to_inferior_object (current_inferior ());
716   Py_INCREF (inf_obj);
717
718   return inf_obj;
719 }
720
721 void
722 gdbpy_initialize_inferior (void)
723 {
724   if (PyType_Ready (&inferior_object_type) < 0)
725     return;
726
727   Py_INCREF (&inferior_object_type);
728   PyModule_AddObject (gdb_module, "Inferior",
729                       (PyObject *) &inferior_object_type);
730
731   infpy_inf_data_key =
732     register_inferior_data_with_cleanup (py_free_inferior);
733
734   observer_attach_new_thread (add_thread_object);
735   observer_attach_thread_exit (delete_thread_object);
736   observer_attach_normal_stop (python_on_normal_stop);
737   observer_attach_target_resumed (python_on_resume);
738   observer_attach_inferior_exit (python_inferior_exit);
739   observer_attach_new_objfile (python_new_objfile);
740
741   membuf_object_type.tp_new = PyType_GenericNew;
742   if (PyType_Ready (&membuf_object_type) < 0)
743     return;
744
745   Py_INCREF (&membuf_object_type);
746   PyModule_AddObject (gdb_module, "Membuf", (PyObject *)
747                       &membuf_object_type);
748 }
749
750 static PyGetSetDef inferior_object_getset[] =
751 {
752   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
753   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
754     NULL },
755   { "was_attached", infpy_get_was_attached, NULL,
756     "True if the inferior was created using 'attach'.", NULL },
757   { NULL }
758 };
759
760 static PyMethodDef inferior_object_methods[] =
761 {
762   { "is_valid", infpy_is_valid, METH_NOARGS,
763     "is_valid () -> Boolean.\n\
764 Return true if this inferior is valid, false if not." },
765   { "threads", infpy_threads, METH_NOARGS,
766     "Return all the threads of this inferior." },
767   { "read_memory", (PyCFunction) infpy_read_memory,
768     METH_VARARGS | METH_KEYWORDS,
769     "read_memory (address, length) -> buffer\n\
770 Return a buffer object for reading from the inferior's memory." },
771   { "write_memory", (PyCFunction) infpy_write_memory,
772     METH_VARARGS | METH_KEYWORDS,
773     "write_memory (address, buffer [, length])\n\
774 Write the given buffer object to the inferior's memory." },
775   { "search_memory", (PyCFunction) infpy_search_memory,
776     METH_VARARGS | METH_KEYWORDS,
777     "search_memory (address, length, pattern) -> long\n\
778 Return a long with the address of a match, or None." },
779   { NULL }
780 };
781
782 static PyTypeObject inferior_object_type =
783 {
784   PyObject_HEAD_INIT (NULL)
785   0,                              /* ob_size */
786   "gdb.Inferior",                 /* tp_name */
787   sizeof (inferior_object),       /* tp_basicsize */
788   0,                              /* tp_itemsize */
789   infpy_dealloc,                  /* tp_dealloc */
790   0,                              /* tp_print */
791   0,                              /* tp_getattr */
792   0,                              /* tp_setattr */
793   0,                              /* tp_compare */
794   0,                              /* tp_repr */
795   0,                              /* tp_as_number */
796   0,                              /* tp_as_sequence */
797   0,                              /* tp_as_mapping */
798   0,                              /* tp_hash  */
799   0,                              /* tp_call */
800   0,                              /* tp_str */
801   0,                              /* tp_getattro */
802   0,                              /* tp_setattro */
803   0,                              /* tp_as_buffer */
804   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
805   "GDB inferior object",          /* tp_doc */
806   0,                              /* tp_traverse */
807   0,                              /* tp_clear */
808   0,                              /* tp_richcompare */
809   0,                              /* tp_weaklistoffset */
810   0,                              /* tp_iter */
811   0,                              /* tp_iternext */
812   inferior_object_methods,        /* tp_methods */
813   0,                              /* tp_members */
814   inferior_object_getset,         /* tp_getset */
815   0,                              /* tp_base */
816   0,                              /* tp_dict */
817   0,                              /* tp_descr_get */
818   0,                              /* tp_descr_set */
819   0,                              /* tp_dictoffset */
820   0,                              /* tp_init */
821   0                               /* tp_alloc */
822 };
823
824 /* Python doesn't provide a decent way to get compatibility here.  */
825 #if HAVE_LIBPYTHON2_4
826 #define CHARBUFFERPROC_NAME getcharbufferproc
827 #else
828 #define CHARBUFFERPROC_NAME charbufferproc
829 #endif
830
831 static PyBufferProcs buffer_procs = {
832   get_read_buffer,
833   get_write_buffer,
834   get_seg_count,
835   /* The cast here works around a difference between Python 2.4 and
836      Python 2.5.  */
837   (CHARBUFFERPROC_NAME) get_char_buffer
838 };
839
840 static PyTypeObject membuf_object_type = {
841   PyObject_HEAD_INIT (NULL)
842   0,                              /*ob_size*/
843   "gdb.Membuf",                   /*tp_name*/
844   sizeof (membuf_object),         /*tp_basicsize*/
845   0,                              /*tp_itemsize*/
846   mbpy_dealloc,                   /*tp_dealloc*/
847   0,                              /*tp_print*/
848   0,                              /*tp_getattr*/
849   0,                              /*tp_setattr*/
850   0,                              /*tp_compare*/
851   0,                              /*tp_repr*/
852   0,                              /*tp_as_number*/
853   0,                              /*tp_as_sequence*/
854   0,                              /*tp_as_mapping*/
855   0,                              /*tp_hash */
856   0,                              /*tp_call*/
857   mbpy_str,                       /*tp_str*/
858   0,                              /*tp_getattro*/
859   0,                              /*tp_setattro*/
860   &buffer_procs,                  /*tp_as_buffer*/
861   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
862   "GDB memory buffer object",     /*tp_doc*/
863   0,                              /* tp_traverse */
864   0,                              /* tp_clear */
865   0,                              /* tp_richcompare */
866   0,                              /* tp_weaklistoffset */
867   0,                              /* tp_iter */
868   0,                              /* tp_iternext */
869   0,                              /* tp_methods */
870   0,                              /* tp_members */
871   0,                              /* tp_getset */
872   0,                              /* tp_base */
873   0,                              /* tp_dict */
874   0,                              /* tp_descr_get */
875   0,                              /* tp_descr_set */
876   0,                              /* tp_dictoffset */
877   0,                              /* tp_init */
878   0,                              /* tp_alloc */
879 };
This page took 0.074264 seconds and 4 git commands to generate.