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