* minsyms.c (install_minimal_symbols): Only switch to gnu-v3 mode
[deliverable/binutils-gdb.git] / gdb / dwarf2loc.c
CommitLineData
4c2df51b
DJ
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"
a55cc764
DJ
29#include "ax.h"
30#include "ax-gdb.h"
e4adbba9 31#include "regcache.h"
4c2df51b
DJ
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. */
45struct 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. */
56static CORE_ADDR
e4adbba9 57dwarf_expr_read_reg (void *baton, int dwarf_regnum, enum lval_type *lvalp,
4c2df51b
DJ
58 CORE_ADDR *addrp)
59{
4c2df51b 60 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
e4adbba9
DJ
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);
4c2df51b 68
e4adbba9
DJ
69 frame_register (debaton->frame, regnum, &optimized, lvalp, addrp, &realnum,
70 buf);
71 result = extract_address (buf, regsize);
4c2df51b
DJ
72
73 return result;
74}
75
76/* Read memory at ADDR (length LEN) into BUF. */
77
78static void
79dwarf_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. */
87static void
88dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length)
89{
da62e633
AC
90 /* FIXME: cagney/2003-03-26: This code should be using
91 get_frame_base_address(), and then implement a dwarf2 specific
92 this_base method. */
4c2df51b
DJ
93 struct symbol *framefunc;
94 struct dwarf2_locexpr_baton *symbaton;
95 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
96 framefunc = get_frame_function (debaton->frame);
97 symbaton = SYMBOL_LOCATION_BATON (framefunc);
98 *start = symbaton->data;
99 *length = symbaton->size;
100}
101
102/* Using the objfile specified in BATON, find the address for the
103 current thread's thread-local storage with offset OFFSET. */
104static CORE_ADDR
105dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
106{
107 struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
108 CORE_ADDR addr;
109
110 if (target_get_thread_local_address_p ())
111 addr = target_get_thread_local_address (inferior_ptid,
112 debaton->objfile,
113 offset);
114 else
115 error ("Cannot find thread-local variables on this target");
116
117 return addr;
118}
119
120/* Evaluate a location description, starting at DATA and with length
121 SIZE, to find the current location of variable VAR in the context
122 of FRAME. */
123static struct value *
124dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
125 unsigned char *data, unsigned short size,
126 struct objfile *objfile)
127{
128 CORE_ADDR result;
129 struct value *retval;
130 struct dwarf_expr_baton baton;
131 struct dwarf_expr_context *ctx;
132
133 baton.frame = frame;
134 baton.objfile = objfile;
135
136 ctx = new_dwarf_expr_context ();
137 ctx->baton = &baton;
138 ctx->read_reg = dwarf_expr_read_reg;
139 ctx->read_mem = dwarf_expr_read_mem;
140 ctx->get_frame_base = dwarf_expr_frame_base;
141 ctx->get_tls_address = dwarf_expr_tls_address;
142
143 dwarf_expr_eval (ctx, data, size);
144
145 retval = allocate_value (SYMBOL_TYPE (var));
146 VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var);
147
148 if (ctx->in_reg)
149 {
150 store_unsigned_integer (VALUE_CONTENTS_RAW (retval),
151 TYPE_LENGTH (SYMBOL_TYPE (var)),
152 dwarf_expr_fetch (ctx, 0));
153 VALUE_LVAL (retval) = lval_register;
154 VALUE_REGNO (retval) = ctx->regnum;
155 }
156 else
157 {
158 result = dwarf_expr_fetch (ctx, 0);
159 VALUE_LVAL (retval) = lval_memory;
160 VALUE_LAZY (retval) = 1;
161 VALUE_ADDRESS (retval) = result;
162 }
163
164 free_dwarf_expr_context (ctx);
165
166 return retval;
167}
168
169
170
171
172\f
173/* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
174
175struct needs_frame_baton
176{
177 int needs_frame;
178};
179
180/* Reads from registers do require a frame. */
181static CORE_ADDR
182needs_frame_read_reg (void *baton, int regnum, enum lval_type *lvalp,
183 CORE_ADDR *addrp)
184{
185 struct needs_frame_baton *nf_baton = baton;
186 nf_baton->needs_frame = 1;
187 return 1;
188}
189
190/* Reads from memory do not require a frame. */
191static void
192needs_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
193{
194 memset (buf, 0, len);
195}
196
197/* Frame-relative accesses do require a frame. */
198static void
199needs_frame_frame_base (void *baton, unsigned char **start, size_t * length)
200{
201 static char lit0 = DW_OP_lit0;
202 struct needs_frame_baton *nf_baton = baton;
203
204 *start = &lit0;
205 *length = 1;
206
207 nf_baton->needs_frame = 1;
208}
209
210/* Thread-local accesses do require a frame. */
211static CORE_ADDR
212needs_frame_tls_address (void *baton, CORE_ADDR offset)
213{
214 struct needs_frame_baton *nf_baton = baton;
215 nf_baton->needs_frame = 1;
216 return 1;
217}
218
219/* Return non-zero iff the location expression at DATA (length SIZE)
220 requires a frame to evaluate. */
221
222static int
223dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
224{
225 struct needs_frame_baton baton;
226 struct dwarf_expr_context *ctx;
227
228 baton.needs_frame = 0;
229
230 ctx = new_dwarf_expr_context ();
231 ctx->baton = &baton;
232 ctx->read_reg = needs_frame_read_reg;
233 ctx->read_mem = needs_frame_read_mem;
234 ctx->get_frame_base = needs_frame_frame_base;
235 ctx->get_tls_address = needs_frame_tls_address;
236
237 dwarf_expr_eval (ctx, data, size);
238
239 free_dwarf_expr_context (ctx);
240
241 return baton.needs_frame;
242}
243
244
245
246\f
247/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
248 evaluator to calculate the location. */
249static struct value *
250locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
251{
252 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
253 struct value *val;
254 val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
255 dlbaton->objfile);
256
257 return val;
258}
259
260/* Return non-zero iff we need a frame to evaluate SYMBOL. */
261static int
262locexpr_read_needs_frame (struct symbol *symbol)
263{
264 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
265 return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
266}
267
268/* Print a natural-language description of SYMBOL to STREAM. */
269static int
270locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
271{
272 /* FIXME: be more extensive. */
273 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
274
275 if (dlbaton->size == 1
276 && dlbaton->data[0] >= DW_OP_reg0
277 && dlbaton->data[0] <= DW_OP_reg31)
278 {
279 int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0);
280 fprintf_filtered (stream,
281 "a variable in register %s", REGISTER_NAME (regno));
282 return 1;
283 }
284
285 fprintf_filtered (stream,
286 "a variable with complex or multiple locations (DWARF2)");
287 return 1;
288}
289
a55cc764
DJ
290
291/* Describe the location of SYMBOL as an agent value in VALUE, generating
292 any necessary bytecode in AX.
293
294 NOTE drow/2003-02-26: This function is extremely minimal, because
295 doing it correctly is extremely complicated and there is no
296 publicly available stub with tracepoint support for me to test
297 against. When there is one this function should be revisited. */
298
299void
300locexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
301 struct axs_value * value)
302{
303 struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
304
305 if (dlbaton->size == 0)
306 error ("Symbol \"%s\" has been optimized out.",
307 SYMBOL_PRINT_NAME (symbol));
308
309 if (dlbaton->size == 1
310 && dlbaton->data[0] >= DW_OP_reg0
311 && dlbaton->data[0] <= DW_OP_reg31)
312 {
313 value->kind = axs_lvalue_register;
314 value->u.reg = dlbaton->data[0] - DW_OP_reg0;
315 }
316 else if (dlbaton->data[0] == DW_OP_regx)
317 {
318 ULONGEST reg;
319 read_uleb128 (dlbaton->data + 1, dlbaton->data + dlbaton->size,
320 &reg);
321 value->kind = axs_lvalue_register;
322 value->u.reg = reg;
323 }
324 else if (dlbaton->data[0] == DW_OP_fbreg)
325 {
326 /* And this is worse than just minimal; we should honor the frame base
327 as above. */
328 int frame_reg;
329 LONGEST frame_offset;
330 unsigned char *buf_end;
331
332 buf_end = read_sleb128 (dlbaton->data + 1, dlbaton->data + dlbaton->size,
333 &frame_offset);
334 if (buf_end != dlbaton->data + dlbaton->size)
335 error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
336 SYMBOL_PRINT_NAME (symbol));
337
338 TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
339 ax_reg (ax, frame_reg);
340 ax_const_l (ax, frame_offset);
341 ax_simple (ax, aop_add);
342
343 ax_const_l (ax, frame_offset);
344 ax_simple (ax, aop_add);
345 value->kind = axs_lvalue_memory;
346 }
347 else
348 error ("Unsupported DWARF opcode in the location of \"%s\".",
349 SYMBOL_PRINT_NAME (symbol));
350}
351
4c2df51b
DJ
352/* The set of location functions used with the DWARF-2 expression
353 evaluator. */
354struct location_funcs dwarf2_locexpr_funcs = {
355 locexpr_read_variable,
356 locexpr_read_needs_frame,
357 locexpr_describe_location,
a55cc764 358 locexpr_tracepoint_var_ref
4c2df51b 359};
This page took 0.105921 seconds and 4 git commands to generate.