/* DWARF 2 location expression support for GDB.

   Copyright (C) 2003-2025 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 "event-top.h"
#include "exceptions.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 "block.h"
#include "cli/cli-cmds.h"
#include "complaints.h"
#include "dwarf2.h"
#include "dwarf2/expr.h"
#include "dwarf2/loc.h"
#include "dwarf2/read.h"
#include "dwarf2/frame.h"
#include "dwarf2/leb.h"
#include "compile/compile.h"
#include <algorithm>
#include <vector>
#include "gdbsupport/underlying.h"
#include "gdbsupport/byte-vector.h"
#include "extract-store-integer.h"

static struct value *dwarf2_evaluate_loc_desc_full
  (struct type *type, const frame_info_ptr &frame, const gdb_byte *data,
   size_t size, dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
   struct type *subobj_type, LONGEST subobj_byte_offset, bool as_lval = true);

/* Until these have formal names, we define these here.
   ref: http://gcc.gnu.org/wiki/DebugFission
   Each entry in .debug_loc.dwo begins with a byte that describes the entry,
   and is then followed by data specific to that entry.  */

enum debug_loc_kind
{
  /* Indicates the end of the list of entries.  */
  DEBUG_LOC_END_OF_LIST = 0,

  /* This is followed by an unsigned LEB128 number that is an index into
     .debug_addr and specifies the base address for all following entries.  */
  DEBUG_LOC_BASE_ADDRESS = 1,

  /* This is followed by two unsigned LEB128 numbers that are indices into
     .debug_addr and specify the beginning and ending addresses, and then
     a normal location expression as in .debug_loc.  */
  DEBUG_LOC_START_END = 2,

  /* This is followed by an unsigned LEB128 number that is an index into
     .debug_addr and specifies the beginning address, and a 4 byte unsigned
     number that specifies the length, and then a normal location expression
     as in .debug_loc.  */
  DEBUG_LOC_START_LENGTH = 3,

  /* This is followed by two unsigned LEB128 operands. The values of these
     operands are the starting and ending offsets, respectively, relative to
     the applicable base address.  */
  DEBUG_LOC_OFFSET_PAIR = 4,

  /* An internal value indicating there is insufficient data.  */
  DEBUG_LOC_BUFFER_OVERFLOW = -1,

  /* An internal value indicating an invalid kind of entry was found.  */
  DEBUG_LOC_INVALID_ENTRY = -2
};

/* Helper function which throws an error if a synthetic pointer is
   invalid.  */

void
invalid_synthetic_pointer (void)
{
  error (_("access outside bounds of object "
	   "referenced via synthetic pointer"));
}

/* Decode the addresses in a non-dwo .debug_loc entry.
   A pointer to the next byte to examine is returned in *NEW_PTR.
   The encoded low,high addresses are return in *LOW,*HIGH.
   The result indicates the kind of entry found.  */

static enum debug_loc_kind
decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end,
			    const gdb_byte **new_ptr,
			    unrelocated_addr *lowp, unrelocated_addr *highp,
			    enum bfd_endian byte_order,
			    unsigned int addr_size,
			    int signed_addr_p)
{
  CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));

  if (buf_end - loc_ptr < 2 * addr_size)
    return DEBUG_LOC_BUFFER_OVERFLOW;

  CORE_ADDR low, high;
  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;

  *new_ptr = loc_ptr;
  *lowp = (unrelocated_addr) low;
  *highp = (unrelocated_addr) high;

  /* A base-address-selection entry.  */
  if ((low & base_mask) == base_mask)
    return DEBUG_LOC_BASE_ADDRESS;

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

  /* We want the caller to apply the base address, so we must return
     DEBUG_LOC_OFFSET_PAIR here.  */
  return DEBUG_LOC_OFFSET_PAIR;
}

/* Decode the addresses in .debug_loclists entry.
   A pointer to the next byte to examine is returned in *NEW_PTR.
   The encoded low,high addresses are return in *LOW,*HIGH.
   The result indicates the kind of entry found.  */

static enum debug_loc_kind
decode_debug_loclists_addresses (dwarf2_per_cu *per_cu,
				 dwarf2_per_objfile *per_objfile,
				 const gdb_byte *loc_ptr,
				 const gdb_byte *buf_end,
				 const gdb_byte **new_ptr,
				 unrelocated_addr *low,
				 unrelocated_addr *high,
				 enum bfd_endian byte_order,
				 unsigned int addr_size,
				 int signed_addr_p)
{
  uint64_t u64;

  if (loc_ptr == buf_end)
    return DEBUG_LOC_BUFFER_OVERFLOW;

  switch (*loc_ptr++)
    {
    case DW_LLE_base_addressx:
      *low = {};
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
      if (loc_ptr == NULL)
	 return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = dwarf2_read_addr_index (per_cu, per_objfile, u64);
      *new_ptr = loc_ptr;
      return DEBUG_LOC_BASE_ADDRESS;

    case DW_LLE_startx_length:
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
      if (loc_ptr == NULL)
	 return DEBUG_LOC_BUFFER_OVERFLOW;

      *low = dwarf2_read_addr_index (per_cu, per_objfile, u64);
      *high = *low;
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
      if (loc_ptr == NULL)
	 return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = (unrelocated_addr) ((uint64_t) *high + u64);
      *new_ptr = loc_ptr;
      return DEBUG_LOC_START_LENGTH;

    case DW_LLE_start_length:
      if (buf_end - loc_ptr < addr_size)
	 return DEBUG_LOC_BUFFER_OVERFLOW;

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

      loc_ptr += addr_size;
      *high = *low;

      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
      if (loc_ptr == NULL)
	 return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = (unrelocated_addr) ((uint64_t) *high + u64);
      *new_ptr = loc_ptr;
      return DEBUG_LOC_START_LENGTH;

    case DW_LLE_end_of_list:
      *new_ptr = loc_ptr;
      return DEBUG_LOC_END_OF_LIST;

    case DW_LLE_base_address:
      if (loc_ptr + addr_size > buf_end)
	return DEBUG_LOC_BUFFER_OVERFLOW;

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

      loc_ptr += addr_size;
      *new_ptr = loc_ptr;
      return DEBUG_LOC_BASE_ADDRESS;

    case DW_LLE_offset_pair:
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
      if (loc_ptr == NULL)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *low = (unrelocated_addr) u64;
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
      if (loc_ptr == NULL)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = (unrelocated_addr) u64;
      *new_ptr = loc_ptr;
      return DEBUG_LOC_OFFSET_PAIR;

    case DW_LLE_start_end:
      if (loc_ptr + 2 * addr_size > buf_end)
	return DEBUG_LOC_BUFFER_OVERFLOW;

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

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

      loc_ptr += addr_size;
      *new_ptr = loc_ptr;
      return DEBUG_LOC_START_END;

    /* Following cases are not supported yet.  */
    case DW_LLE_startx_endx:
    case DW_LLE_default_location:
    default:
      return DEBUG_LOC_INVALID_ENTRY;
    }
}

/* Decode the addresses in .debug_loc.dwo entry.
   A pointer to the next byte to examine is returned in *NEW_PTR.
   The encoded low,high addresses are return in *LOW,*HIGH.
   The result indicates the kind of entry found.  */

static enum debug_loc_kind
decode_debug_loc_dwo_addresses (dwarf2_per_cu *per_cu,
				dwarf2_per_objfile *per_objfile,
				const gdb_byte *loc_ptr,
				const gdb_byte *buf_end,
				const gdb_byte **new_ptr,
				unrelocated_addr *low,
				unrelocated_addr *high,
				enum bfd_endian byte_order)
{
  uint64_t low_index, high_index;

  if (loc_ptr == buf_end)
    return DEBUG_LOC_BUFFER_OVERFLOW;

  switch (*loc_ptr++)
    {
    case DW_LLE_GNU_end_of_list_entry:
      *new_ptr = loc_ptr;
      return DEBUG_LOC_END_OF_LIST;

    case DW_LLE_GNU_base_address_selection_entry:
      *low = {};
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index);
      if (loc_ptr == NULL)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = dwarf2_read_addr_index (per_cu, per_objfile, high_index);
      *new_ptr = loc_ptr;
      return DEBUG_LOC_BASE_ADDRESS;

    case DW_LLE_GNU_start_end_entry:
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &low_index);
      if (loc_ptr == NULL)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *low = dwarf2_read_addr_index (per_cu, per_objfile, low_index);
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index);
      if (loc_ptr == NULL)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = dwarf2_read_addr_index (per_cu, per_objfile, high_index);
      *new_ptr = loc_ptr;
      return DEBUG_LOC_START_END;

    case DW_LLE_GNU_start_length_entry:
      loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &low_index);
      if (loc_ptr == NULL)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *low = dwarf2_read_addr_index (per_cu, per_objfile, low_index);
      if (loc_ptr + 4 > buf_end)
	return DEBUG_LOC_BUFFER_OVERFLOW;

      *high = *low;
      *high = (unrelocated_addr) ((CORE_ADDR) *high
				  + extract_unsigned_integer (loc_ptr, 4,
							      byte_order));
      *new_ptr = loc_ptr + 4;
      return DEBUG_LOC_START_LENGTH;

    default:
      return DEBUG_LOC_INVALID_ENTRY;
    }
}

/* A 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.  */

const gdb_byte *
dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
				 size_t *locexpr_length, const CORE_ADDR pc,
				 bool at_entry)
{
  dwarf2_per_objfile *per_objfile = baton->per_objfile;
  struct objfile *objfile = per_objfile->objfile;
  struct gdbarch *gdbarch = objfile->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int addr_size = baton->per_cu->addr_size ();
  int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
  /* Adjustment for relocatable objects.  */
  CORE_ADDR text_offset = baton->per_objfile->objfile->text_section_offset ();
  unrelocated_addr unrel_pc = (unrelocated_addr) (pc - text_offset);
  unrelocated_addr base_address = baton->base_address;
  const gdb_byte *loc_ptr, *buf_end;

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

  while (1)
    {
      unrelocated_addr low = {}, high = {}; /* init for gcc -Wall */
      int length;
      enum debug_loc_kind kind;
      const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */

      if (baton->dwarf_version < 5 && baton->from_dwo)
	kind = decode_debug_loc_dwo_addresses (baton->per_cu,
					       baton->per_objfile,
					       loc_ptr, buf_end, &new_ptr,
					       &low, &high, byte_order);
      else if (baton->dwarf_version < 5)
	kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr,
					   &low, &high,
					   byte_order, addr_size,
					   signed_addr_p);
      else
	kind = decode_debug_loclists_addresses (baton->per_cu,
						baton->per_objfile,
						loc_ptr, buf_end, &new_ptr,
						&low, &high, byte_order,
						addr_size, signed_addr_p);

      loc_ptr = new_ptr;
      switch (kind)
	{
	case DEBUG_LOC_END_OF_LIST:
	  *locexpr_length = 0;
	  return NULL;

	case DEBUG_LOC_BASE_ADDRESS:
	  base_address = high;
	  continue;

	case DEBUG_LOC_START_END:
	case DEBUG_LOC_START_LENGTH:
	case DEBUG_LOC_OFFSET_PAIR:
	  break;

	case DEBUG_LOC_BUFFER_OVERFLOW:
	case DEBUG_LOC_INVALID_ENTRY:
	  error (_("dwarf2_find_location_expression: "
		   "Corrupted DWARF expression."));

	default:
	  gdb_assert_not_reached ("bad debug_loc_kind");
	}

      /* Otherwise, a location expression entry.
	 If the entry is from a DWO, don't add base address: the entry is from
	 .debug_addr which already has the DWARF "base address". We still add
	 text offset in case we're debugging a PIE executable. However, if the
	 entry is DW_LLE_offset_pair from a DWO, add the base address as the
	 operands are offsets relative to the applicable base address.
	 If the entry is DW_LLE_start_end or DW_LLE_start_length, then
	 it already is an address, and we don't need to add the base.  */
      if (!baton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
	{
	  low = (unrelocated_addr) ((CORE_ADDR) low + (CORE_ADDR) base_address);
	  high = (unrelocated_addr) ((CORE_ADDR) high + (CORE_ADDR) base_address);
	}

      if (baton->dwarf_version < 5)
	{
	  length = extract_unsigned_integer (loc_ptr, 2, byte_order);
	  loc_ptr += 2;
	}
      else
	{
	  unsigned int bytes_read;

	  length = read_unsigned_leb128 (NULL, loc_ptr, &bytes_read);
	  loc_ptr += bytes_read;
	}

      if (low == high && unrel_pc == low && at_entry)
	{
	  /* This is entry PC record present only at entry point
	     of a function.  Verify it is really the function entry point.  */

	  const struct block *pc_block = block_for_pc (pc);
	  struct symbol *pc_func = NULL;

	  if (pc_block)
	    pc_func = pc_block->linkage_function ();

	  if (pc_func && pc == pc_func->value_block ()->entry_pc ())
	    {
	      *locexpr_length = length;
	      return loc_ptr;
	    }
	}

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

      loc_ptr += length;
    }
}

