OSDN Git Service

2003-05-22 Andrew Cagney <cagney@redhat.com>
[pf3gnuchains/pf3gnuchains3x.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 /* A helper function for dealing with location lists.  Given a
44    symbol baton (BATON) and a pc value (PC), find the appropriate
45    location expression, set *LOCEXPR_LENGTH, and return a pointer
46    to the beginning of the expression.  Returns NULL on failure.
47
48    For now, only return the first matching location expression; there
49    can be more than one in the list.  */
50
51 static char *
52 find_location_expression (struct dwarf2_loclist_baton *baton,
53                           size_t *locexpr_length, CORE_ADDR pc)
54 {
55   CORE_ADDR base_address = baton->base_address;
56   CORE_ADDR low, high;
57   char *loc_ptr, *buf_end;
58   unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length;
59   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
60
61   loc_ptr = baton->data;
62   buf_end = baton->data + baton->size;
63
64   while (1)
65     {
66       low = dwarf2_read_address (loc_ptr, buf_end, &length);
67       loc_ptr += length;
68       high = dwarf2_read_address (loc_ptr, buf_end, &length);
69       loc_ptr += length;
70
71       /* An end-of-list entry.  */
72       if (low == 0 && high == 0)
73         return NULL;
74
75       /* A base-address-selection entry.  */
76       if ((low & base_mask) == base_mask)
77         {
78           base_address = high;
79           continue;
80         }
81
82       /* Otherwise, a location expression entry.  */
83       low += base_address;
84       high += base_address;
85
86       length = extract_unsigned_integer (loc_ptr, 2);
87       loc_ptr += 2;
88
89       if (pc >= low && pc < high)
90         {
91           *locexpr_length = length;
92           return loc_ptr;
93         }
94
95       loc_ptr += length;
96     }
97 }
98
99 /* This is the baton used when performing dwarf2 expression
100    evaluation.  */
101 struct dwarf_expr_baton
102 {
103   struct frame_info *frame;
104   struct objfile *objfile;
105 };
106
107 /* Helper functions for dwarf2_evaluate_loc_desc.  */
108
109 /* Using the frame specified in BATON, read register REGNUM.  The lval
110    type will be returned in LVALP, and for lval_memory the register
111    save address will be returned in ADDRP.  */
112 static CORE_ADDR
113 dwarf_expr_read_reg (void *baton, int dwarf_regnum)
114 {
115   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
116   CORE_ADDR result, save_addr;
117   enum lval_type lval_type;
118   char *buf;
119   int optimized, regnum, realnum, regsize;
120
121   regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum);
122   regsize = register_size (current_gdbarch, regnum);
123   buf = (char *) alloca (regsize);
124
125   frame_register (debaton->frame, regnum, &optimized, &lval_type, &save_addr,
126                   &realnum, buf);
127   /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
128      address is always unsigned.  That may or may not be true.  */
129   result = extract_unsigned_integer (buf, regsize);
130
131   return result;
132 }
133
134 /* Read memory at ADDR (length LEN) into BUF.  */
135
136 static void
137 dwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
138 {
139   read_memory (addr, buf, len);
140 }
141
142 /* Using the frame specified in BATON, find the location expression
143    describing the frame base.  Return a pointer to it in START and
144    its length in LENGTH.  */
145 static void
146 dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length)
147 {
148   /* FIXME: cagney/2003-03-26: This code should be using
149      get_frame_base_address(), and then implement a dwarf2 specific
150      this_base method.  */
151   struct symbol *framefunc;
152   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
153
154   framefunc = get_frame_function (debaton->frame);
155
156   if (SYMBOL_LOCATION_FUNCS (framefunc) == &dwarf2_loclist_funcs)
157     {
158       struct dwarf2_loclist_baton *symbaton;
159       symbaton = SYMBOL_LOCATION_BATON (framefunc);
160       *start = find_location_expression (symbaton, length,
161                                          get_frame_pc (debaton->frame));
162     }
163   else
164     {
165       struct dwarf2_locexpr_baton *symbaton;
166       symbaton = SYMBOL_LOCATION_BATON (framefunc);
167       *length = symbaton->size;
168       *start = symbaton->data;
169     }
170
171   if (*start == NULL)
172     error ("Could not find the frame base for \"%s\".",
173            SYMBOL_NATURAL_NAME (framefunc));
174 }
175
176 /* Using the objfile specified in BATON, find the address for the
177    current thread's thread-local storage with offset OFFSET.  */
178 static CORE_ADDR
179 dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
180 {
181   struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
182   CORE_ADDR addr;
183
184   if (target_get_thread_local_address_p ())
185     addr = target_get_thread_local_address (inferior_ptid,
186                                             debaton->objfile,
187                                             offset);
188   else
189     error ("Cannot find thread-local variables on this target");
190
191   return addr;
192 }
193
194 /* Evaluate a location description, starting at DATA and with length
195    SIZE, to find the current location of variable VAR in the context
196    of FRAME.  */
197 static struct value *
198 dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
199                           unsigned char *data, unsigned short size,
200                           struct objfile *objfile)
201 {
202   CORE_ADDR result;
203   struct value *retval;
204   struct dwarf_expr_baton baton;
205   struct dwarf_expr_context *ctx;
206
207   if (size == 0)
208     {
209       retval = allocate_value (SYMBOL_TYPE (var));
210       VALUE_LVAL (retval) = not_lval;
211       VALUE_OPTIMIZED_OUT (retval) = 1;
212     }
213
214   baton.frame = frame;
215   baton.objfile = objfile;
216
217   ctx = new_dwarf_expr_context ();
218   ctx->baton = &baton;
219   ctx->read_reg = dwarf_expr_read_reg;
220   ctx->read_mem = dwarf_expr_read_mem;
221   ctx->get_frame_base = dwarf_expr_frame_base;
222   ctx->get_tls_address = dwarf_expr_tls_address;
223
224   dwarf_expr_eval (ctx, data, size);
225   result = dwarf_expr_fetch (ctx, 0);
226
227   if (ctx->in_reg)
228     {
229       int regnum = DWARF2_REG_TO_REGNUM (result);
230       retval = value_from_register (SYMBOL_TYPE (var), regnum, frame);
231     }
232   else
233     {
234       retval = allocate_value (SYMBOL_TYPE (var));
235       VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var);
236
237       VALUE_LVAL (retval) = lval_memory;
238       VALUE_LAZY (retval) = 1;
239       VALUE_ADDRESS (retval) = result;
240     }
241
242   free_dwarf_expr_context (ctx);
243
244   return retval;
245 }
246
247
248
249
250 \f
251 /* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
252
253 struct needs_frame_baton
254 {
255   int needs_frame;
256 };
257
258 /* Reads from registers do require a frame.  */
259 static CORE_ADDR
260 needs_frame_read_reg (void *baton, int regnum)
261 {
262   struct needs_frame_baton *nf_baton = baton;
263   nf_baton->needs_frame = 1;
264   return 1;
265 }
266
267 /* Reads from memory do not require a frame.  */
268 static void
269 needs_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
270 {
271   memset (buf, 0, len);
272 }
273
274 /* Frame-relative accesses do require a frame.  */
275 static void
276 needs_frame_frame_base (void *baton, unsigned char **start, size_t * length)
277 {
278   static char lit0 = DW_OP_lit0;
279   struct needs_frame_baton *nf_baton = baton;
280
281   *start = &lit0;
282   *length = 1;
283
284   nf_baton->needs_frame = 1;
285 }
286
287 /* Thread-local accesses do require a frame.  */
288 static CORE_ADDR
289 needs_frame_tls_address (void *baton, CORE_ADDR offset)
290 {
291   struct needs_frame_baton *nf_baton = baton;
292   nf_baton->needs_frame = 1;
293   return 1;
294 }
295
296 /* Return non-zero iff the location expression at DATA (length SIZE)
297    requires a frame to evaluate.  */
298
299 static int
300 dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
301 {
302   struct needs_frame_baton baton;
303   struct dwarf_expr_context *ctx;
304
305   baton.needs_frame = 0;
306
307   ctx = new_dwarf_expr_context ();
308   ctx->baton = &baton;
309   ctx->read_reg = needs_frame_read_reg;
310   ctx->read_mem = needs_frame_read_mem;
311   ctx->get_frame_base = needs_frame_frame_base;
312   ctx->get_tls_address = needs_frame_tls_address;
313
314   dwarf_expr_eval (ctx, data, size);
315
316   free_dwarf_expr_context (ctx);
317
318   return baton.needs_frame;
319 }
320
321 static void
322 dwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
323                            struct axs_value * value, unsigned char *data,
324                            int size)
325 {
326   if (size == 0)
327     error ("Symbol \"%s\" has been optimized out.",
328            SYMBOL_PRINT_NAME (symbol));
329
330   if (size == 1
331       && data[0] >= DW_OP_reg0
332       && data[0] <= DW_OP_reg31)
333     {
334       value->kind = axs_lvalue_register;
335       value->u.reg = data[0] - DW_OP_reg0;
336     }
337   else if (data[0] == DW_OP_regx)
338     {
339       ULONGEST reg;
340       read_uleb128 (data + 1, data + size, &reg);
341       value->kind = axs_lvalue_register;
342       value->u.reg = reg;
343     }
344   else if (data[0] == DW_OP_fbreg)
345     {
346       /* And this is worse than just minimal; we should honor the frame base
347          as above.  */
348       int frame_reg;
349       LONGEST frame_offset;
350       unsigned char *buf_end;
351
352       buf_end = read_sleb128 (data + 1, data + size, &frame_offset);
353       if (buf_end != data + size)
354         error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
355                SYMBOL_PRINT_NAME (symbol));
356
357       TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
358       ax_reg (ax, frame_reg);
359       ax_const_l (ax, frame_offset);
360       ax_simple (ax, aop_add);
361
362       ax_const_l (ax, frame_offset);
363       ax_simple (ax, aop_add);
364       value->kind = axs_lvalue_memory;
365     }
366   else
367     error ("Unsupported DWARF opcode in the location of \"%s\".",
368            SYMBOL_PRINT_NAME (symbol));
369 }
370 \f
371 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
372    evaluator to calculate the location.  */
373 static struct value *
374 locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
375 {
376   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
377   struct value *val;
378   val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
379                                   dlbaton->objfile);
380
381   return val;
382 }
383
384 /* Return non-zero iff we need a frame to evaluate SYMBOL.  */
385 static int
386 locexpr_read_needs_frame (struct symbol *symbol)
387 {
388   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
389   return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
390 }
391
392 /* Print a natural-language description of SYMBOL to STREAM.  */
393 static int
394 locexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
395 {
396   /* FIXME: be more extensive.  */
397   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
398
399   if (dlbaton->size == 1
400       && dlbaton->data[0] >= DW_OP_reg0
401       && dlbaton->data[0] <= DW_OP_reg31)
402     {
403       int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0);
404       fprintf_filtered (stream,
405                         "a variable in register %s", REGISTER_NAME (regno));
406       return 1;
407     }
408
409   fprintf_filtered (stream,
410                     "a variable with complex or multiple locations (DWARF2)");
411   return 1;
412 }
413
414
415 /* Describe the location of SYMBOL as an agent value in VALUE, generating
416    any necessary bytecode in AX.
417
418    NOTE drow/2003-02-26: This function is extremely minimal, because
419    doing it correctly is extremely complicated and there is no
420    publicly available stub with tracepoint support for me to test
421    against.  When there is one this function should be revisited.  */
422
423 static void
424 locexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
425                             struct axs_value * value)
426 {
427   struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
428
429   dwarf2_tracepoint_var_ref (symbol, ax, value, dlbaton->data, dlbaton->size);
430 }
431
432 /* The set of location functions used with the DWARF-2 expression
433    evaluator.  */
434 struct location_funcs dwarf2_locexpr_funcs = {
435   locexpr_read_variable,
436   locexpr_read_needs_frame,
437   locexpr_describe_location,
438   locexpr_tracepoint_var_ref
439 };
440
441
442 /* Wrapper functions for location lists.  These generally find
443    the appropriate location expression and call something above.  */
444
445 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
446    evaluator to calculate the location.  */
447 static struct value *
448 loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
449 {
450   struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
451   struct value *val;
452   unsigned char *data;
453   size_t size;
454
455   data = find_location_expression (dlbaton, &size,
456                                    frame ? get_frame_pc (frame) : 0);
457   if (data == NULL)
458     error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
459
460   val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile);
461
462   return val;
463 }
464
465 /* Return non-zero iff we need a frame to evaluate SYMBOL.  */
466 static int
467 loclist_read_needs_frame (struct symbol *symbol)
468 {
469   /* If there's a location list, then assume we need to have a frame
470      to choose the appropriate location expression.  With tracking of
471      global variables this is not necessarily true, but such tracking
472      is disabled in GCC at the moment until we figure out how to
473      represent it.  */
474
475   return 1;
476 }
477
478 /* Print a natural-language description of SYMBOL to STREAM.  */
479 static int
480 loclist_describe_location (struct symbol *symbol, struct ui_file *stream)
481 {
482   /* FIXME: Could print the entire list of locations.  */
483   fprintf_filtered (stream, "a variable with multiple locations");
484   return 1;
485 }
486
487 /* Describe the location of SYMBOL as an agent value in VALUE, generating
488    any necessary bytecode in AX.  */
489 static void
490 loclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
491                             struct axs_value * value)
492 {
493   struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
494   unsigned char *data;
495   size_t size;
496
497   data = find_location_expression (dlbaton, &size, ax->scope);
498   if (data == NULL)
499     error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
500
501   dwarf2_tracepoint_var_ref (symbol, ax, value, data, size);
502 }
503
504 /* The set of location functions used with the DWARF-2 expression
505    evaluator and location lists.  */
506 struct location_funcs dwarf2_loclist_funcs = {
507   loclist_read_variable,
508   loclist_read_needs_frame,
509   loclist_describe_location,
510   loclist_tracepoint_var_ref
511 };