1 /* DWARF 2 location expression support for GDB.
2 Copyright 2003 Free Software Foundation, Inc.
3 Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
5 This file is part of GDB.
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.
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.
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. */
33 #include "elf/dwarf2.h"
34 #include "dwarf2expr.h"
35 #include "dwarf2loc.h"
37 #include "gdb_string.h"
39 #ifndef DWARF2_REG_TO_REGNUM
40 #define DWARF2_REG_TO_REGNUM(REG) (REG)
43 /* This is the baton used when performing dwarf2 expression
45 struct dwarf_expr_baton
47 struct frame_info
*frame
;
48 struct objfile
*objfile
;
51 /* Helper functions for dwarf2_evaluate_loc_desc. */
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. */
57 dwarf_expr_read_reg (void *baton
, int dwarf_regnum
, enum lval_type
*lvalp
,
60 struct dwarf_expr_baton
*debaton
= (struct dwarf_expr_baton
*) baton
;
63 int optimized
, regnum
, realnum
, regsize
;
65 regnum
= DWARF2_REG_TO_REGNUM (dwarf_regnum
);
66 regsize
= register_size (current_gdbarch
, regnum
);
67 buf
= (char *) alloca (regsize
);
69 frame_register (debaton
->frame
, regnum
, &optimized
, lvalp
, addrp
, &realnum
,
71 result
= extract_address (buf
, regsize
);
76 /* Read memory at ADDR (length LEN) into BUF. */
79 dwarf_expr_read_mem (void *baton
, char *buf
, CORE_ADDR addr
, size_t len
)
81 read_memory (addr
, buf
, len
);
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. */
88 dwarf_expr_frame_base (void *baton
, unsigned char **start
, size_t * length
)
90 /* FIXME: cagney/2003-03-26: This code should be using
91 get_frame_base_address(), and then implement a dwarf2 specific
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
;
102 /* Using the objfile specified in BATON, find the address for the
103 current thread's thread-local storage with offset OFFSET. */
105 dwarf_expr_tls_address (void *baton
, CORE_ADDR offset
)
107 struct dwarf_expr_baton
*debaton
= (struct dwarf_expr_baton
*) baton
;
110 if (target_get_thread_local_address_p ())
111 addr
= target_get_thread_local_address (inferior_ptid
,
115 error ("Cannot find thread-local variables on this target");
120 /* Evaluate a location description, starting at DATA and with length
121 SIZE, to find the current location of variable VAR in the context
123 static struct value
*
124 dwarf2_evaluate_loc_desc (struct symbol
*var
, struct frame_info
*frame
,
125 unsigned char *data
, unsigned short size
,
126 struct objfile
*objfile
)
129 struct value
*retval
;
130 struct dwarf_expr_baton baton
;
131 struct dwarf_expr_context
*ctx
;
134 baton
.objfile
= objfile
;
136 ctx
= new_dwarf_expr_context ();
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
;
143 dwarf_expr_eval (ctx
, data
, size
);
145 retval
= allocate_value (SYMBOL_TYPE (var
));
146 VALUE_BFD_SECTION (retval
) = SYMBOL_BFD_SECTION (var
);
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
;
158 result
= dwarf_expr_fetch (ctx
, 0);
159 VALUE_LVAL (retval
) = lval_memory
;
160 VALUE_LAZY (retval
) = 1;
161 VALUE_ADDRESS (retval
) = result
;
164 free_dwarf_expr_context (ctx
);
173 /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
175 struct needs_frame_baton
180 /* Reads from registers do require a frame. */
182 needs_frame_read_reg (void *baton
, int regnum
, enum lval_type
*lvalp
,
185 struct needs_frame_baton
*nf_baton
= baton
;
186 nf_baton
->needs_frame
= 1;
190 /* Reads from memory do not require a frame. */
192 needs_frame_read_mem (void *baton
, char *buf
, CORE_ADDR addr
, size_t len
)
194 memset (buf
, 0, len
);
197 /* Frame-relative accesses do require a frame. */
199 needs_frame_frame_base (void *baton
, unsigned char **start
, size_t * length
)
201 static char lit0
= DW_OP_lit0
;
202 struct needs_frame_baton
*nf_baton
= baton
;
207 nf_baton
->needs_frame
= 1;
210 /* Thread-local accesses do require a frame. */
212 needs_frame_tls_address (void *baton
, CORE_ADDR offset
)
214 struct needs_frame_baton
*nf_baton
= baton
;
215 nf_baton
->needs_frame
= 1;
219 /* Return non-zero iff the location expression at DATA (length SIZE)
220 requires a frame to evaluate. */
223 dwarf2_loc_desc_needs_frame (unsigned char *data
, unsigned short size
)
225 struct needs_frame_baton baton
;
226 struct dwarf_expr_context
*ctx
;
228 baton
.needs_frame
= 0;
230 ctx
= new_dwarf_expr_context ();
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
;
237 dwarf_expr_eval (ctx
, data
, size
);
239 free_dwarf_expr_context (ctx
);
241 return baton
.needs_frame
;
247 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
248 evaluator to calculate the location. */
249 static struct value
*
250 locexpr_read_variable (struct symbol
*symbol
, struct frame_info
*frame
)
252 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
254 val
= dwarf2_evaluate_loc_desc (symbol
, frame
, dlbaton
->data
, dlbaton
->size
,
260 /* Return non-zero iff we need a frame to evaluate SYMBOL. */
262 locexpr_read_needs_frame (struct symbol
*symbol
)
264 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
265 return dwarf2_loc_desc_needs_frame (dlbaton
->data
, dlbaton
->size
);
268 /* Print a natural-language description of SYMBOL to STREAM. */
270 locexpr_describe_location (struct symbol
*symbol
, struct ui_file
*stream
)
272 /* FIXME: be more extensive. */
273 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
275 if (dlbaton
->size
== 1
276 && dlbaton
->data
[0] >= DW_OP_reg0
277 && dlbaton
->data
[0] <= DW_OP_reg31
)
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
));
285 fprintf_filtered (stream
,
286 "a variable with complex or multiple locations (DWARF2)");
291 /* Describe the location of SYMBOL as an agent value in VALUE, generating
292 any necessary bytecode in AX.
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. */
300 locexpr_tracepoint_var_ref (struct symbol
* symbol
, struct agent_expr
* ax
,
301 struct axs_value
* value
)
303 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
305 if (dlbaton
->size
== 0)
306 error ("Symbol \"%s\" has been optimized out.",
307 SYMBOL_PRINT_NAME (symbol
));
309 if (dlbaton
->size
== 1
310 && dlbaton
->data
[0] >= DW_OP_reg0
311 && dlbaton
->data
[0] <= DW_OP_reg31
)
313 value
->kind
= axs_lvalue_register
;
314 value
->u
.reg
= dlbaton
->data
[0] - DW_OP_reg0
;
316 else if (dlbaton
->data
[0] == DW_OP_regx
)
319 read_uleb128 (dlbaton
->data
+ 1, dlbaton
->data
+ dlbaton
->size
,
321 value
->kind
= axs_lvalue_register
;
324 else if (dlbaton
->data
[0] == DW_OP_fbreg
)
326 /* And this is worse than just minimal; we should honor the frame base
329 LONGEST frame_offset
;
330 unsigned char *buf_end
;
332 buf_end
= read_sleb128 (dlbaton
->data
+ 1, dlbaton
->data
+ dlbaton
->size
,
334 if (buf_end
!= dlbaton
->data
+ dlbaton
->size
)
335 error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
336 SYMBOL_PRINT_NAME (symbol
));
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
);
343 ax_const_l (ax
, frame_offset
);
344 ax_simple (ax
, aop_add
);
345 value
->kind
= axs_lvalue_memory
;
348 error ("Unsupported DWARF opcode in the location of \"%s\".",
349 SYMBOL_PRINT_NAME (symbol
));
352 /* The set of location functions used with the DWARF-2 expression
354 struct location_funcs dwarf2_locexpr_funcs
= {
355 locexpr_read_variable
,
356 locexpr_read_needs_frame
,
357 locexpr_describe_location
,
358 locexpr_tracepoint_var_ref