]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/dwarf2/loc.c
Turn many optimized-out value functions into methods
[thirdparty/binutils-gdb.git] / gdb / dwarf2 / loc.c
index 4e1316dcbd4afaa932ffe8172513c59826317e27..616db13488b95be81b52765a59d78c588692dc40 100644 (file)
@@ -1,6 +1,6 @@
 /* DWARF 2 location expression support for GDB.
 
-   Copyright (C) 2003-2021 Free Software Foundation, Inc.
+   Copyright (C) 2003-2023 Free Software Foundation, Inc.
 
    Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
 
@@ -48,9 +48,9 @@
 #include "gdbsupport/byte-vector.h"
 
 static struct value *dwarf2_evaluate_loc_desc_full
-  (struct type *type, struct frame_info *frame, const gdb_byte *data,
+  (struct type *type, frame_info_ptr frame, const gdb_byte *data,
    size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
-   struct type *subobj_type, LONGEST subobj_byte_offset);
+   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
@@ -92,7 +92,7 @@ enum debug_loc_kind
 /* Helper function which throws an error if a synthetic pointer is
    invalid.  */
 
-static void
+void
 invalid_synthetic_pointer (void)
 {
   error (_("access outside bounds of object "
@@ -139,7 +139,9 @@ decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end,
   if (*low == 0 && *high == 0)
     return DEBUG_LOC_END_OF_LIST;
 
-  return DEBUG_LOC_START_END;
+  /* 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.
@@ -353,10 +355,10 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
   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);
-  /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = baton->per_objfile->objfile->text_section_offset ();
-  CORE_ADDR base_address = baton->base_address + base_offset;
+  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 ();
+  CORE_ADDR base_address = baton->base_address;
   const gdb_byte *loc_ptr, *buf_end;
 
   loc_ptr = baton->data;
@@ -394,7 +396,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
          return NULL;
 
        case DEBUG_LOC_BASE_ADDRESS:
-         base_address = high + base_offset;
+         base_address = high;
          continue;
 
        case DEBUG_LOC_START_END:
@@ -414,15 +416,14 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
       /* 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
-        base_offset in case we're debugging a PIE executable. However, if the
+        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 (baton->from_dwo && kind != DEBUG_LOC_OFFSET_PAIR)
-       {
-         low += base_offset;
-         high += base_offset;
-       }
-      else
+        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.  */
+      low += text_offset;
+      high += text_offset;
+      if (!baton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
        {
          low += base_address;
          high += base_address;
@@ -452,7 +453,7 @@ dwarf2_find_location_expression (struct dwarf2_loclist_baton *baton,
          if (pc_block)
            pc_func = block_linkage_function (pc_block);
 
-         if (pc_func && pc == BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (pc_func)))
+         if (pc_func && pc == pc_func->value_block ()->entry_pc ())
            {
              *locexpr_length = length;
              return loc_ptr;
@@ -487,7 +488,7 @@ locexpr_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
    LOC_BLOCK functions using a DWARF expression as its DW_AT_frame_base.  */
 
 static CORE_ADDR
-locexpr_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
+locexpr_get_frame_base (struct symbol *framefunc, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch;
   struct type *type;
@@ -515,7 +516,7 @@ locexpr_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
      dwarf2_evaluate_loc_desc returns a value representing a variable at
      that address.  The frame base address is thus this variable's
      address.  */
-  return value_address (result);
+  return result->address ();
 }
 
 /* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
@@ -544,7 +545,7 @@ loclist_find_frame_base_location (struct symbol *framefunc, CORE_ADDR pc,
    LOC_BLOCK functions using a DWARF location list as its DW_AT_frame_base.  */
 
 static CORE_ADDR
-loclist_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
+loclist_get_frame_base (struct symbol *framefunc, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch;
   struct type *type;
@@ -572,7 +573,7 @@ loclist_get_frame_base (struct symbol *framefunc, struct frame_info *frame)
      dwarf2_evaluate_loc_desc returns a value representing a variable at
      that address.  The frame base address is thus this variable's
      address.  */
-  return value_address (result);
+  return result->address ();
 }
 
 /* Vector for inferior functions as represented by LOC_BLOCK, if the inferior
@@ -584,7 +585,7 @@ const struct symbol_block_ops dwarf2_block_frame_base_loclist_funcs =
   loclist_get_frame_base
 };
 
-/* See dwarf2loc.h.  */
+/* See dwarf2/loc.h.  */
 
 void
 func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc,
@@ -616,7 +617,7 @@ compute_var_value (const char *name)
   return nullptr;
 }
 
-/* See dwarf2loc.h.  */
+/* See dwarf2/loc.h.  */
 
 unsigned int entry_values_debug = 0;
 
@@ -626,38 +627,38 @@ static void
 show_entry_values_debug (struct ui_file *file, int from_tty,
                         struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Entry values and tail call frames debugging is %s.\n"),
-                   value);
+  gdb_printf (file,
+             _("Entry values and tail call frames debugging is %s.\n"),
+             value);
 }
 
-/* Find DW_TAG_call_site's DW_AT_call_target address.
-   CALLER_FRAME (for registers) can be NULL if it is not known.  This function
-   always returns valid address or it throws NO_ENTRY_VALUE_ERROR.  */
+/* See gdbtypes.h.  */
 
-static CORE_ADDR
-call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
-                         struct call_site *call_site,
-                         struct frame_info *caller_frame)
+void
+call_site_target::iterate_over_addresses
+     (struct gdbarch *call_site_gdbarch,
+      const struct call_site *call_site,
+      frame_info_ptr caller_frame,
+      iterate_ftype callback) const
 {
-  switch (FIELD_LOC_KIND (call_site->target))
+  switch (m_loc_kind)
     {
-    case FIELD_LOC_KIND_DWARF_BLOCK:
+    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 = FIELD_DWARF_BLOCK (call_site->target);
+       dwarf_block = m_loc.dwarf_block;
        if (dwarf_block == NULL)
          {
            struct bound_minimal_symbol msym;
            
-           msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
+           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),
+                        paddress (call_site_gdbarch, call_site->pc ()),
                         (msym.minsym == NULL ? "???"
                          : msym.minsym->print_name ()));
                        
@@ -666,12 +667,12 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
          {
            struct bound_minimal_symbol msym;
            
-           msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
+           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),
+                        paddress (call_site_gdbarch, call_site->pc ()),
                         (msym.minsym == NULL ? "???"
                          : msym.minsym->print_name ()));
                        
@@ -684,39 +685,57 @@ call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
                                        dwarf_block->per_objfile);
        /* DW_AT_call_target is a DWARF expression, not a DWARF location.  */
        if (VALUE_LVAL (val) == lval_memory)
-         return value_address (val);
+         callback (val->address ());
        else
-         return value_as_address (val);
+         callback (value_as_address (val));
       }
+      break;
 
-    case FIELD_LOC_KIND_PHYSNAME:
+    case call_site_target::PHYSNAME:
       {
        const char *physname;
        struct bound_minimal_symbol msym;
 
-       physname = FIELD_STATIC_PHYSNAME (call_site->target);
+       physname = m_loc.physname;
 
        /* Handle both the mangled and demangled PHYSNAME.  */
        msym = lookup_minimal_symbol (physname, NULL, NULL);
        if (msym.minsym == NULL)
          {
-           msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
+           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),
+                        physname, paddress (call_site_gdbarch, call_site->pc ()),
                         (msym.minsym == NULL ? "???"
                          : msym.minsym->print_name ()));
                        
          }