/* Implement find_frame_base_location method for LOC_BLOCK functions using
   DWARF expression for its DW_AT_frame_base.  */

static void
locexpr_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
				  const gdb_byte **start, size_t *length)
{
  struct dwarf2_locexpr_baton *symbaton
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (framefunc);

  *length = symbaton->size;
  *start = symbaton->data;
}

/* Implement the struct symbol_block_ops::get_frame_base method for
   LOC_BLOCK functions using a DWARF expression as its DW_AT_frame_base.  */

static CORE_ADDR
locexpr_get_frame_base (struct symbol *framefunc, const frame_info_ptr &frame)
{
  struct gdbarch *gdbarch;
  struct type *type;
  struct dwarf2_locexpr_baton *dlbaton;
  const gdb_byte *start;
  size_t length;
  struct value *result;

  /* If this method is called, then FRAMEFUNC is supposed to be a DWARF block.
     Thus, it's supposed to provide the find_frame_base_location method as
     well.  */
  gdb_assert (framefunc->block_ops ()->find_frame_base_location != nullptr);

  gdbarch = get_frame_arch (frame);
  type = builtin_type (gdbarch)->builtin_data_ptr;
  dlbaton = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (framefunc);

  framefunc->block_ops ()->find_frame_base_location (framefunc,
						     get_frame_pc (frame),
						     &start, &length);
  result = dwarf2_evaluate_loc_desc (type, frame, start, length,
				     dlbaton->per_cu, dlbaton->per_objfile);

  /* The DW_AT_frame_base attribute contains a location description which
     computes the base address itself.  However, the call to
     dwarf2_evaluate_loc_desc returns a value representing a variable at
     that address.  The frame base address is thus this variable's
     address.  */
  return result->address ();
}

/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
   function uses DWARF expression for its DW_AT_frame_base.  */

const struct symbol_block_ops dwarf2_block_frame_base_locexpr_funcs =
{
  locexpr_find_frame_base_location,
  locexpr_get_frame_base
};

/* Implement find_frame_base_location method for LOC_BLOCK functions using
   DWARF location list for its DW_AT_frame_base.  */

static void
loclist_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
				  const gdb_byte **start, size_t *length)
{
  struct dwarf2_loclist_baton *symbaton
    = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (framefunc);

  *start = dwarf2_find_location_expression (symbaton, length, pc);
}

/* Implement the struct symbol_block_ops::get_frame_base method for
   LOC_BLOCK functions using a DWARF location list as its DW_AT_frame_base.  */

static CORE_ADDR
loclist_get_frame_base (struct symbol *framefunc, const frame_info_ptr &frame)
{
  struct gdbarch *gdbarch;
  struct type *type;
  struct dwarf2_loclist_baton *dlbaton;
  const gdb_byte *start;
  size_t length;
  struct value *result;

  /* If this method is called, then FRAMEFUNC is supposed to be a DWARF block.
     Thus, it's supposed to provide the find_frame_base_location method as
     well.  */
  gdb_assert (framefunc->block_ops ()->find_frame_base_location != nullptr);

  gdbarch = get_frame_arch (frame);
  type = builtin_type (gdbarch)->builtin_data_ptr;
  dlbaton = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (framefunc);

  framefunc->block_ops ()->find_frame_base_location (framefunc,
						     get_frame_pc (frame),
						     &start, &length);
  result = dwarf2_evaluate_loc_desc (type, frame, start, length,
				     dlbaton->per_cu, dlbaton->per_objfile);

  /* The DW_AT_frame_base attribute contains a location description which
     computes the base address itself.  However, the call to
     dwarf2_evaluate_loc_desc returns a value representing a variable at
     that address.  The frame base address is thus this variable's
     address.  */
  return result->address ();
}

/* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
   function uses DWARF location list for its DW_AT_frame_base.  */

const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs =
{
  loclist_find_frame_base_location,
  loclist_get_frame_base
};

/* See dwarf2/loc.h.  */

void
func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc,
				 const gdb_byte **start, size_t *length)
{
  if (const symbol_block_ops *block_ops = framefunc->block_ops ();
      block_ops != nullptr)
    block_ops->find_frame_base_location (framefunc, pc, start, length);
  else
    *length = 0;

  if (*length == 0)
    error (_("Could not find the frame base for \"%s\"."),
	   framefunc->natural_name ());
}

/* See loc.h.  */

value *
compute_var_value (const char *name)
{
  struct block_symbol sym = lookup_symbol (name, nullptr, SEARCH_VAR_DOMAIN,
					   nullptr);
  if (sym.symbol != nullptr)
    return value_of_variable (sym.symbol, sym.block);
  return nullptr;
}

/* See dwarf2/loc.h.  */

unsigned int entry_values_debug = 0;

/* Helper to set entry_values_debug.  */

static void
show_entry_values_debug (struct ui_file *file, int from_tty,
			 struct cmd_list_element *c, const char *value)
{
  gdb_printf (file,
	      _("Entry values and tail call frames debugging is %s.\n"),
	      value);
}

/* See gdbtypes.h.  */

void
call_site_target::iterate_over_addresses (gdbarch *call_site_gdbarch,
					  const call_site *call_site,
					  const frame_info_ptr &caller_frame,
					  iterate_ftype callback) const
{
  switch (m_loc_kind)
    {
    case call_site_target::DWARF_BLOCK:
      {
	struct dwarf2_locexpr_baton *dwarf_block;
	struct value *val;
	struct type *caller_core_addr_type;
	struct gdbarch *caller_arch;

	dwarf_block = m_loc.dwarf_block;
	if (dwarf_block == NULL)
	  {
	    bound_minimal_symbol msym
	      = lookup_minimal_symbol_by_pc (call_site->pc () - 1);
	    throw_error (NO_ENTRY_VALUE_ERROR,
			 _("DW_AT_call_target is not specified at %s in %s"),
			 paddress (call_site_gdbarch, call_site->pc ()),
			 (msym.minsym == NULL ? "???"
			  : msym.minsym->print_name ()));
			
	  }
	if (caller_frame == NULL)
	  {
	    bound_minimal_symbol msym
	      = lookup_minimal_symbol_by_pc (call_site->pc () - 1);
	    throw_error (NO_ENTRY_VALUE_ERROR,
			 _("DW_AT_call_target DWARF block resolving "
			   "requires known frame which is currently not "
			   "available at %s in %s"),
			 paddress (call_site_gdbarch, call_site->pc ()),
			 (msym.minsym == NULL ? "???"
			  : msym.minsym->print_name ()));
			
	  }
	caller_arch = get_frame_arch (caller_frame);
	caller_core_addr_type = builtin_type (caller_arch)->builtin_func_ptr;
	val = dwarf2_evaluate_loc_desc (caller_core_addr_type, caller_frame,
					dwarf_block->data, dwarf_block->size,
					dwarf_block->per_cu,
					dwarf_block->per_objfile);
	/* DW_AT_call_target is a DWARF expression, not a DWARF location.  */
	if (val->lval () == lval_memory)
	  callback (val->address ());
	else
	  callback (value_as_address (val));
      }
      break;

    case call_site_target::PHYSNAME:
      {
	const char *physname;

	physname = m_loc.physname;

	/* Handle both the mangled and demangled PHYSNAME.  */
	bound_minimal_symbol msym
	  = lookup_minimal_symbol (current_program_space, physname);
	if (msym.minsym == NULL)
	  {
	    msym = lookup_minimal_symbol_by_pc (call_site->pc () - 1);
	    throw_error (NO_ENTRY_VALUE_ERROR,
			 _("Cannot find function \"%s\" for a call site target "
			   "at %s in %s"),
			 physname, paddress (call_site_gdbarch, call_site->pc ()),
			 (msym.minsym == NULL ? "???"
			  : msym.minsym->print_name ()));
			
	  }

	CORE_ADDR addr = (gdbarch_convert_from_func_ptr_addr
			  (call_site_gdbarch, msym.value_address (),
			   current_inferior ()->top_target ()));
	callback (addr);
      }
      break;

    case call_site_target::PHYSADDR:
      {
	dwarf2_per_objfile *per_objfile = call_site->per_objfile;

	callback (per_objfile->relocate (m_loc.physaddr));
      }
      break;

    case call_site_target::ADDRESSES:
      {
	dwarf2_per_objfile *per_objfile = call_site->per_objfile;

	for (unsigned i = 0; i < m_loc.addresses.length; ++i)
	  callback (per_objfile->relocate (m_loc.addresses.values[i]));
      }
      break;

    default:
      internal_error (_("invalid call site target kind"));
    }
}

/* Convert function entry point exact address ADDR to the function which is
   compliant with TAIL_CALL_LIST_COMPLETE condition.  Throw
   NO_ENTRY_VALUE_ERROR otherwise.  */

static struct symbol *
func_addr_to_tail_call_list (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  struct symbol *sym = find_pc_function (addr);
  struct type *type;

  if (sym == NULL || sym->value_block ()->entry_pc () != addr)
    throw_error (NO_ENTRY_VALUE_ERROR,
		 _("DW_TAG_call_site resolving failed to find function "
		   "name for address %s"),
		 paddress (gdbarch, addr));

  type = sym->type ();
  gdb_assert (type->code () == TYPE_CODE_FUNC);
  gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);

  return sym;
}

/* Verify function with entry point exact address ADDR can never call itself
   via its tail calls (incl. transitively).  Throw NO_ENTRY_VALUE_ERROR if it
   can call itself via tail calls.

   If a function can tail call itself its entry value based parameters are
   unreliable.  There is no verification whether the value of some/all
   parameters is unchanged through the self tail call, we expect if there is
   a self tail call all the parameters can be modified.  */

static void
func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
{
  CORE_ADDR addr;

  /* The verification is completely unordered.  Track here function addresses
     which still need to be iterated.  */
  std::vector<CORE_ADDR> todo;

  /* Track here CORE_ADDRs which were already visited.  */
  gdb::unordered_set<CORE_ADDR> addr_hash;

  todo.push_back (verify_addr);
  while (!todo.empty ())
    {
      struct symbol *func_sym;
      struct call_site *call_site;

      addr = todo.back ();
      todo.pop_back ();

      func_sym = func_addr_to_tail_call_list (gdbarch, addr);

      for (call_site = TYPE_TAIL_CALL_LIST (func_sym->type ());
	   call_site; call_site = call_site->tail_call_next)
	{
	  /* CALLER_FRAME with registers is not available for tail-call jumped
	     frames.  */
	  call_site->iterate_over_addresses (gdbarch, nullptr,
					     [&] (CORE_ADDR target_addr)
	    {
	      if (target_addr == verify_addr)
		{
		  bound_minimal_symbol msym
		    = lookup_minimal_symbol_by_pc (verify_addr);
		  throw_error (NO_ENTRY_VALUE_ERROR,
			       _("DW_OP_entry_value resolving has found "
				 "function \"%s\" at %s can call itself via tail "
				 "calls"),
			       (msym.minsym == NULL ? "???"
				: msym.minsym->print_name ()),
			       paddress (gdbarch, verify_addr));
		}

	      if (addr_hash.insert (target_addr).second)
		todo.push_back (target_addr);
	    });
	}
    }
}

/* Print user readable form of CALL_SITE->PC to gdb_stdlog.  Used only for
   ENTRY_VALUES_DEBUG.  */

static void
tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
{
  CORE_ADDR addr = call_site->pc ();
  bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1);

  gdb_printf (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
	      (msym.minsym == NULL ? "???"
	       : msym.minsym->print_name ()));

}

