/* DWARF 2 location expression support for GDB.

   Copyright (C) 2003, 2005, 2007, 2008, 2009, 2010
   Free Software Foundation, Inc.

   Contributed by Daniel Jacobowitz, MontaVista Software, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "ui-out.h"
#include "value.h"
#include "frame.h"
#include "gdbcore.h"
#include "target.h"
#include "inferior.h"
#include "ax.h"
#include "ax-gdb.h"
#include "regcache.h"
#include "objfiles.h"
#include "exceptions.h"
#include "block.h"

#include "dwarf2.h"
#include "dwarf2expr.h"
#include "dwarf2loc.h"
#include "dwarf2-frame.h"

#include "gdb_string.h"
#include "gdb_assert.h"

extern int dwarf2_always_disassemble;

static void
dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
			 const gdb_byte **start, size_t *length);

/* A helper function for dealing with location lists.  Given a
   symbol baton (BATON) and a pc value (PC), find the appropriate
   location expression, set *LOCEXPR_LENGTH, and return a pointer
   to the beginning of the expression.  Returns NULL on failure.

   For now, only return the first matching location expression; there
   can be more than one in the list.  */

static const gdb_byte *
find_location_expression (struct dwarf2_loclist_baton *baton,
			  size_t *locexpr_length, CORE_ADDR pc)
{
  CORE_ADDR low, high;
  const gdb_byte *loc_ptr, *buf_end;
  int length;
  struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
  int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
  CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
  /* Adjust base_address for relocatable objects.  */
  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
				    SECT_OFF_TEXT (objfile));
  CORE_ADDR base_address = baton->base_address + base_offset;

  loc_ptr = baton->data;
  buf_end = baton->data + baton->size;

  while (1)
    {
      if (buf_end - loc_ptr < 2 * addr_size)
	error (_("find_location_expression: Corrupted DWARF expression."));

      if (signed_addr_p)
	low = extract_signed_integer (loc_ptr, addr_size, byte_order);
      else
	low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
      loc_ptr += addr_size;

      if (signed_addr_p)
	high = extract_signed_integer (loc_ptr, addr_size, byte_order);
      else
	high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
      loc_ptr += addr_size;

      /* A base-address-selection entry.  */
      if ((low & base_mask) == base_mask)
	{
	  base_address = high + base_offset;
	  continue;
	}

      /* An end-of-list entry.  */
      if (low == 0 && high == 0)
	return NULL;

      /* Otherwise, a location expression entry.  */
      low += base_address;
      high += base_address;

      length = extract_unsigned_integer (loc_ptr, 2, byte_order);
      loc_ptr += 2;

      if (pc >= low && pc < high)
	{
	  *locexpr_length = length;
	  return loc_ptr;
	}

      loc_ptr += length;
    }
}

/* This is the baton used when performing dwarf2 expression
   evaluation.  */
struct dwarf_expr_baton
{
  struct frame_info *frame;
  struct dwarf2_per_cu_data *per_cu;
};

/* Helper functions for dwarf2_evaluate_loc_desc.  */

/* Using the frame specified in BATON, return the value of register
   REGNUM, treated as a pointer.  */
static CORE_ADDR
dwarf_expr_read_reg (void *baton, int dwarf_regnum)
{
  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
  struct gdbarch *gdbarch = get_frame_arch (debaton->frame);
  CORE_ADDR result;
  int regnum;

  regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, dwarf_regnum);
  result = address_from_register (builtin_type (gdbarch)->builtin_data_ptr,
				  regnum, debaton->frame);
  return result;
}

/* Read memory at ADDR (length LEN) into BUF.  */

static void
dwarf_expr_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
{
  read_memory (addr, buf, len);
}

/* Using the frame specified in BATON, find the location expression
   describing the frame base.  Return a pointer to it in START and
   its length in LENGTH.  */
static void
dwarf_expr_frame_base (void *baton, const gdb_byte **start, size_t * length)
{
  /* FIXME: cagney/2003-03-26: This code should be using
     get_frame_base_address(), and then implement a dwarf2 specific
     this_base method.  */
  struct symbol *framefunc;
  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;

  /* Use block_linkage_function, which returns a real (not inlined)
     function, instead of get_frame_function, which may return an
     inlined function.  */
  framefunc = block_linkage_function (get_frame_block (debaton->frame, NULL));

  /* If we found a frame-relative symbol then it was certainly within
     some function associated with a frame. If we can't find the frame,
     something has gone wrong.  */
  gdb_assert (framefunc != NULL);

  dwarf_expr_frame_base_1 (framefunc,
			   get_frame_address_in_block (debaton->frame),
			   start, length);
}

static void
dwarf_expr_frame_base_1 (struct symbol *framefunc, CORE_ADDR pc,
			 const gdb_byte **start, size_t *length)
{
  if (SYMBOL_LOCATION_BATON (framefunc) == NULL)
    *start = NULL;
  else if (SYMBOL_COMPUTED_OPS (framefunc) == &dwarf2_loclist_funcs)
    {
      struct dwarf2_loclist_baton *symbaton;

      symbaton = SYMBOL_LOCATION_BATON (framefunc);
      *start = find_location_expression (symbaton, length, pc);
    }
  else
    {
      struct dwarf2_locexpr_baton *symbaton;

      symbaton = SYMBOL_LOCATION_BATON (framefunc);
      if (symbaton != NULL)
	{
	  *length = symbaton->size;
	  *start = symbaton->data;
	}
      else
	*start = NULL;
    }

  if (*start == NULL)
    error (_("Could not find the frame base for \"%s\"."),
	   SYMBOL_NATURAL_NAME (framefunc));
}

/* Helper function for dwarf2_evaluate_loc_desc.  Computes the CFA for
   the frame in BATON.  */

static CORE_ADDR
dwarf_expr_frame_cfa (void *baton)
{
  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;

  return dwarf2_frame_cfa (debaton->frame);
}

/* Using the objfile specified in BATON, find the address for the
   current thread's thread-local storage with offset OFFSET.  */
static CORE_ADDR
dwarf_expr_tls_address (void *baton, CORE_ADDR offset)
{
  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
  struct objfile *objfile = dwarf2_per_cu_objfile (debaton->per_cu);

  return target_translate_tls_address (objfile, offset);
}

/* Call DWARF subroutine from DW_AT_location of DIE at DIE_OFFSET in current CU
   (as is PER_CU).  State of the CTX is not affected by the call and return.  */

static void
per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset,
		   struct dwarf2_per_cu_data *per_cu)
{
  struct dwarf2_locexpr_baton block;

  block = dwarf2_fetch_die_location_block (die_offset, per_cu);

  /* DW_OP_call_ref is currently not supported.  */
  gdb_assert (block.per_cu == per_cu);

  dwarf_expr_eval (ctx, block.data, block.size);
}

/* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc.  */

static void
dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
{
  struct dwarf_expr_baton *debaton = ctx->baton;

  return per_cu_dwarf_call (ctx, die_offset, debaton->per_cu);
}

struct piece_closure
{
  /* Reference count.  */
  int refc;

  /* The number of pieces used to describe this variable.  */
  int n_pieces;

  /* The target address size, used only for DWARF_VALUE_STACK.  */
  int addr_size;

  /* The pieces themselves.  */
  struct dwarf_expr_piece *pieces;
};

/* Allocate a closure for a value formed from separately-described
   PIECES.  */

static struct piece_closure *
allocate_piece_closure (int n_pieces, struct dwarf_expr_piece *pieces,
			int addr_size)
{
  struct piece_closure *c = XZALLOC (struct piece_closure);

  c->refc = 1;
  c->n_pieces = n_pieces;
  c->addr_size = addr_size;
  c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);

  memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));

  return c;
}

/* The lowest-level function to extract bits from a byte buffer.
   SOURCE is the buffer.  It is updated if we read to the end of a
   byte.
   SOURCE_OFFSET_BITS is the offset of the first bit to read.  It is
   updated to reflect the number of bits actually read.
   NBITS is the number of bits we want to read.  It is updated to
   reflect the number of bits actually read.  This function may read
   fewer bits.
   BITS_BIG_ENDIAN is taken directly from gdbarch.
   This function returns the extracted bits.  */

static unsigned int
extract_bits_primitive (const gdb_byte **source,
			unsigned int *source_offset_bits,
			int *nbits, int bits_big_endian)
{
  unsigned int avail, mask, datum;

  gdb_assert (*source_offset_bits < 8);

  avail = 8 - *source_offset_bits;
  if (avail > *nbits)
    avail = *nbits;

  mask = (1 << avail) - 1;
  datum = **source;
  if (bits_big_endian)
    datum >>= 8 - (*source_offset_bits + *nbits);
  else
    datum >>= *source_offset_bits;
  datum &= mask;

  *nbits -= avail;
  *source_offset_bits += avail;
  if (*source_offset_bits >= 8)
    {
      *source_offset_bits -= 8;
      ++*source;
    }

  return datum;
}

