Commit | Line | Data |
---|---|---|
c7c1b3e9 KS |
1 | /* Data structures and API for event locations in GDB. |
2 | Copyright (C) 2013-2015 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 3 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include "defs.h" | |
20 | #include "gdb_assert.h" | |
21 | #include "location.h" | |
22 | #include "symtab.h" | |
23 | #include "language.h" | |
24 | #include "linespec.h" | |
25 | #include "cli/cli-utils.h" | |
26 | #include "probe.h" | |
27 | ||
28 | #include <ctype.h> | |
29 | #include <string.h> | |
30 | ||
31 | /* An event location used to set a stop event in the inferior. | |
32 | This structure is an amalgam of the various ways | |
33 | to specify where a stop event should be set. */ | |
34 | ||
35 | struct event_location | |
36 | { | |
37 | /* The type of this breakpoint specification. */ | |
38 | enum event_location_type type; | |
39 | #define EL_TYPE(PTR) (PTR)->type | |
40 | ||
41 | union | |
42 | { | |
43 | /* A generic "this is a string specification" for a location. | |
44 | This representation is used by both "normal" linespecs and | |
45 | probes. */ | |
46 | char *addr_string; | |
47 | #define EL_LINESPEC(PTR) ((PTR)->u.addr_string) | |
a06efdd6 KS |
48 | |
49 | /* An address in the inferior. */ | |
50 | CORE_ADDR address; | |
51 | #define EL_ADDRESS(PTR) (PTR)->u.address | |
c7c1b3e9 KS |
52 | } u; |
53 | ||
54 | /* Cached string representation of this location. This is used, e.g., to | |
55 | save stop event locations to file. Malloc'd. */ | |
56 | char *as_string; | |
57 | #define EL_STRING(PTR) ((PTR)->as_string) | |
58 | }; | |
59 | ||
60 | /* See description in location.h. */ | |
61 | ||
62 | enum event_location_type | |
63 | event_location_type (const struct event_location *location) | |
64 | { | |
65 | return EL_TYPE (location); | |
66 | } | |
67 | ||
68 | /* See description in location.h. */ | |
69 | ||
70 | struct event_location * | |
71 | new_linespec_location (char **linespec) | |
72 | { | |
73 | struct event_location *location; | |
74 | ||
75 | location = XCNEW (struct event_location); | |
76 | EL_TYPE (location) = LINESPEC_LOCATION; | |
77 | if (*linespec != NULL) | |
78 | { | |
79 | char *p; | |
80 | char *orig = *linespec; | |
81 | ||
82 | linespec_lex_to_end (linespec); | |
83 | p = remove_trailing_whitespace (orig, *linespec); | |
84 | if ((p - orig) > 0) | |
85 | EL_LINESPEC (location) = savestring (orig, p - orig); | |
86 | } | |
87 | return location; | |
88 | } | |
89 | ||
90 | /* See description in location.h. */ | |
91 | ||
92 | const char * | |
93 | get_linespec_location (const struct event_location *location) | |
94 | { | |
95 | gdb_assert (EL_TYPE (location) == LINESPEC_LOCATION); | |
96 | return EL_LINESPEC (location); | |
97 | } | |
98 | ||
99 | /* See description in location.h. */ | |
100 | ||
a06efdd6 KS |
101 | struct event_location * |
102 | new_address_location (CORE_ADDR addr) | |
103 | { | |
104 | struct event_location *location; | |
105 | ||
106 | location = XCNEW (struct event_location); | |
107 | EL_TYPE (location) = ADDRESS_LOCATION; | |
108 | EL_ADDRESS (location) = addr; | |
109 | return location; | |
110 | } | |
111 | ||
112 | /* See description in location.h. */ | |
113 | ||
114 | CORE_ADDR | |
115 | get_address_location (const struct event_location *location) | |
116 | { | |
117 | gdb_assert (EL_TYPE (location) == ADDRESS_LOCATION); | |
118 | return EL_ADDRESS (location); | |
119 | } | |
120 | ||
121 | /* See description in location.h. */ | |
122 | ||
c7c1b3e9 KS |
123 | struct event_location * |
124 | copy_event_location (const struct event_location *src) | |
125 | { | |
126 | struct event_location *dst; | |
127 | ||
128 | dst = XCNEW (struct event_location); | |
129 | EL_TYPE (dst) = EL_TYPE (src); | |
130 | if (EL_STRING (src) != NULL) | |
131 | EL_STRING (dst) = xstrdup (EL_STRING (src)); | |
132 | ||
133 | switch (EL_TYPE (src)) | |
134 | { | |
135 | case LINESPEC_LOCATION: | |
136 | if (EL_LINESPEC (src) != NULL) | |
137 | EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src)); | |
138 | break; | |
139 | ||
a06efdd6 KS |
140 | case ADDRESS_LOCATION: |
141 | EL_ADDRESS (dst) = EL_ADDRESS (src); | |
142 | break; | |
143 | ||
c7c1b3e9 KS |
144 | default: |
145 | gdb_assert_not_reached ("unknown event location type"); | |
146 | } | |
147 | ||
148 | return dst; | |
149 | } | |
150 | ||
151 | /* A cleanup function for struct event_location. */ | |
152 | ||
153 | static void | |
154 | delete_event_location_cleanup (void *data) | |
155 | { | |
156 | struct event_location *location = (struct event_location *) data; | |
157 | ||
158 | delete_event_location (location); | |
159 | } | |
160 | ||
161 | /* See description in location.h. */ | |
162 | ||
163 | struct cleanup * | |
164 | make_cleanup_delete_event_location (struct event_location *location) | |
165 | { | |
166 | return make_cleanup (delete_event_location_cleanup, location); | |
167 | } | |
168 | ||
169 | /* See description in location.h. */ | |
170 | ||
171 | void | |
172 | delete_event_location (struct event_location *location) | |
173 | { | |
174 | if (location != NULL) | |
175 | { | |
176 | xfree (EL_STRING (location)); | |
177 | ||
178 | switch (EL_TYPE (location)) | |
179 | { | |
180 | case LINESPEC_LOCATION: | |
181 | xfree (EL_LINESPEC (location)); | |
182 | break; | |
183 | ||
a06efdd6 KS |
184 | case ADDRESS_LOCATION: |
185 | /* Nothing to do. */ | |
186 | break; | |
187 | ||
c7c1b3e9 KS |
188 | default: |
189 | gdb_assert_not_reached ("unknown event location type"); | |
190 | } | |
191 | ||
192 | xfree (location); | |
193 | } | |
194 | } | |
195 | ||
196 | /* See description in location.h. */ | |
197 | ||
198 | const char * | |
199 | event_location_to_string (struct event_location *location) | |
200 | { | |
201 | if (EL_STRING (location) == NULL) | |
202 | { | |
203 | switch (EL_TYPE (location)) | |
204 | { | |
205 | case LINESPEC_LOCATION: | |
206 | if (EL_LINESPEC (location) != NULL) | |
207 | EL_STRING (location) = xstrdup (EL_LINESPEC (location)); | |
208 | break; | |
209 | ||
a06efdd6 KS |
210 | case ADDRESS_LOCATION: |
211 | EL_STRING (location) | |
212 | = xstrprintf ("*%s", | |
213 | core_addr_to_string (EL_ADDRESS (location))); | |
214 | break; | |
215 | ||
c7c1b3e9 KS |
216 | default: |
217 | gdb_assert_not_reached ("unknown event location type"); | |
218 | } | |
219 | } | |
220 | ||
221 | return EL_STRING (location); | |
222 | } | |
223 | ||
224 | /* See description in location.h. */ | |
225 | ||
226 | struct event_location * | |
227 | string_to_event_location (char **stringp, | |
228 | const struct language_defn *language) | |
229 | { | |
230 | struct event_location *location; | |
231 | ||
a06efdd6 KS |
232 | /* First, check if the string is an address location. */ |
233 | if (*stringp != NULL && **stringp == '*') | |
234 | { | |
235 | const char *arg, *orig; | |
236 | CORE_ADDR addr; | |
237 | ||
238 | orig = arg = *stringp; | |
239 | addr = linespec_expression_to_pc (&arg); | |
240 | location = new_address_location (addr); | |
241 | *stringp += arg - orig; | |
242 | } | |
243 | else | |
244 | { | |
245 | /* Everything else is a linespec. */ | |
246 | location = new_linespec_location (stringp); | |
247 | } | |
248 | ||
c7c1b3e9 KS |
249 | return location; |
250 | } | |
251 | ||
252 | /* See description in location.h. */ | |
253 | ||
254 | int | |
255 | event_location_empty_p (const struct event_location *location) | |
256 | { | |
257 | switch (EL_TYPE (location)) | |
258 | { | |
259 | case LINESPEC_LOCATION: | |
260 | /* Linespecs are never "empty." (NULL is a valid linespec) */ | |
261 | return 0; | |
262 | ||
a06efdd6 KS |
263 | case ADDRESS_LOCATION: |
264 | return 0; | |
265 | ||
c7c1b3e9 KS |
266 | default: |
267 | gdb_assert_not_reached ("unknown event location type"); | |
268 | } | |
269 | } | |
270 | ||
271 | /* See description in location.h. */ | |
272 | ||
273 | void | |
274 | set_event_location_string (struct event_location *location, | |
275 | const char *string) | |
276 | { | |
277 | xfree (EL_STRING (location)); | |
278 | EL_STRING (location) = string == NULL ? NULL : xstrdup (string); | |
279 | } |