/* Intersect RESULTP with CHAIN to keep RESULTP unambiguous, keep in RESULTP
   only top callers and bottom callees which are present in both.  GDBARCH is
   used only for ENTRY_VALUES_DEBUG.  RESULTP is NULL after return if there are
   no remaining possibilities to provide unambiguous non-trivial result.
   RESULTP should point to NULL on the first (initialization) call.  Caller is
   responsible for xfree of any RESULTP data.  */

static void
chain_candidate (struct gdbarch *gdbarch,
		 gdb::unique_xmalloc_ptr<struct call_site_chain> *resultp,
		 const std::vector<struct call_site *> &chain)
{
  long length = chain.size ();
  int callers, callees, idx;

  if (*resultp == NULL)
    {
      /* Create the initial chain containing all the passed PCs.  */

      struct call_site_chain *result
	= ((struct call_site_chain *)
	   xmalloc (sizeof (*result)
		    + sizeof (*result->call_site) * (length - 1)));
      result->length = length;
      result->callers = result->callees = length;
      if (!chain.empty ())
	memcpy (result->call_site, chain.data (),
		sizeof (*result->call_site) * length);
      resultp->reset (result);

      if (entry_values_debug)
	{
	  gdb_printf (gdb_stdlog, "tailcall: initial:");
	  for (idx = 0; idx < length; idx++)
	    tailcall_dump (gdbarch, result->call_site[idx]);
	  gdb_putc ('\n', gdb_stdlog);
	}

      return;
    }

  if (entry_values_debug)
    {
      gdb_printf (gdb_stdlog, "tailcall: compare:");
      for (idx = 0; idx < length; idx++)
	tailcall_dump (gdbarch, chain[idx]);
      gdb_putc ('\n', gdb_stdlog);
    }

  /* Intersect callers.  */

  callers = std::min ((long) (*resultp)->callers, length);
  for (idx = 0; idx < callers; idx++)
    if ((*resultp)->call_site[idx] != chain[idx])
      {
	(*resultp)->callers = idx;
	break;
      }

  /* Intersect callees.  */

  callees = std::min ((long) (*resultp)->callees, length);
  for (idx = 0; idx < callees; idx++)
    if ((*resultp)->call_site[(*resultp)->length - 1 - idx]
	!= chain[length - 1 - idx])
      {
	(*resultp)->callees = idx;
	break;
      }

  if (entry_values_debug)
    {
      gdb_printf (gdb_stdlog, "tailcall: reduced:");
      for (idx = 0; idx < (*resultp)->callers; idx++)
	tailcall_dump (gdbarch, (*resultp)->call_site[idx]);
      gdb_puts (" |", gdb_stdlog);
      for (idx = 0; idx < (*resultp)->callees; idx++)
	tailcall_dump (gdbarch,
		       (*resultp)->call_site[(*resultp)->length
					     - (*resultp)->callees + idx]);
      gdb_putc ('\n', gdb_stdlog);
    }

  if ((*resultp)->callers == 0 && (*resultp)->callees == 0)
    {
      /* There are no common callers or callees.  It could be also a direct
	 call (which has length 0) with ambiguous possibility of an indirect
	 call - CALLERS == CALLEES == 0 is valid during the first allocation
	 but any subsequence processing of such entry means ambiguity.  */
      resultp->reset (NULL);
      return;
    }

  /* See call_site_find_chain_1 why there is no way to reach the bottom callee
     PC again.  In such case there must be two different code paths to reach
     it.  CALLERS + CALLEES equal to LENGTH in the case of self tail-call.  */
  gdb_assert ((*resultp)->callers + (*resultp)->callees <= (*resultp)->length);
}

/* Recursively try to construct the call chain.  GDBARCH, RESULTP, and
   CHAIN are passed to chain_candidate.  ADDR_HASH tracks which
   addresses have already been seen along the current chain.
   CALL_SITE is the call site to visit, and CALLEE_PC is the PC we're
   trying to "reach".  Returns false if an error has already been
   detected and so an early return can be done.  If it makes sense to
   keep trying (even if no answer has yet been found), returns
   true.  */

static bool
call_site_find_chain_2
     (struct gdbarch *gdbarch,
      gdb::unique_xmalloc_ptr<struct call_site_chain> *resultp,
      std::vector<struct call_site *> &chain,
      gdb::unordered_set<CORE_ADDR> &addr_hash,
      struct call_site *call_site,
      CORE_ADDR callee_pc)
{
  std::vector<CORE_ADDR> addresses;
  bool found_exact = false;
  call_site->iterate_over_addresses (gdbarch, nullptr,
				     [&] (CORE_ADDR addr)
    {
      if (addr == callee_pc)
	found_exact = true;
      else
	addresses.push_back (addr);
    });

  if (found_exact)
    {
      chain_candidate (gdbarch, resultp, chain);
      /* If RESULTP was reset, then chain_candidate failed, and so we
	 can tell our callers to early-return.  */
      return *resultp != nullptr;
    }

  for (CORE_ADDR target_func_addr : addresses)
    {
      struct symbol *target_func
	= func_addr_to_tail_call_list (gdbarch, target_func_addr);
      for (struct call_site *target_call_site
	     = TYPE_TAIL_CALL_LIST (target_func->type ());
	   target_call_site != nullptr;
	   target_call_site = target_call_site->tail_call_next)
	{
	  if (addr_hash.insert (target_call_site->pc ()).second)
	    {
	      /* Successfully entered TARGET_CALL_SITE.  */
	      chain.push_back (target_call_site);

	      if (!call_site_find_chain_2 (gdbarch, resultp, chain,
					   addr_hash, target_call_site,
					   callee_pc))
		return false;

	      size_t removed = addr_hash.erase (target_call_site->pc ());
	      gdb_assert (removed == 1);
	      chain.pop_back ();
	    }
	}
    }

  return true;
}

/* Create and return call_site_chain for CALLER_PC and CALLEE_PC.  All
   the assumed frames between them use GDBARCH.  Any unreliability
   results in thrown NO_ENTRY_VALUE_ERROR.  */

static gdb::unique_xmalloc_ptr<call_site_chain>
call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
			CORE_ADDR callee_pc)
{
  CORE_ADDR save_callee_pc = callee_pc;
  gdb::unique_xmalloc_ptr<struct call_site_chain> retval;
  struct call_site *call_site;

  /* CHAIN contains only the intermediate CALL_SITEs.  Neither CALLER_PC's
     call_site nor any possible call_site at CALLEE_PC's function is there.
     Any CALL_SITE in CHAIN will be iterated to its siblings - via
     TAIL_CALL_NEXT.  This is inappropriate for CALLER_PC's call_site.  */
  std::vector<struct call_site *> chain;

  /* A given call site may have multiple associated addresses.  This
     can happen if, e.g., the caller is split by hot/cold
     partitioning.  This vector tracks the ones we haven't visited
     yet.  */
  std::vector<std::vector<CORE_ADDR>> unvisited_addresses;

  /* We are not interested in the specific PC inside the callee function.  */
  callee_pc = get_pc_function_start (callee_pc);
  if (callee_pc == 0)
    throw_error (NO_ENTRY_VALUE_ERROR, _("Unable to find function for PC %s"),
		 paddress (gdbarch, save_callee_pc));

  /* Mark CALL_SITEs so we do not visit the same ones twice.  */
  gdb::unordered_set<CORE_ADDR> addr_hash;

  /* Do not push CALL_SITE to CHAIN.  Push there only the first tail call site
     at the target's function.  All the possible tail call sites in the
     target's function will get iterated as already pushed into CHAIN via their
     TAIL_CALL_NEXT.  */
  call_site = call_site_for_pc (gdbarch, caller_pc);
  /* No need to check the return value here, because we no longer care
     about possible early returns.  */
  call_site_find_chain_2 (gdbarch, &retval, chain, addr_hash, call_site,
			  callee_pc);

  if (retval == NULL)
    {
      bound_minimal_symbol msym_caller
	= lookup_minimal_symbol_by_pc (caller_pc);
      bound_minimal_symbol msym_callee
	= lookup_minimal_symbol_by_pc (callee_pc);
      throw_error (NO_ENTRY_VALUE_ERROR,
		   _("There are no unambiguously determinable intermediate "
		     "callers or callees between caller function \"%s\" at %s "
		     "and callee function \"%s\" at %s"),
		   (msym_caller.minsym == NULL
		    ? "???" : msym_caller.minsym->print_name ()),
		   paddress (gdbarch, caller_pc),
		   (msym_callee.minsym == NULL
		    ? "???" : msym_callee.minsym->print_name ()),
		   paddress (gdbarch, callee_pc));
    }

  return retval;
}

/* Create and return call_site_chain for CALLER_PC and CALLEE_PC.  All the
   assumed frames between them use GDBARCH.  If valid call_site_chain cannot be
   constructed return NULL.  */

gdb::unique_xmalloc_ptr<call_site_chain>
call_site_find_chain (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
		      CORE_ADDR callee_pc)
{
  gdb::unique_xmalloc_ptr<call_site_chain> retval;

  try
    {
      retval = call_site_find_chain_1 (gdbarch, caller_pc, callee_pc);
    }
  catch (const gdb_exception_error &e)
    {
      if (e.error == NO_ENTRY_VALUE_ERROR)
	{
	  if (entry_values_debug)
	    exception_print (gdb_stdout, e);

	  return NULL;
	}
      else
	throw;
    }

  return retval;
}

/* Return 1 if KIND and KIND_U match PARAMETER.  Return 0 otherwise.  */

static int
call_site_parameter_matches (struct call_site_parameter *parameter,
			     enum call_site_parameter_kind kind,
			     union call_site_parameter_u kind_u)
{
  if (kind == parameter->kind)
    switch (kind)
      {
      case CALL_SITE_PARAMETER_DWARF_REG:
	return kind_u.dwarf_reg == parameter->u.dwarf_reg;

      case CALL_SITE_PARAMETER_FB_OFFSET:
	return kind_u.fb_offset == parameter->u.fb_offset;

      case CALL_SITE_PARAMETER_PARAM_OFFSET:
	return kind_u.param_cu_off == parameter->u.param_cu_off;
      }
  return 0;
}

/* See loc.h.  */

