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