-       return BMSYMBOL_VALUE_ADDRESS (msym);
+       callback (msym.value_address ());
       }
+      break;
 
-    case FIELD_LOC_KIND_PHYSADDR:
-      return FIELD_STATIC_PHYSADDR (call_site->target);
+    case call_site_target::PHYSADDR:
+      {
+       dwarf2_per_objfile *per_objfile = call_site->per_objfile;
+       CORE_ADDR delta = per_objfile->objfile->text_section_offset ();
+
+       callback (m_loc.physaddr + delta);
+      }
+      break;
+
+    case call_site_target::ADDRESSES:
+      {
+       dwarf2_per_objfile *per_objfile = call_site->per_objfile;
+       CORE_ADDR delta = per_objfile->objfile->text_section_offset ();
+
+       for (unsigned i = 0; i < m_loc.addresses.length; ++i)
+         callback (m_loc.addresses.values[i] + delta);
+      }
+      break;
 
     default:
-      internal_error (__FILE__, __LINE__, _("invalid call site target kind"));
+      internal_error (_("invalid call site target kind"));
     }
 }
 
@@ -730,13 +749,13 @@ 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 || BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) != addr)
+  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 = SYMBOL_TYPE (sym);
+  type = sym->type ();
   gdb_assert (type->code () == TYPE_CODE_FUNC);
   gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
 
@@ -775,31 +794,31 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
 
       func_sym = func_addr_to_tail_call_list (gdbarch, addr);
 
-      for (call_site = TYPE_TAIL_CALL_LIST (SYMBOL_TYPE (func_sym));
+      for (call_site = TYPE_TAIL_CALL_LIST (func_sym->type ());
           call_site; call_site = call_site->tail_call_next)
        {
-         CORE_ADDR target_addr;
-
          /* CALLER_FRAME with registers is not available for tail-call jumped
             frames.  */
-         target_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
-
-         if (target_addr == verify_addr)
+         call_site->iterate_over_addresses (gdbarch, nullptr,
+                                            [&] (CORE_ADDR target_addr)
            {
-             struct bound_minimal_symbol msym;
-             
-             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 (target_addr == verify_addr)
+               {
+                 struct bound_minimal_symbol msym;
+
+                 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);
+             if (addr_hash.insert (target_addr).second)
+               todo.push_back (target_addr);
+           });
        }
     }
 }
@@ -810,12 +829,12 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
 static void
 tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
 {
-  CORE_ADDR addr = call_site->pc;
+  CORE_ADDR addr = call_site->pc ();
   struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (addr - 1);
 
-  fprintf_unfiltered (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
-                     (msym.minsym == NULL ? "???"
-                      : msym.minsym->print_name ()));
+  gdb_printf (gdb_stdlog, " %s(%s)", paddress (gdbarch, addr),
+             (msym.minsym == NULL ? "???"
+              : msym.minsym->print_name ()));
 
 }
 
@@ -829,9 +848,9 @@ tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
 static void
 chain_candidate (struct gdbarch *gdbarch,
                 gdb::unique_xmalloc_ptr<struct call_site_chain> *resultp,
-                std::vector<struct call_site *> *chain)
+                const std::vector<struct call_site *> &chain)
 {
-  long length = chain->size ();
+  long length = chain.size ();
   int callers, callees, idx;
 
   if (*resultp == NULL)
@@ -844,17 +863,17 @@ chain_candidate (struct gdbarch *gdbarch,
                    + sizeof (*result->call_site) * (length - 1)));
       result->length = length;
       result->callers = result->callees = length;
