xref: /dflybsd-src/contrib/gdb-7/gdb/python/py-inferior.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
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