]> Git Repo - binutils.git/blob - gdb/python/py-inferior.c
a3d5952a10bfccd2480939affb78fac1d1477f86
[binutils.git] / gdb / python / py-inferior.c
1 /* Python interface to inferiors.
2
3    Copyright (C) 2009-2021 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
33 struct 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
44 struct 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
59 extern PyTypeObject inferior_object_type
60     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
61
62 static const struct inferior_data *infpy_inf_data_key;
63
64 struct membuf_object {
65   PyObject_HEAD
66   void *buffer;
67
68   /* These are kept just for mbpy_str.  */
69   CORE_ADDR addr;
70   CORE_ADDR length;
71 };
72
73 extern 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
87 static void
88 python_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
106 static void
107 python_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
121 static void
122 python_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
133 static void
134 python_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
146 static void
147 python_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
159 static void
160 python_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
168 static void
169 python_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
189 static void
190 python_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
217 gdbpy_ref<inferior_object>
218 inferior_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.  */
245 static void
246 python_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.  */
273 static void
274 python_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
299 gdbpy_ref<>
300 thread_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
317 static void
318 add_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
353 static void
354 delete_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
385 static PyObject *
386 infpy_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
419 static PyObject *
420 infpy_get_num (PyObject *self, void *closure)
421 {
422   inferior_object *inf = (inferior_object *) self;
423
424   INFPY_REQUIRE_VALID (inf);
425
426   return gdb_py_object_from_longest (inf->inferior->num).release ();
427 }
428
429 static PyObject *
430 infpy_get_pid (PyObject *self, void *closure)
431 {
432   inferior_object *inf = (inferior_object *) self;
433
434   INFPY_REQUIRE_VALID (inf);
435
436   return gdb_py_object_from_longest (inf->inferior->pid).release ();
437 }
438
439 static PyObject *
440 infpy_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
452 static PyObject *
453 infpy_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.  */
467 PyObject *
468 gdbpy_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.  */
494 static PyObject *
495 infpy_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.  */
546 static PyObject *
547 infpy_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.  */
588 static void
589 mbpy_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.  */
596 static PyObject *
597 mbpy_str (PyObject *self)
598 {
599   membuf_object *membuf_obj = (membuf_object *) self;
600
601   return PyString_FromFormat (_("Memory buffer for address %s, \
602 which is %s bytes long."),
603                               paddress (python_gdbarch, membuf_obj->addr),
604                               pulongest (membuf_obj->length));
605 }
606
607 #ifdef IS_PY3K
608
609 static int
610 get_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
628 static Py_ssize_t
629 get_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
645 static Py_ssize_t
646 get_write_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
647 {
648   return get_read_buffer (self, segment, ptrptr);
649 }
650
651 static Py_ssize_t
652 get_seg_count (PyObject *self, Py_ssize_t *lenp)
653 {
654   if (lenp)
655     *lenp = ((membuf_object *) self)->length;
656
657   return 1;
658 }
659
660 static Py_ssize_t
661 get_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.  */
682 static PyObject *
683 infpy_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
747 static PyObject *
748 infpy_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
761 static PyObject *
762 infpy_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
819 static PyObject *
820 infpy_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
831 static PyObject *
832 infpy_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
845 static void
846 infpy_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.  */
860 static void
861 py_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
887 PyObject *
888 gdbpy_selected_inferior (PyObject *self, PyObject *args)
889 {
890   return ((PyObject *)
891           inferior_to_inferior_object (current_inferior ()).release ());
892 }
893
894 int
895 gdbpy_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
928 static 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
939 static PyMethodDef inferior_object_methods[] =
940 {
941   { "is_valid", infpy_is_valid, METH_NOARGS,
942     "is_valid () -> Boolean.\n\
943 Return 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\
949 Return 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\
953 Write 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\
957 Return 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\
962 Return thread object corresponding to thread handle.\n\
963 This 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\
967 Return thread object corresponding to thread handle." },
968   { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
969     "architecture () -> gdb.Architecture\n\
970 Return architecture of this inferior." },
971   { NULL }
972 };
973
974 PyTypeObject 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
1017 static PyBufferProcs buffer_procs =
1018 {
1019   get_buffer
1020 };
1021
1022 #else
1023
1024 static 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
1032 PyTypeObject 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 };
This page took 0.077652 seconds and 2 git commands to generate.