/* Extract some bits from a source buffer and move forward in the
   buffer.
   
   SOURCE is the source buffer.  It is updated as bytes are read.
   SOURCE_OFFSET_BITS is the offset into SOURCE.  It is updated as
   bits are read.
   NBITS is the number of bits to read.
   BITS_BIG_ENDIAN is taken directly from gdbarch.
   
   This function returns the bits that were read.  */

static unsigned int
extract_bits (const gdb_byte **source, unsigned int *source_offset_bits,
	      int nbits, int bits_big_endian)
{
  unsigned int datum;

  gdb_assert (nbits > 0 && nbits <= 8);

  datum = extract_bits_primitive (source, source_offset_bits, &nbits,
				  bits_big_endian);
  if (nbits > 0)
    {
      unsigned int more;

      more = extract_bits_primitive (source, source_offset_bits, &nbits,
				     bits_big_endian);
      if (bits_big_endian)
	datum <<= nbits;
      else
	more <<= nbits;
      datum |= more;
    }

  return datum;
}

/* Write some bits into a buffer and move forward in the buffer.
   
   DATUM is the bits to write.  The low-order bits of DATUM are used.
   DEST is the destination buffer.  It is updated as bytes are
   written.
   DEST_OFFSET_BITS is the bit offset in DEST at which writing is
   done.
   NBITS is the number of valid bits in DATUM.
   BITS_BIG_ENDIAN is taken directly from gdbarch.  */

static void
insert_bits (unsigned int datum,
	     gdb_byte *dest, unsigned int dest_offset_bits,
	     int nbits, int bits_big_endian)
{
  unsigned int mask;

  gdb_assert (dest_offset_bits >= 0 && dest_offset_bits + nbits <= 8);

  mask = (1 << nbits) - 1;
  if (bits_big_endian)
    {
      datum <<= 8 - (dest_offset_bits + nbits);
      mask <<= 8 - (dest_offset_bits + nbits);
    }
  else
    {
      datum <<= dest_offset_bits;
      mask <<= dest_offset_bits;
    }

  gdb_assert ((datum & ~mask) == 0);

  *dest = (*dest & ~mask) | datum;
}

/* Copy bits from a source to a destination.
   
   DEST is where the bits should be written.
   DEST_OFFSET_BITS is the bit offset into DEST.
   SOURCE is the source of bits.
   SOURCE_OFFSET_BITS is the bit offset into SOURCE.
   BIT_COUNT is the number of bits to copy.
   BITS_BIG_ENDIAN is taken directly from gdbarch.  */

static void
copy_bitwise (gdb_byte *dest, unsigned int dest_offset_bits,
	      const gdb_byte *source, unsigned int source_offset_bits,
	      unsigned int bit_count,
	      int bits_big_endian)
{
  unsigned int dest_avail;
  int datum;

  /* Reduce everything to byte-size pieces.  */
  dest += dest_offset_bits / 8;
  dest_offset_bits %= 8;
  source += source_offset_bits / 8;
  source_offset_bits %= 8;

  dest_avail = 8 - dest_offset_bits % 8;

  /* See if we can fill the first destination byte.  */
  if (dest_avail < bit_count)
    {
      datum = extract_bits (&source, &source_offset_bits, dest_avail,
			    bits_big_endian);
      insert_bits (datum, dest, dest_offset_bits, dest_avail, bits_big_endian);
      ++dest;
      dest_offset_bits = 0;
      bit_count -= dest_avail;
    }

  /* Now, either DEST_OFFSET_BITS is byte-aligned, or we have fewer
     than 8 bits remaining.  */
  gdb_assert (dest_offset_bits % 8 == 0 || bit_count < 8);
  for (; bit_count >= 8; bit_count -= 8)
    {
      datum = extract_bits (&source, &source_offset_bits, 8, bits_big_endian);
      *dest++ = (gdb_byte) datum;
    }

  /* Finally, we may have a few leftover bits.  */
  gdb_assert (bit_count <= 8 - dest_offset_bits % 8);
  if (bit_count > 0)
    {
      datum = extract_bits (&source, &source_offset_bits, bit_count,
			    bits_big_endian);
      insert_bits (datum, dest, dest_offset_bits, bit_count, bits_big_endian);
    }
}

static void
read_pieced_value (struct value *v)
{
  int i;
  long offset = 0;
  ULONGEST bits_to_skip;
  gdb_byte *contents;
  struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
  struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v));
  size_t type_len;
  size_t buffer_size = 0;
  char *buffer = NULL;
  struct cleanup *cleanup;
  int bits_big_endian
    = gdbarch_bits_big_endian (get_type_arch (value_type (v)));

  if (value_type (v) != value_enclosing_type (v))
    internal_error (__FILE__, __LINE__,
		    _("Should not be able to create a lazy value with "
		      "an enclosing type"));

  cleanup = make_cleanup (free_current_contents, &buffer);

  contents = value_contents_raw (v);
  bits_to_skip = 8 * value_offset (v);
  if (value_bitsize (v))
    {
      bits_to_skip += value_bitpos (v);
      type_len = value_bitsize (v);
    }
  else
    type_len = 8 * TYPE_LENGTH (value_type (v));

  for (i = 0; i < c->n_pieces && offset < type_len; i++)
    {
      struct dwarf_expr_piece *p = &c->pieces[i];
      size_t this_size, this_size_bits;
      long dest_offset_bits, source_offset_bits, source_offset;
      const gdb_byte *intermediate_buffer;

      /* Compute size, source, and destination offsets for copying, in
	 bits.  */
      this_size_bits = p->size;
      if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
	{
	  bits_to_skip -= this_size_bits;
	  continue;
	}
      if (this_size_bits > type_len - offset)
	this_size_bits = type_len - offset;
      if (bits_to_skip > 0)
	{
	  dest_offset_bits = 0;
	  source_offset_bits = bits_to_skip;
	  this_size_bits -= bits_to_skip;
	  bits_to_skip = 0;
	}
      else
	{
	  dest_offset_bits = offset;
	  source_offset_bits = 0;
	}

      this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
      source_offset = source_offset_bits / 8;
      if (buffer_size < this_size)
	{
	  buffer_size = this_size;
	  buffer = xrealloc (buffer, buffer_size);
	}
      intermediate_buffer = buffer;

      /* Copy from the source to DEST_BUFFER.  */
      switch (p->location)
	{
	case DWARF_VALUE_REGISTER:
	  {
	    struct gdbarch *arch = get_frame_arch (frame);
	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
	    int reg_offset = source_offset;

	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
		&& this_size < register_size (arch, gdb_regnum))
	      {
		/* Big-endian, and we want less than full size.  */
		reg_offset = register_size (arch, gdb_regnum) - this_size;
		/* We want the lower-order THIS_SIZE_BITS of the bytes
		   we extract from the register.  */
		source_offset_bits += 8 * this_size - this_size_bits;
	      }

	    if (gdb_regnum != -1)
	      {
		get_frame_register_bytes (frame, gdb_regnum, reg_offset, 
					  this_size, buffer);
	      }
	    else
	      {
		error (_("Unable to access DWARF register number %s"),
		       paddress (arch, p->v.value));
	      }
	  }
	  break;

	case DWARF_VALUE_MEMORY:
	  if (p->v.mem.in_stack_memory)
	    read_stack (p->v.mem.addr + source_offset, buffer, this_size);
	  else
	    read_memory (p->v.mem.addr + source_offset, buffer, this_size);
	  break;

	case DWARF_VALUE_STACK:
	  {
	    struct gdbarch *gdbarch = get_type_arch (value_type (v));
	    size_t n = this_size;

	    if (n > c->addr_size - source_offset)
	      n = (c->addr_size >= source_offset
		   ? c->addr_size - source_offset
		   : 0);
	    if (n == 0)
	      {
		/* Nothing.  */
	      }
	    else if (source_offset == 0)
	      store_unsigned_integer (buffer, n,
				      gdbarch_byte_order (gdbarch),
				      p->v.value);
	    else
	      {
		gdb_byte bytes[sizeof (ULONGEST)];

		store_unsigned_integer (bytes, n + source_offset,
					gdbarch_byte_order (gdbarch),
					p->v.value);
		memcpy (buffer, bytes + source_offset, n);
	      }
	  }
	  break;

	case DWARF_VALUE_LITERAL:
	  {
	    size_t n = this_size;

	    if (n > p->v.literal.length - source_offset)
	      n = (p->v.literal.length >= source_offset
		   ? p->v.literal.length - source_offset
		   : 0);
	    if (n != 0)
	      intermediate_buffer = p->v.literal.data + source_offset;
	  }
	  break;

	case DWARF_VALUE_OPTIMIZED_OUT:
	  set_value_optimized_out (v, 1);
	  break;

	default:
	  internal_error (__FILE__, __LINE__, _("invalid location type"));
	}

      if (p->location != DWARF_VALUE_OPTIMIZED_OUT)
	copy_bitwise (contents, dest_offset_bits,
		      intermediate_buffer, source_offset_bits % 8,
		      this_size_bits, bits_big_endian);

      offset += this_size_bits;
    }

  do_cleanups (cleanup);
}

