1130803Smarcel/* DWARF 2 location expression support for GDB.
2130803Smarcel   Copyright 2003 Free Software Foundation, Inc.
3130803Smarcel   Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
4130803Smarcel
5130803Smarcel   This file is part of GDB.
6130803Smarcel
7130803Smarcel   This program is free software; you can redistribute it and/or modify
8130803Smarcel   it under the terms of the GNU General Public License as published by
9130803Smarcel   the Free Software Foundation; either version 2 of the License, or (at
10130803Smarcel   your option) any later version.
11130803Smarcel
12130803Smarcel   This program is distributed in the hope that it will be useful, but
13130803Smarcel   WITHOUT ANY WARRANTY; without even the implied warranty of
14130803Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15130803Smarcel   General Public License for more details.
16130803Smarcel
17130803Smarcel   You should have received a copy of the GNU General Public License
18130803Smarcel   along with this program; if not, write to the Free Software
19130803Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
20130803Smarcel   Boston, MA 02111-1307, USA.  */
21130803Smarcel
22130803Smarcel#include "defs.h"
23130803Smarcel#include "ui-out.h"
24130803Smarcel#include "value.h"
25130803Smarcel#include "frame.h"
26130803Smarcel#include "gdbcore.h"
27130803Smarcel#include "target.h"
28130803Smarcel#include "inferior.h"
29130803Smarcel#include "ax.h"
30130803Smarcel#include "ax-gdb.h"
31130803Smarcel#include "regcache.h"
32130803Smarcel#include "objfiles.h"
33130803Smarcel
34130803Smarcel#include "elf/dwarf2.h"
35130803Smarcel#include "dwarf2expr.h"
36130803Smarcel#include "dwarf2loc.h"
37130803Smarcel
38130803Smarcel#include "gdb_string.h"
39130803Smarcel
40130803Smarcel#ifndef DWARF2_REG_TO_REGNUM
41130803Smarcel#define DWARF2_REG_TO_REGNUM(REG) (REG)
42130803Smarcel#endif
43130803Smarcel
44130803Smarcel/* A helper function for dealing with location lists.  Given a
45130803Smarcel   symbol baton (BATON) and a pc value (PC), find the appropriate
46130803Smarcel   location expression, set *LOCEXPR_LENGTH, and return a pointer
47130803Smarcel   to the beginning of the expression.  Returns NULL on failure.
48130803Smarcel
49130803Smarcel   For now, only return the first matching location expression; there
50130803Smarcel   can be more than one in the list.  */
51130803Smarcel
52130803Smarcelstatic char *
53130803Smarcelfind_location_expression (struct dwarf2_loclist_baton *baton,
54130803Smarcel			  size_t *locexpr_length, CORE_ADDR pc)
55130803Smarcel{
56130803Smarcel  CORE_ADDR low, high;
57130803Smarcel  char *loc_ptr, *buf_end;
58130803Smarcel  unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length;
59130803Smarcel  CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
60130803Smarcel  /* Adjust base_address for relocatable objects.  */
61130803Smarcel  CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
62130803Smarcel				    SECT_OFF_TEXT (baton->objfile));
63130803Smarcel  CORE_ADDR base_address = baton->base_address + base_offset;
64130803Smarcel
65130803Smarcel  loc_ptr = baton->data;
66130803Smarcel  buf_end = baton->data + baton->size;
67130803Smarcel
68130803Smarcel  while (1)
69130803Smarcel    {
70130803Smarcel      low = dwarf2_read_address (loc_ptr, buf_end, &length);
71130803Smarcel      loc_ptr += length;
72130803Smarcel      high = dwarf2_read_address (loc_ptr, buf_end, &length);
73130803Smarcel      loc_ptr += length;
74130803Smarcel
75130803Smarcel      /* An end-of-list entry.  */
76130803Smarcel      if (low == 0 && high == 0)
77130803Smarcel	return NULL;
78130803Smarcel
79130803Smarcel      /* A base-address-selection entry.  */
80130803Smarcel      if ((low & base_mask) == base_mask)
81130803Smarcel	{
82130803Smarcel	  base_address = high;
83130803Smarcel	  continue;
84130803Smarcel	}
85130803Smarcel
86130803Smarcel      /* Otherwise, a location expression entry.  */
87130803Smarcel      low += base_address;
88130803Smarcel      high += base_address;
89130803Smarcel
90130803Smarcel      length = extract_unsigned_integer (loc_ptr, 2);
91130803Smarcel      loc_ptr += 2;
92130803Smarcel
93130803Smarcel      if (pc >= low && pc < high)
94130803Smarcel	{
95130803Smarcel	  *locexpr_length = length;
96130803Smarcel	  return loc_ptr;
97130803Smarcel	}
98130803Smarcel
99130803Smarcel      loc_ptr += length;
100130803Smarcel    }
101130803Smarcel}
102130803Smarcel
103130803Smarcel/* This is the baton used when performing dwarf2 expression
104130803Smarcel   evaluation.  */
105130803Smarcelstruct dwarf_expr_baton
106130803Smarcel{
107130803Smarcel  struct frame_info *frame;
108130803Smarcel  struct objfile *objfile;
109130803Smarcel};
110130803Smarcel
111130803Smarcel/* Helper functions for dwarf2_evaluate_loc_desc.  */
112130803Smarcel
113130803Smarcel/* Using the frame specified in BATON, read register REGNUM.  The lval
114130803Smarcel   type will be returned in LVALP, and for lval_memory the register
115130803Smarcel   save address will be returned in ADDRP.  */
116130803Smarcelstatic CORE_ADDR
117130803Smarceldwarf_expr_read_reg (void *baton, int dwarf_regnum)
118130803Smarcel{
119130803Smarcel  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
120130803Smarcel  CORE_ADDR result, save_addr;
121130803Smarcel  enum lval_type lval_type;
122130803Smarcel  char *buf;
123130803Smarcel  int optimized, regnum, realnum, regsize;
124130803Smarcel
125130803Smarcel  regnum = DWARF2_REG_TO_REGNUM (dwarf_regnum);
126130803Smarcel  regsize = register_size (current_gdbarch, regnum);
127130803Smarcel  buf = (char *) alloca (regsize);
128130803Smarcel
129130803Smarcel  frame_register (debaton->frame, regnum, &optimized, &lval_type, &save_addr,
130130803Smarcel		  &realnum, buf);
131130803Smarcel  /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
132130803Smarcel     address is always unsigned.  That may or may not be true.  */
133130803Smarcel  result = extract_unsigned_integer (buf, regsize);
134130803Smarcel
135130803Smarcel  return result;
136130803Smarcel}
137130803Smarcel
138130803Smarcel/* Read memory at ADDR (length LEN) into BUF.  */
139130803Smarcel
140130803Smarcelstatic void
141130803Smarceldwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
142130803Smarcel{
143130803Smarcel  read_memory (addr, buf, len);
144130803Smarcel}
145130803Smarcel
146130803Smarcel/* Using the frame specified in BATON, find the location expression
147130803Smarcel   describing the frame base.  Return a pointer to it in START and
148130803Smarcel   its length in LENGTH.  */
149130803Smarcelstatic void
150130803Smarceldwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length)
151130803Smarcel{
152130803Smarcel  /* FIXME: cagney/2003-03-26: This code should be using
153130803Smarcel     get_frame_base_address(), and then implement a dwarf2 specific
154130803Smarcel     this_base method.  */
155130803Smarcel  struct symbol *framefunc;
156130803Smarcel  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
157130803Smarcel
158130803Smarcel  framefunc = get_frame_function (debaton->frame);
159130803Smarcel
160130803Smarcel  if (SYMBOL_OPS (framefunc) == &dwarf2_loclist_funcs)
161130803Smarcel    {
162130803Smarcel      struct dwarf2_loclist_baton *symbaton;
163130803Smarcel      symbaton = SYMBOL_LOCATION_BATON (framefunc);
164130803Smarcel      *start = find_location_expression (symbaton, length,
165130803Smarcel					 get_frame_pc (debaton->frame));
166130803Smarcel    }
167130803Smarcel  else
168130803Smarcel    {
169130803Smarcel      struct dwarf2_locexpr_baton *symbaton;
170130803Smarcel      symbaton = SYMBOL_LOCATION_BATON (framefunc);
171130803Smarcel      *length = symbaton->size;
172130803Smarcel      *start = symbaton->data;
173130803Smarcel    }
174130803Smarcel
175130803Smarcel  if (*start == NULL)
176130803Smarcel    error ("Could not find the frame base for \"%s\".",
177130803Smarcel	   SYMBOL_NATURAL_NAME (framefunc));
178130803Smarcel}
179130803Smarcel
180130803Smarcel/* Using the objfile specified in BATON, find the address for the
181130803Smarcel   current thread's thread-local storage with offset OFFSET.  */
182130803Smarcelstatic CORE_ADDR
183130803Smarceldwarf_expr_tls_address (void *baton, CORE_ADDR offset)
184130803Smarcel{
185130803Smarcel  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
186130803Smarcel  CORE_ADDR addr;
187130803Smarcel
188130803Smarcel  if (target_get_thread_local_address_p ())
189130803Smarcel    addr = target_get_thread_local_address (inferior_ptid,
190130803Smarcel					    debaton->objfile,
191130803Smarcel					    offset);
192130803Smarcel  /* It wouldn't be wrong here to try a gdbarch method, too; finding
193130803Smarcel     TLS is an ABI-specific thing.  But we don't do that yet.  */
194130803Smarcel  else
195130803Smarcel    error ("Cannot find thread-local variables on this target");
196130803Smarcel
197130803Smarcel  return addr;
198130803Smarcel}
199130803Smarcel
200130803Smarcel/* Evaluate a location description, starting at DATA and with length
201130803Smarcel   SIZE, to find the current location of variable VAR in the context
202130803Smarcel   of FRAME.  */
203130803Smarcelstatic struct value *
204130803Smarceldwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
205130803Smarcel			  unsigned char *data, unsigned short size,
206130803Smarcel			  struct objfile *objfile)
207130803Smarcel{
208130803Smarcel  CORE_ADDR result;
209130803Smarcel  struct value *retval;
210130803Smarcel  struct dwarf_expr_baton baton;
211130803Smarcel  struct dwarf_expr_context *ctx;
212130803Smarcel
213130803Smarcel  if (size == 0)
214130803Smarcel    {
215130803Smarcel      retval = allocate_value (SYMBOL_TYPE (var));
216130803Smarcel      VALUE_LVAL (retval) = not_lval;
217130803Smarcel      VALUE_OPTIMIZED_OUT (retval) = 1;
218130803Smarcel    }
219130803Smarcel
220130803Smarcel  baton.frame = frame;
221130803Smarcel  baton.objfile = objfile;
222130803Smarcel
223130803Smarcel  ctx = new_dwarf_expr_context ();
224130803Smarcel  ctx->baton = &baton;
225130803Smarcel  ctx->read_reg = dwarf_expr_read_reg;
226130803Smarcel  ctx->read_mem = dwarf_expr_read_mem;
227130803Smarcel  ctx->get_frame_base = dwarf_expr_frame_base;
228130803Smarcel  ctx->get_tls_address = dwarf_expr_tls_address;
229130803Smarcel
230130803Smarcel  dwarf_expr_eval (ctx, data, size);
231130803Smarcel  result = dwarf_expr_fetch (ctx, 0);
232130803Smarcel
233130803Smarcel  if (ctx->in_reg)
234130803Smarcel    {
235130803Smarcel      int regnum = DWARF2_REG_TO_REGNUM (result);
236130803Smarcel      retval = value_from_register (SYMBOL_TYPE (var), regnum, frame);
237130803Smarcel    }
238130803Smarcel  else
239130803Smarcel    {
240130803Smarcel      retval = allocate_value (SYMBOL_TYPE (var));
241130803Smarcel      VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var);
242130803Smarcel
243130803Smarcel      VALUE_LVAL (retval) = lval_memory;
244130803Smarcel      VALUE_LAZY (retval) = 1;
245130803Smarcel      VALUE_ADDRESS (retval) = result;
246130803Smarcel    }
247130803Smarcel
248130803Smarcel  free_dwarf_expr_context (ctx);
249130803Smarcel
250130803Smarcel  return retval;
251130803Smarcel}
252130803Smarcel
253130803Smarcel
254130803Smarcel
255130803Smarcel
256130803Smarcel
257130803Smarcel/* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */
258130803Smarcel
259130803Smarcelstruct needs_frame_baton
260130803Smarcel{
261130803Smarcel  int needs_frame;
262130803Smarcel};
263130803Smarcel
264130803Smarcel/* Reads from registers do require a frame.  */
265130803Smarcelstatic CORE_ADDR
266130803Smarcelneeds_frame_read_reg (void *baton, int regnum)
267130803Smarcel{
268130803Smarcel  struct needs_frame_baton *nf_baton = baton;
269130803Smarcel  nf_baton->needs_frame = 1;
270130803Smarcel  return 1;
271130803Smarcel}
272130803Smarcel
273130803Smarcel/* Reads from memory do not require a frame.  */
274130803Smarcelstatic void
275130803Smarcelneeds_frame_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
276130803Smarcel{
277130803Smarcel  memset (buf, 0, len);
278130803Smarcel}
279130803Smarcel
280130803Smarcel/* Frame-relative accesses do require a frame.  */
281130803Smarcelstatic void
282130803Smarcelneeds_frame_frame_base (void *baton, unsigned char **start, size_t * length)
283130803Smarcel{
284130803Smarcel  static char lit0 = DW_OP_lit0;
285130803Smarcel  struct needs_frame_baton *nf_baton = baton;
286130803Smarcel
287130803Smarcel  *start = &lit0;
288130803Smarcel  *length = 1;
289130803Smarcel
290130803Smarcel  nf_baton->needs_frame = 1;
291130803Smarcel}
292130803Smarcel
293130803Smarcel/* Thread-local accesses do require a frame.  */
294130803Smarcelstatic CORE_ADDR
295130803Smarcelneeds_frame_tls_address (void *baton, CORE_ADDR offset)
296130803Smarcel{
297130803Smarcel  struct needs_frame_baton *nf_baton = baton;
298130803Smarcel  nf_baton->needs_frame = 1;
299130803Smarcel  return 1;
300130803Smarcel}
301130803Smarcel
302130803Smarcel/* Return non-zero iff the location expression at DATA (length SIZE)
303130803Smarcel   requires a frame to evaluate.  */
304130803Smarcel
305130803Smarcelstatic int
306130803Smarceldwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
307130803Smarcel{
308130803Smarcel  struct needs_frame_baton baton;
309130803Smarcel  struct dwarf_expr_context *ctx;
310130803Smarcel  int in_reg;
311130803Smarcel
312130803Smarcel  baton.needs_frame = 0;
313130803Smarcel
314130803Smarcel  ctx = new_dwarf_expr_context ();
315130803Smarcel  ctx->baton = &baton;
316130803Smarcel  ctx->read_reg = needs_frame_read_reg;
317130803Smarcel  ctx->read_mem = needs_frame_read_mem;
318130803Smarcel  ctx->get_frame_base = needs_frame_frame_base;
319130803Smarcel  ctx->get_tls_address = needs_frame_tls_address;
320130803Smarcel
321130803Smarcel  dwarf_expr_eval (ctx, data, size);
322130803Smarcel
323130803Smarcel  in_reg = ctx->in_reg;
324130803Smarcel
325130803Smarcel  free_dwarf_expr_context (ctx);
326130803Smarcel
327130803Smarcel  return baton.needs_frame || in_reg;
328130803Smarcel}
329130803Smarcel
330130803Smarcelstatic void
331130803Smarceldwarf2_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
332130803Smarcel			   struct axs_value * value, unsigned char *data,
333130803Smarcel			   int size)
334130803Smarcel{
335130803Smarcel  if (size == 0)
336130803Smarcel    error ("Symbol \"%s\" has been optimized out.",
337130803Smarcel	   SYMBOL_PRINT_NAME (symbol));
338130803Smarcel
339130803Smarcel  if (size == 1
340130803Smarcel      && data[0] >= DW_OP_reg0
341130803Smarcel      && data[0] <= DW_OP_reg31)
342130803Smarcel    {
343130803Smarcel      value->kind = axs_lvalue_register;
344130803Smarcel      value->u.reg = data[0] - DW_OP_reg0;
345130803Smarcel    }
346130803Smarcel  else if (data[0] == DW_OP_regx)
347130803Smarcel    {
348130803Smarcel      ULONGEST reg;
349130803Smarcel      read_uleb128 (data + 1, data + size, &reg);
350130803Smarcel      value->kind = axs_lvalue_register;
351130803Smarcel      value->u.reg = reg;
352130803Smarcel    }
353130803Smarcel  else if (data[0] == DW_OP_fbreg)
354130803Smarcel    {
355130803Smarcel      /* And this is worse than just minimal; we should honor the frame base
356130803Smarcel	 as above.  */
357130803Smarcel      int frame_reg;
358130803Smarcel      LONGEST frame_offset;
359130803Smarcel      unsigned char *buf_end;
360130803Smarcel
361130803Smarcel      buf_end = read_sleb128 (data + 1, data + size, &frame_offset);
362130803Smarcel      if (buf_end != data + size)
363130803Smarcel	error ("Unexpected opcode after DW_OP_fbreg for symbol \"%s\".",
364130803Smarcel	       SYMBOL_PRINT_NAME (symbol));
365130803Smarcel
366130803Smarcel      TARGET_VIRTUAL_FRAME_POINTER (ax->scope, &frame_reg, &frame_offset);
367130803Smarcel      ax_reg (ax, frame_reg);
368130803Smarcel      ax_const_l (ax, frame_offset);
369130803Smarcel      ax_simple (ax, aop_add);
370130803Smarcel
371130803Smarcel      ax_const_l (ax, frame_offset);
372130803Smarcel      ax_simple (ax, aop_add);
373130803Smarcel      value->kind = axs_lvalue_memory;
374130803Smarcel    }
375130803Smarcel  else
376130803Smarcel    error ("Unsupported DWARF opcode in the location of \"%s\".",
377130803Smarcel	   SYMBOL_PRINT_NAME (symbol));
378130803Smarcel}
379130803Smarcel
380130803Smarcel/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
381130803Smarcel   evaluator to calculate the location.  */
382130803Smarcelstatic struct value *
383130803Smarcellocexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
384130803Smarcel{
385130803Smarcel  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
386130803Smarcel  struct value *val;
387130803Smarcel  val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
388130803Smarcel				  dlbaton->objfile);
389130803Smarcel
390130803Smarcel  return val;
391130803Smarcel}
392130803Smarcel
393130803Smarcel/* Return non-zero iff we need a frame to evaluate SYMBOL.  */
394130803Smarcelstatic int
395130803Smarcellocexpr_read_needs_frame (struct symbol *symbol)
396130803Smarcel{
397130803Smarcel  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
398130803Smarcel  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size);
399130803Smarcel}
400130803Smarcel
401130803Smarcel/* Print a natural-language description of SYMBOL to STREAM.  */
402130803Smarcelstatic int
403130803Smarcellocexpr_describe_location (struct symbol *symbol, struct ui_file *stream)
404130803Smarcel{
405130803Smarcel  /* FIXME: be more extensive.  */
406130803Smarcel  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
407130803Smarcel
408130803Smarcel  if (dlbaton->size == 1
409130803Smarcel      && dlbaton->data[0] >= DW_OP_reg0
410130803Smarcel      && dlbaton->data[0] <= DW_OP_reg31)
411130803Smarcel    {
412130803Smarcel      int regno = DWARF2_REG_TO_REGNUM (dlbaton->data[0] - DW_OP_reg0);
413130803Smarcel      fprintf_filtered (stream,
414130803Smarcel			"a variable in register %s", REGISTER_NAME (regno));
415130803Smarcel      return 1;
416130803Smarcel    }
417130803Smarcel
418130803Smarcel  /* The location expression for a TLS variable looks like this (on a
419130803Smarcel     64-bit LE machine):
420130803Smarcel
421130803Smarcel     DW_AT_location    : 10 byte block: 3 4 0 0 0 0 0 0 0 e0
422130803Smarcel                        (DW_OP_addr: 4; DW_OP_GNU_push_tls_address)
423130803Smarcel
424130803Smarcel     0x3 is the encoding for DW_OP_addr, which has an operand as long
425130803Smarcel     as the size of an address on the target machine (here is 8
426130803Smarcel     bytes).  0xe0 is the encoding for DW_OP_GNU_push_tls_address.
427130803Smarcel     The operand represents the offset at which the variable is within
428130803Smarcel     the thread local storage.  */
429130803Smarcel
430130803Smarcel  if (dlbaton->size > 1
431130803Smarcel      && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
432130803Smarcel    if (dlbaton->data[0] == DW_OP_addr)
433130803Smarcel      {
434130803Smarcel	int bytes_read;
435130803Smarcel	CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
436130803Smarcel						&dlbaton->data[dlbaton->size - 1],
437130803Smarcel						&bytes_read);
438130803Smarcel	fprintf_filtered (stream,
439130803Smarcel			  "a thread-local variable at offset %s in the "
440130803Smarcel			  "thread-local storage for `%s'",
441130803Smarcel			  paddr_nz (offset), dlbaton->objfile->name);
442130803Smarcel	return 1;
443130803Smarcel      }
444130803Smarcel
445130803Smarcel
446130803Smarcel  fprintf_filtered (stream,
447130803Smarcel		    "a variable with complex or multiple locations (DWARF2)");
448130803Smarcel  return 1;
449130803Smarcel}
450130803Smarcel
451130803Smarcel
452130803Smarcel/* Describe the location of SYMBOL as an agent value in VALUE, generating
453130803Smarcel   any necessary bytecode in AX.
454130803Smarcel
455130803Smarcel   NOTE drow/2003-02-26: This function is extremely minimal, because
456130803Smarcel   doing it correctly is extremely complicated and there is no
457130803Smarcel   publicly available stub with tracepoint support for me to test
458130803Smarcel   against.  When there is one this function should be revisited.  */
459130803Smarcel
460130803Smarcelstatic void
461130803Smarcellocexpr_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
462130803Smarcel			    struct axs_value * value)
463130803Smarcel{
464130803Smarcel  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
465130803Smarcel
466130803Smarcel  dwarf2_tracepoint_var_ref (symbol, ax, value, dlbaton->data, dlbaton->size);
467130803Smarcel}
468130803Smarcel
469130803Smarcel/* The set of location functions used with the DWARF-2 expression
470130803Smarcel   evaluator.  */
471130803Smarcelconst struct symbol_ops dwarf2_locexpr_funcs = {
472130803Smarcel  locexpr_read_variable,
473130803Smarcel  locexpr_read_needs_frame,
474130803Smarcel  locexpr_describe_location,
475130803Smarcel  locexpr_tracepoint_var_ref
476130803Smarcel};
477130803Smarcel
478130803Smarcel
479130803Smarcel/* Wrapper functions for location lists.  These generally find
480130803Smarcel   the appropriate location expression and call something above.  */
481130803Smarcel
482130803Smarcel/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
483130803Smarcel   evaluator to calculate the location.  */
484130803Smarcelstatic struct value *
485130803Smarcelloclist_read_variable (struct symbol *symbol, struct frame_info *frame)
486130803Smarcel{
487130803Smarcel  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
488130803Smarcel  struct value *val;
489130803Smarcel  unsigned char *data;
490130803Smarcel  size_t size;
491130803Smarcel
492130803Smarcel  data = find_location_expression (dlbaton, &size,
493130803Smarcel				   frame ? get_frame_pc (frame) : 0);
494130803Smarcel  if (data == NULL)
495242936Semaste    {
496242936Semaste      val = allocate_value (SYMBOL_TYPE (symbol));
497242936Semaste      VALUE_LVAL (val) = not_lval;
498242936Semaste      VALUE_OPTIMIZED_OUT (val) = 1;
499242936Semaste    }
500242936Semaste  else
501242936Semaste    val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
502242936Semaste				    dlbaton->objfile);
503130803Smarcel
504130803Smarcel  return val;
505130803Smarcel}
506130803Smarcel
507130803Smarcel/* Return non-zero iff we need a frame to evaluate SYMBOL.  */
508130803Smarcelstatic int
509130803Smarcelloclist_read_needs_frame (struct symbol *symbol)
510130803Smarcel{
511130803Smarcel  /* If there's a location list, then assume we need to have a frame
512130803Smarcel     to choose the appropriate location expression.  With tracking of
513130803Smarcel     global variables this is not necessarily true, but such tracking
514130803Smarcel     is disabled in GCC at the moment until we figure out how to
515130803Smarcel     represent it.  */
516130803Smarcel
517130803Smarcel  return 1;
518130803Smarcel}
519130803Smarcel
520130803Smarcel/* Print a natural-language description of SYMBOL to STREAM.  */
521130803Smarcelstatic int
522130803Smarcelloclist_describe_location (struct symbol *symbol, struct ui_file *stream)
523130803Smarcel{
524130803Smarcel  /* FIXME: Could print the entire list of locations.  */
525130803Smarcel  fprintf_filtered (stream, "a variable with multiple locations");
526130803Smarcel  return 1;
527130803Smarcel}
528130803Smarcel
529130803Smarcel/* Describe the location of SYMBOL as an agent value in VALUE, generating
530130803Smarcel   any necessary bytecode in AX.  */
531130803Smarcelstatic void
532130803Smarcelloclist_tracepoint_var_ref (struct symbol * symbol, struct agent_expr * ax,
533130803Smarcel			    struct axs_value * value)
534130803Smarcel{
535130803Smarcel  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
536130803Smarcel  unsigned char *data;
537130803Smarcel  size_t size;
538130803Smarcel
539130803Smarcel  data = find_location_expression (dlbaton, &size, ax->scope);
540130803Smarcel  if (data == NULL)
541130803Smarcel    error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
542130803Smarcel
543130803Smarcel  dwarf2_tracepoint_var_ref (symbol, ax, value, data, size);
544130803Smarcel}
545130803Smarcel
546130803Smarcel/* The set of location functions used with the DWARF-2 expression
547130803Smarcel   evaluator and location lists.  */
548130803Smarcelconst struct symbol_ops dwarf2_loclist_funcs = {
549130803Smarcel  loclist_read_variable,
550130803Smarcel  loclist_read_needs_frame,
551130803Smarcel  loclist_describe_location,
552130803Smarcel  loclist_tracepoint_var_ref
553130803Smarcel};
554