Explicit locations: introduce address locations
[deliverable/binutils-gdb.git] / gdb / location.c
CommitLineData
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
35struct 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
62enum event_location_type
63event_location_type (const struct event_location *location)
64{
65 return EL_TYPE (location);
66}
67
68/* See description in location.h. */
69
70struct event_location *
71new_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
92const char *
93get_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
101struct event_location *
102new_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
114CORE_ADDR
115get_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
123struct event_location *
124copy_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
153static void
154delete_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
163struct cleanup *
164make_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
171void
172delete_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
198const char *
199event_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
226struct event_location *
227string_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
254int
255event_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
273void
274set_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.034473 seconds and 4 git commands to generate.