static void
write_pieced_value (struct value *to, struct value *from)
{
  int i;
  long offset = 0;
  ULONGEST bits_to_skip;
  const gdb_byte *contents;
  struct piece_closure *c = (struct piece_closure *) value_computed_closure (to);
  struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to));
  size_t type_len;
  size_t buffer_size = 0;
  char *buffer = NULL;
  struct cleanup *cleanup;
  int bits_big_endian
    = gdbarch_bits_big_endian (get_type_arch (value_type (to)));

  if (frame == NULL)
    {
      set_value_optimized_out (to, 1);
      return;
    }

  cleanup = make_cleanup (free_current_contents, &buffer);

  contents = value_contents (from);
  bits_to_skip = 8 * value_offset (to);
  if (value_bitsize (to))
    {
      bits_to_skip += value_bitpos (to);
      type_len = value_bitsize (to);
    }
  else
    type_len = 8 * TYPE_LENGTH (value_type (to));

  for (i = 0; i < c->n_pieces && offset < type_len; i++)
    {
      struct dwarf_expr_piece *p = &c->pieces[i];
      size_t this_size_bits, this_size;
      long dest_offset_bits, source_offset_bits, dest_offset, source_offset;
      int need_bitwise;
      const gdb_byte *source_buffer;

      this_size_bits = p->size;
      if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
	{
	  bits_to_skip -= this_size_bits;
	  continue;
	}
      if (this_size_bits > type_len - offset)
	this_size_bits = type_len - offset;
      if (bits_to_skip > 0)
	{
	  dest_offset_bits = bits_to_skip;
	  source_offset_bits = 0;
	  this_size_bits -= bits_to_skip;
	  bits_to_skip = 0;
	}
      else
	{
	  dest_offset_bits = 0;
	  source_offset_bits = offset;
	}

      this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
      source_offset = source_offset_bits / 8;
      dest_offset = dest_offset_bits / 8;
      if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0)
	{
	  source_buffer = contents + source_offset;
	  need_bitwise = 0;
	}
      else
	{
	  if (buffer_size < this_size)
	    {
	      buffer_size = this_size;
	      buffer = xrealloc (buffer, buffer_size);
	    }
	  source_buffer = buffer;
	  need_bitwise = 1;
	}

      switch (p->location)
	{
	case DWARF_VALUE_REGISTER:
	  {
	    struct gdbarch *arch = get_frame_arch (frame);
	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
	    int reg_offset = dest_offset;

	    if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
		&& this_size <= register_size (arch, gdb_regnum))
	      /* Big-endian, and we want less than full size.  */
	      reg_offset = register_size (arch, gdb_regnum) - this_size;

	    if (gdb_regnum != -1)
	      {
		if (need_bitwise)
		  {
		    get_frame_register_bytes (frame, gdb_regnum, reg_offset,
					      this_size, buffer);
		    copy_bitwise (buffer, dest_offset_bits,
				  contents, source_offset_bits,
				  this_size_bits,
				  bits_big_endian);
		  }

		put_frame_register_bytes (frame, gdb_regnum, reg_offset, 
					  this_size, source_buffer);
	      }
	    else
	      {
		error (_("Unable to write to DWARF register number %s"),
		       paddress (arch, p->v.value));
	      }
	  }
	  break;
	case DWARF_VALUE_MEMORY:
	  if (need_bitwise)
	    {
	      /* Only the first and last bytes can possibly have any
		 bits reused.  */
	      read_memory (p->v.mem.addr + dest_offset, buffer, 1);
	      read_memory (p->v.mem.addr + dest_offset + this_size - 1,
			   buffer + this_size - 1, 1);
	      copy_bitwise (buffer, dest_offset_bits,
			    contents, source_offset_bits,
			    this_size_bits,
			    bits_big_endian);
	    }

	  write_memory (p->v.mem.addr + dest_offset,
			source_buffer, this_size);
	  break;
	default:
	  set_value_optimized_out (to, 1);
	  break;
	}
      offset += this_size_bits;
    }

  do_cleanups (cleanup);
}

static int
check_pieced_value_bits (const struct value *value, int bit_offset,
			 int bit_length, int validity)
{
  struct piece_closure *c
    = (struct piece_closure *) value_computed_closure (value);
  int i;

  bit_offset += 8 * value_offset (value);
  if (value_bitsize (value))
    bit_offset += value_bitpos (value);

  for (i = 0; i < c->n_pieces && bit_length > 0; i++)
    {
      struct dwarf_expr_piece *p = &c->pieces[i];
      size_t this_size_bits = p->size;

      if (bit_offset > 0)
	{
	  if (bit_offset >= this_size_bits)
	    {
	      bit_offset -= this_size_bits;
	      continue;
	    }

	  bit_length -= this_size_bits - bit_offset;
	  bit_offset = 0;
	}
      else
	bit_length -= this_size_bits;

      if (p->location == DWARF_VALUE_OPTIMIZED_OUT)
	{
	  if (validity)
	    return 0;
	}
      else
	{
	  if (!validity)
	    return 1;
	}
    }

  return validity;
}

static int
check_pieced_value_validity (const struct value *value, int bit_offset,
			     int bit_length)
{
  return check_pieced_value_bits (value, bit_offset, bit_length, 1);
}

static int
check_pieced_value_invalid (const struct value *value)
{
  return check_pieced_value_bits (value, 0,
				  8 * TYPE_LENGTH (value_type (value)), 0);
}

static void *
copy_pieced_value_closure (const struct value *v)
{
  struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
  
  ++c->refc;
  return c;
}

static void
free_pieced_value_closure (struct value *v)
{
  struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);

  --c->refc;
  if (c->refc == 0)
    {
      xfree (c->pieces);
      xfree (c);
    }
}

/* Functions for accessing a variable described by DW_OP_piece.  */
static struct lval_funcs pieced_value_funcs = {
  read_pieced_value,
  write_pieced_value,
  check_pieced_value_validity,
  check_pieced_value_invalid,
  copy_pieced_value_closure,
  free_pieced_value_closure
};

/* Evaluate a location description, starting at DATA and with length
   SIZE, to find the current location of variable of TYPE in the context
   of FRAME.  */

static struct value *
dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
			  const gdb_byte *data, unsigned short size,
			  struct dwarf2_per_cu_data *per_cu)
{
  struct value *retval;
  struct dwarf_expr_baton baton;
  struct dwarf_expr_context *ctx;
  struct cleanup *old_chain;

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

  baton.frame = frame;
  baton.per_cu = per_cu;

  ctx = new_dwarf_expr_context ();
  old_chain = make_cleanup_free_dwarf_expr_context (ctx);

  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
  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_frame_cfa = dwarf_expr_frame_cfa;
  ctx->get_tls_address = dwarf_expr_tls_address;
  ctx->dwarf_call = dwarf_expr_dwarf_call;

  dwarf_expr_eval (ctx, data, size);
  if (ctx->num_pieces > 0)
    {
      struct piece_closure *c;
      struct frame_id frame_id = get_frame_id (frame);

      c = allocate_piece_closure (ctx->num_pieces, ctx->pieces,
				  ctx->addr_size);
      retval = allocate_computed_value (type, &pieced_value_funcs, c);
      VALUE_FRAME_ID (retval) = frame_id;
    }
  else
    {
      switch (ctx->location)
	{
	case DWARF_VALUE_REGISTER:
	  {
	    struct gdbarch *arch = get_frame_arch (frame);
	    ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
	    int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);

	    if (gdb_regnum != -1)
	      retval = value_from_register (type, gdb_regnum, frame);
	    else
	      error (_("Unable to access DWARF register number %s"),
		     paddress (arch, dwarf_regnum));
	  }
	  break;

	case DWARF_VALUE_MEMORY:
	  {
	    CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
	    int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);

	    retval = allocate_value (type);
	    VALUE_LVAL (retval) = lval_memory;
	    set_value_lazy (retval, 1);
	    if (in_stack_memory)
	      set_value_stack (retval, 1);
	    set_value_address (retval, address);
	  }
	  break;

	case DWARF_VALUE_STACK:
	  {
	    ULONGEST value = dwarf_expr_fetch (ctx, 0);
	    bfd_byte *contents;
	    size_t n = ctx->addr_size;

	    retval = allocate_value (type);
	    contents = value_contents_raw (retval);
	    if (n > TYPE_LENGTH (type))
	      n = TYPE_LENGTH (type);
	    store_unsigned_integer (contents, n,
				    gdbarch_byte_order (ctx->gdbarch),
				    value);
	  }
	  break;

	case DWARF_VALUE_LITERAL:
	  {
	    bfd_byte *contents;
	    size_t n = ctx->len;

	    retval = allocate_value (type);
	    contents = value_contents_raw (retval);
	    if (n > TYPE_LENGTH (type))
	      n = TYPE_LENGTH (type);
	    memcpy (contents, ctx->data, n);
	  }
	  break;

	  /* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context --
	     it can only be encountered when making a piece.  */
	case DWARF_VALUE_OPTIMIZED_OUT:
	default:
	  internal_error (__FILE__, __LINE__, _("invalid location type"));
	}
    }

  set_value_initialized (retval, ctx->initialized);

  do_cleanups (old_chain);

  return retval;
}