struct call_site_parameter *
dwarf_expr_reg_to_entry_parameter (const frame_info_ptr &initial_frame,
				   call_site_parameter_kind kind,
				   call_site_parameter_u kind_u,
				   dwarf2_per_cu **per_cu_return,
				   dwarf2_per_objfile **per_objfile_return)
{
  CORE_ADDR func_addr, caller_pc;
  struct gdbarch *gdbarch;
  frame_info_ptr caller_frame;
  struct call_site *call_site;
  int iparams;
  /* Initialize it just to avoid a GCC false warning.  */
  struct call_site_parameter *parameter = NULL;
  CORE_ADDR target_addr;
  frame_info_ptr frame = initial_frame;

  while (get_frame_type (frame) == INLINE_FRAME)
    {
      frame = get_prev_frame_always (frame);
      gdb_assert (frame != NULL);
    }

  func_addr = get_frame_func (frame);
  gdbarch = get_frame_arch (frame);
  caller_frame = get_prev_frame (frame);
  if (gdbarch != frame_unwind_arch (frame))
    {
      bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (func_addr);
      struct gdbarch *caller_gdbarch = frame_unwind_arch (frame);

      throw_error (NO_ENTRY_VALUE_ERROR,
		   _("DW_OP_entry_value resolving callee gdbarch %s "
		     "(of %s (%s)) does not match caller gdbarch %s"),
		   gdbarch_bfd_arch_info (gdbarch)->printable_name,
		   paddress (gdbarch, func_addr),
		   (msym.minsym == NULL ? "???"
		    : msym.minsym->print_name ()),
		   gdbarch_bfd_arch_info (caller_gdbarch)->printable_name);
    }

  if (caller_frame == NULL)
    {
      bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (func_addr);

      throw_error (NO_ENTRY_VALUE_ERROR, _("DW_OP_entry_value resolving "
					   "requires caller of %s (%s)"),
		   paddress (gdbarch, func_addr),
		   (msym.minsym == NULL ? "???"
		    : msym.minsym->print_name ()));
    }
  caller_pc = get_frame_pc (caller_frame);
  call_site = call_site_for_pc (gdbarch, caller_pc);

  bool found = false;
  unsigned count = 0;
  call_site->iterate_over_addresses (gdbarch, caller_frame,
				     [&] (CORE_ADDR addr)
    {
      /* Preserve any address.  */
      target_addr = addr;
      ++count;
      if (addr == func_addr)
	found = true;
    });
  if (!found)
    {
      struct minimal_symbol *target_msym, *func_msym;

      target_msym = lookup_minimal_symbol_by_pc (target_addr).minsym;
      func_msym = lookup_minimal_symbol_by_pc (func_addr).minsym;
      throw_error (NO_ENTRY_VALUE_ERROR,
		   _("DW_OP_entry_value resolving expects callee %s at %s %s"
		     "but the called frame is for %s at %s"),
		   (target_msym == NULL ? "???"
					: target_msym->print_name ()),
		   paddress (gdbarch, target_addr),
		   (count > 0
		    ? _("(but note there are multiple addresses not listed)")
		    : ""),
		   func_msym == NULL ? "???" : func_msym->print_name (),
		   paddress (gdbarch, func_addr));
    }

  /* No entry value based parameters would be reliable if this function can
     call itself via tail calls.  */
  func_verify_no_selftailcall (gdbarch, func_addr);

  for (iparams = 0; iparams < call_site->parameter_count; iparams++)
    {
      parameter = &call_site->parameter[iparams];
      if (call_site_parameter_matches (parameter, kind, kind_u))
	break;
    }
  if (iparams == call_site->parameter_count)
    {
      struct minimal_symbol *msym
	= lookup_minimal_symbol_by_pc (caller_pc).minsym;

      /* DW_TAG_call_site_parameter will be missing just if GCC could not
	 determine its value.  */
      throw_error (NO_ENTRY_VALUE_ERROR, _("Cannot find matching parameter "
					   "at DW_TAG_call_site %s at %s"),
		   paddress (gdbarch, caller_pc),
		   msym == NULL ? "???" : msym->print_name ()); 
    }

  *per_cu_return = call_site->per_cu;
  *per_objfile_return = call_site->per_objfile;
  return parameter;
}

/* Return value for PARAMETER matching DEREF_SIZE.  If DEREF_SIZE is -1, return
   the normal DW_AT_call_value block.  Otherwise return the
   DW_AT_call_data_value (dereferenced) block.

   TYPE and CALLER_FRAME specify how to evaluate the DWARF block into returned
   struct value.

   Function always returns non-NULL, non-optimized out value.  It throws
   NO_ENTRY_VALUE_ERROR if it cannot resolve the value for any reason.  */

static struct value *
dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
				CORE_ADDR deref_size, struct type *type,
				const frame_info_ptr &caller_frame,
				dwarf2_per_cu *per_cu,
				dwarf2_per_objfile *per_objfile)
{
  const gdb_byte *data_src;
  size_t size;

  data_src = deref_size == -1 ? parameter->value : parameter->data_value;
  size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;

  /* DEREF_SIZE size is not verified here.  */
  if (data_src == NULL)
    throw_error (NO_ENTRY_VALUE_ERROR,
		 _("Cannot resolve DW_AT_call_data_value"));

  return dwarf2_evaluate_loc_desc (type, caller_frame, data_src, size, per_cu,
				   per_objfile, false);
}

/* VALUE must be of type lval_computed with entry_data_value_funcs.  Perform
   the indirect method on it, that is use its stored target value, the sole
   purpose of entry_data_value_funcs..  */

static struct value *
entry_data_value_coerce_ref (const struct value *value)
{
  struct type *checked_type = check_typedef (value->type ());
  struct value *target_val;

  if (!TYPE_IS_REFERENCE (checked_type))
    return NULL;

  target_val = (struct value *) value->computed_closure ();
  target_val->incref ();
  return target_val;
}

/* Implement copy_closure.  */

static void *
entry_data_value_copy_closure (const struct value *v)
{
  struct value *target_val = (struct value *) v->computed_closure ();

  target_val->incref ();
  return target_val;
}

/* Implement free_closure.  */

static void
entry_data_value_free_closure (struct value *v)
{
  struct value *target_val = (struct value *) v->computed_closure ();

  target_val->decref ();
}

/* Vector for methods for an entry value reference where the referenced value
   is stored in the caller.  On the first dereference use
   DW_AT_call_data_value in the caller.  */

static const struct lval_funcs entry_data_value_funcs =
{
  NULL,	/* read */
  NULL,	/* write */
  nullptr,
  NULL,	/* indirect */
  entry_data_value_coerce_ref,
  NULL,	/* check_synthetic_pointer */
  entry_data_value_copy_closure,
  entry_data_value_free_closure
};

/* See dwarf2/loc.h.  */
struct value *
value_of_dwarf_reg_entry (struct type *type, const frame_info_ptr &frame,
			  enum call_site_parameter_kind kind,
			  union call_site_parameter_u kind_u)
{
  struct type *checked_type = check_typedef (type);
  struct type *target_type = checked_type->target_type ();
  frame_info_ptr caller_frame = get_prev_frame (frame);
  struct value *outer_val, *target_val, *val;
  struct call_site_parameter *parameter;
  dwarf2_per_cu *caller_per_cu;
  dwarf2_per_objfile *caller_per_objfile;

  parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
						 &caller_per_cu,
						 &caller_per_objfile);

  outer_val = dwarf_entry_parameter_to_value (parameter, -1 /* deref_size */,
					      type, caller_frame,
					      caller_per_cu,
					      caller_per_objfile);

  /* Check if DW_AT_call_data_value cannot be used.  If it should be
     used and it is not available do not fall back to OUTER_VAL - dereferencing
     TYPE_CODE_REF with non-entry data value would give current value - not the
     entry value.  */

  if (!TYPE_IS_REFERENCE (checked_type)
      || checked_type->target_type () == NULL)
    return outer_val;

  target_val = dwarf_entry_parameter_to_value (parameter,
					       target_type->length (),
					       target_type, caller_frame,
					       caller_per_cu,
					       caller_per_objfile);

  val = value::allocate_computed (type, &entry_data_value_funcs,
				 release_value (target_val).release ());

  /* Copy the referencing pointer to the new computed value.  */
  memcpy (val->contents_raw ().data (),
	  outer_val->contents_raw ().data (),
	  checked_type->length ());
  val->set_lazy (false);

  return val;
}

/* Read parameter of TYPE at (callee) FRAME's function entry.  DATA and
   SIZE are DWARF block used to match DW_AT_location at the caller's
   DW_TAG_call_site_parameter.

   Function always returns non-NULL value.  It throws NO_ENTRY_VALUE_ERROR if it
   cannot resolve the parameter for any reason.  */

static struct value *
value_of_dwarf_block_entry (struct type *type, const frame_info_ptr &frame,
			    const gdb_byte *block, size_t block_len)
{
  union call_site_parameter_u kind_u;

  kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (block, block + block_len);
  if (kind_u.dwarf_reg != -1)
    return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_DWARF_REG,
				     kind_u);

  if (dwarf_block_to_fb_offset (block, block + block_len, &kind_u.fb_offset))
    return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_FB_OFFSET,
				     kind_u);

  /* This can normally happen - throw NO_ENTRY_VALUE_ERROR to get the message
     suppressed during normal operation.  The expression can be arbitrary if
     there is no caller-callee entry value binding expected.  */
  throw_error (NO_ENTRY_VALUE_ERROR,
	       _("DWARF-2 expression error: DW_OP_entry_value is supported "
		 "only for single DW_OP_reg* or for DW_OP_fbreg(*)"));
}

/* Fetch a DW_AT_const_value through a synthetic pointer.  */

static struct value *
fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset,
					  dwarf2_per_cu *per_cu,
					  dwarf2_per_objfile *per_objfile,
					  struct type *type)
{
  struct value *result = NULL;
  const gdb_byte *bytes;
  LONGEST len;

  auto_obstack temp_obstack;
  bytes = dwarf2_fetch_constant_bytes (die, per_cu, per_objfile,
				       &temp_obstack, &len);

  if (bytes != NULL)
    {
      if (byte_offset >= 0
	  && byte_offset + type->target_type ()->length () <= len)
	{
	  bytes += byte_offset;
	  result = value_from_contents (type->target_type (), bytes);
	}
      else
	invalid_synthetic_pointer ();
    }
  else
    result = value::allocate_optimized_out (type->target_type ());

  return result;
}

/* See loc.h.  */

struct value *
indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
			    dwarf2_per_cu *per_cu,
			    dwarf2_per_objfile *per_objfile,
			    const frame_info_ptr &frame, struct type *type,
			    bool resolve_abstract_p)
{
  /* Fetch the location expression of the DIE we're pointing to.  */
  auto get_frame_address_in_block_wrapper = [frame] ()
    {
     return get_frame_address_in_block (frame);
    };
  struct dwarf2_locexpr_baton baton
    = dwarf2_fetch_die_loc_sect_off (die, per_cu, per_objfile,
				     get_frame_address_in_block_wrapper,
				     resolve_abstract_p);

  /* Get type of pointed-to DIE.  */
  struct type *orig_type = dwarf2_fetch_die_type_sect_off (die, per_cu,
							   per_objfile);
  if (orig_type == NULL)
    invalid_synthetic_pointer ();

  /* If pointed-to DIE has a DW_AT_location, evaluate it and return the
     resulting value.  Otherwise, it may have a DW_AT_const_value instead,
     or it may've been optimized out.  */
  if (baton.data != NULL)
    return dwarf2_evaluate_loc_desc_full (orig_type, frame, baton.data,
					  baton.size, baton.per_cu,
					  baton.per_objfile,
					  type->target_type (),
					  byte_offset);
  else
    return fetch_const_value_from_synthetic_pointer (die, byte_offset, per_cu,
						     per_objfile, type);
}

/* 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.  If SUBOBJ_TYPE is non-NULL, return instead the
   location of the subobject of type SUBOBJ_TYPE at byte offset
   SUBOBJ_BYTE_OFFSET within the variable of type TYPE.  */

static struct value *
dwarf2_evaluate_loc_desc_full (struct type *type, const frame_info_ptr &frame,
			       const gdb_byte *data, size_t size,
			       dwarf2_per_cu *per_cu,
			       dwarf2_per_objfile *per_objfile,
			       struct type *subobj_type,
			       LONGEST subobj_byte_offset,
			       bool as_lval)
{
  if (subobj_type == NULL)
    {
      subobj_type = type;
      subobj_byte_offset = 0;
    }
  else if (subobj_byte_offset < 0)
    invalid_synthetic_pointer ();

  if (size == 0)
    return value::allocate_optimized_out (subobj_type);

  dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());

  value *retval;
  scoped_value_mark free_values;

  try
    {
      retval = ctx.evaluate (data, size, as_lval, per_cu, frame, nullptr,
			     type, subobj_type, subobj_byte_offset);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == NOT_AVAILABLE_ERROR)
	{
	  free_values.free_to_mark ();
	  retval = value::allocate (subobj_type);
	  retval->mark_bytes_unavailable (0,
					  subobj_type->length ());
	  return retval;
	}
      else if (ex.error == NO_ENTRY_VALUE_ERROR)
	{
	  if (entry_values_debug)
	    exception_print (gdb_stdout, ex);
	  free_values.free_to_mark ();
	  return value::allocate_optimized_out (subobj_type);
	}
      else
	throw;
    }

  /* We need to clean up all the values that are not needed any more.
     The problem with a value_ref_ptr class is that it disconnects the
     RETVAL from the value garbage collection, so we need to make
     a copy of that value on the stack to keep everything consistent.
     The value_ref_ptr will clean up after itself at the end of this block.  */
  value_ref_ptr value_holder = value_ref_ptr::new_reference (retval);
  free_values.free_to_mark ();

  return retval->copy ();
}

/* The exported interface to dwarf2_evaluate_loc_desc_full; it always
   passes 0 as the byte_offset.  */

struct value *
dwarf2_evaluate_loc_desc (struct type *type, const frame_info_ptr &frame,
			  const gdb_byte *data, size_t size,
			  dwarf2_per_cu *per_cu,
			  dwarf2_per_objfile *per_objfile, bool as_lval)
{
  return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu,
					per_objfile, NULL, 0, as_lval);
}

