Explicit locations: introduce address locations
[deliverable/binutils-gdb.git] / gdb / location.c
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)
48
49 /* An address in the inferior. */
50 CORE_ADDR address;
51 #define EL_ADDRESS(PTR) (PTR)->u.address
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
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
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
140 case ADDRESS_LOCATION:
141 EL_ADDRESS (dst) = EL_ADDRESS (src);
142 break;
143
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
184 case ADDRESS_LOCATION:
185 /* Nothing to do. */
186 break;
187
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
210 case ADDRESS_LOCATION:
211 EL_STRING (location)
212 = xstrprintf ("*%s",
213 core_addr_to_string (EL_ADDRESS (location)));
214 break;
215
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
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
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
263 case ADDRESS_LOCATION:
264 return 0;
265
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 }
This page took 0.037213 seconds and 4 git commands to generate.