/* Helper functions and baton for dwarf2_loc_desc_needs_frame.  */

struct needs_frame_baton
{
  int needs_frame;
  struct dwarf2_per_cu_data *per_cu;
};

/* Reads from registers do require a frame.  */
static CORE_ADDR
needs_frame_read_reg (void *baton, int regnum)
{
  struct needs_frame_baton *nf_baton = baton;

  nf_baton->needs_frame = 1;
  return 1;
}

/* Reads from memory do not require a frame.  */
static void
needs_frame_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, size_t len)
{
  memset (buf, 0, len);
}

/* Frame-relative accesses do require a frame.  */
static void
needs_frame_frame_base (void *baton, const gdb_byte **start, size_t * length)
{
  static gdb_byte lit0 = DW_OP_lit0;
  struct needs_frame_baton *nf_baton = baton;

  *start = &lit0;
  *length = 1;

  nf_baton->needs_frame = 1;
}

/* CFA accesses require a frame.  */

static CORE_ADDR
needs_frame_frame_cfa (void *baton)
{
  struct needs_frame_baton *nf_baton = baton;

  nf_baton->needs_frame = 1;
  return 1;
}

/* Thread-local accesses do require a frame.  */
static CORE_ADDR
needs_frame_tls_address (void *baton, CORE_ADDR offset)
{
  struct needs_frame_baton *nf_baton = baton;

  nf_baton->needs_frame = 1;
  return 1;
}

/* Helper interface of per_cu_dwarf_call for dwarf2_loc_desc_needs_frame.  */

static void
needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
{
  struct needs_frame_baton *nf_baton = ctx->baton;

  return per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu);
}

/* Return non-zero iff the location expression at DATA (length SIZE)
   requires a frame to evaluate.  */

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

  baton.needs_frame = 0;
  baton.per_cu = per_cu;

  ctx = new_dwarf_expr_context ();
  old_chain = make_cleanup_free_dwarf_expr_context (ctx);

  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
  ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
  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_frame_cfa = needs_frame_frame_cfa;
  ctx->get_tls_address = needs_frame_tls_address;
  ctx->dwarf_call = needs_frame_dwarf_call;

  dwarf_expr_eval (ctx, data, size);

  in_reg = ctx->location == DWARF_VALUE_REGISTER;

  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].location == DWARF_VALUE_REGISTER)
          in_reg = 1;
    }

  do_cleanups (old_chain);

  return baton.needs_frame || in_reg;
}

/* A helper function that throws an unimplemented error mentioning a
   given DWARF operator.  */

static void
unimplemented (unsigned int op)
{
  error (_("DWARF operator %s cannot be translated to an agent expression"),
	 dwarf_stack_op_name (op, 1));
}

/* A helper function to convert a DWARF register to an arch register.
   ARCH is the architecture.
   DWARF_REG is the register.
   This will throw an exception if the DWARF register cannot be
   translated to an architecture register.  */

static int
translate_register (struct gdbarch *arch, int dwarf_reg)
{
  int reg = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_reg);
  if (reg == -1)
    error (_("Unable to access DWARF register number %d"), dwarf_reg);
  return reg;
}

/* A helper function that emits an access to memory.  ARCH is the
   target architecture.  EXPR is the expression which we are building.
   NBITS is the number of bits we want to read.  This emits the
   opcodes needed to read the memory and then extract the desired
   bits.  */

static void
access_memory (struct gdbarch *arch, struct agent_expr *expr, ULONGEST nbits)
{
  ULONGEST nbytes = (nbits + 7) / 8;

  gdb_assert (nbits > 0 && nbits <= sizeof (LONGEST));

  if (trace_kludge)
    ax_trace_quick (expr, nbytes);

  if (nbits <= 8)
    ax_simple (expr, aop_ref8);
  else if (nbits <= 16)
    ax_simple (expr, aop_ref16);
  else if (nbits <= 32)
    ax_simple (expr, aop_ref32);
  else
    ax_simple (expr, aop_ref64);

  /* If we read exactly the number of bytes we wanted, we're done.  */
  if (8 * nbytes == nbits)
    return;

  if (gdbarch_bits_big_endian (arch))
    {
      /* On a bits-big-endian machine, we want the high-order
	 NBITS.  */
      ax_const_l (expr, 8 * nbytes - nbits);
      ax_simple (expr, aop_rsh_unsigned);
    }
  else
    {
      /* On a bits-little-endian box, we want the low-order NBITS.  */
      ax_zero_ext (expr, nbits);
    }
}

/* Compile a DWARF location expression to an agent expression.
   
   EXPR is the agent expression we are building.
   LOC is the agent value we modify.
   ARCH is the architecture.
   ADDR_SIZE is the size of addresses, in bytes.
   OP_PTR is the start of the location expression.
   OP_END is one past the last byte of the location expression.
   
   This will throw an exception for various kinds of errors -- for
   example, if the expression cannot be compiled, or if the expression
   is invalid.  */

static void
compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc,
		     struct gdbarch *arch, unsigned int addr_size,
		     const gdb_byte *op_ptr, const gdb_byte *op_end,
		     struct dwarf2_per_cu_data *per_cu)
{
  struct cleanup *cleanups;
  int i, *offsets;
  VEC(int) *dw_labels = NULL, *patches = NULL;
  const gdb_byte * const base = op_ptr;
  const gdb_byte *previous_piece = op_ptr;
  enum bfd_endian byte_order = gdbarch_byte_order (arch);
  ULONGEST bits_collected = 0;
  unsigned int addr_size_bits = 8 * addr_size;
  int bits_big_endian = gdbarch_bits_big_endian (arch);

  offsets = xmalloc ((op_end - op_ptr) * sizeof (int));
  cleanups = make_cleanup (xfree, offsets);

  for (i = 0; i < op_end - op_ptr; ++i)
    offsets[i] = -1;

  make_cleanup (VEC_cleanup (int), &dw_labels);
  make_cleanup (VEC_cleanup (int), &patches);

  /* By default we are making an address.  */
  loc->kind = axs_lvalue_memory;

