Home | History | Annotate | Line # | Download | only in python
py-infevents.c revision 1.5
      1  1.1  christos /* Python interface to inferior function events.
      2  1.1  christos 
      3  1.5  christos    Copyright (C) 2013-2017 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "defs.h"
     21  1.1  christos #include "py-event.h"
     22  1.5  christos #include "py-ref.h"
     23  1.1  christos 
     24  1.3  christos extern PyTypeObject inferior_call_pre_event_object_type
     25  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
     26  1.3  christos extern PyTypeObject inferior_call_post_event_object_type
     27  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
     28  1.3  christos extern PyTypeObject register_changed_event_object_type
     29  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
     30  1.3  christos extern PyTypeObject memory_changed_event_object_type
     31  1.1  christos     CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object");
     32  1.1  christos 
     33  1.1  christos /* Construct either a gdb.InferiorCallPreEvent or a
     34  1.1  christos    gdb.InferiorCallPostEvent. */
     35  1.1  christos 
     36  1.1  christos static PyObject *
     37  1.1  christos create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid,
     38  1.1  christos 				   CORE_ADDR addr)
     39  1.1  christos {
     40  1.5  christos   gdbpy_ref<> event;
     41  1.1  christos   int failed;
     42  1.1  christos 
     43  1.1  christos   switch (flag)
     44  1.1  christos     {
     45  1.1  christos     case INFERIOR_CALL_PRE:
     46  1.5  christos       event.reset (create_event_object (&inferior_call_pre_event_object_type));
     47  1.1  christos       break;
     48  1.1  christos     case INFERIOR_CALL_POST:
     49  1.5  christos       event.reset (create_event_object (&inferior_call_post_event_object_type));
     50  1.1  christos       break;
     51  1.1  christos     default:
     52  1.5  christos       gdb_assert_not_reached ("invalid inferior_call_kind");
     53  1.1  christos     }
     54  1.1  christos 
     55  1.5  christos   gdbpy_ref<> ptid_obj (gdbpy_create_ptid_object (ptid));
     56  1.1  christos   if (ptid_obj == NULL)
     57  1.5  christos     return NULL;
     58  1.1  christos 
     59  1.5  christos   if (evpy_add_attribute (event.get (), "ptid", ptid_obj.get ()) < 0)
     60  1.5  christos     return NULL;
     61  1.1  christos 
     62  1.5  christos   gdbpy_ref<> addr_obj (PyLong_FromLongLong (addr));
     63  1.1  christos   if (addr_obj == NULL)
     64  1.5  christos     return NULL;
     65  1.5  christos 
     66  1.5  christos   if (evpy_add_attribute (event.get (), "address", addr_obj.get ()) < 0)
     67  1.5  christos     return NULL;
     68  1.1  christos 
     69  1.5  christos   return event.release ();
     70  1.1  christos }
     71  1.1  christos 
     72  1.1  christos /* Construct a gdb.RegisterChangedEvent containing the affected
     73  1.1  christos    register number. */
     74  1.1  christos 
     75  1.1  christos static PyObject *
     76  1.1  christos create_register_changed_event_object (struct frame_info *frame,
     77  1.1  christos 				      int regnum)
     78  1.1  christos {
     79  1.5  christos   gdbpy_ref<> event (create_event_object (&register_changed_event_object_type));
     80  1.1  christos   if (event == NULL)
     81  1.1  christos     return NULL;
     82  1.1  christos 
     83  1.5  christos   gdbpy_ref<> frame_obj (frame_info_to_frame_object (frame));
     84  1.1  christos   if (frame_obj == NULL)
     85  1.5  christos     return NULL;
     86  1.1  christos 
     87  1.5  christos   if (evpy_add_attribute (event.get (), "frame", frame_obj.get ()) < 0)
     88  1.5  christos     return NULL;
     89  1.1  christos 
     90  1.5  christos   gdbpy_ref<> regnum_obj (PyLong_FromLongLong (regnum));
     91  1.1  christos   if (regnum_obj == NULL)
     92  1.5  christos     return NULL;
     93  1.1  christos 
     94  1.5  christos   if (evpy_add_attribute (event.get (), "regnum", regnum_obj.get ()) < 0)
     95  1.5  christos     return NULL;
     96  1.5  christos 
     97  1.5  christos   return event.release ();
     98  1.1  christos }
     99  1.1  christos 
    100  1.1  christos /* Construct a gdb.MemoryChangedEvent describing the extent of the
    101  1.1  christos    affected memory. */
    102  1.1  christos 
    103  1.1  christos static PyObject *
    104  1.1  christos create_memory_changed_event_object (CORE_ADDR addr, ssize_t len)
    105  1.1  christos {
    106  1.5  christos   gdbpy_ref<> event (create_event_object (&memory_changed_event_object_type));
    107  1.1  christos 
    108  1.1  christos   if (event == NULL)
    109  1.1  christos     return NULL;
    110  1.1  christos 
    111  1.5  christos   gdbpy_ref<> addr_obj (PyLong_FromLongLong (addr));
    112  1.1  christos   if (addr_obj == NULL)
    113  1.5  christos     return NULL;
    114  1.1  christos 
    115  1.5  christos   if (evpy_add_attribute (event.get (), "address", addr_obj.get ()) < 0)
    116  1.5  christos     return NULL;
    117  1.1  christos 
    118  1.5  christos   gdbpy_ref<> len_obj (PyLong_FromLong (len));
    119  1.1  christos   if (len_obj == NULL)
    120  1.5  christos     return NULL;
    121  1.5  christos 
    122  1.5  christos   if (evpy_add_attribute (event.get (), "length", len_obj.get ()) < 0)
    123  1.5  christos     return NULL;
    124  1.1  christos 
    125  1.5  christos   return event.release ();
    126  1.1  christos }
    127  1.1  christos 
    128  1.1  christos /* Callback function which notifies observers when an event occurs which
    129  1.1  christos    calls a function in the inferior.
    130  1.1  christos    This function will create a new Python inferior-call event object.
    131  1.1  christos    Return -1 if emit fails.  */
    132  1.1  christos 
    133  1.1  christos int
    134  1.1  christos emit_inferior_call_event (inferior_call_kind flag, ptid_t thread,
    135  1.1  christos 			  CORE_ADDR addr)
    136  1.1  christos {
    137  1.1  christos   if (evregpy_no_listeners_p (gdb_py_events.inferior_call))
    138  1.1  christos     return 0;
    139  1.1  christos 
    140  1.5  christos   gdbpy_ref<> event (create_inferior_call_event_object (flag, thread, addr));
    141  1.1  christos   if (event != NULL)
    142  1.5  christos     return evpy_emit_event (event.get (), gdb_py_events.inferior_call);
    143  1.1  christos   return -1;
    144  1.1  christos }
    145  1.1  christos 
    146  1.1  christos /* Callback when memory is modified by the user.  This function will
    147  1.1  christos    create a new Python memory changed event object. */
    148  1.1  christos 
    149  1.1  christos int
    150  1.1  christos emit_memory_changed_event (CORE_ADDR addr, ssize_t len)
    151  1.1  christos {
    152  1.1  christos   if (evregpy_no_listeners_p (gdb_py_events.memory_changed))
    153  1.1  christos     return 0;
    154  1.1  christos 
    155  1.5  christos   gdbpy_ref<> event (create_memory_changed_event_object (addr, len));
    156  1.1  christos   if (event != NULL)
    157  1.5  christos     return evpy_emit_event (event.get (), gdb_py_events.memory_changed);
    158  1.1  christos   return -1;
    159  1.1  christos }
    160  1.1  christos 
    161  1.1  christos /* Callback when a register is modified by the user.  This function
    162  1.1  christos    will create a new Python register changed event object. */
    163  1.1  christos 
    164  1.1  christos int
    165  1.1  christos emit_register_changed_event (struct frame_info* frame, int regnum)
    166  1.1  christos {
    167  1.1  christos   if (evregpy_no_listeners_p (gdb_py_events.register_changed))
    168  1.1  christos     return 0;
    169  1.1  christos 
    170  1.5  christos   gdbpy_ref<> event (create_register_changed_event_object (frame, regnum));
    171  1.1  christos   if (event != NULL)
    172  1.5  christos     return evpy_emit_event (event.get (), gdb_py_events.register_changed);
    173  1.1  christos   return -1;
    174  1.1  christos }
    175  1.1  christos 
    176  1.1  christos 
    177  1.1  christos GDBPY_NEW_EVENT_TYPE (inferior_call_pre,
    178  1.1  christos 		      "gdb.InferiorCallPreEvent",
    179  1.1  christos 		      "InferiorCallPreEvent",
    180  1.1  christos 		      "GDB inferior function pre-call event object",
    181  1.3  christos 		      event_object_type);
    182  1.1  christos 
    183  1.1  christos GDBPY_NEW_EVENT_TYPE (inferior_call_post,
    184  1.1  christos 		      "gdb.InferiorCallPostEvent",
    185  1.1  christos 		      "InferiorCallPostEvent",
    186  1.1  christos 		      "GDB inferior function post-call event object",
    187  1.3  christos 		      event_object_type);
    188  1.1  christos 
    189  1.1  christos GDBPY_NEW_EVENT_TYPE (register_changed,
    190  1.1  christos 		      "gdb.RegisterChangedEvent",
    191  1.1  christos 		      "RegisterChangedEvent",
    192  1.1  christos 		      "GDB register change event object",
    193  1.3  christos 		      event_object_type);
    194  1.1  christos 
    195  1.1  christos GDBPY_NEW_EVENT_TYPE (memory_changed,
    196  1.1  christos 		      "gdb.MemoryChangedEvent",
    197  1.1  christos 		      "MemoryChangedEvent",
    198  1.1  christos 		      "GDB memory change event object",
    199  1.3  christos 		      event_object_type);
    200