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