  while (op_ptr < op_end)
    {
      enum dwarf_location_atom op = *op_ptr;
      ULONGEST uoffset, reg;
      LONGEST offset;
      int i;

      offsets[op_ptr - base] = expr->len;
      ++op_ptr;

      /* Our basic approach to code generation is to map DWARF
	 operations directly to AX operations.  However, there are
	 some differences.

	 First, DWARF works on address-sized units, but AX always uses
	 LONGEST.  For most operations we simply ignore this
	 difference; instead we generate sign extensions as needed
	 before division and comparison operations.  It would be nice
	 to omit the sign extensions, but there is no way to determine
	 the size of the target's LONGEST.  (This code uses the size
	 of the host LONGEST in some cases -- that is a bug but it is
	 difficult to fix.)

	 Second, some DWARF operations cannot be translated to AX.
	 For these we simply fail.  See
	 http://sourceware.org/bugzilla/show_bug.cgi?id=11662.  */
      switch (op)
	{
	case DW_OP_lit0:
	case DW_OP_lit1:
	case DW_OP_lit2:
	case DW_OP_lit3:
	case DW_OP_lit4:
	case DW_OP_lit5:
	case DW_OP_lit6:
	case DW_OP_lit7:
	case DW_OP_lit8:
	case DW_OP_lit9:
	case DW_OP_lit10:
	case DW_OP_lit11:
	case DW_OP_lit12:
	case DW_OP_lit13:
	case DW_OP_lit14:
	case DW_OP_lit15:
	case DW_OP_lit16:
	case DW_OP_lit17:
	case DW_OP_lit18:
	case DW_OP_lit19:
	case DW_OP_lit20:
	case DW_OP_lit21:
	case DW_OP_lit22:
	case DW_OP_lit23:
	case DW_OP_lit24:
	case DW_OP_lit25:
	case DW_OP_lit26:
	case DW_OP_lit27:
	case DW_OP_lit28:
	case DW_OP_lit29:
	case DW_OP_lit30:
	case DW_OP_lit31:
	  ax_const_l (expr, op - DW_OP_lit0);
	  break;

	case DW_OP_addr:
	  ax_const_l (expr, extract_unsigned_integer (op_ptr,
						      addr_size, byte_order));
	  op_ptr += addr_size;
	  break;

	case DW_OP_const1u:
	  ax_const_l (expr, extract_unsigned_integer (op_ptr, 1, byte_order));
	  op_ptr += 1;
	  break;
	case DW_OP_const1s:
	  ax_const_l (expr, extract_signed_integer (op_ptr, 1, byte_order));
	  op_ptr += 1;
	  break;
	case DW_OP_const2u:
	  ax_const_l (expr, extract_unsigned_integer (op_ptr, 2, byte_order));
	  op_ptr += 2;
	  break;
	case DW_OP_const2s:
	  ax_const_l (expr, extract_signed_integer (op_ptr, 2, byte_order));
	  op_ptr += 2;
	  break;
	case DW_OP_const4u:
	  ax_const_l (expr, extract_unsigned_integer (op_ptr, 4, byte_order));
	  op_ptr += 4;
	  break;
	case DW_OP_const4s:
	  ax_const_l (expr, extract_signed_integer (op_ptr, 4, byte_order));
	  op_ptr += 4;
	  break;
	case DW_OP_const8u:
	  ax_const_l (expr, extract_unsigned_integer (op_ptr, 8, byte_order));
	  op_ptr += 8;
	  break;
	case DW_OP_const8s:
	  ax_const_l (expr, extract_signed_integer (op_ptr, 8, byte_order));
	  op_ptr += 8;
	  break;
	case DW_OP_constu:
	  op_ptr = read_uleb128 (op_ptr, op_end, &uoffset);
	  ax_const_l (expr, uoffset);
	  break;
	case DW_OP_consts:
	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
	  ax_const_l (expr, offset);
	  break;

	case DW_OP_reg0:
	case DW_OP_reg1:
	case DW_OP_reg2:
	case DW_OP_reg3:
	case DW_OP_reg4:
	case DW_OP_reg5:
	case DW_OP_reg6:
	case DW_OP_reg7:
	case DW_OP_reg8:
	case DW_OP_reg9:
	case DW_OP_reg10:
	case DW_OP_reg11:
	case DW_OP_reg12:
	case DW_OP_reg13:
	case DW_OP_reg14:
	case DW_OP_reg15:
	case DW_OP_reg16:
	case DW_OP_reg17:
	case DW_OP_reg18:
	case DW_OP_reg19:
	case DW_OP_reg20:
	case DW_OP_reg21:
	case DW_OP_reg22:
	case DW_OP_reg23:
	case DW_OP_reg24:
	case DW_OP_reg25:
	case DW_OP_reg26:
	case DW_OP_reg27:
	case DW_OP_reg28:
	case DW_OP_reg29:
	case DW_OP_reg30:
	case DW_OP_reg31:
	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
	  loc->u.reg = translate_register (arch, op - DW_OP_reg0);
	  loc->kind = axs_lvalue_register;
	  break;

	case DW_OP_regx:
	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_regx");
	  loc->u.reg = translate_register (arch, reg);
	  loc->kind = axs_lvalue_register;
	  break;

	case DW_OP_implicit_value:
	  {
	    ULONGEST len;

	    op_ptr = read_uleb128 (op_ptr, op_end, &len);
	    if (op_ptr + len > op_end)
	      error (_("DW_OP_implicit_value: too few bytes available."));
	    if (len > sizeof (ULONGEST))
	      error (_("Cannot translate DW_OP_implicit_value of %d bytes"),
		     (int) len);

	    ax_const_l (expr, extract_unsigned_integer (op_ptr, len,
							byte_order));
	    op_ptr += len;
	    dwarf_expr_require_composition (op_ptr, op_end,
					    "DW_OP_implicit_value");

	    loc->kind = axs_rvalue;
	  }
	  break;

	case DW_OP_stack_value:
	  dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value");
	  loc->kind = axs_rvalue;
	  break;

	case DW_OP_breg0:
	case DW_OP_breg1:
	case DW_OP_breg2:
	case DW_OP_breg3:
	case DW_OP_breg4:
	case DW_OP_breg5:
	case DW_OP_breg6:
	case DW_OP_breg7:
	case DW_OP_breg8:
	case DW_OP_breg9:
	case DW_OP_breg10:
	case DW_OP_breg11:
	case DW_OP_breg12:
	case DW_OP_breg13:
	case DW_OP_breg14:
	case DW_OP_breg15:
	case DW_OP_breg16:
	case DW_OP_breg17:
	case DW_OP_breg18:
	case DW_OP_breg19:
	case DW_OP_breg20:
	case DW_OP_breg21:
	case DW_OP_breg22:
	case DW_OP_breg23:
	case DW_OP_breg24:
	case DW_OP_breg25:
	case DW_OP_breg26:
	case DW_OP_breg27:
	case DW_OP_breg28:
	case DW_OP_breg29:
	case DW_OP_breg30:
	case DW_OP_breg31:
	  op_ptr = read_sleb128 (op_ptr, op_end, &offset);
	  i = translate_register (arch, op - DW_OP_breg0);
	  ax_reg (expr, i);
	  if (offset != 0)
	    {
	      ax_const_l (expr, offset);
	      ax_simple (expr, aop_add);
	    }
	  break;
	case DW_OP_bregx:
	  {
	    op_ptr = read_uleb128 (op_ptr, op_end, &reg);
	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
	    i = translate_register (arch, reg);
	    ax_reg (expr, i);
	    if (offset != 0)
	      {
		ax_const_l (expr, offset);
		ax_simple (expr, aop_add);
	      }
	  }
	  break;
	case DW_OP_fbreg:
	  {
	    const gdb_byte *datastart;
	    size_t datalen;
	    unsigned int before_stack_len;
	    struct block *b;
	    struct symbol *framefunc;
	    LONGEST base_offset = 0;

	    b = block_for_pc (expr->scope);

	    if (!b)
	      error (_("No block found for address"));

	    framefunc = block_linkage_function (b);

	    if (!framefunc)
	      error (_("No function found for block"));

	    dwarf_expr_frame_base_1 (framefunc, expr->scope,
				     &datastart, &datalen);

	    op_ptr = read_sleb128 (op_ptr, op_end, &offset);
	    compile_dwarf_to_ax (expr, loc, arch, addr_size, datastart,
				 datastart + datalen, per_cu);

	    if (offset != 0)
	      {
		ax_const_l (expr, offset);
		ax_simple (expr, aop_add);
	      }

	    loc->kind = axs_lvalue_memory;
	  }
	  break;

	case DW_OP_dup:
	  ax_simple (expr, aop_dup);
	  break;

	case DW_OP_drop:
	  ax_simple (expr, aop_pop);
	  break;

	case DW_OP_pick:
	  offset = *op_ptr++;
	  unimplemented (op);
	  break;
	  
	case DW_OP_swap:
	  ax_simple (expr, aop_swap);
	  break;

	case DW_OP_over:
	  /* We can't directly support DW_OP_over, but GCC emits it as
	     part of a sequence to implement signed modulus.  As a
	     hack, we recognize this sequence.  Note that if GCC ever
	     generates a branch to the middle of this sequence, then
	     we will die somehow.  */
	  if (op_end - op_ptr >= 4
	      && op_ptr[0] == DW_OP_over
	      && op_ptr[1] == DW_OP_div
	      && op_ptr[2] == DW_OP_mul
	      && op_ptr[3] == DW_OP_minus)
	    {
	      /* Sign extend the operands.  */
	      ax_ext (expr, addr_size_bits);
	      ax_simple (expr, aop_swap);
	      ax_ext (expr, addr_size_bits);
	      ax_simple (expr, aop_swap);
	      ax_simple (expr, aop_rem_signed);
	      op_ptr += 4;
	    }
	  else
	    unimplemented (op);
	  break;

	case DW_OP_rot:
	  unimplemented (op);
	  break;

	case DW_OP_deref:
	case DW_OP_deref_size:
	  {
	    int size;

	    if (op == DW_OP_deref_size)
	      size = *op_ptr++;
	    else
	      size = addr_size;

	    switch (size)
	      {
	      case 8:
		ax_simple (expr, aop_ref8);
		break;
	      case 16:
		ax_simple (expr, aop_ref16);
		break;
	      case 32:
		ax_simple (expr, aop_ref32);
		break;
	      case 64:
		ax_simple (expr, aop_ref64);
		break;
	      default:
		error (_("Unsupported size %d in %s"),
		       size, dwarf_stack_op_name (op, 1));
	      }
	  }
	  break;

	case DW_OP_abs:
	  /* Sign extend the operand.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_dup);
	  ax_const_l (expr, 0);
	  ax_simple (expr, aop_less_signed);
	  ax_simple (expr, aop_log_not);
	  i = ax_goto (expr, aop_if_goto);
	  /* We have to emit 0 - X.  */
	  ax_const_l (expr, 0);
	  ax_simple (expr, aop_swap);
	  ax_simple (expr, aop_sub);
	  ax_label (expr, i, expr->len);
	  break;

	case DW_OP_neg:
	  /* No need to sign extend here.  */
	  ax_const_l (expr, 0);
	  ax_simple (expr, aop_swap);
	  ax_simple (expr, aop_sub);
	  break;

	case DW_OP_not:
	  /* Sign extend the operand.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_bit_not);
	  break;

	case DW_OP_plus_uconst:
	  op_ptr = read_uleb128 (op_ptr, op_end, &reg);
	  /* It would be really weird to emit `DW_OP_plus_uconst 0',
	     but we micro-optimize anyhow.  */
	  if (reg != 0)
	    {
	      ax_const_l (expr, reg);
	      ax_simple (expr, aop_add);
	    }
	  break;

	case DW_OP_and:
	  ax_simple (expr, aop_bit_and);
	  break;

	case DW_OP_div:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_simple (expr, aop_div_signed);
	  break;

	case DW_OP_minus:
	  ax_simple (expr, aop_sub);
	  break;

	case DW_OP_mod:
	  ax_simple (expr, aop_rem_unsigned);
	  break;

	case DW_OP_mul:
	  ax_simple (expr, aop_mul);
	  break;

	case DW_OP_or:
	  ax_simple (expr, aop_bit_or);
	  break;

	case DW_OP_plus:
	  ax_simple (expr, aop_add);
	  break;

	case DW_OP_shl:
	  ax_simple (expr, aop_lsh);
	  break;

	case DW_OP_shr:
	  ax_simple (expr, aop_rsh_unsigned);
	  break;

	case DW_OP_shra:
	  ax_simple (expr, aop_rsh_signed);
	  break;

	case DW_OP_xor:
	  ax_simple (expr, aop_bit_xor);
	  break;

	case DW_OP_le:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  /* Note no swap here: A <= B is !(B < A).  */
	  ax_simple (expr, aop_less_signed);
	  ax_simple (expr, aop_log_not);
	  break;

	case DW_OP_ge:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  /* A >= B is !(A < B).  */
	  ax_simple (expr, aop_less_signed);
	  ax_simple (expr, aop_log_not);
	  break;

	case DW_OP_eq:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  /* No need for a second swap here.  */
	  ax_simple (expr, aop_equal);
	  break;

	case DW_OP_lt:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_simple (expr, aop_less_signed);
	  break;

	case DW_OP_gt:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  /* Note no swap here: A > B is B < A.  */
	  ax_simple (expr, aop_less_signed);
	  break;

	case DW_OP_ne:
	  /* Sign extend the operands.  */
	  ax_ext (expr, addr_size_bits);
	  ax_simple (expr, aop_swap);
	  ax_ext (expr, addr_size_bits);
	  /* No need for a swap here.  */
	  ax_simple (expr, aop_equal);
	  ax_simple (expr, aop_log_not);
	  break;

	case DW_OP_call_frame_cfa:
	  unimplemented (op);
	  break;

	case DW_OP_GNU_push_tls_address:
	  unimplemented (op);
	  break;

	case DW_OP_skip:
	  offset = extract_signed_integer (op_ptr, 2, byte_order);
	  op_ptr += 2;
	  i = ax_goto (expr, aop_goto);
	  VEC_safe_push (int, dw_labels, op_ptr + offset - base);
	  VEC_safe_push (int, patches, i);
	  break;

	case DW_OP_bra:
	  offset = extract_signed_integer (op_ptr, 2, byte_order);
	  op_ptr += 2;
	  /* Zero extend the operand.  */
	  ax_zero_ext (expr, addr_size_bits);
	  i = ax_goto (expr, aop_if_goto);
	  VEC_safe_push (int, dw_labels, op_ptr + offset - base);
	  VEC_safe_push (int, patches, i);
	  break;

	case DW_OP_nop:
	  break;

        case DW_OP_piece:
	case DW_OP_bit_piece:
	  {
	    ULONGEST size, offset;

	    if (op_ptr - 1 == previous_piece)
	      error (_("Cannot translate empty pieces to agent expressions"));
	    previous_piece = op_ptr - 1;

            op_ptr = read_uleb128 (op_ptr, op_end, &size);
	    if (op == DW_OP_piece)
	      {
		size *= 8;
		offset = 0;
	      }
	    else
	      op_ptr = read_uleb128 (op_ptr, op_end, &offset);

	    if (bits_collected + size > 8 * sizeof (LONGEST))
	      error (_("Expression pieces exceed word size"));

	    /* Access the bits.  */
	    switch (loc->kind)
	      {
	      case axs_lvalue_register:
		ax_reg (expr, loc->u.reg);
		break;

	      case axs_lvalue_memory:
		/* Offset the pointer, if needed.  */
		if (offset > 8)
		  {
		    ax_const_l (expr, offset / 8);
		    ax_simple (expr, aop_add);
		    offset %= 8;
		  }
		access_memory (arch, expr, size);
		break;
	      }

	    /* For a bits-big-endian target, shift up what we already
	       have.  For a bits-little-endian target, shift up the
	       new data.  Note that there is a potential bug here if
	       the DWARF expression leaves multiple values on the
	       stack.  */
	    if (bits_collected > 0)
	      {
		if (bits_big_endian)
		  {
		    ax_simple (expr, aop_swap);
		    ax_const_l (expr, size);
		    ax_simple (expr, aop_lsh);
		    /* We don't need a second swap here, because
		       aop_bit_or is symmetric.  */
		  }
		else
		  {
		    ax_const_l (expr, size);
		    ax_simple (expr, aop_lsh);
		  }
		ax_simple (expr, aop_bit_or);
	      }

	    bits_collected += size;
	    loc->kind = axs_rvalue;
	  }
	  break;

	case DW_OP_GNU_uninit:
	  unimplemented (op);

	case DW_OP_call2:
	case DW_OP_call4:
	  {
	    struct dwarf2_locexpr_baton block;
	    int size = (op == DW_OP_call2 ? 2 : 4);

	    uoffset = extract_unsigned_integer (op_ptr, size, byte_order);
	    op_ptr += size;

	    block = dwarf2_fetch_die_location_block (uoffset, per_cu);

	    /* DW_OP_call_ref is currently not supported.  */
	    gdb_assert (block.per_cu == per_cu);

	    compile_dwarf_to_ax (expr, loc, arch, addr_size,
				 block.data, block.data + block.size,
				 per_cu);
	  }
	  break;

	case DW_OP_call_ref:
	  unimplemented (op);

	default:
	  error (_("Unhandled dwarf expression opcode 0x%x"), op);
	}
    }

