]> Git Repo - binutils.git/blob - gdb/python/py-inferior.c
Refactor Python "gdb" module into a proper Python package, by introducing
[binutils.git] / gdb / python / py-inferior.c
1 /* Python interface to inferiors.
2
3    Copyright (C) 2009-2012 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 gdb_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       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
161       if (!inf_obj)
162           return NULL;
163
164       inf_obj->inferior = inferior;
165       inf_obj->threads = NULL;
166       inf_obj->nthreads = 0;
167
168       set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
169
170     }
171   else
172     Py_INCREF ((PyObject *)inf_obj);
173
174   return (PyObject *) inf_obj;
175 }
176
177 /* Finds the Python Inferior object for the given PID.  Returns a
178    reference, or NULL if PID does not match any inferior object. */
179
180 PyObject *
181 find_inferior_object (int pid)
182 {
183   struct inferior *inf = find_inferior_pid (pid);
184
185   if (inf)
186     return inferior_to_inferior_object (inf);
187
188   return NULL;
189 }
190
191 thread_object *
192 find_thread_object (ptid_t ptid)
193 {
194   int pid;
195   struct threadlist_entry *thread;
196   PyObject *inf_obj;
197   thread_object *found = NULL;
198
199   pid = PIDGET (ptid);
200   if (pid == 0)
201     return NULL;
202
203   inf_obj = find_inferior_object (pid);
204
205   if (! inf_obj)
206     return NULL;
207
208   for (thread = ((inferior_object *)inf_obj)->threads; thread;
209        thread = thread->next)
210     if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
211       {
212         found = thread->thread_obj;
213         break;
214       }
215
216   Py_DECREF (inf_obj);
217
218   if (found)
219     return found;
220
221   return NULL;
222 }
223
224 static void
225 add_thread_object (struct thread_info *tp)
226 {
227   struct cleanup *cleanup;
228   thread_object *thread_obj;
229   inferior_object *inf_obj;
230   struct threadlist_entry *entry;
231
232   cleanup = ensure_python_env (python_gdbarch, python_language);
233
234   thread_obj = create_thread_object (tp);
235   if (!thread_obj)
236     {
237       gdbpy_print_stack ();
238       do_cleanups (cleanup);
239       return;
240     }
241
242   inf_obj = (inferior_object *) thread_obj->inf_obj;
243
244   entry = xmalloc (sizeof (struct threadlist_entry));
245   entry->thread_obj = thread_obj;
246   entry->next = inf_obj->threads;
247
248   inf_obj->threads = entry;
249   inf_obj->nthreads++;
250
251   do_cleanups (cleanup);
252 }
253
254 static void
255 delete_thread_object (struct thread_info *tp, int ignore)
256 {
257   struct cleanup *cleanup;
258   inferior_object *inf_obj;
259   struct threadlist_entry **entry, *tmp;
260   
261   cleanup = ensure_python_env (python_gdbarch, python_language);
262
263   inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
264   if (!inf_obj)
265     {
266       do_cleanups (cleanup);
267       return;
268     }
269
270   /* Find thread entry in its inferior's thread_list.  */
271   for (entry = &inf_obj->threads; *entry != NULL; entry =
272          &(*entry)->next)
273     if ((*entry)->thread_obj->thread == tp)
274       break;
275
276   if (!*entry)
277     {
278       Py_DECREF (inf_obj);
279       do_cleanups (cleanup);
280       return;
281     }
282
283   tmp = *entry;
284   tmp->thread_obj->thread = NULL;
285
286   *entry = (*entry)->next;
287   inf_obj->nthreads--;
288
289   Py_DECREF (tmp->thread_obj);
290   Py_DECREF (inf_obj);
291   xfree (tmp);
292
293   do_cleanups (cleanup);
294 }
295
296 static PyObject *
297 infpy_threads (PyObject *self, PyObject *args)
298 {
299   int i;
300   struct threadlist_entry *entry;
301   inferior_object *inf_obj = (inferior_object *) self;
302   PyObject *tuple;
303   volatile struct gdb_exception except;
304
305   INFPY_REQUIRE_VALID (inf_obj);
306
307   TRY_CATCH (except, RETURN_MASK_ALL)
308     update_thread_list ();
309   GDB_PY_HANDLE_EXCEPTION (except);
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 Inferior.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, *result;
412   volatile struct gdb_exception except;
413   static char *keywords[] = { "address", "length", NULL };
414
415   if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
416                                      &addr_obj, &length_obj))
417     return NULL;
418
419   TRY_CATCH (except, RETURN_MASK_ALL)
420     {
421       if (!get_addr_from_python (addr_obj, &addr)
422           || !get_addr_from_python (length_obj, &length))
423         {
424           error = 1;
425           break;
426         }
427
428       buffer = xmalloc (length);
429
430       read_memory (addr, buffer, length);
431     }
432   if (except.reason < 0)
433     {
434       xfree (buffer);
435       GDB_PY_HANDLE_EXCEPTION (except);
436     }
437
438   if (error)
439     {
440       xfree (buffer);
441       return NULL;
442     }
443
444   membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
445   if (membuf_obj == NULL)
446     {
447       xfree (buffer);
448       PyErr_SetString (PyExc_MemoryError,
449                        _("Could not allocate memory buffer object."));
450       return NULL;
451     }
452
453   membuf_obj->buffer = buffer;
454   membuf_obj->addr = addr;
455   membuf_obj->length = length;
456
457   result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
458                                          Py_END_OF_BUFFER);
459   Py_DECREF (membuf_obj);
460   return result;
461 }
462
463 /* Implementation of Inferior.write_memory (address, buffer [, length]).
464    Writes the contents of BUFFER (a Python object supporting the read
465    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
466    bytes from BUFFER, or its entire contents if the argument is not
467    provided.  The function returns nothing.  Returns NULL on error, with
468    a python exception set.  */
469 static PyObject *
470 infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
471 {
472   Py_ssize_t buf_len;
473   int error = 0;
474   const char *buffer;
475   CORE_ADDR addr, length;
476   PyObject *addr_obj, *length_obj = NULL;
477   volatile struct gdb_exception except;
478   static char *keywords[] = { "address", "buffer", "length", NULL };
479
480
481   if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords,
482                                      &addr_obj, &buffer, &buf_len,
483                                      &length_obj))
484     return NULL;
485
486   TRY_CATCH (except, RETURN_MASK_ALL)
487     {
488       if (!get_addr_from_python (addr_obj, &addr))
489         {
490           error = 1;
491           break;
492         }
493
494       if (!length_obj)
495         length = buf_len;
496       else if (!get_addr_from_python (length_obj, &length))
497         {
498           error = 1;
499           break;
500         }
501       write_memory_with_notification (addr, buffer, length);
502     }
503   GDB_PY_HANDLE_EXCEPTION (except);
504
505   if (error)
506     return NULL;
507
508   Py_RETURN_NONE;
509 }
510
511 /* Destructor of Membuf objects.  */
512 static void
513 mbpy_dealloc (PyObject *self)
514 {
515   xfree (((membuf_object *) self)->buffer);
516   self->ob_type->tp_free (self);
517 }
518
519 /* Return a description of the Membuf object.  */
520 static PyObject *
521 mbpy_str (PyObject *self)
522 {
523   membuf_object *membuf_obj = (membuf_object *) self;
524
525   return PyString_FromFormat (_("Memory buffer for address %s, \
526 which is %s bytes long."),
527                               paddress (python_gdbarch, membuf_obj->addr),
528                               pulongest (membuf_obj->length));
529 }
530
531 static Py_ssize_t
532 get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
533 {
534   membuf_object *membuf_obj = (membuf_object *) self;
535
536   if (segment)
537     {
538       PyErr_SetString (PyExc_SystemError,
539                        _("The memory buffer supports only one segment."));
540       return -1;
541     }
542
543   *ptrptr = membuf_obj->buffer;
544
545   return membuf_obj->length;
546 }
547
548 static Py_ssize_t
549 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
550 {
551   return get_read_buffer (self, segment, ptrptr);
552 }
553
554 static Py_ssize_t
555 get_seg_count (PyObject *self, Py_ssize_t *lenp)
556 {
557   if (lenp)
558     *lenp = ((membuf_object *) self)->length;
559
560   return 1;
561 }
562
563 static Py_ssize_t
564 get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
565 {
566   void *ptr = NULL;
567   Py_ssize_t ret;
568
569   ret = get_read_buffer (self, segment, &ptr);
570   *ptrptr = (char *) ptr;
571
572   return ret;
573 }
574
575 /* Implementation of
576    gdb.search_memory (address, length, pattern).  ADDRESS is the
577    address to start the search.  LENGTH specifies the scope of the
578    search from ADDRESS.  PATTERN is the pattern to search for (and
579    must be a Python object supporting the buffer protocol).
580    Returns a Python Long object holding the address where the pattern
581    was located, or if the pattern was not found, returns None.  Returns NULL
582    on error, with a python exception set.  */
583 static PyObject *
584 infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
585 {
586   CORE_ADDR start_addr, length;
587   static char *keywords[] = { "address", "length", "pattern", NULL };
588   PyObject *pattern, *start_addr_obj, *length_obj;
589   volatile struct gdb_exception except;
590   Py_ssize_t pattern_size;
591   const void *buffer;
592   CORE_ADDR found_addr;
593   int found = 0;
594
595   if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
596                                      &start_addr_obj, &length_obj,
597                                      &pattern))
598     return NULL;
599
600   if (get_addr_from_python (start_addr_obj, &start_addr)
601       && get_addr_from_python (length_obj, &length))
602     {
603       if (!length)
604         {
605           PyErr_SetString (PyExc_ValueError,
606                            _("Search range is empty."));
607           return NULL;
608         }
609       /* Watch for overflows.  */
610       else if (length > CORE_ADDR_MAX
611                || (start_addr + length - 1) < start_addr)
612         {
613           PyErr_SetString (PyExc_ValueError,
614                            _("The search range is too large."));
615
616           return NULL;
617         }
618     }
619   else
620     return NULL;
621
622   if (!PyObject_CheckReadBuffer (pattern))
623     {
624       PyErr_SetString (PyExc_RuntimeError,
625                        _("The pattern is not a Python buffer."));
626
627       return NULL;
628     }
629
630   if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1)
631     return NULL;
632
633   TRY_CATCH (except, RETURN_MASK_ALL)
634     {
635       found = target_search_memory (start_addr, length,
636                                     buffer, pattern_size,
637                                     &found_addr);
638     }
639   GDB_PY_HANDLE_EXCEPTION (except);
640
641   if (found)
642     return PyLong_FromLong (found_addr);
643   else
644     Py_RETURN_NONE;
645 }
646
647 /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
648    Returns True if this inferior object still exists in GDB.  */
649
650 static PyObject *
651 infpy_is_valid (PyObject *self, PyObject *args)
652 {
653   inferior_object *inf = (inferior_object *) self;
654
655   if (! inf->inferior)
656     Py_RETURN_FALSE;
657
658   Py_RETURN_TRUE;
659 }
660
661 static void
662 infpy_dealloc (PyObject *obj)
663 {
664   inferior_object *inf_obj = (inferior_object *) obj;
665   struct inferior *inf = inf_obj->inferior;
666
667   if (! inf)
668     return;
669
670   set_inferior_data (inf, infpy_inf_data_key, NULL);
671 }
672
673 /* Clear the INFERIOR pointer in an Inferior object and clear the
674    thread list.  */
675 static void
676 py_free_inferior (struct inferior *inf, void *datum)
677 {
678
679   struct cleanup *cleanup;
680   inferior_object *inf_obj = datum;
681   struct threadlist_entry *th_entry, *th_tmp;
682
683   cleanup = ensure_python_env (python_gdbarch, python_language);
684
685   inf_obj->inferior = NULL;
686
687   /* Deallocate threads list.  */
688   for (th_entry = inf_obj->threads; th_entry != NULL;)
689     {
690       Py_DECREF (th_entry->thread_obj);
691
692       th_tmp = th_entry;
693       th_entry = th_entry->next;
694       xfree (th_tmp);
695     }
696
697   inf_obj->nthreads = 0;
698
699   Py_DECREF ((PyObject *) inf_obj);
700   do_cleanups (cleanup);
701 }
702
703 /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
704    Returns the current inferior object.  */
705
706 PyObject *
707 gdbpy_selected_inferior (PyObject *self, PyObject *args)
708 {
709   PyObject *inf_obj;
710
711   inf_obj = inferior_to_inferior_object (current_inferior ());
712   Py_INCREF (inf_obj);
713
714   return inf_obj;
715 }
716
717 void
718 gdbpy_initialize_inferior (void)
719 {
720   if (PyType_Ready (&inferior_object_type) < 0)
721     return;
722
723   Py_INCREF (&inferior_object_type);
724   PyModule_AddObject (gdb_module, "Inferior",
725                       (PyObject *) &inferior_object_type);
726
727   infpy_inf_data_key =
728     register_inferior_data_with_cleanup (NULL, py_free_inferior);
729
730   observer_attach_new_thread (add_thread_object);
731   observer_attach_thread_exit (delete_thread_object);
732   observer_attach_normal_stop (python_on_normal_stop);
733   observer_attach_target_resumed (python_on_resume);
734   observer_attach_inferior_exit (python_inferior_exit);
735   observer_attach_new_objfile (python_new_objfile);
736
737   membuf_object_type.tp_new = PyType_GenericNew;
738   if (PyType_Ready (&membuf_object_type) < 0)
739     return;
740
741   Py_INCREF (&membuf_object_type);
742   PyModule_AddObject (gdb_module, "Membuf", (PyObject *)
743                       &membuf_object_type);
744 }
745
746 static PyGetSetDef inferior_object_getset[] =
747 {
748   { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
749   { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
750     NULL },
751   { "was_attached", infpy_get_was_attached, NULL,
752     "True if the inferior was created using 'attach'.", NULL },
753   { NULL }
754 };
755
756 static PyMethodDef inferior_object_methods[] =
757 {
758   { "is_valid", infpy_is_valid, METH_NOARGS,
759     "is_valid () -> Boolean.\n\
760 Return true if this inferior is valid, false if not." },
761   { "threads", infpy_threads, METH_NOARGS,
762     "Return all the threads of this inferior." },
763   { "read_memory", (PyCFunction) infpy_read_memory,
764     METH_VARARGS | METH_KEYWORDS,
765     "read_memory (address, length) -> buffer\n\
766 Return a buffer object for reading from the inferior's memory." },
767   { "write_memory", (PyCFunction) infpy_write_memory,
768     METH_VARARGS | METH_KEYWORDS,
769     "write_memory (address, buffer [, length])\n\
770 Write the given buffer object to the inferior's memory." },
771   { "search_memory", (PyCFunction) infpy_search_memory,
772     METH_VARARGS | METH_KEYWORDS,
773     "search_memory (address, length, pattern) -> long\n\
774 Return a long with the address of a match, or None." },
775   { NULL }
776 };
777
778 static PyTypeObject inferior_object_type =
779 {
780   PyObject_HEAD_INIT (NULL)
781   0,                              /* ob_size */
782   "gdb.Inferior",                 /* tp_name */
783   sizeof (inferior_object),       /* tp_basicsize */
784   0,                              /* tp_itemsize */
785   infpy_dealloc,                  /* tp_dealloc */
786   0,                              /* tp_print */
787   0,                              /* tp_getattr */
788   0,                              /* tp_setattr */
789   0,                              /* tp_compare */
790   0,                              /* tp_repr */
791   0,                              /* tp_as_number */
792   0,                              /* tp_as_sequence */
793   0,                              /* tp_as_mapping */
794   0,                              /* tp_hash  */
795   0,                              /* tp_call */
796   0,                              /* tp_str */
797   0,                              /* tp_getattro */
798   0,                              /* tp_setattro */
799   0,                              /* tp_as_buffer */
800   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /* tp_flags */
801   "GDB inferior object",          /* tp_doc */
802   0,                              /* tp_traverse */
803   0,                              /* tp_clear */
804   0,                              /* tp_richcompare */
805   0,                              /* tp_weaklistoffset */
806   0,                              /* tp_iter */
807   0,                              /* tp_iternext */
808   inferior_object_methods,        /* tp_methods */
809   0,                              /* tp_members */
810   inferior_object_getset,         /* tp_getset */
811   0,                              /* tp_base */
812   0,                              /* tp_dict */
813   0,                              /* tp_descr_get */
814   0,                              /* tp_descr_set */
815   0,                              /* tp_dictoffset */
816   0,                              /* tp_init */
817   0                               /* tp_alloc */
818 };
819
820 /* Python doesn't provide a decent way to get compatibility here.  */
821 #if HAVE_LIBPYTHON2_4
822 #define CHARBUFFERPROC_NAME getcharbufferproc
823 #else
824 #define CHARBUFFERPROC_NAME charbufferproc
825 #endif
826
827 static PyBufferProcs buffer_procs = {
828   get_read_buffer,
829   get_write_buffer,
830   get_seg_count,
831   /* The cast here works around a difference between Python 2.4 and
832      Python 2.5.  */
833   (CHARBUFFERPROC_NAME) get_char_buffer
834 };
835
836 static PyTypeObject membuf_object_type = {
837   PyObject_HEAD_INIT (NULL)
838   0,                              /*ob_size*/
839   "gdb.Membuf",                   /*tp_name*/
840   sizeof (membuf_object),         /*tp_basicsize*/
841   0,                              /*tp_itemsize*/
842   mbpy_dealloc,                   /*tp_dealloc*/
843   0,                              /*tp_print*/
844   0,                              /*tp_getattr*/
845   0,                              /*tp_setattr*/
846   0,                              /*tp_compare*/
847   0,                              /*tp_repr*/
848   0,                              /*tp_as_number*/
849   0,                              /*tp_as_sequence*/
850   0,                              /*tp_as_mapping*/
851   0,                              /*tp_hash */
852   0,                              /*tp_call*/
853   mbpy_str,                       /*tp_str*/
854   0,                              /*tp_getattro*/
855   0,                              /*tp_setattro*/
856   &buffer_procs,                  /*tp_as_buffer*/
857   Py_TPFLAGS_DEFAULT,             /*tp_flags*/
858   "GDB memory buffer object",     /*tp_doc*/
859   0,                              /* tp_traverse */
860   0,                              /* tp_clear */
861   0,                              /* tp_richcompare */
862   0,                              /* tp_weaklistoffset */
863   0,                              /* tp_iter */
864   0,                              /* tp_iternext */
865   0,                              /* tp_methods */
866   0,                              /* tp_members */
867   0,                              /* tp_getset */
868   0,                              /* tp_base */
869   0,                              /* tp_dict */
870   0,                              /* tp_descr_get */
871   0,                              /* tp_descr_set */
872   0,                              /* tp_dictoffset */
873   0,                              /* tp_init */
874   0,                              /* tp_alloc */
875 };
This page took 0.075553 seconds and 4 git commands to generate.