-      if (!chain->empty ())
-       memcpy (result->call_site, chain->data (),
+      if (!chain.empty ())
+       memcpy (result->call_site, chain.data (),
                sizeof (*result->call_site) * length);
       resultp->reset (result);
 
       if (entry_values_debug)
        {
-         fprintf_unfiltered (gdb_stdlog, "tailcall: initial:");
+         gdb_printf (gdb_stdlog, "tailcall: initial:");
          for (idx = 0; idx < length; idx++)
            tailcall_dump (gdbarch, result->call_site[idx]);
-         fputc_unfiltered ('\n', gdb_stdlog);
+         gdb_putc ('\n', gdb_stdlog);
        }
 
       return;
@@ -862,17 +881,17 @@ chain_candidate (struct gdbarch *gdbarch,
 
   if (entry_values_debug)
     {
-      fprintf_unfiltered (gdb_stdlog, "tailcall: compare:");
+      gdb_printf (gdb_stdlog, "tailcall: compare:");
       for (idx = 0; idx < length; idx++)
-       tailcall_dump (gdbarch, chain->at (idx));
-      fputc_unfiltered ('\n', gdb_stdlog);
+       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->at (idx))
+    if ((*resultp)->call_site[idx] != chain[idx])
       {
        (*resultp)->callers = idx;
        break;
@@ -883,7 +902,7 @@ chain_candidate (struct gdbarch *gdbarch,
   callees = std::min ((long) (*resultp)->callees, length);
   for (idx = 0; idx < callees; idx++)
     if ((*resultp)->call_site[(*resultp)->length - 1 - idx]
-       != chain->at (length - 1 - idx))
+       != chain[length - 1 - idx])
       {
        (*resultp)->callees = idx;
        break;
@@ -891,15 +910,15 @@ chain_candidate (struct gdbarch *gdbarch,
 
   if (entry_values_debug)
     {
-      fprintf_unfiltered (gdb_stdlog, "tailcall: reduced:");
+      gdb_printf (gdb_stdlog, "tailcall: reduced:");
       for (idx = 0; idx < (*resultp)->callers; idx++)
        tailcall_dump (gdbarch, (*resultp)->call_site[idx]);
-      fputs_unfiltered (" |", gdb_stdlog);
+      gdb_puts (" |", gdb_stdlog);
       for (idx = 0; idx < (*resultp)->callees; idx++)
        tailcall_dump (gdbarch,
                       (*resultp)->call_site[(*resultp)->length
                                             - (*resultp)->callees + idx]);
-      fputc_unfiltered ('\n', gdb_stdlog);
+      gdb_putc ('\n', gdb_stdlog);
     }
 
   if ((*resultp)->callers == 0 && (*resultp)->callees == 0)
@@ -918,11 +937,75 @@ chain_candidate (struct gdbarch *gdbarch,
   gdb_assert ((*resultp)->callers + (*resultp)->callees <= (*resultp)->length);
 }
 
-/* Create and return call_site_chain for CALLER_PC and CALLEE_PC.  All the
-   assumed frames between them use GDBARCH.  Use depth first search so we can
-   keep single CHAIN of call_site's back to CALLER_PC.  Function recursion
-   would have needless GDB stack overhead.  Any unreliability results
-   in thrown NO_ENTRY_VALUE_ERROR.  */
+/* 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,
+      std::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,
@@ -938,6 +1021,12 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
      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)
@@ -952,74 +1041,10 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
      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);
-
-  while (call_site)
-    {
-      CORE_ADDR target_func_addr;
-      struct call_site *target_call_site;
-
-      /* CALLER_FRAME with registers is not available for tail-call jumped
-        frames.  */
-      target_func_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
-
-      if (target_func_addr == callee_pc)
-       {
-         chain_candidate (gdbarch, &retval, &chain);
-         if (retval == NULL)
-           break;
-
-         /* There is no way to reach CALLEE_PC again as we would prevent
-            entering it twice as being already marked in ADDR_HASH.  */
-         target_call_site = NULL;
-       }
-      else
-       {
-         struct symbol *target_func;
-
-         target_func = func_addr_to_tail_call_list (gdbarch, target_func_addr);
-         target_call_site = TYPE_TAIL_CALL_LIST (SYMBOL_TYPE (target_func));
-       }
-
-      do
-       {
-         /* Attempt to visit TARGET_CALL_SITE.  */
-
-         if (target_call_site)
-           {
-             if (addr_hash.insert (target_call_site->pc).second)
-               {
-                 /* Successfully entered TARGET_CALL_SITE.  */
-
-                 chain.push_back (target_call_site);
-                 break;
-               }
-           }
-
-         /* Backtrack (without revisiting the originating call_site).  Try the
-            callers's sibling; if there isn't any try the callers's callers's
-            sibling etc.  */
-
-         target_call_site = NULL;
-         while (!chain.empty ())
-           {
-             call_site = chain.back ();
-             chain.pop_back ();
-
-             size_t removed = addr_hash.erase (call_site->pc);
-             gdb_assert (removed == 1);
-
-             target_call_site = call_site->tail_call_next;
-             if (target_call_site)
-               break;
-           }
-       }
-      while (target_call_site);
-
-      if (chain.empty ())
-       call_site = NULL;
-      else
-       call_site = chain.back ();
-    }
+  /* 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)
     {
@@ -1097,7 +1122,7 @@ call_site_parameter_matches (struct call_site_parameter *parameter,
 /* See loc.h.  */
 
 struct call_site_parameter *
-dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
+dwarf_expr_reg_to_entry_parameter (frame_info_ptr frame,
                                   enum call_site_parameter_kind kind,
                                   union call_site_parameter_u kind_u,
                                   dwarf2_per_cu_data **per_cu_return,
@@ -1105,7 +1130,7 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
 {
   CORE_ADDR func_addr, caller_pc;
   struct gdbarch *gdbarch;
-  struct frame_info *caller_frame;
+  frame_info_ptr caller_frame;
   struct call_site *call_site;
   int iparams;
   /* Initialize it just to avoid a GCC false warning.  */
@@ -1151,19 +1176,32 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
   caller_pc = get_frame_pc (caller_frame);
   call_site = call_site_for_pc (gdbarch, caller_pc);
 
-  target_addr = call_site_to_target_addr (gdbarch, call_site, caller_frame);
-  if (target_addr != func_addr)
+  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 "
+                  _("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));
     }
@@ -1209,12 +1247,11 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
 static struct value *
 dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
                                CORE_ADDR deref_size, struct type *type,
-                               struct frame_info *caller_frame,
+                               frame_info_ptr caller_frame,
                                dwarf2_per_cu_data *per_cu,
                                dwarf2_per_objfile *per_objfile)
 {
   const gdb_byte *data_src;
-  gdb_byte *data;
   size_t size;
 
   data_src = deref_size == -1 ? parameter->value : parameter->data_value;
@@ -1225,15 +1262,8 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
     throw_error (NO_ENTRY_VALUE_ERROR,
                 _("Cannot resolve DW_AT_call_data_value"));
 
-  /* DW_AT_call_value is a DWARF expression, not a DWARF
-     location.  Postprocessing of DWARF_VALUE_MEMORY would lose the type from
-     DWARF block.  */
-  data = (gdb_byte *) alloca (size + 1);
-  memcpy (data, data_src, size);
-  data[size] = DW_OP_stack_value;
-
-  return dwarf2_evaluate_loc_desc (type, caller_frame, data, size + 1, per_cu,
-                                  per_objfile);
+  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
@@ -1243,14 +1273,14 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
 static struct value *
 entry_data_value_coerce_ref (const struct value *value)
 {
-  struct type *checked_type = check_typedef (value_type (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 (value);
-  value_incref (target_val);
+  target_val = (struct value *) value->computed_closure ();
+  target_val->incref ();
   return target_val;
 }
 
@@ -1259,9 +1289,9 @@ entry_data_value_coerce_ref (const struct value *value)
 static void *
 entry_data_value_copy_closure (const struct value *v)
 {
-  struct value *target_val = (struct value *) value_computed_closure (v);
+  struct value *target_val = (struct value *) v->computed_closure ();
 
-  value_incref (target_val);
+  target_val->incref ();
   return target_val;
 }
 
@@ -1270,9 +1300,9 @@ entry_data_value_copy_closure (const struct value *v)
 static void
 entry_data_value_free_closure (struct value *v)
 {
-  struct value *target_val = (struct value *) value_computed_closure (v);
+  struct value *target_val = (struct value *) v->computed_closure ();
 
-  value_decref (target_val);
+  target_val->decref ();
 }
 
 /* Vector for methods for an entry value reference where the referenced value
@@ -1283,6 +1313,7 @@ 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 */
@@ -1290,21 +1321,15 @@ static const struct lval_funcs entry_data_value_funcs =
   entry_data_value_free_closure
 };
 
-/* Read parameter of TYPE at (callee) FRAME's function entry.  KIND and KIND_U
-   are 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_reg_entry (struct type *type, struct frame_info *frame,
+/* See dwarf2/loc.h.  */
+struct value *
+value_of_dwarf_reg_entry (struct type *type, 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 = TYPE_TARGET_TYPE (checked_type);
-  struct frame_info *caller_frame = get_prev_frame (frame);
+  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_data *caller_per_cu;
@@ -1325,22 +1350,23 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
      entry value.  */
 
   if (!TYPE_IS_REFERENCE (checked_type)
-      || TYPE_TARGET_TYPE (checked_type) == NULL)
+      || checked_type->target_type () == NULL)
     return outer_val;
 
   target_val = dwarf_entry_parameter_to_value (parameter,
-                                              TYPE_LENGTH (target_type),
+                                              target_type->length (),
                                               target_type, caller_frame,
                                               caller_per_cu,
                                               caller_per_objfile);
 
-  val = allocate_computed_value (type, &entry_data_value_funcs,
+  val = value::allocate_computed (type, &entry_data_value_funcs,
                                 release_value (target_val).release ());
 
   /* Copy the referencing pointer to the new computed value.  */
-  memcpy (value_contents_raw (val), value_contents_raw (outer_val),
-         TYPE_LENGTH (checked_type));
-  set_value_lazy (val, 0);
+  memcpy (val->contents_raw ().data (),
+         outer_val->contents_raw ().data (),
+         checked_type->length ());
+  val->set_lazy (0);
 
   return val;
 }
@@ -1353,7 +1379,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
    cannot resolve the parameter for any reason.  */
 
 static struct value *
-value_of_dwarf_block_entry (struct type *type, struct frame_info *frame,
+value_of_dwarf_block_entry (struct type *type, frame_info_ptr frame,
                            const gdb_byte *block, size_t block_len)
 {
   union call_site_parameter_u kind_u;
@@ -1394,16 +1420,16 @@ fetch_const_value_from_synthetic_pointer (sect_offset die, LONGEST byte_offset,
   if (bytes != NULL)
     {
       if (byte_offset >= 0
-         && byte_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)) <= len)
+         && byte_offset + type->target_type ()->length () <= len)
        {
          bytes += byte_offset;
-         result = value_from_contents (TYPE_TARGET_TYPE (type), bytes);
+         result = value_from_contents (type->target_type (), bytes);
        }
       else
        invalid_synthetic_pointer ();
     }
   else
-    result = allocate_optimized_out_value (TYPE_TARGET_TYPE (type));
+    result = value::allocate_optimized_out (type->target_type ());
 
   return result;
 }
@@ -1414,7 +1440,7 @@ struct value *
 indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
                            dwarf2_per_cu_data *per_cu,
                            dwarf2_per_objfile *per_objfile,
-                           struct frame_info *frame, struct type *type,
+                           frame_info_ptr frame, struct type *type,
                            bool resolve_abstract_p)
 {
   /* Fetch the location expression of the DIE we're pointing to.  */
@@ -1440,7 +1466,7 @@ indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
     return dwarf2_evaluate_loc_desc_full (orig_type, frame, baton.data,
                                          baton.size, baton.per_cu,
                                          baton.per_objfile,
-                                         TYPE_TARGET_TYPE (type),
+                                         type->target_type (),
                                          byte_offset);
   else
     return fetch_const_value_from_synthetic_pointer (die, byte_offset, per_cu,
@@ -1454,15 +1480,14 @@ indirect_synthetic_pointer (sect_offset die, LONGEST byte_offset,
    SUBOBJ_BYTE_OFFSET within the variable of type TYPE.  */
 
 static struct value *
-dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+dwarf2_evaluate_loc_desc_full (struct type *type, frame_info_ptr frame,
                               const gdb_byte *data, size_t size,
                               dwarf2_per_cu_data *per_cu,
                               dwarf2_per_objfile *per_objfile,
                               struct type *subobj_type,
-                              LONGEST subobj_byte_offset)
+                              LONGEST subobj_byte_offset,
+                              bool as_lval)
 {
-  struct value *retval;
-
   if (subobj_type == NULL)
     {
       subobj_type = type;
@@ -1472,30 +1497,26 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
     invalid_synthetic_pointer ();
 
   if (size == 0)
-    return allocate_optimized_out_value (subobj_type);
+    return value::allocate_optimized_out (subobj_type);
 
-  dwarf_expr_context ctx (per_objfile);
-  ctx.frame = frame;
-  ctx.per_cu = per_cu;
-  ctx.obj_address = 0;
+  dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
 
+  value *retval;
   scoped_value_mark free_values;
 
-  ctx.gdbarch = per_objfile->objfile->arch ();
-  ctx.addr_size = per_cu->addr_size ();
-
   try
     {
-      ctx.eval (data, size);
+      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 = allocate_value (subobj_type);
-         mark_value_bytes_unavailable (retval, 0,
-                                       TYPE_LENGTH (subobj_type));
+         retval = value::allocate (subobj_type);
+         retval->mark_bytes_unavailable (0,
+                                         subobj_type->length ());
          return retval;
        }
       else if (ex.error == NO_ENTRY_VALUE_ERROR)
@@ -1503,174 +1524,34 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
          if (entry_values_debug)
            exception_print (gdb_stdout, ex);
          free_values.free_to_mark ();
-         return allocate_optimized_out_value (subobj_type);
+         return value::allocate_optimized_out (subobj_type);
        }
       else
        throw;
     }
 
-  if (ctx.pieces.size () > 0)
-    {
-      struct piece_closure *c;
-      ULONGEST bit_size = 0;
-
-      for (dwarf_expr_piece &piece : ctx.pieces)
-       bit_size += piece.size;
-      /* Complain if the expression is larger than the size of the
-        outer type.  */
-      if (bit_size > 8 * TYPE_LENGTH (type))
-       invalid_synthetic_pointer ();
-
-      c = allocate_piece_closure (per_cu, per_objfile, std::move (ctx.pieces),
-                                 frame);
-      /* We must clean up the value chain after creating the piece
-        closure but before allocating the result.  */
-      free_values.free_to_mark ();
-      retval = allocate_computed_value (subobj_type,
-                                       &pieced_value_funcs, c);
-      set_value_offset (retval, subobj_byte_offset);
-    }
-  else
-    {
-      switch (ctx.location)
-       {
-       case DWARF_VALUE_REGISTER:
-         {
-           struct gdbarch *arch = get_frame_arch (frame);
-           int dwarf_regnum
-             = longest_to_int (value_as_long (ctx.fetch (0)));
-           int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, dwarf_regnum);
-
-           if (subobj_byte_offset != 0)
-             error (_("cannot use offset on synthetic pointer to register"));
-           free_values.free_to_mark ();
-           retval = value_from_register (subobj_type, gdb_regnum, frame);
-           if (value_optimized_out (retval))
-             {
-               struct value *tmp;
-
-               /* This means the register has undefined value / was
-                  not saved.  As we're computing the location of some
-                  variable etc. in the program, not a value for
-                  inspecting a register ($pc, $sp, etc.), return a
-                  generic optimized out value instead, so that we show
-                  <optimized out> instead of <not saved>.  */
-               tmp = allocate_value (subobj_type);
-               value_contents_copy (tmp, 0, retval, 0,
-                                    TYPE_LENGTH (subobj_type));
-               retval = tmp;
-             }
-         }
-         break;
-
-       case DWARF_VALUE_MEMORY:
-         {
-           struct type *ptr_type;
-           CORE_ADDR address = ctx.fetch_address (0);
-           bool in_stack_memory = ctx.fetch_in_stack_memory (0);
-
-           /* DW_OP_deref_size (and possibly other operations too) may
-              create a pointer instead of an address.  Ideally, the
-              pointer to address conversion would be performed as part
-              of those operations, but the type of the object to
-              which the address refers is not known at the time of
-              the operation.  Therefore, we do the conversion here
-              since the type is readily available.  */
-
-           switch (subobj_type->code ())
-             {
-               case TYPE_CODE_FUNC:
-               case TYPE_CODE_METHOD:
-                 ptr_type = builtin_type (ctx.gdbarch)->builtin_func_ptr;
-                 break;
-               default:
-                 ptr_type = builtin_type (ctx.gdbarch)->builtin_data_ptr;
-                 break;
-             }
-           address = value_as_address (value_from_pointer (ptr_type, address));
-
-           free_values.free_to_mark ();
-           retval = value_at_lazy (subobj_type,
-                                   address + subobj_byte_offset);
-           if (in_stack_memory)
-             set_value_stack (retval, 1);
-         }
-         break;
-
-       case DWARF_VALUE_STACK:
-         {
-           struct value *value = ctx.fetch (0);
-           size_t n = TYPE_LENGTH (value_type (value));
-           size_t len = TYPE_LENGTH (subobj_type);
-           size_t max = TYPE_LENGTH (type);
-           gdbarch *objfile_gdbarch = per_objfile->objfile->arch ();
-
-           if (subobj_byte_offset + len > max)
-             invalid_synthetic_pointer ();
-
-           /* Preserve VALUE because we are going to free values back
-              to the mark, but we still need the value contents
-              below.  */
-           value_ref_ptr value_holder = value_ref_ptr::new_reference (value);
-           free_values.free_to_mark ();
+  /* 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 ();
 
-           retval = allocate_value (subobj_type);
-
-           /* The given offset is relative to the actual object.  */
-           if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
-             subobj_byte_offset += n - max;
-
-           memcpy (value_contents_raw (retval),
-                   value_contents_all (value) + subobj_byte_offset, len);
-         }
-         break;
-
-       case DWARF_VALUE_LITERAL:
-         {
-           bfd_byte *contents;
-           size_t n = TYPE_LENGTH (subobj_type);
-
-           if (subobj_byte_offset + n > ctx.len)
-             invalid_synthetic_pointer ();
-
-           free_values.free_to_mark ();
-           retval = allocate_value (subobj_type);
-           contents = value_contents_raw (retval);
-           memcpy (contents, ctx.data + subobj_byte_offset, n);
-         }
-         break;
-
-       case DWARF_VALUE_OPTIMIZED_OUT:
-         free_values.free_to_mark ();
-         retval = allocate_optimized_out_value (subobj_type);
-         break;
-
-         /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced
-            operation by execute_stack_op.  */
-       case DWARF_VALUE_IMPLICIT_POINTER:
-         /* DWARF_VALUE_OPTIMIZED_OUT can't occur in this context --
-            it can only be encountered when making a piece.  */
-       default:
-         internal_error (__FILE__, __LINE__, _("invalid location type"));
-       }
-    }
-
-  set_value_initialized (retval, ctx.initialized);
-
-  return retval;
+  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, struct frame_info *frame,
+dwarf2_evaluate_loc_desc (struct type *type, frame_info_ptr frame,
                          const gdb_byte *data, size_t size,
                          dwarf2_per_cu_data *per_cu,
-                         dwarf2_per_objfile *per_objfile)
+                         dwarf2_per_objfile *per_objfile, bool as_lval)
 {
   return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu,
-                                       per_objfile, NULL, 0);
+                                       per_objfile, NULL, 0, as_lval);
 }
 
 /* Evaluates a dwarf expression and stores the result in VAL,
@@ -1678,43 +1559,39 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
    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_INITIAL_VALUE is true if the address (either from ADDR_STACK,
-   or the default of 0) should be pushed on the DWARF expression
-   evaluation stack before evaluating the expression; this is required
-   by certain forms of DWARF expression.  Returns 1 on success, 0
-   otherwise.  */
+
+   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,
-                          struct frame_info *frame,
+                          frame_info_ptr frame,
                           const struct property_addr_info *addr_stack,
                           CORE_ADDR *valp,
-                          bool push_initial_value,
+                          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;
-  dwarf_expr_context ctx (per_objfile);
+  dwarf2_per_cu_data *per_cu = dlbaton->per_cu;
+  dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
 
-  ctx.frame = frame;
-  ctx.per_cu = dlbaton->per_cu;
-  if (addr_stack != nullptr)
-    {
-      ctx.obj_address = addr_stack->addr;
-      ctx.data_view = addr_stack->valaddr;
-    }
-
-  ctx.gdbarch = per_objfile->objfile->arch ();
-  ctx.addr_size = dlbaton->per_cu->addr_size ();
+  value *result;
+  scoped_value_mark free_values;
 
-  if (push_initial_value)
-    ctx.push_address (ctx.obj_address, false);
+  /* Place any initial values onto the expression stack.  */
+  for (const auto &val : push_values)
+    ctx.push_address (val, false);
 
   try
     {
-      ctx.eval (dlbaton->data, dlbaton->size);
+      result = ctx.evaluate (dlbaton->data, dlbaton->size,
+                            true, per_cu, frame, addr_stack);
     }
   catch (const gdb_exception_error &ex)
     {
@@ -1732,43 +1609,39 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
        throw;
     }
 
-  switch (ctx.location)
+  if (result->optimized_out ())
+    return 0;
+
+  if (VALUE_LVAL (result) == lval_memory)
+    *valp = result->address ();
+  else
     {
-    case DWARF_VALUE_STACK:
-      *is_reference = false;
-      /* FALLTHROUGH */
-
-    case DWARF_VALUE_REGISTER:
-    case DWARF_VALUE_MEMORY:
-      *valp = ctx.fetch_address (0);
-      if (ctx.location == DWARF_VALUE_REGISTER)
-       *valp = read_addr_from_reg (frame, *valp);
-      return 1;
-    case DWARF_VALUE_LITERAL:
-      *valp = extract_signed_integer (ctx.data, ctx.len,
-                                     gdbarch_byte_order (ctx.gdbarch));
-      return 1;
-      /* Unsupported dwarf values.  */
-    case DWARF_VALUE_OPTIMIZED_OUT:
-    case DWARF_VALUE_IMPLICIT_POINTER:
-      break;
+      if (VALUE_LVAL (result) == not_lval)
+       *is_reference = false;
+
+      *valp = value_as_address (result);
     }
 
-  return 0;
+  return 1;
 }
 
-/* See dwarf2loc.h.  */
+/* See dwarf2/loc.h.  */
 
 bool
 dwarf2_evaluate_property (const struct dynamic_prop *prop,
-                         struct frame_info *frame,
+                         frame_info_ptr frame,
                          const struct property_addr_info *addr_stack,
                          CORE_ADDR *value,
-                         bool push_initial_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;
+
   if (frame == NULL && has_stack_frames ())
     frame = get_selected_frame (NULL);
 
@@ -1782,7 +1655,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
 
        bool is_reference = baton->locexpr.is_reference;
        if (dwarf2_locexpr_baton_eval (&baton->locexpr, frame, addr_stack,
-                                      value, push_initial_value, &is_reference))
+                                      value, push_values, &is_reference))
          {
            if (is_reference)
              {
@@ -1794,7 +1667,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
                gdb_assert (baton->property_type != NULL);
 
                struct type *type = check_typedef (baton->property_type);
-               if (TYPE_LENGTH (type) < sizeof (CORE_ADDR)
+               if (type->length () < sizeof (CORE_ADDR)
                    && !type->is_unsigned ())
                  {
                    /* If we have a valid return candidate and it's value
@@ -1836,7 +1709,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
            val = dwarf2_evaluate_loc_desc (baton->property_type, frame, data,
                                            size, baton->loclist.per_cu,
                                            baton->loclist.per_objfile);
-           if (!value_optimized_out (val))
+           if (!val->optimized_out ())
              {
                *value = value_as_address (val);
                return true;
@@ -1891,7 +1764,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop,
   return false;
 }
 
-/* See dwarf2loc.h.  */
+/* See dwarf2/loc.h.  */
 
 void
 dwarf2_compile_property_to_c (string_file *stream,
@@ -2380,7 +2253,7 @@ unimplemented (unsigned int op)
           op);
 }
 
-/* See dwarf2loc.h.
+/* 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
@@ -2413,7 +2286,7 @@ throw_bad_regnum_error (ULONGEST dwarf_reg)
         pulongest (dwarf_reg));
 }
 
-/* See dwarf2loc.h.  */
+/* See dwarf2/loc.h.  */
 
 int
 dwarf_reg_to_regnum_or_error (struct gdbarch *arch, ULONGEST dwarf_reg)
@@ -3157,7 +3030,7 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
     {
       int targ = offsets[dw_labels[i]];
       if (targ == -1)
-       internal_error (__FILE__, __LINE__, _("invalid label"));
+       internal_error (_("invalid label"));
       ax_label (expr, patches[i], targ);
     }
 }
@@ -3166,13 +3039,13 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
    evaluator to calculate the location.  */
 static struct value *
-locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
+locexpr_read_variable (struct symbol *symbol, 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 (symbol), frame, dlbaton->data,
+  val = dwarf2_evaluate_loc_desc (symbol->type (), frame, dlbaton->data,
                                  dlbaton->size, dlbaton->per_cu,
                                  dlbaton->per_objfile);
 
@@ -3184,12 +3057,12 @@ locexpr_read_variable (struct symbol *symbol, struct frame_info *frame)
    will be thrown.  */
 
 static struct value *
-locexpr_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
+locexpr_read_variable_at_entry (struct symbol *symbol, 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 (symbol), frame, dlbaton->data,
+  return value_of_dwarf_block_entry (symbol->type (), frame, dlbaton->data,
                                     dlbaton->size);
 }
 
@@ -3263,8 +3136,8 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
 
   if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31)
     {
-      fprintf_filtered (stream, _("a variable in $%s"),
-                       locexpr_regname (gdbarch, data[0] - DW_OP_reg0));
+      gdb_printf (stream, _("a variable in $%s"),
+                 locexpr_regname (gdbarch, data[0] - DW_OP_reg0));
       data += 1;
     }
   else if (data[0] == DW_OP_regx)
@@ -3272,8 +3145,8 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       uint64_t reg;
 
       data = safe_read_uleb128 (data + 1, end, &reg);
-      fprintf_filtered (stream, _("a variable in $%s"),
-                       locexpr_regname (gdbarch, reg));
+      gdb_printf (stream, _("a variable in $%s"),
+                 locexpr_regname (gdbarch, reg));
     }
   else if (data[0] == DW_OP_fbreg)
     {
@@ -3329,10 +3202,10 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
          return save_data;
        }
 
-      fprintf_filtered (stream,
-                       _("a variable at frame base reg $%s offset %s+%s"),
-                       locexpr_regname (gdbarch, frame_reg),
-                       plongest (base_offset), plongest (frame_offset));
+      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))
@@ -3341,10 +3214,10 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
 
       data = safe_read_sleb128 (data + 1, end, &offset);
 