/* Evaluates a dwarf expression and stores the result in VAL,
   expecting that the dwarf expression only produces a single
   CORE_ADDR.  FRAME is the frame in which the expression is
   evaluated.  ADDR_STACK is a context (location of a variable) and
   might be needed to evaluate the location expression.

   PUSH_VALUES is an array of values to be pushed to the expression stack
   before evaluation starts.  PUSH_VALUES[0] is pushed first, then
   PUSH_VALUES[1], and so on.

   Returns 1 on success, 0 otherwise.  */

static int
dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
			   const frame_info_ptr &frame,
			   const struct property_addr_info *addr_stack,
			   CORE_ADDR *valp,
			   gdb::array_view<CORE_ADDR> push_values,
			   bool *is_reference)
{
  if (dlbaton == NULL || dlbaton->size == 0)
    return 0;

  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
  dwarf2_per_cu *per_cu = dlbaton->per_cu;
  dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());

  value *result;
  scoped_value_mark free_values;

  /* Place any initial values onto the expression stack.  */
  for (const auto &val : push_values)
    ctx.push_address (val, false);

  try
    {
      result = ctx.evaluate (dlbaton->data, dlbaton->size,
			     true, per_cu, frame, addr_stack);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == NOT_AVAILABLE_ERROR)
	{
	  return 0;
	}
      else if (ex.error == NO_ENTRY_VALUE_ERROR)
	{
	  if (entry_values_debug)
	    exception_print (gdb_stdout, ex);
	  return 0;
	}
      else
	throw;
    }

  if (result->optimized_out ())
    return 0;

  if (result->lval () == lval_memory)
    *valp = result->address ();
  else
    {
      if (result->lval () == not_lval)
	*is_reference = false;

      *valp = value_as_address (result);
    }

  return 1;
}

/* See dwarf2/loc.h.  */

bool
dwarf2_evaluate_property (const dynamic_prop *prop,
			  const frame_info_ptr &initial_frame,
			  const property_addr_info *addr_stack,
			  CORE_ADDR *value,
			  gdb::array_view<CORE_ADDR> push_values)
{
  if (prop == NULL)
    return false;

  /* Evaluating a property should not change the current language.
     Without this here this could happen if the code below selects a
     frame.  */
  scoped_restore_current_language save_language;
  frame_info_ptr frame = initial_frame;

  if (frame == NULL && has_stack_frames ())
    frame = get_selected_frame (NULL);

  switch (prop->kind ())
    {
    case PROP_LOCEXPR:
      {
	const struct dwarf2_property_baton *baton = prop->baton ();
	gdb_assert (baton->property_type != NULL);

	bool is_reference = baton->locexpr.is_reference;
	if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame, addr_stack,
				       value, push_values, &is_reference))
	  {
	    if (is_reference)
	      {
		struct value *val = value_at (baton->property_type, *value);
		*value = value_as_address (val);
	      }
	    else
	      {
		gdb_assert (baton->property_type != NULL);

		struct type *type = check_typedef (baton->property_type);
		if (type->length () < sizeof (CORE_ADDR)
		    && !type->is_unsigned ())
		  {
		    /* If we have a valid return candidate and it's value
		       is signed, we have to sign-extend the value because
		       CORE_ADDR on 64bit machine has 8 bytes but address
		       size of an 32bit application is bytes.  */
		    const int addr_size
		      = (baton->locexpr.per_cu->addr_size ()
			 * TARGET_CHAR_BIT);
		    const CORE_ADDR neg_mask
		      = (~((CORE_ADDR) 0) <<  (addr_size - 1));

		    /* Check if signed bit is set and sign-extend values.  */
		    if (*value & neg_mask)
		      *value |= neg_mask;
		  }
	      }
	    return true;
	  }
      }
      break;

    case PROP_LOCLIST:
      {
	const dwarf2_property_baton *baton = prop->baton ();
	CORE_ADDR pc;
	const gdb_byte *data;
	struct value *val;
	size_t size;

	if (frame == NULL
	    || !get_frame_address_in_block_if_available (frame, &pc))
	  return false;

	data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
	if (data != NULL)
	  {
	    val = dwarf2_evaluate_loc_desc (baton->property_type, frame, data,
					    size, baton->loclist.per_cu,
					    baton->loclist.per_objfile);
	    if (!val->optimized_out ())
	      {
		*value = value_as_address (val);
		return true;
	      }
	  }
      }
      break;

    case PROP_CONST:
      *value = prop->const_val ();
      return true;

    case PROP_FIELD:
      {
	const dwarf2_property_baton *baton = prop->baton ();
	const struct property_addr_info *pinfo;

	for (pinfo = addr_stack; pinfo != NULL; pinfo = pinfo->next)
	  {
	    /* This approach lets us avoid checking the qualifiers.  */
	    if (TYPE_MAIN_TYPE (pinfo->type)
		== TYPE_MAIN_TYPE (baton->property_type))
	      break;
	  }
	if (pinfo == NULL)
	  error (_("cannot find reference address for offset property"));

	struct field resolved_field = baton->field;
	resolve_dynamic_field (resolved_field, pinfo, initial_frame);

	/* Storage for memory if we need to read it.  */
	gdb::byte_vector memory;
	const gdb_byte *bytes = pinfo->valaddr.data ();
	if (bytes == nullptr)
	  {
	    int bitpos = resolved_field.loc_bitpos ();
	    int bitsize = resolved_field.bitsize ();
	    if (bitsize == 0)
	      bitsize = check_typedef (resolved_field.type ())->length () * 8;

	    /* Read just the minimum number of bytes needed to satisfy
	       unpack_field_as_long.  So, update the resolved field's
	       starting offset to remove any unnecessary leading
	       bytes.  */
	    int byte_offset = bitpos / 8;

	    bitpos %= 8;
	    resolved_field.set_loc_bitpos (bitpos);

	    /* Make sure to include any remaining bit offset in the
	       size computation, in case the value straddles a
	       byte.  */
	    int byte_length = align_up (bitsize + bitpos, 8) / 8;
	    memory.resize (byte_length);

	    read_memory (pinfo->addr + byte_offset, memory.data (),
			 byte_length);
	    bytes = memory.data ();
	  }
	*value = unpack_field_as_long (bytes, &resolved_field);
	return true;
      }

    case PROP_VARIABLE_NAME:
      {
	struct value *val = compute_var_value (prop->variable_name ());
	if (val != nullptr)
	  {
	    *value = value_as_long (val);
	    return true;
	  }
      }
      break;
    }

  return false;
}

/* See dwarf2/loc.h.  */

void
dwarf2_compile_property_to_c (string_file *stream,
			      const char *result_name,
			      struct gdbarch *gdbarch,
			      std::vector<bool> &registers_used,
			      const struct dynamic_prop *prop,
			      CORE_ADDR pc,
			      struct symbol *sym)
{
#if defined (HAVE_COMPILE)
  const dwarf2_property_baton *baton = prop->baton ();
  const gdb_byte *data;
  size_t size;
  dwarf2_per_cu *per_cu;
  dwarf2_per_objfile *per_objfile;

  if (prop->kind () == PROP_LOCEXPR)
    {
      data = baton->locexpr.data;
      size = baton->locexpr.size;
      per_cu = baton->locexpr.per_cu;
      per_objfile = baton->locexpr.per_objfile;
    }
  else
    {
      gdb_assert (prop->kind () == PROP_LOCLIST);

      data = dwarf2_find_location_expression (&baton->loclist, &size, pc);
      per_cu = baton->loclist.per_cu;
      per_objfile = baton->loclist.per_objfile;
    }

  compile_dwarf_bounds_to_c (stream, result_name, prop, sym, pc,
			     gdbarch, registers_used,
			     per_cu->addr_size (),
			     data, data + size, per_cu, per_objfile);
#else
  gdb_assert_not_reached ("Compile support was disabled");
#endif
}

/* Compute the correct symbol_needs_kind value for the location
   expression in EXPR.

   Implemented by traversing the logical control flow graph of the
   expression.  */