  /* Patch all the branches we emitted.  */
  for (i = 0; i < VEC_length (int, patches); ++i)
    {
      int targ = offsets[VEC_index (int, dw_labels, i)];
      if (targ == -1)
	internal_error (__FILE__, __LINE__, _("invalid label"));
      ax_label (expr, VEC_index (int, patches, i), targ);
    }

  do_cleanups (cleanups);
}


/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
   evaluator to calculate the location.  */
static struct value *
locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
{
  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  struct value *val;

  val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, dlbaton->data,
				  dlbaton->size, dlbaton->per_cu);

  return val;
}

/* Return non-zero iff we need a frame to evaluate SYMBOL.  */
static int
locexpr_read_needs_frame (struct symbol *symbol)
{
  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);

  return dwarf2_loc_desc_needs_frame (dlbaton->data, dlbaton->size,
				      dlbaton->per_cu);
}

/* Return true if DATA points to the end of a piece.  END is one past
   the last byte in the expression.  */

static int
piece_end_p (const gdb_byte *data, const gdb_byte *end)
{
  return data == end || data[0] == DW_OP_piece || data[0] == DW_OP_bit_piece;
}

/* Nicely describe a single piece of a location, returning an updated
   position in the bytecode sequence.  This function cannot recognize
   all locations; if a location is not recognized, it simply returns
   DATA.  */

