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