2003-03-27 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
1 /* DWARF 2 location expression support for GDB.
2 Copyright 2003 Free Software Foundation, Inc.
3 Contributed by Daniel Jacobowitz, MontaVista Software, 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 2 of the License, or (at
10 your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 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, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 #include "defs.h"
23 #include "ui-out.h"
24 #include "value.h"
25 #include "frame.h"
26 #include "gdbcore.h"
27 #include "target.h"
28 #include "inferior.h"
29 #include "ax.h"
30 #include "ax-gdb.h"
31 #include "regcache.h"
32
33 #include "elf/dwarf2.h"
34 #include "dwarf2expr.h"
35 #include "dwarf2loc.h"
36
37 #include "gdb_string.h"
38
39 #ifndef DWARF2_REG_TO_REGNUM
40 #define DWARF2_REG_TO_REGNUM(REG) (REG)
41 #endif
42
43 /* This is the baton used when performing dwarf2 expression
44 evaluation. */
45 struct dwarf_expr_baton
46 {
47 struct frame_info *frame;
48 struct objfile *objfile;
49 };
50
51 /* Helper functions for dwarf2_evaluate_loc_desc. */
52
53 /* Using the frame specified in BATON, read register REGNUM. The lval
54 type will be returned in LVALP, and for lval_memory the register
55 save address will be returned in ADDRP. */
56 static CORE_ADDR
57 dwarf_expr_read_reg (void *baton, int dwarf_regnum, enum lval_type *lvalp,
58 CORE_ADDR *addrp)
59 {
60 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
61 CORE_ADDR result;
62 char *buf;
63 int optimized, regnum, realnum, regsize;
64
65 regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum);
66 regsize = register_size (current_gdbarch, regnum);
67 buf = (char *) alloca (regsize);
68
69 frame_register (debaton->frame, regnum, &optimized, lvalp, addrp, &realnum,
70 buf);
71 result = extract_address (buf, regsize);
72
73 return result;
74 }
75
76 /* Read memory at ADDR (length LEN) into BUF. */
77
78 static void
79 dwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
80 {
81 read_memory (addr, buf, len);
82 }
83
84 /* Using the frame specified in BATON, find the location expression
85 describing the frame base. Return a pointer to it in START and
86 its length in LENGTH. */
87 static void
88 dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length)
89 {
90 struct symbol *framefunc;
91 struct dwarf2_locexpr_baton *symbaton;
92 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
93 framefunc = get_frame_function (debaton->frame);
94 symbaton = SYMBOL_LOCATION_BATON (framefunc);
95 *start = symbaton->data;
96 *length = symbaton->size;
97 }
98
99 /* Using the objfile specified in BATON, find the address for the
100 current thread's thread-local storage with offset OFFSET. */
101 static CORE_ADDR
102 dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
103 {
104 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
105 CORE_ADDR addr;
106
107 if (target_get_thread_local_address_p ())
108 addr = target_get_thread_local_address (inferior_ptid,
109 debaton->objfile,
110 offset);
111 else
112 error ("Cannot find thread-local variables on this target");
113
114 return addr;
115 }
116
117 /* Evaluate a location description, starting at DATA and with length
118 SIZE, to find the current location of variable VAR in the context
119 of FRAME. */
120 static struct value *
121 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
122 unsigned char *data, unsigned short size,
123 struct objfile *objfile)
124 {
125 CORE_ADDR result;
126 struct value *retval;
127 struct dwarf_expr_baton baton;
128 struct dwarf_expr_context *ctx;
129
130 baton.frame = frame;
131 baton.objfile = objfile;
132
133 ctx = new_dwarf_expr_context ();
134 ctx->baton = &baton;
135 ctx->read_reg = dwarf_expr_read_reg;
136 ctx->read_mem = dwarf_expr_read_mem;
137 ctx->get_frame_base = dwarf_expr_frame_base;
138 ctx->get_tls_address = dwarf_expr_tls_address;
139
140 dwarf_expr_eval (ctx, data, size);
141
142 retval = allocate_value (SYMBOL_TYPE (var));
143 VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var);
144
145 if (ctx->in_reg)
146 {
147 store_unsigned_integer (VALUE_CONTENTS_RAW (retval),
148 TYPE_LENGTH (SYMBOL_TYPE (var)),
149 dwarf_expr_fetch (ctx, 0));
150 VALUE_LVAL (retval) = lval_register;
151 VALUE_REGNO (retval) = ctx->regnum;
152 }
153 else
154 {
155 result = dwarf_expr_fetch (ctx, 0);
156 VALUE_LVAL (retval) = lval_memory;
157 VALUE_LAZY (retval) = 1;
158 VALUE_ADDRESS (retval) = result;
159 }
160
161 free_dwarf_expr_context (ctx);
162
163 return retval;
164 }
165
166
167
168
169 \f
170 /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
171
172 struct needs_frame_baton
173 {
174 int needs_frame;
175 };
176
177 /* Reads from registers do require a frame. */
178 static CORE_ADDR
179 needs_frame_read_reg (void *baton, int regnum, enum lval_type *lvalp,
180 CORE_ADDR *addrp)
181 {
182 struct needs_frame_baton *nf_baton = baton;
183 nf_baton->needs_frame = 1;
184 return 1;
185 }
186
187 /* Reads from memory do not require a frame. */
188 static void
189 needs_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
190 {
191 memset (buf, 0, len);
192 }
193
194 /* Frame-relative accesses do require a frame. */
195 static void
196 needs_frame_frame_base (void *baton, unsigned char **start, size_t * length)
197 {
198 static char lit0 = DW_OP_lit0;
199 struct needs_frame_baton *nf_baton = baton;
200
201 *start = &lit0;
202 *length = 1;
203
204 nf_baton->needs_frame = 1;
205 }
206
207 /* Thread-local accesses do require a frame. */
208 static CORE_ADDR
209 needs_frame_tls_address (void *baton, CORE_ADDR offset)
210 {
211 struct needs_frame_baton *nf_baton = baton;
212 nf_baton->needs_frame = 1;
213 return 1;
214 }
215
216 /* Return non-zero iff the location expression at DATA (length SIZE)
217 requires a frame to evaluate. */
218
219 static int
220 dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
221 {
222 struct needs_frame_baton baton;
223 struct dwarf_expr_context *ctx;
224
225 baton.needs_frame = 0;
226
227 ctx = new_dwarf_expr_context ();
228 ctx->baton = &baton;
229 ctx->read_reg = needs_frame_read_reg;
230 ctx->read_mem = needs_frame_read_mem;
231 ctx->get_frame_base = needs_frame_frame_base;
232 ctx->get_tls_address = needs_frame_tls_address;
233
234 dwarf_expr_eval (ctx, data, size);
235
236 free_dwarf_expr_context (ctx);
237
238 return baton.needs_frame;
239 }
240
241
242
243 \f
244 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
245 evaluator to calculate the location. */
246 static struct value *
247 locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
248 {
249 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
250 struct value *val;
251 val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
252 dlbaton->objfile);
253
254 return val;
255 }
256
257 /* Return non-zero iff we need a frame to evaluate SYMBOL. */
258 static int
259 locexpr_read_needs_frame (struct symbol *symbol)
260 {
261 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
262 return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
263 }
264
265 /* Print a natural-language description of SYMBOL to STREAM. */
266 static int
267 locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
268 {
269 /* FIXME: be more extensive. */
270 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
271
272 if (dlbaton->size == 1
273 && dlbaton->data[0] >= DW_OP_reg0
274 && dlbaton->data[0] <= DW_OP_reg31)
275 {
276 int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0);
277 fprintf_filtered (stream,
278 "a variable in register %s", REGISTER_NAME (regno));
279 return 1;
280 }
281
282 fprintf_filtered (stream,
283 "a variable with complex or multiple locations (DWARF2)");
284 return 1;
285 }
286
287
288 /* Describe the location of SYMBOL as an agent value in VALUE, generating
289 any necessary bytecode in AX.
290
291 NOTE drow/2003-02-26: This function is extremely minimal, because
292 doing it correctly is extremely complicated and there is no
293 publicly available stub with tracepoint support for me to test
294 against. When there is one this function should be revisited. */
295
296 void
297 locexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
298 struct axs_value * value)
299 {
300 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
301
302 if (dlbaton->size == 0)
303 error ("Symbol \"%s\" has been optimized out.",
304 SYMBOL_PRINT_NAME (symbol));
305
306 if (dlbaton->size == 1
307 && dlbaton->data[0] >= DW_OP_reg0
308 && dlbaton->data[0] <= DW_OP_reg31)
309 {
310 value->kind = axs_lvalue_register;
311 value->u.reg = dlbaton->data[0] - DW_OP_reg0;
312 }
313 else if (dlbaton->data[0] == DW_OP_regx)
314 {
315 ULONGEST reg;
316 read_uleb128 (dlbaton->data + 1, dlbaton->data + dlbaton->size,
317 &reg);
318 value->kind = axs_lvalue_register;
319 value->u.reg = reg;
320 }
321 else if (dlbaton->data[0] == DW_OP_fbreg)
322 {
323 /* And this is worse than just minimal; we should honor the frame base
324 as above. */
325 int frame_reg;
326 LONGEST frame_offset;
327 unsigned char *buf_end;
328
329 buf_end = read_sleb128 (dlbaton->data + 1, dlbaton->data + dlbaton->size,
330 &frame_offset);
331 if (buf_end != dlbaton->data + dlbaton->size)
332 error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
333 SYMBOL_PRINT_NAME (symbol));
334
335 TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
336 ax_reg (ax, frame_reg);
337 ax_const_l (ax, frame_offset);
338 ax_simple (ax, aop_add);
339
340 ax_const_l (ax, frame_offset);
341 ax_simple (ax, aop_add);
342 value->kind = axs_lvalue_memory;
343 }
344 else
345 error ("Unsupported DWARF opcode in the location of \"%s\".",
346 SYMBOL_PRINT_NAME (symbol));
347 }
348
349 /* The set of location functions used with the DWARF-2 expression
350 evaluator. */
351 struct location_funcs dwarf2_locexpr_funcs = {
352 locexpr_read_variable,
353 locexpr_read_needs_frame,
354 locexpr_describe_location,
355 locexpr_tracepoint_var_ref
356 };
This page took 0.036588 seconds and 4 git commands to generate.