static const gdb_byte *
locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
				 CORE_ADDR addr, struct objfile *objfile,
				 const gdb_byte *data, const gdb_byte *end,
				 unsigned int addr_size)
{
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  int regno;

  if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31)
    {
      regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, data[0] - DW_OP_reg0);
      fprintf_filtered (stream, _("a variable in $%s"),
			gdbarch_register_name (gdbarch, regno));
      data += 1;
    }
  else if (data[0] == DW_OP_regx)
    {
      ULONGEST reg;

      data = read_uleb128 (data + 1, end, &reg);
      regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, reg);
      fprintf_filtered (stream, _("a variable in $%s"),
			gdbarch_register_name (gdbarch, regno));
    }
  else if (data[0] == DW_OP_fbreg)
    {
      struct block *b;
      struct symbol *framefunc;
      int frame_reg = 0;
      LONGEST frame_offset;
      const gdb_byte *base_data, *new_data;
      size_t base_size;
      LONGEST base_offset = 0;

      new_data = read_sleb128 (data + 1, end, &frame_offset);
      if (!piece_end_p (new_data, end))
	return data;
      data = new_data;

      b = block_for_pc (addr);

      if (!b)
	error (_("No block found for address for symbol \"%s\"."),
	       SYMBOL_PRINT_NAME (symbol));

      framefunc = block_linkage_function (b);

      if (!framefunc)
	error (_("No function found for block for symbol \"%s\"."),
	       SYMBOL_PRINT_NAME (symbol));

      dwarf_expr_frame_base_1 (framefunc, addr, &base_data, &base_size);

      if (base_data[0] >= DW_OP_breg0 && base_data[0] <= DW_OP_breg31)
	{
	  const gdb_byte *buf_end;
	  
	  frame_reg = base_data[0] - DW_OP_breg0;
	  buf_end = read_sleb128 (base_data + 1,
				  base_data + base_size, &base_offset);
	  if (buf_end != base_data + base_size)
	    error (_("Unexpected opcode after DW_OP_breg%u for symbol \"%s\"."),
		   frame_reg, SYMBOL_PRINT_NAME (symbol));
	}
      else if (base_data[0] >= DW_OP_reg0 && base_data[0] <= DW_OP_reg31)
	{
	  /* The frame base is just the register, with no offset.  */
	  frame_reg = base_data[0] - DW_OP_reg0;
	  base_offset = 0;
	}
      else
	{
	  /* We don't know what to do with the frame base expression,
	     so we can't trace this variable; give up.  */
	  error (_("Cannot describe location of symbol \"%s\"; "
		   "DWARF 2 encoding not handled, "
		   "first opcode in base data is 0x%x."),
		 SYMBOL_PRINT_NAME (symbol), base_data[0]);
	}

      regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, frame_reg);

      fprintf_filtered (stream, _("a variable at frame base reg $%s offset %s+%s"),
			gdbarch_register_name (gdbarch, regno),
			plongest (base_offset), plongest (frame_offset));
    }
  else if (data[0] >= DW_OP_breg0 && data[0] <= DW_OP_breg31
	   && piece_end_p (data, end))
    {
      LONGEST offset;

      regno = gdbarch_dwarf2_reg_to_regnum (gdbarch, data[0] - DW_OP_breg0);

      data = read_sleb128 (data + 1, end, &offset);

      fprintf_filtered (stream,
			_("a variable at offset %s from base reg $%s"),
			plongest (offset),
			gdbarch_register_name (gdbarch, regno));
    }

  /* The location expression for a TLS variable looks like this (on a
     64-bit LE machine):

     DW_AT_location    : 10 byte block: 3 4 0 0 0 0 0 0 0 e0
                        (DW_OP_addr: 4; DW_OP_GNU_push_tls_address)
     
     0x3 is the encoding for DW_OP_addr, which has an operand as long
     as the size of an address on the target machine (here is 8
     bytes).  0xe0 is the encoding for DW_OP_GNU_push_tls_address.
     The operand represents the offset at which the variable is within
     the thread local storage.  */

  else if (data + 1 + addr_size < end
	   && data[0] == DW_OP_addr
	   && data[1 + addr_size] == DW_OP_GNU_push_tls_address
	   && piece_end_p (data + 2 + addr_size, end))
    {
      ULONGEST offset;
      offset = extract_unsigned_integer (data + 1, addr_size,
					 gdbarch_byte_order (gdbarch));

      fprintf_filtered (stream, 
			_("a thread-local variable at offset 0x%s "
			  "in the thread-local storage for `%s'"),
			phex_nz (offset, addr_size), objfile->name);

      data += 1 + addr_size + 1;
    }
  else if (data[0] >= DW_OP_lit0
	   && data[0] <= DW_OP_lit31
	   && data + 1 < end
	   && data[1] == DW_OP_stack_value)
    {
      fprintf_filtered (stream, _("the constant %d"), data[0] - DW_OP_lit0);
      data += 2;
    }

  return data;
}

/* Disassemble an expression, stopping at the end of a piece or at the
   end of the expression.  Returns a pointer to the next unread byte
   in the input expression.  If ALL is nonzero, then this function
   will keep going until it reaches the end of the expression.  */

static const gdb_byte *
disassemble_dwarf_expression (struct ui_file *stream,
			      struct gdbarch *arch, unsigned int addr_size,
			      int offset_size,
			      const gdb_byte *data, const gdb_byte *end,
			      int all)
{
  const gdb_byte *start = data;

  fprintf_filtered (stream, _("a complex DWARF expression:\n"));

  while (data < end
	 && (all
	     || (data[0] != DW_OP_piece && data[0] != DW_OP_bit_piece)))
    {
      enum dwarf_location_atom op = *data++;
      ULONGEST ul;
      LONGEST l;
      const char *name;

      name = dwarf_stack_op_name (op, 0);

      if (!name)
	error (_("Unrecognized DWARF opcode 0x%02x at %ld"),
	       op, (long) (data - start));
      fprintf_filtered (stream, "  % 4ld: %s", (long) (data - start), name);

      switch (op)
	{
	case DW_OP_addr:
	  ul = extract_unsigned_integer (data, addr_size,
					 gdbarch_byte_order (arch));
	  data += addr_size;
	  fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
	  break;

	case DW_OP_const1u:
	  ul = extract_unsigned_integer (data, 1, gdbarch_byte_order (arch));
	  data += 1;
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;
	case DW_OP_const1s:
	  l = extract_signed_integer (data, 1, gdbarch_byte_order (arch));
	  data += 1;
	  fprintf_filtered (stream, " %s", plongest (l));
	  break;
	case DW_OP_const2u:
	  ul = extract_unsigned_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;
	case DW_OP_const2s:
	  l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  fprintf_filtered (stream, " %s", plongest (l));
	  break;
	case DW_OP_const4u:
	  ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
	  data += 4;
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;
	case DW_OP_const4s:
	  l = extract_signed_integer (data, 4, gdbarch_byte_order (arch));
	  data += 4;
	  fprintf_filtered (stream, " %s", plongest (l));
	  break;
	case DW_OP_const8u:
	  ul = extract_unsigned_integer (data, 8, gdbarch_byte_order (arch));
	  data += 8;
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;
	case DW_OP_const8s:
	  l = extract_signed_integer (data, 8, gdbarch_byte_order (arch));
	  data += 8;
	  fprintf_filtered (stream, " %s", plongest (l));
	  break;
	case DW_OP_constu:
	  data = read_uleb128 (data, end, &ul);
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;
	case DW_OP_consts:
	  data = read_sleb128 (data, end, &l);
	  fprintf_filtered (stream, " %s", plongest (l));
	  break;

	case DW_OP_reg0:
	case DW_OP_reg1:
	case DW_OP_reg2:
	case DW_OP_reg3:
	case DW_OP_reg4:
	case DW_OP_reg5:
	case DW_OP_reg6:
	case DW_OP_reg7:
	case DW_OP_reg8:
	case DW_OP_reg9:
	case DW_OP_reg10:
	case DW_OP_reg11:
	case DW_OP_reg12:
	case DW_OP_reg13:
	case DW_OP_reg14:
	case DW_OP_reg15:
	case DW_OP_reg16:
	case DW_OP_reg17:
	case DW_OP_reg18:
	case DW_OP_reg19:
	case DW_OP_reg20:
	case DW_OP_reg21:
	case DW_OP_reg22:
	case DW_OP_reg23:
	case DW_OP_reg24:
	case DW_OP_reg25:
	case DW_OP_reg26:
	case DW_OP_reg27:
	case DW_OP_reg28:
	case DW_OP_reg29:
	case DW_OP_reg30:
	case DW_OP_reg31:
	  fprintf_filtered (stream, " [$%s]",
			    gdbarch_register_name (arch, op - DW_OP_reg0));
	  break;

	case DW_OP_regx:
	  data = read_uleb128 (data, end, &ul);
	  fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
			    gdbarch_register_name (arch, (int) ul));
	  break;

	case DW_OP_implicit_value:
	  data = read_uleb128 (data, end, &ul);
	  data += ul;
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_breg0:
	case DW_OP_breg1:
	case DW_OP_breg2:
	case DW_OP_breg3:
	case DW_OP_breg4:
	case DW_OP_breg5:
	case DW_OP_breg6:
	case DW_OP_breg7:
	case DW_OP_breg8:
	case DW_OP_breg9:
	case DW_OP_breg10:
	case DW_OP_breg11:
	case DW_OP_breg12:
	case DW_OP_breg13:
	case DW_OP_breg14:
	case DW_OP_breg15:
	case DW_OP_breg16:
	case DW_OP_breg17:
	case DW_OP_breg18:
	case DW_OP_breg19:
	case DW_OP_breg20:
	case DW_OP_breg21:
	case DW_OP_breg22:
	case DW_OP_breg23:
	case DW_OP_breg24:
	case DW_OP_breg25:
	case DW_OP_breg26:
	case DW_OP_breg27:
	case DW_OP_breg28:
	case DW_OP_breg29:
	case DW_OP_breg30:
	case DW_OP_breg31:
	  data = read_sleb128 (data, end, &ul);
	  fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
			    gdbarch_register_name (arch, op - DW_OP_breg0));
	  break;

	case DW_OP_bregx:
	  {
	    ULONGEST offset;

	    data = read_uleb128 (data, end, &ul);
	    data = read_sleb128 (data, end, &offset);
	    fprintf_filtered (stream, " register %s [$%s] offset %s",
			      pulongest (ul),
			      gdbarch_register_name (arch, (int) ul),
			      pulongest (offset));
	  }
	  break;

	case DW_OP_fbreg:
	  data = read_sleb128 (data, end, &ul);
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_xderef_size:
	case DW_OP_deref_size:
	case DW_OP_pick:
	  fprintf_filtered (stream, " %d", *data);
	  ++data;
	  break;

	case DW_OP_plus_uconst:
	  data = read_uleb128 (data, end, &ul);
	  fprintf_filtered (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_skip:
	  l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  fprintf_filtered (stream, " to %ld",
			    (long) (data + l - start));
	  break;

	case DW_OP_bra:
	  l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  fprintf_filtered (stream, " %ld",
			    (long) (data + l - start));
	  break;

	case DW_OP_call2:
	  ul = extract_unsigned_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  fprintf_filtered (stream, " offset %s", phex_nz (ul, 2));
	  break;

	case DW_OP_call4:
	  ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
	  data += 4;
	  fprintf_filtered (stream, " offset %s", phex_nz (ul, 4));
	  break;

	case DW_OP_call_ref:
	  ul = extract_unsigned_integer (data, offset_size,
					 gdbarch_byte_order (arch));
	  data += offset_size;
	  fprintf_filtered (stream, " offset %s", phex_nz (ul, offset_size));
	  break;

        case DW_OP_piece:
	  data = read_uleb128 (data, end, &ul);
	  fprintf_filtered (stream, " %s (bytes)", pulongest (ul));
	  break;

	case DW_OP_bit_piece:
	  {
	    ULONGEST offset;

	    data = read_uleb128 (data, end, &ul);
	    data = read_uleb128 (data, end, &offset);
	    fprintf_filtered (stream, " size %s offset %s (bits)",
			      pulongest (ul), pulongest (offset));
	  }
	  break;
	}

      fprintf_filtered (stream, "\n");
    }

  return data;
}