static enum symbol_needs_kind
dwarf2_get_symbol_read_needs (gdb::array_view<const gdb_byte> expr,
			      dwarf2_per_cu *per_cu,
			      dwarf2_per_objfile *per_objfile,
			      bfd_endian byte_order,
			      int addr_size,
			      int ref_addr_size,
			      int depth = 0)
{
  enum symbol_needs_kind symbol_needs = SYMBOL_NEEDS_NONE;

  /* If the expression is empty, we have nothing to do.  */
  if (expr.empty ())
    return symbol_needs;

  const gdb_byte *expr_end = expr.data () + expr.size ();

  /* List of operations to visit.  Operations in this list are not visited yet,
     so are not in VISITED_OPS (and vice-versa).  */
  std::vector<const gdb_byte *> ops_to_visit;

  /* Operations already visited.  */
  gdb::unordered_set<const gdb_byte *> visited_ops;

  /* Insert OP in OPS_TO_VISIT if it is within the expression's range and
     hasn't been visited yet.  */
  auto insert_in_ops_to_visit
    = [expr_end, &visited_ops, &ops_to_visit] (const gdb_byte *op_ptr)
      {
	if (op_ptr >= expr_end)
	  return;

	if (visited_ops.find (op_ptr) != visited_ops.end ())
	  return;

	ops_to_visit.push_back (op_ptr);
      };

  /* Expressions can invoke other expressions with DW_OP_call*.  Protect against
     a loop of calls.  */
  const int max_depth = 256;

  if (depth > max_depth)
    error (_("DWARF-2 expression error: Loop detected."));

  depth++;

  /* Initialize the to-visit list with the first operation.  */
  insert_in_ops_to_visit (&expr[0]);

  while (!ops_to_visit.empty ())
    {
      /* Pop one op to visit, mark it as visited.  */
      const gdb_byte *op_ptr = ops_to_visit.back ();
      ops_to_visit.pop_back ();
      gdb_assert (visited_ops.find (op_ptr) == visited_ops.end ());
      visited_ops.insert (op_ptr);

      dwarf_location_atom op = (dwarf_location_atom) *op_ptr;

      /* Most operations have a single possible following operation
	 (they are not conditional branches).  The code below updates
	 OP_PTR to point to that following operation, which is pushed
	 back to OPS_TO_VISIT, if needed, at the bottom.  Here, leave
	 OP_PTR pointing just after the operand.  */
      op_ptr++;

      /* The DWARF expression might have a bug causing an infinite
	 loop.  In that case, quitting is the only way out.  */
      QUIT;

      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:
	case DW_OP_stack_value:
	case DW_OP_dup:
	case DW_OP_drop:
	case DW_OP_swap:
	case DW_OP_over:
	case DW_OP_rot:
	case DW_OP_deref:
	case DW_OP_abs:
	case DW_OP_neg:
	case DW_OP_not:
	case DW_OP_and:
	case DW_OP_div:
	case DW_OP_minus:
	case DW_OP_mod:
	case DW_OP_mul:
	case DW_OP_or:
	case DW_OP_plus:
	case DW_OP_shl:
	case DW_OP_shr:
	case DW_OP_shra:
	case DW_OP_xor:
	case DW_OP_le:
	case DW_OP_ge:
	case DW_OP_eq:
	case DW_OP_lt:
	case DW_OP_gt:
	case DW_OP_ne:
	case DW_OP_nop:
	case DW_OP_GNU_uninit:
	case DW_OP_push_object_address:
	  break;

	case DW_OP_GNU_push_tls_address:
	case DW_OP_form_tls_address:
	  if (symbol_needs <= SYMBOL_NEEDS_REGISTERS)
	    symbol_needs = SYMBOL_NEEDS_REGISTERS;
	  break;

	case DW_OP_convert:
	case DW_OP_GNU_convert:
	case DW_OP_reinterpret:
	case DW_OP_GNU_reinterpret:
	case DW_OP_addrx:
	case DW_OP_GNU_addr_index:
	case DW_OP_constx:
	case DW_OP_GNU_const_index:
	case DW_OP_constu:
	case DW_OP_plus_uconst:
	case DW_OP_piece:
	  op_ptr = safe_skip_leb128 (op_ptr, expr_end);
	  break;

	case DW_OP_consts:
	  op_ptr = safe_skip_leb128 (op_ptr, expr_end);
	  break;

	case DW_OP_bit_piece:
	  op_ptr = safe_skip_leb128 (op_ptr, expr_end);
	  op_ptr = safe_skip_leb128 (op_ptr, expr_end);
	  break;

	case DW_OP_deref_type:
	case DW_OP_GNU_deref_type:
	  op_ptr++;
	  op_ptr = safe_skip_leb128 (op_ptr, expr_end);
	  break;

	case DW_OP_addr:
	  op_ptr += addr_size;
	  break;

	case DW_OP_const1u:
	case DW_OP_const1s:
	  op_ptr += 1;
	  break;

	case DW_OP_const2u:
	case DW_OP_const2s:
	  op_ptr += 2;
	  break;

	case DW_OP_const4s:
	case DW_OP_const4u:
	  op_ptr += 4;
	  break;

	case DW_OP_const8s:
	case DW_OP_const8u:
	  op_ptr += 8;
	  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:
	case DW_OP_regx:
	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:
	case DW_OP_bregx:
	case DW_OP_fbreg:
	case DW_OP_call_frame_cfa:
	case DW_OP_entry_value:
	case DW_OP_GNU_entry_value:
	case DW_OP_GNU_parameter_ref:
	case DW_OP_regval_type:
	case DW_OP_GNU_regval_type:
	  symbol_needs = SYMBOL_NEEDS_FRAME;
	  break;

	case DW_OP_implicit_value:
	  {
	    uint64_t uoffset;
	    op_ptr = safe_read_uleb128 (op_ptr, expr_end, &uoffset);
	    op_ptr += uoffset;
	    break;
	  }

	case DW_OP_implicit_pointer:
	case DW_OP_GNU_implicit_pointer:
	  op_ptr += ref_addr_size;
	  op_ptr = safe_skip_leb128 (op_ptr, expr_end);
	  break;

	case DW_OP_deref_size:
	case DW_OP_pick:
	  op_ptr++;
	  break;

	case DW_OP_skip:
	  {
	    int64_t offset = extract_signed_integer (op_ptr, 2, byte_order);
	    op_ptr += 2;
	    op_ptr += offset;
	    break;
	  }

	case DW_OP_bra:
	  {
	    /* This is the only operation that pushes two operations in
	       the to-visit list, so handle it all here.  */
	    LONGEST offset = extract_signed_integer (op_ptr, 2, byte_order);
	    op_ptr += 2;

	    insert_in_ops_to_visit (op_ptr + offset);
	    insert_in_ops_to_visit (op_ptr);
	    continue;
	  }

	case DW_OP_call2:
	case DW_OP_call4:
	  {
	    unsigned int len = op == DW_OP_call2 ? 2 : 4;
	    cu_offset cu_off
	      = (cu_offset) extract_unsigned_integer (op_ptr, len, byte_order);
	    op_ptr += len;

	    auto get_frame_pc = [&symbol_needs] ()
	      {
		symbol_needs = SYMBOL_NEEDS_FRAME;
		return 0;
	      };

	    struct dwarf2_locexpr_baton baton
	      = dwarf2_fetch_die_loc_cu_off (cu_off, per_cu,
					     per_objfile,
					     get_frame_pc);

	    /* If SYMBOL_NEEDS_FRAME is returned from the previous call,
	       we dont have to check the baton content.  */
	    if (symbol_needs != SYMBOL_NEEDS_FRAME)
	      {
		gdbarch *arch = baton.per_objfile->objfile->arch ();
		gdb::array_view<const gdb_byte> sub_expr (baton.data,
							  baton.size);
		symbol_needs
		  = dwarf2_get_symbol_read_needs (sub_expr,
						  baton.per_cu,
						  baton.per_objfile,
						  gdbarch_byte_order (arch),
						  baton.per_cu->addr_size (),
						  baton.per_cu->ref_addr_size (),
						  depth);
	      }
	    break;
	  }

	case DW_OP_GNU_variable_value:
	  {
	    sect_offset sect_off
	      = (sect_offset) extract_unsigned_integer (op_ptr,
							ref_addr_size,
							byte_order);
	    op_ptr += ref_addr_size;

	    struct type *die_type
	      = dwarf2_fetch_die_type_sect_off (sect_off, per_cu,
						per_objfile);

	    if (die_type == NULL)
	      error (_("Bad DW_OP_GNU_variable_value DIE."));

	    /* Note: Things still work when the following test is
	       removed.  This test and error is here to conform to the
	       proposed specification.  */
	    if (die_type->code () != TYPE_CODE_INT
	       && die_type->code () != TYPE_CODE_PTR)
	      error (_("Type of DW_OP_GNU_variable_value DIE must be "
		       "an integer or pointer."));

	    auto get_frame_pc = [&symbol_needs] ()
	      {
		symbol_needs = SYMBOL_NEEDS_FRAME;
		return 0;
	      };

	    struct dwarf2_locexpr_baton baton
	      = dwarf2_fetch_die_loc_sect_off (sect_off, per_cu,
					       per_objfile,
					       get_frame_pc, true);

	    /* If SYMBOL_NEEDS_FRAME is returned from the previous call,
	       we dont have to check the baton content.  */
	    if (symbol_needs != SYMBOL_NEEDS_FRAME)
	      {
		gdbarch *arch = baton.per_objfile->objfile->arch ();
		gdb::array_view<const gdb_byte> sub_expr (baton.data,
							  baton.size);
		symbol_needs
		  = dwarf2_get_symbol_read_needs (sub_expr,
						  baton.per_cu,
						  baton.per_objfile,
						  gdbarch_byte_order (arch),
						  baton.per_cu->addr_size (),
						  baton.per_cu->ref_addr_size (),
						  depth);
	      }
	    break;
	  }

	case DW_OP_const_type:
	case DW_OP_GNU_const_type:
	  {
	    uint64_t uoffset;
	    op_ptr = safe_read_uleb128 (op_ptr, expr_end, &uoffset);
	    gdb_byte offset = *op_ptr++;
	    op_ptr += offset;
	    break;
	  }

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

      /* If it is known that a frame information is
	 needed we can stop parsing the expression.  */
      if (symbol_needs == SYMBOL_NEEDS_FRAME)
	break;

      insert_in_ops_to_visit (op_ptr);
    }

  return symbol_needs;
}

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

[[noreturn]] static void
unimplemented (unsigned int op)
{
  const char *name = get_DW_OP_name (op);

  if (name)
    error (_("DWARF operator %s cannot be translated to an agent expression"),
	   name);
  else
    error (_("Unknown DWARF operator 0x%02x cannot be translated "
	     "to an agent expression"),
	   op);
}

/* See dwarf2/loc.h.

   This is basically a wrapper on gdbarch_dwarf2_reg_to_regnum so that we
   can issue a complaint, which is better than having every target's
   implementation of dwarf2_reg_to_regnum do it.  */

int
dwarf_reg_to_regnum (struct gdbarch *arch, int dwarf_reg)
{
  int reg = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_reg);

  if (reg == -1)
    {
      complaint (_("bad DWARF register number %d"), dwarf_reg);
    }
  return reg;
}

/* Subroutine of dwarf_reg_to_regnum_or_error to simplify it.
   Throw an error because DWARF_REG is bad.  */

static void
throw_bad_regnum_error (ULONGEST dwarf_reg)
{
  /* Still want to print -1 as "-1".
     We *could* have int and ULONGEST versions of dwarf2_reg_to_regnum_or_error
     but that's overkill for now.  */
  if ((int) dwarf_reg == dwarf_reg)
    error (_("Unable to access DWARF register number %d"), (int) dwarf_reg);
  error (_("Unable to access DWARF register number %s"),
	 pulongest (dwarf_reg));
}

/* See dwarf2/loc.h.  */

int
dwarf_reg_to_regnum_or_error (struct gdbarch *arch, ULONGEST dwarf_reg)
{
  int reg;

  if (dwarf_reg > INT_MAX)
    throw_bad_regnum_error (dwarf_reg);
  /* Yes, we will end up issuing a complaint and an error if DWARF_REG is
     bad, but that's ok.  */
  reg = dwarf_reg_to_regnum (arch, (int) dwarf_reg);
  if (reg == -1)
    throw_bad_regnum_error (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 (nbytes > 0 && nbytes <= sizeof (LONGEST));

  if (expr->tracing)
    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_byte_order (arch) == BFD_ENDIAN_BIG)
    {
      /* 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
dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
			   unsigned int addr_size, const gdb_byte *op_ptr,
			   const gdb_byte *op_end, dwarf2_per_cu *per_cu,
			   dwarf2_per_objfile *per_objfile)
{
  gdbarch *arch = expr->gdbarch;
  std::vector<int> dw_labels, patches;
  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;
  bool bits_big_endian = byte_order == BFD_ENDIAN_BIG;

  std::vector<int> offsets (op_end - op_ptr, -1);

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

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

      offsets[op_ptr - base] = expr->buf.size ();
      ++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:
	  uoffset = extract_unsigned_integer (op_ptr, addr_size, byte_order);
	  op_ptr += addr_size;
	  /* Some versions of GCC emit DW_OP_addr before
	     DW_OP_GNU_push_tls_address.  In this case the value is an
	     index, not an address.  We don't support things like
	     branching between the address and the TLS op.  */
	  if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
	    uoffset += per_objfile->objfile->text_section_offset ();
	  ax_const_l (expr, uoffset);
	  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 = safe_read_uleb128 (op_ptr, op_end, &uoffset);
	  ax_const_l (expr, uoffset);
	  break;

	case DW_OP_consts:
	  op_ptr = safe_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 = dwarf_reg_to_regnum_or_error (arch, op - DW_OP_reg0);
	  loc->kind = axs_lvalue_register;
	  break;

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

	case DW_OP_implicit_value:
	  {
	    uint64_t len;

	    op_ptr = safe_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 = safe_read_sleb128 (op_ptr, op_end, &offset);
	  i = dwarf_reg_to_regnum_or_error (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 = safe_read_uleb128 (op_ptr, op_end, &reg);
	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
	    i = dwarf_reg_to_regnum_or_error (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;
	    const struct block *b;
	    struct symbol *framefunc;

	    b = block_for_pc (expr->scope);

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

	    framefunc = b->linkage_function ();

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

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

	    op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
	    dwarf2_compile_expr_to_ax (expr, loc, addr_size, datastart,
				       datastart + datalen, per_cu,
				       per_objfile);
	    if (loc->kind == axs_lvalue_register)
	      require_rvalue (expr, loc);

	    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++;
	  ax_pick (expr, offset);
	  break;

	case DW_OP_swap:
	  ax_simple (expr, aop_swap);
	  break;

	case DW_OP_over:
	  ax_pick (expr, 1);
	  break;

	case DW_OP_rot:
	  ax_simple (expr, aop_rot);
	  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;

	    if (size != 1 && size != 2 && size != 4 && size != 8)
	      error (_("Unsupported size %d in %s"),
		     size, get_DW_OP_name (op));
	    access_memory (arch, expr, size * TARGET_CHAR_BIT);
	  }
	  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->buf.size ());
	  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 = safe_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:
	  {
	    int regnum;
	    CORE_ADDR text_offset;
	    LONGEST off;
	    const gdb_byte *cfa_start, *cfa_end;

	    if (dwarf2_fetch_cfa_info (arch, expr->scope, per_cu,
				       &regnum, &off,
				       &text_offset, &cfa_start, &cfa_end))
	      {
		/* Register.  */
		ax_reg (expr, regnum);
		if (off != 0)
		  {
		    ax_const_l (expr, off);
		    ax_simple (expr, aop_add);
		  }
	      }
	    else
	      {
		/* Another expression.  */
		ax_const_l (expr, text_offset);
		dwarf2_compile_expr_to_ax (expr, loc, addr_size, cfa_start,
					   cfa_end, per_cu, per_objfile);
	      }

	    loc->kind = axs_lvalue_memory;
	  }
	  break;

	case DW_OP_GNU_push_tls_address:
	case DW_OP_form_tls_address:
	  unimplemented (op);
	  break;

	case DW_OP_push_object_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);
	  dw_labels.push_back (op_ptr + offset - base);
	  patches.push_back (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);
	  dw_labels.push_back (op_ptr + offset - base);
	  patches.push_back (i);
	  break;

	case DW_OP_nop:
	  break;

	case DW_OP_piece:
	case DW_OP_bit_piece:
	  {
	    uint64_t size;

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

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

	    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 (uoffset > 8)
		  {
		    ax_const_l (expr, uoffset / 8);
		    ax_simple (expr, aop_add);
		    uoffset %= 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;

	    auto get_frame_pc_from_expr = [expr] ()
	      {
		return expr->scope;
	      };
	    cu_offset cuoffset = (cu_offset) uoffset;
	    block = dwarf2_fetch_die_loc_cu_off (cuoffset, per_cu, per_objfile,
						 get_frame_pc_from_expr);

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

	    dwarf2_compile_expr_to_ax (expr, loc, addr_size, block.data,
				       block.data + block.size, per_cu,
				       per_objfile);
	  }
	  break;

	case DW_OP_call_ref:
	  unimplemented (op);

	case DW_OP_GNU_variable_value:
	  unimplemented (op);

	default:
	  unimplemented (op);
	}
    }

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


/* 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, const frame_info_ptr &frame)
{
  struct dwarf2_locexpr_baton *dlbaton
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
  struct value *val;

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

  return val;
}

/* Return the value of SYMBOL in FRAME at (callee) FRAME's function
   entry.  SYMBOL should be a function parameter, otherwise NO_ENTRY_VALUE_ERROR
   will be thrown.  */

static struct value *
locexpr_read_variable_at_entry (struct symbol *symbol, const frame_info_ptr &frame)
{
  struct dwarf2_locexpr_baton *dlbaton
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);

  return value_of_dwarf_block_entry (symbol->type (), frame, dlbaton->data,
				     dlbaton->size);
}

