static int
dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size)
{
  struct needs_frame_baton baton;
  struct dwarf_expr_context *ctx;
  int in_reg;

  baton.needs_frame = 0;

  ctx = new_dwarf_expr_context ();
  ctx->baton = &baton;
  ctx->read_reg = needs_frame_read_reg;
  ctx->read_mem = needs_frame_read_mem;
  ctx->get_frame_base = needs_frame_frame_base;
  ctx->get_tls_address = needs_frame_tls_address;

  dwarf_expr_eval (ctx, data, size);

  in_reg = ctx->in_reg;

  if (ctx->num_pieces > 0)
    {
      int i;

      /* If the location has several pieces, and any of them are in
         registers, then we will need a frame to fetch them from.  */
      for (i = 0; i < ctx->num_pieces; i++)
        if (ctx->pieces[i].in_reg)
          in_reg = 1;
    }

  free_dwarf_expr_context (ctx);

  return baton.needs_frame || in_reg;
}
static CORE_ADDR
execute_stack_op (unsigned char *exp, ULONGEST len,
		  struct frame_info *next_frame, CORE_ADDR initial)
{
  struct dwarf_expr_context *ctx;
  CORE_ADDR result;

  ctx = new_dwarf_expr_context ();
  ctx->baton = next_frame;
  ctx->read_reg = read_reg;
  ctx->read_mem = read_mem;
  ctx->get_frame_base = no_get_frame_base;
  ctx->get_tls_address = no_get_tls_address;

  dwarf_expr_push (ctx, initial);
  dwarf_expr_eval (ctx, exp, len);
  result = dwarf_expr_fetch (ctx, 0);

  if (ctx->in_reg)
    result = read_reg (next_frame, result);

  free_dwarf_expr_context (ctx);

  return result;
}
/* Evaluate a location description, starting at DATA and with length
   SIZE, to find the current location of variable VAR in the context
   of FRAME.  */
static struct value *
dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
			  unsigned char *data, unsigned short size,
			  struct objfile *objfile)
{
  CORE_ADDR result;
  struct value *retval;
  struct dwarf_expr_baton baton;
  struct dwarf_expr_context *ctx;

  if (size == 0)
    {
      retval = allocate_value (SYMBOL_TYPE (var));
      VALUE_LVAL (retval) = not_lval;
      VALUE_OPTIMIZED_OUT (retval) = 1;
    }

  baton.frame = frame;
  baton.objfile = objfile;

  ctx = new_dwarf_expr_context ();
  ctx->baton = &baton;
  ctx->read_reg = dwarf_expr_read_reg;
  ctx->read_mem = dwarf_expr_read_mem;
  ctx->get_frame_base = dwarf_expr_frame_base;
  ctx->get_tls_address = dwarf_expr_tls_address;

  dwarf_expr_eval (ctx, data, size);
  result = dwarf_expr_fetch (ctx, 0);

  if (ctx->in_reg)
    {
      int regnum = DWARF2_REG_TO_REGNUM (result);
      retval = value_from_register (SYMBOL_TYPE (var), regnum, frame);
    }
  else
    {
      retval = allocate_value (SYMBOL_TYPE (var));
      VALUE_BFD_SECTION (retval) = SYMBOL_BFD_SECTION (var);

      VALUE_LVAL (retval) = lval_memory;
      VALUE_LAZY (retval) = 1;
      VALUE_ADDRESS (retval) = result;
    }

  free_dwarf_expr_context (ctx);

  return retval;
}
static int
dwarf2_loc_desc_needs_frame (unsigned char *data, unsigned short size)
{
  struct needs_frame_baton baton;
  struct dwarf_expr_context *ctx;
  int in_reg;

  baton.needs_frame = 0;

  ctx = new_dwarf_expr_context ();
  ctx->baton = &baton;
  ctx->read_reg = needs_frame_read_reg;
  ctx->read_mem = needs_frame_read_mem;
  ctx->get_frame_base = needs_frame_frame_base;
  ctx->get_tls_address = needs_frame_tls_address;

  dwarf_expr_eval (ctx, data, size);

  in_reg = ctx->in_reg;

  free_dwarf_expr_context (ctx);

  return baton.needs_frame || in_reg;
}
/* Evaluate a location description, starting at DATA and with length
   SIZE, to find the current location of variable VAR in the context
   of FRAME.  */
static struct value *
dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
			  gdb_byte *data, unsigned short size,
			  struct objfile *objfile)
{
  struct gdbarch *arch = get_frame_arch (frame);
  struct value *retval;
  struct dwarf_expr_baton baton;
  struct dwarf_expr_context *ctx;

  if (size == 0)
    {
      retval = allocate_value (SYMBOL_TYPE (var));
      VALUE_LVAL (retval) = not_lval;
      set_value_optimized_out (retval, 1);
      return retval;
    }

  baton.frame = frame;
  baton.objfile = objfile;

  ctx = new_dwarf_expr_context ();
  ctx->baton = &baton;
  ctx->read_reg = dwarf_expr_read_reg;
  ctx->read_mem = dwarf_expr_read_mem;
  ctx->get_frame_base = dwarf_expr_frame_base;
  ctx->get_tls_address = dwarf_expr_tls_address;

  dwarf_expr_eval (ctx, data, size);
  if (ctx->num_pieces > 0)
    {
      int i;
      long offset = 0;
      bfd_byte *contents;

      retval = allocate_value (SYMBOL_TYPE (var));
      contents = value_contents_raw (retval);
      for (i = 0; i < ctx->num_pieces; i++)
	{
	  struct dwarf_expr_piece *p = &ctx->pieces[i];
	  if (p->in_reg)
	    {
	      bfd_byte regval[MAX_REGISTER_SIZE];
	      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum
				 (arch, p->value);
	      get_frame_register (frame, gdb_regnum, regval);
	      memcpy (contents + offset, regval, p->size);
	    }
	  else /* In memory?  */
	    {
	      read_memory (p->value, contents + offset, p->size);
	    }
	  offset += p->size;
	}
    }
  else if (ctx->in_reg)
    {
      CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0);
      int gdb_regnum = gdbarch_dwarf2_reg_to_regnum
			 (arch, dwarf_regnum);
      retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame);
    }
  else
    {
      CORE_ADDR address = dwarf_expr_fetch (ctx, 0);

      retval = allocate_value (SYMBOL_TYPE (var));
      VALUE_LVAL (retval) = lval_memory;
      set_value_lazy (retval, 1);
      VALUE_ADDRESS (retval) = address;
    }

  set_value_initialized (retval, ctx->initialized);

  free_dwarf_expr_context (ctx);

  return retval;
}