/* Describe a single location, which may in turn consist of multiple
   pieces.  */

static void
locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
			     struct ui_file *stream,
			     const gdb_byte *data, int size,
			     struct objfile *objfile, unsigned int addr_size,
			     int offset_size)
{
  const gdb_byte *end = data + size;
  int first_piece = 1, bad = 0;

  while (data < end)
    {
      const gdb_byte *here = data;
      int disassemble = 1;

      if (first_piece)
	first_piece = 0;
      else
	fprintf_filtered (stream, _(", and "));

      if (!dwarf2_always_disassemble)
	{
	  data = locexpr_describe_location_piece (symbol, stream, addr, objfile,
						  data, end, addr_size);
	  /* If we printed anything, or if we have an empty piece,
	     then don't disassemble.  */
	  if (data != here
	      || data[0] == DW_OP_piece
	      || data[0] == DW_OP_bit_piece)
	    disassemble = 0;
	}
      if (disassemble)
	data = disassemble_dwarf_expression (stream, get_objfile_arch (objfile),
					     addr_size, offset_size, data, end,
					     dwarf2_always_disassemble);

      if (data < end)
	{
	  int empty = data == here;
	      
	  if (disassemble)
	    fprintf_filtered (stream, "   ");
	  if (data[0] == DW_OP_piece)
	    {
	      ULONGEST bytes;

	      data = read_uleb128 (data + 1, end, &bytes);

	      if (empty)
		fprintf_filtered (stream, _("an empty %s-byte piece"),
				  pulongest (bytes));
	      else
		fprintf_filtered (stream, _(" [%s-byte piece]"),
				  pulongest (bytes));
	    }
	  else if (data[0] == DW_OP_bit_piece)
	    {
	      ULONGEST bits, offset;

	      data = read_uleb128 (data + 1, end, &bits);
	      data = read_uleb128 (data, end, &offset);

	      if (empty)
		fprintf_filtered (stream,
				  _("an empty %s-bit piece"),
				  pulongest (bits));
	      else
		fprintf_filtered (stream,
				  _(" [%s-bit piece, offset %s bits]"),
				  pulongest (bits), pulongest (offset));
	    }
	  else
	    {
	      bad = 1;
	      break;
	    }
	}
    }

  if (bad || data > end)
    error (_("Corrupted DWARF2 expression for \"%s\"."),
	   SYMBOL_PRINT_NAME (symbol));
}

/* Print a natural-language description of SYMBOL to STREAM.  This
   version is for a symbol with a single location.  */

static void
locexpr_describe_location (struct symbol *symbol, CORE_ADDR addr,
			   struct ui_file *stream)
{
  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
  unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
  int offset_size = dwarf2_per_cu_offset_size (dlbaton->per_cu);

  locexpr_describe_location_1 (symbol, addr, stream, dlbaton->data, dlbaton->size,
			       objfile, addr_size, offset_size);
}

/* Describe the location of SYMBOL as an agent value in VALUE, generating
   any necessary bytecode in AX.  */

static void
locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
			    struct agent_expr *ax, struct axs_value *value)
{
  struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);

  if (dlbaton->data == NULL || dlbaton->size == 0)
    value->optimized_out = 1;
  else
    compile_dwarf_to_ax (ax, value, gdbarch, addr_size,
			 dlbaton->data, dlbaton->data + dlbaton->size,
			 dlbaton->per_cu);
}

/* The set of location functions used with the DWARF-2 expression
   evaluator.  */
const struct symbol_computed_ops dwarf2_locexpr_funcs = {
  locexpr_read_variable,
  locexpr_read_needs_frame,
  locexpr_describe_location,
  locexpr_tracepoint_var_ref
};


/* Wrapper functions for location lists.  These generally find
   the appropriate location expression and call something above.  */

/* Return the value of SYMBOL in FRAME using the DWARF-2 expression
   evaluator to calculate the location.  */
static struct value *
loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
{
  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  struct value *val;
  const gdb_byte *data;
  size_t size;

  data = find_location_expression (dlbaton, &size,
				   frame ? get_frame_address_in_block (frame)
				   : 0);
  if (data == NULL)
    {
      val = allocate_value (SYMBOL_TYPE (symbol));
      VALUE_LVAL (val) = not_lval;
      set_value_optimized_out (val, 1);
    }
  else
    val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size,
				    dlbaton->per_cu);

  return val;
}

/* Return non-zero iff we need a frame to evaluate SYMBOL.  */
static int
loclist_read_needs_frame (struct symbol *symbol)
{
  /* If there's a location list, then assume we need to have a frame
     to choose the appropriate location expression.  With tracking of
     global variables this is not necessarily true, but such tracking
     is disabled in GCC at the moment until we figure out how to
     represent it.  */

  return 1;
}

/* Print a natural-language description of SYMBOL to STREAM.  This
   version applies when there is a list of different locations, each
   with a specified address range.  */

static void
loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
			   struct ui_file *stream)
{
  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  CORE_ADDR low, high;
  const gdb_byte *loc_ptr, *buf_end;
  int length, first = 1;
  struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
  struct gdbarch *gdbarch = get_objfile_arch (objfile);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
  int offset_size = dwarf2_per_cu_offset_size (dlbaton->per_cu);
  int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd);
  CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
  /* Adjust base_address for relocatable objects.  */
  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
				    SECT_OFF_TEXT (objfile));
  CORE_ADDR base_address = dlbaton->base_address + base_offset;

  loc_ptr = dlbaton->data;
  buf_end = dlbaton->data + dlbaton->size;

  fprintf_filtered (stream, _("multi-location:\n"));

  /* Iterate through locations until we run out.  */
  while (1)
    {
      if (buf_end - loc_ptr < 2 * addr_size)
	error (_("Corrupted DWARF expression for symbol \"%s\"."),
	       SYMBOL_PRINT_NAME (symbol));

      if (signed_addr_p)
	low = extract_signed_integer (loc_ptr, addr_size, byte_order);
      else
	low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
      loc_ptr += addr_size;

      if (signed_addr_p)
	high = extract_signed_integer (loc_ptr, addr_size, byte_order);
      else
	high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
      loc_ptr += addr_size;

      /* A base-address-selection entry.  */
      if ((low & base_mask) == base_mask)
	{
	  base_address = high + base_offset;
	  fprintf_filtered (stream, _("  Base address %s"),
			    paddress (gdbarch, base_address));
	  continue;
	}

      /* An end-of-list entry.  */
      if (low == 0 && high == 0)
	break;

      /* Otherwise, a location expression entry.  */
      low += base_address;
      high += base_address;

      length = extract_unsigned_integer (loc_ptr, 2, byte_order);
      loc_ptr += 2;

      /* (It would improve readability to print only the minimum
	 necessary digits of the second number of the range.)  */
      fprintf_filtered (stream, _("  Range %s-%s: "),
			paddress (gdbarch, low), paddress (gdbarch, high));

      /* Now describe this particular location.  */
      locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
				   objfile, addr_size, offset_size);

      fprintf_filtered (stream, "\n");

      loc_ptr += length;
    }
}

/* Describe the location of SYMBOL as an agent value in VALUE, generating
   any necessary bytecode in AX.  */
static void
loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
			    struct agent_expr *ax, struct axs_value *value)
{
  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
  const gdb_byte *data;
  size_t size;
  unsigned int addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);

  data = find_location_expression (dlbaton, &size, ax->scope);
  if (data == NULL || size == 0)
    value->optimized_out = 1;
  else
    compile_dwarf_to_ax (ax, value, gdbarch, addr_size, data, data + size,
			 dlbaton->per_cu);
}

/* The set of location functions used with the DWARF-2 expression
   evaluator and location lists.  */
const struct symbol_computed_ops dwarf2_loclist_funcs = {
  loclist_read_variable,
  loclist_read_needs_frame,
  loclist_describe_location,
  loclist_tracepoint_var_ref
};
