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