/* Implementation of get_symbol_read_needs from
   symbol_computed_ops.  */

static enum symbol_needs_kind
locexpr_get_symbol_read_needs (struct symbol *symbol)
{
  struct dwarf2_locexpr_baton *dlbaton
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);

  gdbarch *arch = dlbaton->per_objfile->objfile->arch ();
  gdb::array_view<const gdb_byte> expr (dlbaton->data, dlbaton->size);

  return dwarf2_get_symbol_read_needs (expr,
				       dlbaton->per_cu,
				       dlbaton->per_objfile,
				       gdbarch_byte_order (arch),
				       dlbaton->per_cu->addr_size (),
				       dlbaton->per_cu->ref_addr_size ());
}

/* 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;
}

/* Helper for locexpr_describe_location_piece that finds the name of a
   DWARF register.  */

static const char *
locexpr_regname (struct gdbarch *gdbarch, int dwarf_regnum)
{
  int regnum;

  /* This doesn't use dwarf_reg_to_regnum_or_error on purpose.
     We'd rather print *something* here than throw an error.  */
  regnum = dwarf_reg_to_regnum (gdbarch, dwarf_regnum);
  /* gdbarch_register_name may just return "", return something more
     descriptive for bad register numbers.  */
  if (regnum == -1)
    {
      /* The text is output as "$bad_register_number".
	 That is why we use the underscores.  */
      return _("bad_register_number");
    }
  return gdbarch_register_name (gdbarch, regnum);
}

/* 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.  If there is an error during reading, e.g. we run off the end
   of the buffer, an error is thrown.  */

