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 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
;
99 /* Using the objfile specified in BATON, find the address for the
100 current thread's thread-local storage with offset OFFSET. */
102 dwarf_expr_tls_address (void *baton
, CORE_ADDR offset
)
104 struct dwarf_expr_baton
*debaton
= (struct dwarf_expr_baton
*) baton
;
107 if (target_get_thread_local_address_p ())
108 addr
= target_get_thread_local_address (inferior_ptid
,
112 error ("Cannot find thread-local variables on this target");
117 /* Evaluate a location description, starting at DATA and with length
118 SIZE, to find the current location of variable VAR in the context
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
)
126 struct value
*retval
;
127 struct dwarf_expr_baton baton
;
128 struct dwarf_expr_context
*ctx
;
131 baton
.objfile
= objfile
;
133 ctx
= new_dwarf_expr_context ();
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
;
140 dwarf_expr_eval (ctx
, data
, size
);
142 retval
= allocate_value (SYMBOL_TYPE (var
));
143 VALUE_BFD_SECTION (retval
) = SYMBOL_BFD_SECTION (var
);
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
;
155 result
= dwarf_expr_fetch (ctx
, 0);
156 VALUE_LVAL (retval
) = lval_memory
;
157 VALUE_LAZY (retval
) = 1;
158 VALUE_ADDRESS (retval
) = result
;
161 free_dwarf_expr_context (ctx
);
170 /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */
172 struct needs_frame_baton
177 /* Reads from registers do require a frame. */
179 needs_frame_read_reg (void *baton
, int regnum
, enum lval_type
*lvalp
,
182 struct needs_frame_baton
*nf_baton
= baton
;
183 nf_baton
->needs_frame
= 1;
187 /* Reads from memory do not require a frame. */
189 needs_frame_read_mem (void *baton
, char *buf
, CORE_ADDR addr
, size_t len
)
191 memset (buf
, 0, len
);
194 /* Frame-relative accesses do require a frame. */
196 needs_frame_frame_base (void *baton
, unsigned char **start
, size_t * length
)
198 static char lit0
= DW_OP_lit0
;
199 struct needs_frame_baton
*nf_baton
= baton
;
204 nf_baton
->needs_frame
= 1;
207 /* Thread-local accesses do require a frame. */
209 needs_frame_tls_address (void *baton
, CORE_ADDR offset
)
211 struct needs_frame_baton
*nf_baton
= baton
;
212 nf_baton
->needs_frame
= 1;
216 /* Return non-zero iff the location expression at DATA (length SIZE)
217 requires a frame to evaluate. */
220 dwarf2_loc_desc_needs_frame (unsigned char *data
, unsigned short size
)
222 struct needs_frame_baton baton
;
223 struct dwarf_expr_context
*ctx
;
225 baton
.needs_frame
= 0;
227 ctx
= new_dwarf_expr_context ();
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
;
234 dwarf_expr_eval (ctx
, data
, size
);
236 free_dwarf_expr_context (ctx
);
238 return baton
.needs_frame
;
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
)
249 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
251 val
= dwarf2_evaluate_loc_desc (symbol
, frame
, dlbaton
->data
, dlbaton
->size
,
257 /* Return non-zero iff we need a frame to evaluate SYMBOL. */
259 locexpr_read_needs_frame (struct symbol
*symbol
)
261 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
262 return dwarf2_loc_desc_needs_frame (dlbaton
->data
, dlbaton
->size
);
265 /* Print a natural-language description of SYMBOL to STREAM. */
267 locexpr_describe_location (struct symbol
*symbol
, struct ui_file
*stream
)
269 /* FIXME: be more extensive. */
270 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
272 if (dlbaton
->size
== 1
273 && dlbaton
->data
[0] >= DW_OP_reg0
274 && dlbaton
->data
[0] <= DW_OP_reg31
)
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
));
282 fprintf_filtered (stream
,
283 "a variable with complex or multiple locations (DWARF2)");
288 /* Describe the location of SYMBOL as an agent value in VALUE, generating
289 any necessary bytecode in AX.
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. */
297 locexpr_tracepoint_var_ref (struct symbol
* symbol
, struct agent_expr
* ax
,
298 struct axs_value
* value
)
300 struct dwarf2_locexpr_baton
*dlbaton
= SYMBOL_LOCATION_BATON (symbol
);
302 if (dlbaton
->size
== 0)
303 error ("Symbol \"%s\" has been optimized out.",
304 SYMBOL_PRINT_NAME (symbol
));
306 if (dlbaton
->size
== 1
307 && dlbaton
->data
[0] >= DW_OP_reg0
308 && dlbaton
->data
[0] <= DW_OP_reg31
)
310 value
->kind
= axs_lvalue_register
;
311 value
->u
.reg
= dlbaton
->data
[0] - DW_OP_reg0
;
313 else if (dlbaton
->data
[0] == DW_OP_regx
)
316 read_uleb128 (dlbaton
->data
+ 1, dlbaton
->data
+ dlbaton
->size
,
318 value
->kind
= axs_lvalue_register
;
321 else if (dlbaton
->data
[0] == DW_OP_fbreg
)
323 /* And this is worse than just minimal; we should honor the frame base
326 LONGEST frame_offset
;
327 unsigned char *buf_end
;
329 buf_end
= read_sleb128 (dlbaton
->data
+ 1, dlbaton
->data
+ dlbaton
->size
,
331 if (buf_end
!= dlbaton
->data
+ dlbaton
->size
)
332 error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
333 SYMBOL_PRINT_NAME (symbol
));
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
);
340 ax_const_l (ax
, frame_offset
);
341 ax_simple (ax
, aop_add
);
342 value
->kind
= axs_lvalue_memory
;
345 error ("Unsupported DWARF opcode in the location of \"%s\".",
346 SYMBOL_PRINT_NAME (symbol
));
349 /* The set of location functions used with the DWARF-2 expression
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