1 /* Python interface to inferior function events. 2 3 Copyright (C) 2013-2023 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 "py-event.h" 22 23 /* Construct either a gdb.InferiorCallPreEvent or a 24 gdb.InferiorCallPostEvent. */ 25 26 static gdbpy_ref<> 27 create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid, 28 CORE_ADDR addr) 29 { 30 gdbpy_ref<> event; 31 32 switch (flag) 33 { 34 case INFERIOR_CALL_PRE: 35 event = create_event_object (&inferior_call_pre_event_object_type); 36 break; 37 case INFERIOR_CALL_POST: 38 event = create_event_object (&inferior_call_post_event_object_type); 39 break; 40 default: 41 gdb_assert_not_reached ("invalid inferior_call_kind"); 42 } 43 44 gdbpy_ref<> ptid_obj (gdbpy_create_ptid_object (ptid)); 45 if (ptid_obj == NULL) 46 return NULL; 47 48 if (evpy_add_attribute (event.get (), "ptid", ptid_obj.get ()) < 0) 49 return NULL; 50 51 gdbpy_ref<> addr_obj = gdb_py_object_from_ulongest (addr); 52 if (addr_obj == NULL) 53 return NULL; 54 55 if (evpy_add_attribute (event.get (), "address", addr_obj.get ()) < 0) 56 return NULL; 57 58 return event; 59 } 60 61 /* Construct a gdb.RegisterChangedEvent containing the affected 62 register number. */ 63 64 static gdbpy_ref<> 65 create_register_changed_event_object (frame_info_ptr frame, 66 int regnum) 67 { 68 gdbpy_ref<> event = create_event_object (®ister_changed_event_object_type); 69 if (event == NULL) 70 return NULL; 71 72 gdbpy_ref<> frame_obj (frame_info_to_frame_object (frame)); 73 if (frame_obj == NULL) 74 return NULL; 75 76 if (evpy_add_attribute (event.get (), "frame", frame_obj.get ()) < 0) 77 return NULL; 78 79 gdbpy_ref<> regnum_obj = gdb_py_object_from_longest (regnum); 80 if (regnum_obj == NULL) 81 return NULL; 82 83 if (evpy_add_attribute (event.get (), "regnum", regnum_obj.get ()) < 0) 84 return NULL; 85 86 return event; 87 } 88 89 /* Construct a gdb.MemoryChangedEvent describing the extent of the 90 affected memory. */ 91 92 static gdbpy_ref<> 93 create_memory_changed_event_object (CORE_ADDR addr, ssize_t len) 94 { 95 gdbpy_ref<> event = create_event_object (&memory_changed_event_object_type); 96 97 if (event == NULL) 98 return NULL; 99 100 gdbpy_ref<> addr_obj = gdb_py_object_from_ulongest (addr); 101 if (addr_obj == NULL) 102 return NULL; 103 104 if (evpy_add_attribute (event.get (), "address", addr_obj.get ()) < 0) 105 return NULL; 106 107 gdbpy_ref<> len_obj = gdb_py_object_from_longest (len); 108 if (len_obj == NULL) 109 return NULL; 110 111 if (evpy_add_attribute (event.get (), "length", len_obj.get ()) < 0) 112 return NULL; 113 114 return event; 115 } 116 117 /* Callback function which notifies observers when an event occurs which 118 calls a function in the inferior. 119 This function will create a new Python inferior-call event object. 120 Return -1 if emit fails. */ 121 122 int 123 emit_inferior_call_event (inferior_call_kind flag, ptid_t thread, 124 CORE_ADDR addr) 125 { 126 if (evregpy_no_listeners_p (gdb_py_events.inferior_call)) 127 return 0; 128 129 gdbpy_ref<> event = create_inferior_call_event_object (flag, thread, addr); 130 if (event != NULL) 131 return evpy_emit_event (event.get (), gdb_py_events.inferior_call); 132 return -1; 133 } 134 135 /* Callback when memory is modified by the user. This function will 136 create a new Python memory changed event object. */ 137 138 int 139 emit_memory_changed_event (CORE_ADDR addr, ssize_t len) 140 { 141 if (evregpy_no_listeners_p (gdb_py_events.memory_changed)) 142 return 0; 143 144 gdbpy_ref<> event = create_memory_changed_event_object (addr, len); 145 if (event != NULL) 146 return evpy_emit_event (event.get (), gdb_py_events.memory_changed); 147 return -1; 148 } 149 150 /* Callback when a register is modified by the user. This function 151 will create a new Python register changed event object. */ 152 153 int 154 emit_register_changed_event (frame_info_ptr frame, int regnum) 155 { 156 if (evregpy_no_listeners_p (gdb_py_events.register_changed)) 157 return 0; 158 159 gdbpy_ref<> event = create_register_changed_event_object (frame, regnum); 160 if (event != NULL) 161 return evpy_emit_event (event.get (), gdb_py_events.register_changed); 162 return -1; 163 } 164