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 (®ister_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