static const gdb_byte *
locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
				 CORE_ADDR addr, dwarf2_per_cu *per_cu,
				 dwarf2_per_objfile *per_objfile,
				 const gdb_byte *data, const gdb_byte *end,
				 unsigned int addr_size)
{
  objfile *objfile = per_objfile->objfile;
  struct gdbarch *gdbarch = objfile->arch ();
  size_t leb128_size;

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

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

      new_data = safe_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 ());

      framefunc = b->linkage_function ();

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

      func_get_frame_base_dwarf_block (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 = safe_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 ());
	}
      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.  */
	  return save_data;
	}

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

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

      gdb_printf (stream,
		  _("a variable at offset %s from base reg $%s"),
		  plongest (offset),
		  locexpr_regname (gdbarch, data[0] - DW_OP_breg0));
    }

  /* 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).  Note that more recent version of GCC emit DW_OP_const4u
     or DW_OP_const8u, depending on address size, rather than
     DW_OP_addr.  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
	       || (addr_size == 4 && data[0] == DW_OP_const4u)
	       || (addr_size == 8 && data[0] == DW_OP_const8u))
	   && (data[1 + addr_size] == DW_OP_GNU_push_tls_address
	       || data[1 + addr_size] == DW_OP_form_tls_address)
	   && piece_end_p (data + 2 + addr_size, end))
    {
      ULONGEST offset;
      offset = extract_unsigned_integer (data + 1, addr_size,
					 gdbarch_byte_order (gdbarch));

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

      data += 1 + addr_size + 1;
    }

  /* With -gsplit-dwarf a TLS variable can also look like this:
     DW_AT_location    : 3 byte block: fc 4 e0
			(DW_OP_GNU_const_index: 4;
			 DW_OP_GNU_push_tls_address) |
			 3 byte block a2 4 e0
			(DW_OP_constx: 4;
			 DW_OP_form_tls_address)  */
  else if (data + 3 <= end
	   && data + 1 + (leb128_size = skip_leb128 (data + 1, end)) < end
	   && (data[0] == DW_OP_constx || data[0] == DW_OP_GNU_const_index)
	   && leb128_size > 0
	   && (data[1 + leb128_size] == DW_OP_GNU_push_tls_address
	       || data[1 + leb128_size] == DW_OP_form_tls_address)
	   && piece_end_p (data + 2 + leb128_size, end))
    {
      uint64_t offset;

      data = safe_read_uleb128 (data + 1, end, &offset);
      offset = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, offset);
      gdb_printf (stream, 
		  _("a thread-local variable at offset 0x%s "
		    "in the thread-local storage for `%s'"),
		  phex_nz (offset, addr_size), objfile_name (objfile));
      ++data;
    }

  else if (data[0] >= DW_OP_lit0
	   && data[0] <= DW_OP_lit31
	   && data + 1 < end
	   && data[1] == DW_OP_stack_value)
    {
      gdb_printf (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.
   If there is an error during reading, e.g. we run off the end
   of the buffer, an error is thrown.  */

static const gdb_byte *
disassemble_dwarf_expression (struct ui_file *stream,
			      struct gdbarch *arch, unsigned int addr_size,
			      int offset_size, const gdb_byte *start,
			      const gdb_byte *data, const gdb_byte *end,
			      int indent, int all,
			      dwarf2_per_cu *per_cu,
			      dwarf2_per_objfile *per_objfile)
{
  while (data < end
	 && (all
	     || (data[0] != DW_OP_piece && data[0] != DW_OP_bit_piece)))
    {
      enum dwarf_location_atom op = (enum dwarf_location_atom) *data++;
      uint64_t ul;
      int64_t l;
      const char *name;

      name = get_DW_OP_name (op);

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

      switch (op)
	{
	case DW_OP_addr:
	  ul = extract_unsigned_integer (data, addr_size,
					 gdbarch_byte_order (arch));
	  data += addr_size;
	  gdb_printf (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;
	  gdb_printf (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_const1s:
	  l = extract_signed_integer (data, 1, gdbarch_byte_order (arch));
	  data += 1;
	  gdb_printf (stream, " %s", plongest (l));
	  break;

	case DW_OP_const2u:
	  ul = extract_unsigned_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  gdb_printf (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_const2s:
	  l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
	  data += 2;
	  gdb_printf (stream, " %s", plongest (l));
	  break;

	case DW_OP_const4u:
	  ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
	  data += 4;
	  gdb_printf (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_const4s:
	  l = extract_signed_integer (data, 4, gdbarch_byte_order (arch));
	  data += 4;
	  gdb_printf (stream, " %s", plongest (l));
	  break;

	case DW_OP_const8u:
	  ul = extract_unsigned_integer (data, 8, gdbarch_byte_order (arch));
	  data += 8;
	  gdb_printf (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_const8s:
	  l = extract_signed_integer (data, 8, gdbarch_byte_order (arch));
	  data += 8;
	  gdb_printf (stream, " %s", plongest (l));
	  break;

	case DW_OP_constu:
	  data = safe_read_uleb128 (data, end, &ul);
	  gdb_printf (stream, " %s", pulongest (ul));
	  break;

	case DW_OP_consts:
	  data = safe_read_sleb128 (data, end, &l);
	  gdb_printf (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:
	  gdb_printf (stream, " [$%s]",
		      locexpr_regname (arch, op - DW_OP_reg0));
	  break;

	case DW_OP_regx:
	  data = safe_read_uleb128 (data, end, &ul);
	  gdb_printf (stream, " %s [$%s]", pulongest (ul),
		      locexpr_regname (arch, (int) ul));
	  break;

	case DW_OP_implicit_value:
	  data = safe_read_uleb128 (data, end, &ul);
	  data += ul;
	  gdb_printf (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 = safe_read_sleb128 (data, end, &l);
	  gdb_printf (stream, " %s [$%s]", plongest (l),
		      locexpr_regname (arch, op - DW_OP_breg0));
	  break;

	case DW_OP_bregx:
	  data = safe_read_uleb128 (data, end, &ul);
	  data = safe_read_sleb128 (data, end, &l);
	  gdb_printf (stream, " register %s [$%s] offset %s",
		      pulongest (ul),
		      locexpr_regname (arch, (int) ul),
		      plongest (l));
	  break;

	case DW_OP_fbreg:
	  data = safe_read_sleb128 (data, end, &l);
	  gdb_printf (stream, " %s", plongest (l));
	  break;

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

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

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

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

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

	case DW_OP_call4:
	  ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
	  data += 4;
	  gdb_printf (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;
	  gdb_printf (stream, " offset %s", phex_nz (ul, offset_size));
	  break;

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

	case DW_OP_bit_piece:
	  {
	    uint64_t offset;

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

	case DW_OP_implicit_pointer:
	case DW_OP_GNU_implicit_pointer:
	  {
	    ul = extract_unsigned_integer (data, offset_size,
					   gdbarch_byte_order (arch));
	    data += offset_size;

	    data = safe_read_sleb128 (data, end, &l);

	    gdb_printf (stream, " DIE %s offset %s",
			phex_nz (ul, offset_size),
			plongest (l));
	  }
	  break;

	case DW_OP_deref_type:
	case DW_OP_GNU_deref_type:
	  {
	    int deref_addr_size = *data++;
	    struct type *type;

	    data = safe_read_uleb128 (data, end, &ul);
	    cu_offset offset = (cu_offset) ul;
	    type = dwarf2_get_die_type (offset, per_cu, per_objfile);
	    gdb_printf (stream, "<");
	    type_print (type, "", stream, -1);
	    gdb_printf (stream, " [0x%s]> %d",
			phex_nz (to_underlying (offset), 0),
			deref_addr_size);
	  }
	  break;

	case DW_OP_const_type:
	case DW_OP_GNU_const_type:
	  {
	    struct type *type;

	    data = safe_read_uleb128 (data, end, &ul);
	    cu_offset type_die = (cu_offset) ul;
	    type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
	    gdb_printf (stream, "<");
	    type_print (type, "", stream, -1);
	    gdb_printf (stream, " [0x%s]>",
			phex_nz (to_underlying (type_die), 0));

	    int n = *data++;
	    gdb_printf (stream, " %d byte block:", n);
	    for (int i = 0; i < n; ++i)
	      gdb_printf (stream, " %02x", data[i]);
	    data += n;
	  }
	  break;

	case DW_OP_regval_type:
	case DW_OP_GNU_regval_type:
	  {
	    uint64_t reg;
	    struct type *type;

	    data = safe_read_uleb128 (data, end, &reg);
	    data = safe_read_uleb128 (data, end, &ul);
	    cu_offset type_die = (cu_offset) ul;

	    type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
	    gdb_printf (stream, "<");
	    type_print (type, "", stream, -1);
	    gdb_printf (stream, " [0x%s]> [$%s]",
			phex_nz (to_underlying (type_die), 0),
			locexpr_regname (arch, reg));
	  }
	  break;

	case DW_OP_convert:
	case DW_OP_GNU_convert:
	case DW_OP_reinterpret:
	case DW_OP_GNU_reinterpret:
	  {
	    data = safe_read_uleb128 (data, end, &ul);
	    cu_offset type_die = (cu_offset) ul;

	    if (to_underlying (type_die) == 0)
	      gdb_printf (stream, "<0>");
	    else
	      {
		struct type *type;

		type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
		gdb_printf (stream, "<");
		type_print (type, "", stream, -1);
		gdb_printf (stream, " [0x%s]>",
			    phex_nz (to_underlying (type_die), 0));
	      }
	  }
	  break;

	case DW_OP_entry_value:
	case DW_OP_GNU_entry_value:
	  data = safe_read_uleb128 (data, end, &ul);
	  gdb_putc ('\n', stream);
	  disassemble_dwarf_expression (stream, arch, addr_size, offset_size,
					start, data, data + ul, indent + 2,
					all, per_cu, per_objfile);
	  data += ul;
	  continue;

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

	case DW_OP_addrx:
	case DW_OP_GNU_addr_index:
	  data = safe_read_uleb128 (data, end, &ul);
	  ul = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, ul);
	  gdb_printf (stream, " 0x%s", phex_nz (ul, addr_size));
	  break;

	case DW_OP_constx:
	case DW_OP_GNU_const_index:
	  data = safe_read_uleb128 (data, end, &ul);
	  ul = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, ul);
	  gdb_printf (stream, " %s", pulongest (ul));
	  break;

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

      gdb_printf (stream, "\n");
    }

  return data;
}

static bool dwarf_always_disassemble;

static void
show_dwarf_always_disassemble (struct ui_file *file, int from_tty,
			       struct cmd_list_element *c, const char *value)
{
  gdb_printf (file,
	      _("Whether to always disassemble "
		"DWARF expressions is %s.\n"),
	      value);
}

/* 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, size_t size,
			     unsigned int addr_size,
			     int offset_size, dwarf2_per_cu *per_cu,
			     dwarf2_per_objfile *per_objfile)
{
  const gdb_byte *end = data + size;
  int first_piece = 1, bad = 0;
  objfile *objfile = per_objfile->objfile;

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

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

      if (!dwarf_always_disassemble)
	{
	  data = locexpr_describe_location_piece (symbol, stream,
						  addr, per_cu, per_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)
	{
	  gdb_printf (stream, _("a complex DWARF expression:\n"));
	  data = disassemble_dwarf_expression (stream,
					       objfile->arch (),
					       addr_size, offset_size, data,
					       data, end, 0,
					       dwarf_always_disassemble,
					       per_cu, per_objfile);
	}

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

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

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

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

	      if (empty)
		gdb_printf (stream,
			    _("an empty %s-bit piece"),
			    pulongest (bits));
	      else
		gdb_printf (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 ());
}

/* 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
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
  unsigned int addr_size = dlbaton->per_cu->addr_size ();
  int offset_size = dlbaton->per_cu->offset_size ();

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

/* 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 agent_expr *ax,
			    struct axs_value *value)
{
  struct dwarf2_locexpr_baton *dlbaton
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (symbol);
  unsigned int addr_size = dlbaton->per_cu->addr_size ();

  if (dlbaton->size == 0)
    value->optimized_out = 1;
  else
    dwarf2_compile_expr_to_ax (ax, value, addr_size, dlbaton->data,
			       dlbaton->data + dlbaton->size, dlbaton->per_cu,
			       dlbaton->per_objfile);
}

/* symbol_computed_ops 'generate_c_location' method.  */

static void
locexpr_generate_c_location (struct symbol *sym, string_file *stream,
			     struct gdbarch *gdbarch,
			     std::vector<bool> &registers_used,
			     CORE_ADDR pc, const char *result_name)
{
#if defined (HAVE_COMPILE)
  struct dwarf2_locexpr_baton *dlbaton
    = (struct dwarf2_locexpr_baton *) SYMBOL_LOCATION_BATON (sym);
  unsigned int addr_size = dlbaton->per_cu->addr_size ();

  if (dlbaton->size == 0)
    error (_("symbol \"%s\" is optimized out"), sym->natural_name ());

  compile_dwarf_expr_to_c (stream, result_name,
			   sym, pc, gdbarch, registers_used, addr_size,
			   dlbaton->data, dlbaton->data + dlbaton->size,
			   dlbaton->per_cu, dlbaton->per_objfile);
#else
  gdb_assert_not_reached ("Compile support was disabled");
#endif
}

/* 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_variable_at_entry,
  locexpr_get_symbol_read_needs,
  locexpr_describe_location,
  0,	/* location_has_loclist */
  locexpr_tracepoint_var_ref,
  locexpr_generate_c_location
};


/* 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, const frame_info_ptr &frame)
{
  struct dwarf2_loclist_baton *dlbaton
    = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
  struct value *val;
  const gdb_byte *data;
  size_t size;
  CORE_ADDR pc = frame ? get_frame_address_in_block (frame) : 0;

  data = dwarf2_find_location_expression (dlbaton, &size, pc);
  val = dwarf2_evaluate_loc_desc (symbol->type (), frame, data, size,
				  dlbaton->per_cu, dlbaton->per_objfile);

  return val;
}

/* Read variable SYMBOL like loclist_read_variable at (callee) FRAME's function
   entry.  SYMBOL should be a function parameter, otherwise NO_ENTRY_VALUE_ERROR
   will be thrown.

   Function always returns non-NULL value, it may be marked optimized out if
   inferior frame information is not available.  It throws NO_ENTRY_VALUE_ERROR
   if it cannot resolve the parameter for any reason.  */

static struct value *
loclist_read_variable_at_entry (struct symbol *symbol, const frame_info_ptr &frame)
{
  struct dwarf2_loclist_baton *dlbaton
    = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
  const gdb_byte *data;
  size_t size;
  CORE_ADDR pc;

  if (frame == NULL || !get_frame_func_if_available (frame, &pc))
    return value::allocate_optimized_out (symbol->type ());

  data = dwarf2_find_location_expression (dlbaton, &size, pc, true);
  if (data == NULL)
    return value::allocate_optimized_out (symbol->type ());

  return value_of_dwarf_block_entry (symbol->type (), frame, data, size);
}

/* Implementation of get_symbol_read_needs from
   symbol_computed_ops.  */

static enum symbol_needs_kind
loclist_symbol_needs (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 SYMBOL_NEEDS_FRAME;
}

/* 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
    = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
  const gdb_byte *loc_ptr, *buf_end;
  dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
  struct objfile *objfile = per_objfile->objfile;
  struct gdbarch *gdbarch = objfile->arch ();
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned int addr_size = dlbaton->per_cu->addr_size ();
  int offset_size = dlbaton->per_cu->offset_size ();
  int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
  unrelocated_addr base_address = dlbaton->base_address;
  int done = 0;

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

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

  /* Iterate through locations until we run out.  */
  while (!done)
    {
      unrelocated_addr low = {}, high = {}; /* init for gcc -Wall */
      int length;
      enum debug_loc_kind kind;
      const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */

      if (dlbaton->dwarf_version < 5 && dlbaton->from_dwo)
	kind = decode_debug_loc_dwo_addresses (dlbaton->per_cu,
					       per_objfile,
					       loc_ptr, buf_end, &new_ptr,
					       &low, &high, byte_order);
      else if (dlbaton->dwarf_version < 5)
	kind = decode_debug_loc_addresses (loc_ptr, buf_end, &new_ptr,
					   &low, &high,
					   byte_order, addr_size,
					   signed_addr_p);
      else
	kind = decode_debug_loclists_addresses (dlbaton->per_cu,
						per_objfile,
						loc_ptr, buf_end, &new_ptr,
						&low, &high, byte_order,
						addr_size, signed_addr_p);
      loc_ptr = new_ptr;
      switch (kind)
	{
	case DEBUG_LOC_END_OF_LIST:
	  done = 1;
	  continue;

	case DEBUG_LOC_BASE_ADDRESS:
	  base_address = high;
	  gdb_printf (stream, _("  Base address %s"),
		      paddress (gdbarch, (CORE_ADDR) base_address));
	  continue;

	case DEBUG_LOC_START_END:
	case DEBUG_LOC_START_LENGTH:
	case DEBUG_LOC_OFFSET_PAIR:
	  break;

	case DEBUG_LOC_BUFFER_OVERFLOW:
	case DEBUG_LOC_INVALID_ENTRY:
	  error (_("Corrupted DWARF expression for symbol \"%s\"."),
		 symbol->print_name ());

	default:
	  gdb_assert_not_reached ("bad debug_loc_kind");
	}

      /* Otherwise, a location expression entry.  */
      if (!dlbaton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
	{
	  low = (unrelocated_addr) ((CORE_ADDR) low
				    + (CORE_ADDR) base_address);
	  high = (unrelocated_addr) ((CORE_ADDR) high
				     + (CORE_ADDR) base_address);
	}

      CORE_ADDR low_reloc = per_objfile->relocate (low);
      CORE_ADDR high_reloc = per_objfile->relocate (high);

      if (dlbaton->dwarf_version < 5)
	 {
	   length = extract_unsigned_integer (loc_ptr, 2, byte_order);
	   loc_ptr += 2;
	 }
      else
	 {
	   unsigned int bytes_read;
	   length = read_unsigned_leb128 (NULL, loc_ptr, &bytes_read);
	   loc_ptr += bytes_read;
	 }

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

      /* Now describe this particular location.  */
      locexpr_describe_location_1 (symbol, low_reloc, stream, loc_ptr, length,
				   addr_size, offset_size,
				   dlbaton->per_cu, per_objfile);

      gdb_printf (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 agent_expr *ax,
			    struct axs_value *value)
{
  struct dwarf2_loclist_baton *dlbaton
    = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
  const gdb_byte *data;
  size_t size;
  unsigned int addr_size = dlbaton->per_cu->addr_size ();

  data = dwarf2_find_location_expression (dlbaton, &size, ax->scope);
  if (size == 0)
    value->optimized_out = 1;
  else
    dwarf2_compile_expr_to_ax (ax, value, addr_size, data, data + size,
			       dlbaton->per_cu, dlbaton->per_objfile);
}

/* symbol_computed_ops 'generate_c_location' method.  */

static void
loclist_generate_c_location (struct symbol *sym, string_file *stream,
			     struct gdbarch *gdbarch,
			     std::vector<bool> &registers_used,
			     CORE_ADDR pc, const char *result_name)
{
#if defined (HAVE_COMPILE)
  struct dwarf2_loclist_baton *dlbaton
    = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (sym);
  unsigned int addr_size = dlbaton->per_cu->addr_size ();
  const gdb_byte *data;
  size_t size;

  data = dwarf2_find_location_expression (dlbaton, &size, pc);
  if (size == 0)
    error (_("symbol \"%s\" is optimized out"), sym->natural_name ());

  compile_dwarf_expr_to_c (stream, result_name,
			   sym, pc, gdbarch, registers_used, addr_size,
			   data, data + size,
			   dlbaton->per_cu,
			   dlbaton->per_objfile);
#else
  gdb_assert_not_reached ("Compile support was disabled");
#endif
}

/* 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_variable_at_entry,
  loclist_symbol_needs,
  loclist_describe_location,
  1,	/* location_has_loclist */
  loclist_tracepoint_var_ref,
  loclist_generate_c_location
};

void _initialize_dwarf2loc ();
void
_initialize_dwarf2loc ()
{
  add_setshow_zuinteger_cmd ("entry-values", class_maintenance,
			     &entry_values_debug,
			     _("\
Set entry values and tail call frames debugging."),
			     _("\
Show entry values and tail call frames debugging."),
			     _("\
When non-zero, the process of determining parameter values from\n\
function entry point and tail call frames will be printed."),
			     NULL,
			     show_entry_values_debug,
			     &setdebuglist, &showdebuglist);

  add_setshow_boolean_cmd ("always-disassemble", class_obscure,
			   &dwarf_always_disassemble, _("\
Set whether `info address' always disassembles DWARF expressions."), _("\
Show whether `info address' always disassembles DWARF expressions."), _("\
When enabled, DWARF expressions are always printed in an assembly-like\n\
syntax.  When disabled, expressions will be printed in a more\n\
conversational style, when possible."),
			   NULL,
			   show_dwarf_always_disassemble,
			   &set_dwarf_cmdlist,
			   &show_dwarf_cmdlist);
}