-      fprintf_filtered (stream,
-                       _("a variable at offset %s from base reg $%s"),
-                       plongest (offset),
-                       locexpr_regname (gdbarch, data[0] - DW_OP_breg0));
+      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
@@ -3373,10 +3246,10 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       offset = extract_unsigned_integer (data + 1, addr_size,
                                         gdbarch_byte_order (gdbarch));
 
-      fprintf_filtered (stream, 
-                       _("a thread-local variable at offset 0x%s "
-                         "in the thread-local storage for `%s'"),
-                       phex_nz (offset, addr_size), objfile_name (objfile));
+      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;
     }
@@ -3397,10 +3270,10 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
 
       data = safe_read_uleb128 (data + 1, end, &offset);
       offset = dwarf2_read_addr_index (per_cu, per_objfile, offset);
-      fprintf_filtered (stream, 
-                       _("a thread-local variable at offset 0x%s "
-                         "in the thread-local storage for `%s'"),
-                       phex_nz (offset, addr_size), objfile_name (objfile));
+      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;
     }
 
@@ -3409,7 +3282,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
           && data + 1 < end
           && data[1] == DW_OP_stack_value)
     {
-      fprintf_filtered (stream, _("the constant %d"), data[0] - DW_OP_lit0);
+      gdb_printf (stream, _("the constant %d"), data[0] - DW_OP_lit0);
       data += 2;
     }
 
@@ -3446,8 +3319,8 @@ disassemble_dwarf_expression (struct ui_file *stream,
       if (!name)
        error (_("Unrecognized DWARF opcode 0x%02x at %ld"),
               op, (long) (data - 1 - start));
-      fprintf_filtered (stream, "  %*ld: %s", indent + 4,
-                       (long) (data - 1 - start), name);
+      gdb_printf (stream, "  %*ld: %s", indent + 4,
+                 (long) (data - 1 - start), name);
 
       switch (op)
        {
@@ -3455,65 +3328,65 @@ disassemble_dwarf_expression (struct ui_file *stream,
          ul = extract_unsigned_integer (data, addr_size,
                                         gdbarch_byte_order (arch));
          data += addr_size;
-         fprintf_filtered (stream, " 0x%s", phex_nz (ul, 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;
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_const1s:
          l = extract_signed_integer (data, 1, gdbarch_byte_order (arch));
          data += 1;
-         fprintf_filtered (stream, " %s", plongest (l));
+         gdb_printf (stream, " %s", plongest (l));
          break;
 
        case DW_OP_const2u:
          ul = extract_unsigned_integer (data, 2, gdbarch_byte_order (arch));
          data += 2;
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_const2s:
          l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
          data += 2;
-         fprintf_filtered (stream, " %s", plongest (l));
+         gdb_printf (stream, " %s", plongest (l));
          break;
 
        case DW_OP_const4u:
          ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
          data += 4;
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_const4s:
          l = extract_signed_integer (data, 4, gdbarch_byte_order (arch));
          data += 4;
-         fprintf_filtered (stream, " %s", plongest (l));
+         gdb_printf (stream, " %s", plongest (l));
          break;
 
        case DW_OP_const8u:
          ul = extract_unsigned_integer (data, 8, gdbarch_byte_order (arch));
          data += 8;
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_const8s:
          l = extract_signed_integer (data, 8, gdbarch_byte_order (arch));
          data += 8;
-         fprintf_filtered (stream, " %s", plongest (l));
+         gdb_printf (stream, " %s", plongest (l));
          break;
 
        case DW_OP_constu:
          data = safe_read_uleb128 (data, end, &ul);
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_consts:
          data = safe_read_sleb128 (data, end, &l);
-         fprintf_filtered (stream, " %s", plongest (l));
+         gdb_printf (stream, " %s", plongest (l));
          break;
 
        case DW_OP_reg0:
@@ -3548,20 +3421,20 @@ disassemble_dwarf_expression (struct ui_file *stream,
        case DW_OP_reg29:
        case DW_OP_reg30:
        case DW_OP_reg31:
-         fprintf_filtered (stream, " [$%s]",
-                           locexpr_regname (arch, op - DW_OP_reg0));
+         gdb_printf (stream, " [$%s]",
+                     locexpr_regname (arch, op - DW_OP_reg0));
          break;
 
        case DW_OP_regx:
          data = safe_read_uleb128 (data, end, &ul);
-         fprintf_filtered (stream, " %s [$%s]", pulongest (ul),
-                           locexpr_regname (arch, (int) 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;
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_breg0:
@@ -3597,72 +3470,72 @@ disassemble_dwarf_expression (struct ui_file *stream,
        case DW_OP_breg30:
        case DW_OP_breg31:
          data = safe_read_sleb128 (data, end, &l);
-         fprintf_filtered (stream, " %s [$%s]", plongest (l),
-                           locexpr_regname (arch, op - DW_OP_breg0));
+         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);
-         fprintf_filtered (stream, " register %s [$%s] offset %s",
-                           pulongest (ul),
-                           locexpr_regname (arch, (int) ul),
-                           plongest (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);
-         fprintf_filtered (stream, " %s", plongest (l));
+         gdb_printf (stream, " %s", plongest (l));
          break;
 
        case DW_OP_xderef_size:
        case DW_OP_deref_size:
        case DW_OP_pick:
-         fprintf_filtered (stream, " %d", *data);
+         gdb_printf (stream, " %d", *data);
          ++data;
          break;
 
        case DW_OP_plus_uconst:
          data = safe_read_uleb128 (data, end, &ul);
-         fprintf_filtered (stream, " %s", pulongest (ul));
+         gdb_printf (stream, " %s", pulongest (ul));
          break;
 
        case DW_OP_skip:
          l = extract_signed_integer (data, 2, gdbarch_byte_order (arch));
          data += 2;
-         fprintf_filtered (stream, " to %ld",
-                           (long) (data + l - start));
+         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;
-         fprintf_filtered (stream, " %ld",
-                           (long) (data + l - start));
+         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;
-         fprintf_filtered (stream, " offset %s", phex_nz (ul, 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;
-         fprintf_filtered (stream, " offset %s", phex_nz (ul, 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;
-         fprintf_filtered (stream, " offset %s", phex_nz (ul, offset_size));
+         gdb_printf (stream, " offset %s", phex_nz (ul, offset_size));
          break;
 
        case DW_OP_piece:
          data = safe_read_uleb128 (data, end, &ul);
-         fprintf_filtered (stream, " %s (bytes)", pulongest (ul));
+         gdb_printf (stream, " %s (bytes)", pulongest (ul));
          break;
 
        case DW_OP_bit_piece:
@@ -3671,8 +3544,8 @@ disassemble_dwarf_expression (struct ui_file *stream,
 
            data = safe_read_uleb128 (data, end, &ul);
            data = safe_read_uleb128 (data, end, &offset);
-           fprintf_filtered (stream, " size %s offset %s (bits)",
-                             pulongest (ul), pulongest (offset));
+           gdb_printf (stream, " size %s offset %s (bits)",
+                       pulongest (ul), pulongest (offset));
          }
          break;
 
@@ -3685,9 +3558,9 @@ disassemble_dwarf_expression (struct ui_file *stream,
 
            data = safe_read_sleb128 (data, end, &l);
 
-           fprintf_filtered (stream, " DIE %s offset %s",
-                             phex_nz (ul, offset_size),
-                             plongest (l));
+           gdb_printf (stream, " DIE %s offset %s",
+                       phex_nz (ul, offset_size),
+                       plongest (l));
          }
          break;
 
@@ -3700,11 +3573,11 @@ disassemble_dwarf_expression (struct ui_file *stream,
            data = safe_read_uleb128 (data, end, &ul);
            cu_offset offset = (cu_offset) ul;
            type = dwarf2_get_die_type (offset, per_cu, per_objfile);
-           fprintf_filtered (stream, "<");
+           gdb_printf (stream, "<");
            type_print (type, "", stream, -1);
-           fprintf_filtered (stream, " [0x%s]> %d",
-                             phex_nz (to_underlying (offset), 0),
-                             deref_addr_size);
+           gdb_printf (stream, " [0x%s]> %d",
+                       phex_nz (to_underlying (offset), 0),
+                       deref_addr_size);
          }
          break;
 
@@ -3716,15 +3589,15 @@ disassemble_dwarf_expression (struct ui_file *stream,
            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);
-           fprintf_filtered (stream, "<");
+           gdb_printf (stream, "<");
            type_print (type, "", stream, -1);
-           fprintf_filtered (stream, " [0x%s]>",
-                             phex_nz (to_underlying (type_die), 0));
+           gdb_printf (stream, " [0x%s]>",
+                       phex_nz (to_underlying (type_die), 0));
 
            int n = *data++;
-           fprintf_filtered (stream, " %d byte block:", n);
+           gdb_printf (stream, " %d byte block:", n);
            for (int i = 0; i < n; ++i)
-             fprintf_filtered (stream, " %02x", data[i]);
+             gdb_printf (stream, " %02x", data[i]);
            data += n;
          }
          break;
@@ -3740,11 +3613,11 @@ disassemble_dwarf_expression (struct ui_file *stream,
            cu_offset type_die = (cu_offset) ul;
 
            type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
-           fprintf_filtered (stream, "<");
+           gdb_printf (stream, "<");
            type_print (type, "", stream, -1);
-           fprintf_filtered (stream, " [0x%s]> [$%s]",
-                             phex_nz (to_underlying (type_die), 0),
-                             locexpr_regname (arch, reg));
+           gdb_printf (stream, " [0x%s]> [$%s]",
+                       phex_nz (to_underlying (type_die), 0),
+                       locexpr_regname (arch, reg));
          }
          break;
 
@@ -3757,16 +3630,16 @@ disassemble_dwarf_expression (struct ui_file *stream,
            cu_offset type_die = (cu_offset) ul;
 
            if (to_underlying (type_die) == 0)
-             fprintf_filtered (stream, "<0>");
+             gdb_printf (stream, "<0>");
            else
              {
                struct type *type;
 
                type = dwarf2_get_die_type (type_die, per_cu, per_objfile);
-               fprintf_filtered (stream, "<");
+               gdb_printf (stream, "<");
                type_print (type, "", stream, -1);
-               fprintf_filtered (stream, " [0x%s]>",
-                                 phex_nz (to_underlying (type_die), 0));
+               gdb_printf (stream, " [0x%s]>",
+                           phex_nz (to_underlying (type_die), 0));
              }
          }
          break;
@@ -3774,7 +3647,7 @@ disassemble_dwarf_expression (struct ui_file *stream,
        case DW_OP_entry_value:
        case DW_OP_GNU_entry_value:
          data = safe_read_uleb128 (data, end, &ul);
-         fputc_filtered ('\n', stream);
+         gdb_putc ('\n', stream);
          disassemble_dwarf_expression (stream, arch, addr_size, offset_size,
                                        start, data, data + ul, indent + 2,
                                        all, per_cu, per_objfile);
@@ -3784,31 +3657,31 @@ disassemble_dwarf_expression (struct ui_file *stream,
        case DW_OP_GNU_parameter_ref:
          ul = extract_unsigned_integer (data, 4, gdbarch_byte_order (arch));
          data += 4;
-         fprintf_filtered (stream, " offset %s", phex_nz (ul, 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 = dwarf2_read_addr_index (per_cu, per_objfile, ul);
-         fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
+         gdb_printf (stream, " 0x%s", phex_nz (ul, addr_size));
          break;
 
        case DW_OP_GNU_const_index:
          data = safe_read_uleb128 (data, end, &ul);
          ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
-         fprintf_filtered (stream, " %s", pulongest (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;
-         fprintf_filtered (stream, " offset %s", phex_nz (ul, offset_size));
+         gdb_printf (stream, " offset %s", phex_nz (ul, offset_size));
          break;
        }
 
-      fprintf_filtered (stream, "\n");
+      gdb_printf (stream, "\n");
     }
 
   return data;
@@ -3820,10 +3693,10 @@ static void
 show_dwarf_always_disassemble (struct ui_file *file, int from_tty,
                               struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file,
-                   _("Whether to always disassemble "
-                     "DWARF expressions is %s.\n"),
-                   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
@@ -3849,7 +3722,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
       if (first_piece)
        first_piece = 0;
       else
-       fprintf_filtered (stream, _(", and "));
+       gdb_printf (stream, _(", and "));
 
       if (!dwarf_always_disassemble)
        {
@@ -3865,7 +3738,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
        }
       if (disassemble)
        {
-         fprintf_filtered (stream, _("a complex DWARF expression:\n"));
+         gdb_printf (stream, _("a complex DWARF expression:\n"));
          data = disassemble_dwarf_expression (stream,
                                               objfile->arch (),
                                               addr_size, offset_size, data,
@@ -3879,7 +3752,7 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
          int empty = data == here;
              
          if (disassemble)
-           fprintf_filtered (stream, "   ");
+           gdb_printf (stream, "   ");
          if (data[0] == DW_OP_piece)
            {
              uint64_t bytes;
@@ -3887,11 +3760,11 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
              data = safe_read_uleb128 (data + 1, end, &bytes);
 
              if (empty)
-               fprintf_filtered (stream, _("an empty %s-byte piece"),
-                                 pulongest (bytes));
+               gdb_printf (stream, _("an empty %s-byte piece"),
+                           pulongest (bytes));
              else
-               fprintf_filtered (stream, _(" [%s-byte piece]"),
-                                 pulongest (bytes));
+               gdb_printf (stream, _(" [%s-byte piece]"),
+                           pulongest (bytes));
            }
          else if (data[0] == DW_OP_bit_piece)
            {
@@ -3901,13 +3774,13 @@ locexpr_describe_location_1 (struct symbol *symbol, CORE_ADDR addr,
              data = safe_read_uleb128 (data, end, &offset);
 
              if (empty)
-               fprintf_filtered (stream,
-                                 _("an empty %s-bit piece"),
-                                 pulongest (bits));
+               gdb_printf (stream,
+                           _("an empty %s-bit piece"),
+                           pulongest (bits));
              else
-               fprintf_filtered (stream,
-                                 _(" [%s-bit piece, offset %s bits]"),
-                                 pulongest (bits), pulongest (offset));
+               gdb_printf (stream,
+                           _(" [%s-bit piece, offset %s bits]"),
+                           pulongest (bits), pulongest (offset));
            }
          else
            {
@@ -3999,7 +3872,7 @@ const struct symbol_computed_ops dwarf2_locexpr_funcs = {
 /* Return the value of SYMBOL in FRAME using the DWARF-2 expression
    evaluator to calculate the location.  */
 static struct value *
-loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
+loclist_read_variable (struct symbol *symbol, frame_info_ptr frame)
 {
   struct dwarf2_loclist_baton *dlbaton
     = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
@@ -4009,7 +3882,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
   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 (symbol), frame, data, size,
+  val = dwarf2_evaluate_loc_desc (symbol->type (), frame, data, size,
                                  dlbaton->per_cu, dlbaton->per_objfile);
 
   return val;
@@ -4024,7 +3897,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
    if it cannot resolve the parameter for any reason.  */
 
 static struct value *
-loclist_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
+loclist_read_variable_at_entry (struct symbol *symbol, frame_info_ptr frame)
 {
   struct dwarf2_loclist_baton *dlbaton
     = (struct dwarf2_loclist_baton *) SYMBOL_LOCATION_BATON (symbol);
@@ -4033,13 +3906,13 @@ loclist_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
   CORE_ADDR pc;
 
   if (frame == NULL || !get_frame_func_if_available (frame, &pc))
-    return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+    return value::allocate_optimized_out (symbol->type ());
 
   data = dwarf2_find_location_expression (dlbaton, &size, pc);
   if (data == NULL)
-    return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+    return value::allocate_optimized_out (symbol->type ());
 
-  return value_of_dwarf_block_entry (SYMBOL_TYPE (symbol), frame, data, size);
+  return value_of_dwarf_block_entry (symbol->type (), frame, data, size);
 }
 
 /* Implementation of get_symbol_read_needs from
@@ -4074,16 +3947,16 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   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);
-  /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = objfile->text_section_offset ();
-  CORE_ADDR base_address = dlbaton->base_address + base_offset;
+  int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
+  /* Adjustment for relocatable objects.  */
+  CORE_ADDR text_offset = objfile->text_section_offset ();
+  CORE_ADDR base_address = dlbaton->base_address;
   int done = 0;
 
   loc_ptr = dlbaton->data;
   buf_end = dlbaton->data + dlbaton->size;
 
-  fprintf_filtered (stream, _("multi-location:\n"));
+  gdb_printf (stream, _("multi-location:\n"));
 
   /* Iterate through locations until we run out.  */
   while (!done)
@@ -4117,9 +3990,9 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
          continue;
 
        case DEBUG_LOC_BASE_ADDRESS:
-         base_address = high + base_offset;
-         fprintf_filtered (stream, _("  Base address %s"),
-                           paddress (gdbarch, base_address));
+         base_address = high;
+         gdb_printf (stream, _("  Base address %s"),
+                     paddress (gdbarch, base_address));
          continue;
 
        case DEBUG_LOC_START_END:
@@ -4137,8 +4010,13 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
        }
 
       /* Otherwise, a location expression entry.  */
-      low += base_address;
-      high += base_address;
+      low += text_offset;
+      high += text_offset;
+      if (!dlbaton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
+       {
+         low += base_address;
+         high += base_address;
+       }
 
       low = gdbarch_adjust_dwarf2_addr (gdbarch, low);
       high = gdbarch_adjust_dwarf2_addr (gdbarch, high);
@@ -4157,15 +4035,15 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 
       /* (It would improve readability to print only the minimum
         necessary digits of the second number of the range.)  */
-      fprintf_filtered (stream, _("  Range %s-%s: "),
-                       paddress (gdbarch, low), paddress (gdbarch, high));
+      gdb_printf (stream, _("  Range %s-%s: "),
+                 paddress (gdbarch, low), paddress (gdbarch, high));
 
       /* Now describe this particular location.  */
       locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
                                   addr_size, offset_size,
                                   dlbaton->per_cu, dlbaton->per_objfile);
 
-      fprintf_filtered (stream, "\n");
+      gdb_printf (stream, "\n");
 
       loc_ptr += length;
     }