public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v4 0/5] Smart pointer wrapper for frame_info
@ 2022-08-30 10:08 Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 1/5] Remove frame_id_eq Bruno Larsen
                   ` (5 more replies)
  0 siblings, 6 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-08-30 10:08 UTC (permalink / raw)
  To: gdb-patches

GDB occasionally gets bugs where a frame_info is kept alive across a
call to reinit_frame_cache.  This causes a use-after-free and, if
you're lucky, a crash.

This series aims to make this setup more "reliable", in the sense that
you'll always get a crash if you break the rules.  This is done by
wrapping frame_info in a smart pointer class, and having
reinit_frame_cache invalidate all the pointers.

Tromey's original plan was that these pointers could be automatically
reinflated after being invalidated, but most uses of the class would not
need to be reinflated, and setting everything up to be reinflatable
would be quite expensive, as calculating a frame_id requires some
unwinding.

I added a prepare_reinflate method, which stashes the relevant frame_id
and allows the pointer to be reinflated. However, reinflation is done
manually for now because doing it when reinit_frame_cache was creating
weird problems.

Changelog:
v3:
    Reverted instrusive list changes
    Guile doesn't get fancy pointers because of exceptions through longjumps.

v2:
    Fix commit squashing and email threading
Version 2 had some problematic squashing of commits, and I tried to add
some unit tests, but those didn't work out, so I eventually dropped
that.

Bruno Larsen (2):
  Continue making GDB use frame_info_ptr
  gdb/frame: Add reinflation method for frame_info_ptr

Tom Tromey (3):
  Remove frame_id_eq
  Introduce frame_info_ptr smart pointer class
  Change GDB to use frame_info_ptr

 gdb/aarch64-fbsd-tdep.c                       |   2 +-
 gdb/aarch64-linux-tdep.c                      |   2 +-
 gdb/aarch64-tdep.c                            |  34 +-
 gdb/ada-lang.c                                |  10 +-
 gdb/ada-lang.h                                |   4 +-
 gdb/alpha-linux-tdep.c                        |   2 +-
 gdb/alpha-mdebug-tdep.c                       |  16 +-
 gdb/alpha-netbsd-tdep.c                       |   2 +-
 gdb/alpha-obsd-tdep.c                         |   2 +-
 gdb/alpha-tdep.c                              |  22 +-
 gdb/alpha-tdep.h                              |   2 +-
 gdb/amd64-darwin-tdep.c                       |   2 +-
 gdb/amd64-fbsd-tdep.c                         |   2 +-
 gdb/amd64-linux-tdep.c                        |   6 +-
 gdb/amd64-netbsd-tdep.c                       |   4 +-
 gdb/amd64-obsd-tdep.c                         |  12 +-
 gdb/amd64-sol2-tdep.c                         |   2 +-
 gdb/amd64-tdep.c                              |  34 +-
 gdb/amd64-tdep.h                              |   2 +-
 gdb/amd64-windows-tdep.c                      |  12 +-
 gdb/arc-linux-tdep.c                          |   4 +-
 gdb/arc-tdep.c                                |  20 +-
 gdb/arc-tdep.h                                |   4 +-
 gdb/arch-utils.c                              |   6 +-
 gdb/arch-utils.h                              |   8 +-
 gdb/arm-fbsd-tdep.c                           |   2 +-
 gdb/arm-linux-tdep.c                          |  14 +-
 gdb/arm-obsd-tdep.c                           |   2 +-
 gdb/arm-tdep.c                                |  64 ++--
 gdb/arm-tdep.h                                |   4 +-
 gdb/arm-wince-tdep.c                          |   2 +-
 gdb/avr-tdep.c                                |  14 +-
 gdb/ax-gdb.c                                  |   2 +-
 gdb/bfin-linux-tdep.c                         |   2 +-
 gdb/bfin-tdep.c                               |  12 +-
 gdb/blockframe.c                              |   8 +-
 gdb/bpf-tdep.c                                |   8 +-
 gdb/break-catch-throw.c                       |   2 +-
 gdb/breakpoint.c                              |  20 +-
 gdb/c-lang.c                                  |   2 +-
 gdb/cli/cli-cmds.c                            |   2 +-
 gdb/compile/compile-c-symbols.c               |   2 +-
 gdb/compile/compile-cplus-symbols.c           |   2 +-
 gdb/compile/compile-loc2c.c                   |   2 +-
 gdb/cp-abi.c                                  |   2 +-
 gdb/cp-abi.h                                  |   6 +-
 gdb/cris-tdep.c                               |  36 +-
 gdb/csky-linux-tdep.c                         |   2 +-
 gdb/csky-tdep.c                               |  22 +-
 gdb/defs.h                                    |   2 +-
 gdb/dtrace-probe.c                            |   4 +-
 gdb/dummy-frame.c                             |  12 +-
 gdb/dummy-frame.h                             |   2 +-
 gdb/dwarf2/expr.c                             |  20 +-
 gdb/dwarf2/expr.h                             |   6 +-
 gdb/dwarf2/frame-tailcall.c                   |  41 +--
 gdb/dwarf2/frame-tailcall.h                   |   6 +-
 gdb/dwarf2/frame.c                            |  39 +--
 gdb/dwarf2/frame.h                            |  12 +-
 gdb/dwarf2/loc.c                              |  38 +--
 gdb/dwarf2/loc.h                              |   8 +-
 gdb/elfread.c                                 |   4 +-
 gdb/eval.c                                    |   2 +-
 gdb/extension-priv.h                          |   2 +-
 gdb/extension.c                               |   2 +-
 gdb/extension.h                               |   4 +-
 gdb/f-valprint.c                              |   2 +-
 gdb/findvar.c                                 |  26 +-
 gdb/frame-base.c                              |   8 +-
 gdb/frame-base.h                              |  12 +-
 gdb/frame-id.h                                | 135 ++++++++
 gdb/frame-info.h                              | 206 +++++++++++
 gdb/frame-unwind.c                            |  26 +-
 gdb/frame-unwind.h                            |  36 +-
 gdb/frame.c                                   | 323 +++++++++---------
 gdb/frame.h                                   | 278 +++++----------
 gdb/frv-linux-tdep.c                          |  10 +-
 gdb/frv-tdep.c                                |  10 +-
 gdb/ft32-tdep.c                               |   8 +-
 gdb/gcore.c                                   |   2 +-
 gdb/gdbarch-components.py                     |  30 +-
 gdb/gdbarch-gen.h                             |  60 ++--
 gdb/gdbarch-selftests.c                       |   2 +-
 gdb/gdbarch.c                                 |  30 +-
 gdb/gdbtypes.h                                |   5 +-
 gdb/gnu-v3-abi.c                              |   2 +-
 gdb/h8300-tdep.c                              |  12 +-
 gdb/hppa-bsd-tdep.c                           |   2 +-
 gdb/hppa-linux-tdep.c                         |   8 +-
 gdb/hppa-netbsd-tdep.c                        |   4 +-
 gdb/hppa-tdep.c                               |  32 +-
 gdb/hppa-tdep.h                               |   8 +-
 gdb/i386-bsd-tdep.c                           |   2 +-
 gdb/i386-darwin-tdep.c                        |   4 +-
 gdb/i386-darwin-tdep.h                        |   2 +-
 gdb/i386-fbsd-tdep.c                          |   2 +-
 gdb/i386-gnu-tdep.c                           |   6 +-
 gdb/i386-linux-tdep.c                         |  10 +-
 gdb/i386-netbsd-tdep.c                        |   4 +-
 gdb/i386-nto-tdep.c                           |   4 +-
 gdb/i386-obsd-tdep.c                          |  10 +-
 gdb/i386-sol2-tdep.c                          |   2 +-
 gdb/i386-tdep.c                               |  54 +--
 gdb/i386-tdep.h                               |  10 +-
 gdb/i386-windows-tdep.c                       |   2 +-
 gdb/i387-tdep.c                               |   6 +-
 gdb/i387-tdep.h                               |   8 +-
 gdb/ia64-libunwind-tdep.c                     |  12 +-
 gdb/ia64-libunwind-tdep.h                     |  12 +-
 gdb/ia64-tdep.c                               |  54 +--
 gdb/ia64-tdep.h                               |   4 +-
 gdb/infcall.c                                 |   4 +-
 gdb/infcmd.c                                  |  30 +-
 gdb/inferior.h                                |   6 +-
 gdb/infrun.c                                  |  78 +++--
 gdb/infrun.h                                  |   4 +-
 gdb/inline-frame.c                            |  14 +-
 gdb/inline-frame.h                            |   4 +-
 gdb/iq2000-tdep.c                             |  10 +-
 gdb/jit.c                                     |  12 +-
 gdb/language.c                                |   6 +-
 gdb/language.h                                |   8 +-
 gdb/lm32-tdep.c                               |   8 +-
 gdb/loongarch-linux-tdep.c                    |   4 +-
 gdb/loongarch-tdep.c                          |   8 +-
 gdb/loongarch-tdep.h                          |   2 +-
 gdb/m32c-tdep.c                               |  10 +-
 gdb/m32r-linux-tdep.c                         |  14 +-
 gdb/m32r-tdep.c                               |   8 +-
 gdb/m68hc11-tdep.c                            |  16 +-
 gdb/m68k-linux-tdep.c                         |  12 +-
 gdb/m68k-tdep.c                               |  18 +-
 gdb/m68k-tdep.h                               |   2 +-
 gdb/macroscope.c                              |   2 +-
 gdb/mep-tdep.c                                |   8 +-
 gdb/mi/mi-cmd-stack.c                         |  29 +-
 gdb/mi/mi-main.c                              |  12 +-
 gdb/microblaze-linux-tdep.c                   |   4 +-
 gdb/microblaze-tdep.c                         |  10 +-
 gdb/minsyms.c                                 |   2 +-
 gdb/mips-fbsd-tdep.c                          |   4 +-
 gdb/mips-linux-tdep.c                         |  22 +-
 gdb/mips-netbsd-tdep.c                        |   2 +-
 gdb/mips-sde-tdep.c                           |  12 +-
 gdb/mips-tdep.c                               |  96 +++---
 gdb/mips-tdep.h                               |   2 +-
 gdb/mips64-obsd-tdep.c                        |   2 +-
 gdb/mn10300-linux-tdep.c                      |   4 +-
 gdb/mn10300-tdep.c                            |   8 +-
 gdb/moxie-tdep.c                              |   8 +-
 gdb/msp430-tdep.c                             |  10 +-
 gdb/nds32-tdep.c                              |  20 +-
 gdb/nios2-linux-tdep.c                        |   4 +-
 gdb/nios2-tdep.c                              |  22 +-
 gdb/nios2-tdep.h                              |   2 +-
 gdb/objc-lang.c                               |  10 +-
 gdb/observable.h                              |   2 +-
 gdb/or1k-linux-tdep.c                         |   4 +-
 gdb/or1k-tdep.c                               |  12 +-
 gdb/ppc-fbsd-tdep.c                           |   8 +-
 gdb/ppc-linux-tdep.c                          |  12 +-
 gdb/ppc-netbsd-tdep.c                         |   2 +-
 gdb/ppc-obsd-tdep.c                           |   8 +-
 gdb/ppc-tdep.h                                |   4 +-
 gdb/ppc64-tdep.c                              |  20 +-
 gdb/ppc64-tdep.h                              |   4 +-
 gdb/printcmd.c                                |   4 +-
 gdb/probe.c                                   |   4 +-
 gdb/probe.h                                   |   4 +-
 gdb/python/py-event.h                         |   2 +-
 gdb/python/py-finishbreakpoint.c              |   6 +-
 gdb/python/py-frame.c                         |  44 +--
 gdb/python/py-framefilter.c                   |  22 +-
 gdb/python/py-inferior.c                      |   2 +-
 gdb/python/py-infevents.c                     |   4 +-
 gdb/python/py-symbol.c                        |   6 +-
 gdb/python/py-unwind.c                        |  12 +-
 gdb/python/python-internal.h                  |   6 +-
 gdb/record-btrace.c                           |  32 +-
 gdb/riscv-fbsd-tdep.c                         |   2 +-
 gdb/riscv-linux-tdep.c                        |   6 +-
 gdb/riscv-tdep.c                              |  12 +-
 gdb/riscv-tdep.h                              |   2 +-
 gdb/rl78-tdep.c                               |  12 +-
 gdb/rs6000-aix-tdep.c                         |  10 +-
 gdb/rs6000-tdep.c                             |  34 +-
 gdb/rx-tdep.c                                 |  16 +-
 gdb/s12z-tdep.c                               |  10 +-
 gdb/s390-linux-tdep.c                         |   8 +-
 gdb/s390-tdep.c                               |  38 +--
 gdb/s390-tdep.h                               |   2 +-
 gdb/sentinel-frame.c                          |   6 +-
 gdb/sh-linux-tdep.c                           |   6 +-
 gdb/sh-tdep.c                                 |  16 +-
 gdb/skip.c                                    |   2 +-
 gdb/sol2-tdep.c                               |   2 +-
 gdb/sol2-tdep.h                               |   2 +-
 gdb/solib-svr4.c                              |   4 +-
 gdb/sparc-linux-tdep.c                        |   6 +-
 gdb/sparc-netbsd-tdep.c                       |  12 +-
 gdb/sparc-obsd-tdep.c                         |   8 +-
 gdb/sparc-sol2-tdep.c                         |   8 +-
 gdb/sparc-tdep.c                              |  20 +-
 gdb/sparc-tdep.h                              |  12 +-
 gdb/sparc64-fbsd-tdep.c                       |   8 +-
 gdb/sparc64-linux-tdep.c                      |   8 +-
 gdb/sparc64-netbsd-tdep.c                     |  10 +-
 gdb/sparc64-obsd-tdep.c                       |  16 +-
 gdb/sparc64-sol2-tdep.c                       |   8 +-
 gdb/sparc64-tdep.c                            |  10 +-
 gdb/sparc64-tdep.h                            |   4 +-
 gdb/stack.c                                   | 119 ++++---
 gdb/stack.h                                   |   4 +-
 gdb/stap-probe.c                              |   4 +-
 gdb/std-regs.c                                |   8 +-
 gdb/symfile.h                                 |   2 +-
 gdb/symtab.h                                  |  10 +-
 .../gdb.python/pretty-print-call-by-hand.c    |  53 +++
 .../gdb.python/pretty-print-call-by-hand.exp  | 136 ++++++++
 .../gdb.python/pretty-print-call-by-hand.py   |  41 +++
 gdb/tic6x-linux-tdep.c                        |   4 +-
 gdb/tic6x-tdep.c                              |  22 +-
 gdb/tic6x-tdep.h                              |   2 +-
 gdb/tilegx-linux-tdep.c                       |   2 +-
 gdb/tilegx-tdep.c                             |  12 +-
 gdb/top.c                                     |   2 +-
 gdb/tracepoint.c                              |   5 +-
 gdb/trad-frame.c                              |  10 +-
 gdb/trad-frame.h                              |  10 +-
 gdb/tramp-frame.c                             |  10 +-
 gdb/tramp-frame.h                             |   6 +-
 gdb/tui/tui-disasm.c                          |   2 +-
 gdb/tui/tui-disasm.h                          |   2 +-
 gdb/tui/tui-hooks.c                           |   6 +-
 gdb/tui/tui-regs.c                            |   8 +-
 gdb/tui/tui-regs.h                            |   4 +-
 gdb/tui/tui-source.c                          |   4 +-
 gdb/tui/tui-source.h                          |   2 +-
 gdb/tui/tui-stack.c                           |   4 +-
 gdb/tui/tui-stack.h                           |   4 +-
 gdb/tui/tui-winsource.c                       |   4 +-
 gdb/tui/tui-winsource.h                       |   2 +-
 gdb/user-regs.c                               |   4 +-
 gdb/user-regs.h                               |   6 +-
 gdb/v850-tdep.c                               |  10 +-
 gdb/valops.c                                  |  10 +-
 gdb/value.c                                   |   6 +-
 gdb/value.h                                   |  16 +-
 gdb/varobj.c                                  |   8 +-
 gdb/vax-tdep.c                                |  14 +-
 gdb/xstormy16-tdep.c                          |  12 +-
 gdb/xtensa-tdep.c                             |  22 +-
 gdb/z80-tdep.c                                |   6 +-
 253 files changed, 2172 insertions(+), 1702 deletions(-)
 create mode 100644 gdb/frame-id.h
 create mode 100644 gdb/frame-info.h
 create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
 create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
 create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.py

-- 
2.37.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 1/5] Remove frame_id_eq
  2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
@ 2022-08-30 10:08 ` Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 2/5] Introduce frame_info_ptr smart pointer class Bruno Larsen
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-08-30 10:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: blarsen, Tom Tromey

From: Tom Tromey <tom@tromey.com>

This replaces frame_id_eq with operator== and operator!=.  I wrote
this for a version of this series that I later abandoned; but since it
simplifies the code, I left this patch in.
---
 gdb/breakpoint.c                 |  2 +-
 gdb/dummy-frame.c                |  4 +--
 gdb/elfread.c                    |  2 +-
 gdb/frame-unwind.c               |  2 +-
 gdb/frame.c                      | 27 +++++++++----------
 gdb/frame.h                      | 30 ++++++++-------------
 gdb/guile/scm-frame.c            |  2 +-
 gdb/ia64-tdep.c                  |  4 +--
 gdb/infrun.c                     | 46 +++++++++++++++-----------------
 gdb/mi/mi-cmd-stack.c            |  4 +--
 gdb/mi/mi-main.c                 |  2 +-
 gdb/python/py-finishbreakpoint.c |  2 +-
 gdb/python/py-frame.c            |  2 +-
 gdb/record-btrace.c              |  6 ++---
 gdb/stack.c                      |  4 +--
 gdb/tracepoint.c                 |  3 +--
 gdb/value.c                      |  2 +-
 17 files changed, 65 insertions(+), 79 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index dae96d205be..5397dee6733 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5323,7 +5323,7 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
      breakpoint or a single step breakpoint.  */
 
   if (frame_id_p (b->frame_id)
-      && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
+      && b->frame_id != get_stack_frame_id (get_current_frame ()))
     {
       bs->stop = 0;
       return;
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index 40b455c7e4a..2fef6eae562 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -47,7 +47,7 @@ static int
 dummy_frame_id_eq (struct dummy_frame_id *id1,
 		   struct dummy_frame_id *id2)
 {
-  return frame_id_eq (id1->id, id2->id) && id1->thread == id2->thread;
+  return id1->id == id2->id && id1->thread == id2->thread;
 }
 
 /* List of dummy_frame destructors.  */
@@ -130,7 +130,7 @@ static bool
 pop_dummy_frame_bpt (struct breakpoint *b, struct dummy_frame *dummy)
 {
   if (b->thread == dummy->id.thread->global_num
-      && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id))
+      && b->disposition == disp_del && b->frame_id == dummy->id.id)
     {
       while (b->related_breakpoint != b)
 	delete_breakpoint (b->related_breakpoint);
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 08db208ebbb..e8b4a8e9177 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -946,7 +946,7 @@ elf_gnu_ifunc_resolver_stop (code_breakpoint *b)
 
       if (b_return->thread == thread_id
 	  && b_return->loc->requested_address == prev_pc
-	  && frame_id_eq (b_return->frame_id, prev_frame_id))
+	  && b_return->frame_id == prev_frame_id)
 	break;
     }
 
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 78fc8dd4bcf..78e3f1d8bad 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -229,7 +229,7 @@ default_frame_unwind_stop_reason (struct frame_info *this_frame,
 {
   struct frame_id this_id = get_frame_id (this_frame);
 
-  if (frame_id_eq (this_id, outer_frame_id))
+  if (this_id == outer_frame_id)
     return UNWIND_OUTERMOST;
   else
     return UNWIND_NO_REASON;
diff --git a/gdb/frame.c b/gdb/frame.c
index ae45e22d613..c0cf3d585bf 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -244,7 +244,7 @@ frame_addr_hash (const void *ap)
 }
 
 /* Internal equality function for the hash table.  This function
-   defers equality operations to frame_id_eq.  */
+   defers equality operations to frame_id::operator==.  */
 
 static int
 frame_addr_hash_eq (const void *a, const void *b)
@@ -252,8 +252,7 @@ frame_addr_hash_eq (const void *a, const void *b)
   const struct frame_info *f_entry = (const struct frame_info *) a;
   const struct frame_info *f_element = (const struct frame_info *) b;
 
-  return frame_id_eq (f_entry->this_id.value,
-		      f_element->this_id.value);
+  return f_entry->this_id.value == f_element->this_id.value;
 }
 
 /* Internal function to create the frame_stash hash table.  100 seems
@@ -752,28 +751,28 @@ frame_id_artificial_p (frame_id l)
 }
 
 bool
-frame_id_eq (frame_id l, frame_id r)
+frame_id::operator== (const frame_id &r) const
 {
   bool eq;
 
-  if (l.stack_status == FID_STACK_INVALID
+  if (stack_status == FID_STACK_INVALID
       || r.stack_status == FID_STACK_INVALID)
     /* Like a NaN, if either ID is invalid, the result is false.
        Note that a frame ID is invalid iff it is the null frame ID.  */
     eq = false;
-  else if (l.stack_status != r.stack_status || l.stack_addr != r.stack_addr)
+  else if (stack_status != r.stack_status || stack_addr != r.stack_addr)
     /* If .stack addresses are different, the frames are different.  */
     eq = false;
-  else if (l.code_addr_p && r.code_addr_p && l.code_addr != r.code_addr)
+  else if (code_addr_p && r.code_addr_p && code_addr != r.code_addr)
     /* An invalid code addr is a wild card.  If .code addresses are
        different, the frames are different.  */
     eq = false;
-  else if (l.special_addr_p && r.special_addr_p
-	   && l.special_addr != r.special_addr)
+  else if (special_addr_p && r.special_addr_p
+	   && special_addr != r.special_addr)
     /* An invalid special addr is a wild card (or unused).  Otherwise
        if special addresses are different, the frames are different.  */
     eq = false;
-  else if (l.artificial_depth != r.artificial_depth)
+  else if (artificial_depth != r.artificial_depth)
     /* If artificial depths are different, the frames must be different.  */
     eq = false;
   else
@@ -781,7 +780,7 @@ frame_id_eq (frame_id l, frame_id r)
     eq = true;
 
   frame_debug_printf ("l=%s, r=%s -> %d",
-		      l.to_string ().c_str (), r.to_string ().c_str (), eq);
+		      to_string ().c_str (), r.to_string ().c_str (), eq);
 
   return eq;
 }
@@ -875,7 +874,7 @@ frame_find_by_id (struct frame_id id)
     return NULL;
 
   /* Check for the sentinel frame.  */
-  if (frame_id_eq (id, sentinel_frame_id))
+  if (id == sentinel_frame_id)
     return sentinel_frame;
 
   /* Try using the frame stash first.  Finding it there removes the need
@@ -894,7 +893,7 @@ frame_find_by_id (struct frame_id id)
     {
       struct frame_id self = get_frame_id (frame);
 
-      if (frame_id_eq (id, self))
+      if (id == self)
 	/* An exact match.  */
 	return frame;
 
@@ -1738,7 +1737,7 @@ lookup_selected_frame (struct frame_id a_frame_id, int frame_level)
 	 it's highly unlikely the search by level finds the wrong
 	 frame, it's 99.9(9)% of the time (for all practical purposes)
 	 safe.  */
-      && frame_id_eq (get_frame_id (frame), a_frame_id))
+      && get_frame_id (frame) == a_frame_id)
     {
       /* Cool, all is fine.  */
       select_frame (frame);
diff --git a/gdb/frame.h b/gdb/frame.h
index b9a3793cc23..75bb3bd2aa0 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -173,6 +173,16 @@ struct frame_id
 
   /* Return a string representation of this frame id.  */
   std::string to_string () const;
+
+  /* Returns true when this frame_id and R identify the same
+     frame.  */
+  bool operator== (const frame_id &r) const;
+
+  /* Inverse of ==.  */
+  bool operator!= (const frame_id &r) const
+  {
+    return !(*this == r);
+  }
 };
 
 /* Save and restore the currently selected frame.  */
@@ -269,9 +279,6 @@ extern bool frame_id_p (frame_id l);
    TAILCALL_FRAME.  */
 extern bool frame_id_artificial_p (frame_id l);
 
-/* Returns true when L and R identify the same frame.  */
-extern bool frame_id_eq (frame_id l, frame_id r);
-
 /* Frame types.  Some are real, some are signal trampolines, and some
    are completely artificial (dummy).  */
 
@@ -498,22 +505,7 @@ extern CORE_ADDR get_frame_base (struct frame_info *);
 
 /* Return the per-frame unique identifer.  Can be used to relocate a
    frame after a frame cache flush (and other similar operations).  If
-   FI is NULL, return the null_frame_id.
-
-   NOTE: kettenis/20040508: These functions return a structure.  On
-   platforms where structures are returned in static storage (vax,
-   m68k), this may trigger compiler bugs in code like:
-
-   if (frame_id_eq (get_frame_id (l), get_frame_id (r)))
-
-   where the return value from the first get_frame_id (l) gets
-   overwritten by the second get_frame_id (r).  Please avoid writing
-   code like this.  Use code like:
-
-   struct frame_id id = get_frame_id (l);
-   if (frame_id_eq (id, get_frame_id (r)))
-
-   instead, since that avoids the bug.  */
+   FI is NULL, return the null_frame_id.  */
 extern struct frame_id get_frame_id (struct frame_info *fi);
 extern struct frame_id get_stack_frame_id (struct frame_info *fi);
 extern struct frame_id frame_unwind_caller_id (struct frame_info *next_frame);
diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c
index 159603b8008..77764944208 100644
--- a/gdb/guile/scm-frame.c
+++ b/gdb/guile/scm-frame.c
@@ -134,7 +134,7 @@ frscm_eq_frame_smob (const void *ap, const void *bp)
   const frame_smob *a = (const frame_smob *) ap;
   const frame_smob *b = (const frame_smob *) bp;
 
-  return (frame_id_eq (a->frame_id, b->frame_id)
+  return (a->frame_id == b->frame_id
 	  && a->inferior == b->inferior
 	  && a->inferior != NULL);
 }
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index b7c1c0decae..1e24debf17f 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -2901,7 +2901,7 @@ ia64_libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
   CORE_ADDR bsp;
 
   libunwind_frame_this_id (this_frame, this_cache, &id);
-  if (frame_id_eq (id, outer_frame_id))
+  if (id == outer_frame_id)
     {
       (*this_id) = outer_frame_id;
       return;
@@ -3032,7 +3032,7 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
   struct frame_id id = outer_frame_id;
 
   libunwind_frame_this_id (this_frame, this_cache, &id);
-  if (frame_id_eq (id, outer_frame_id))
+  if (id == outer_frame_id)
     {
       (*this_id) = outer_frame_id;
       return;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 033699bc3f7..f846eb050a5 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -4565,7 +4565,7 @@ stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
        frame != NULL;
        frame = get_prev_frame (frame))
     {
-      if (frame_id_eq (get_frame_id (frame), step_frame_id))
+      if (get_frame_id (frame) == step_frame_id)
 	return true;
 
       if (get_frame_type (frame) != INLINE_FRAME)
@@ -4595,7 +4595,7 @@ inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
       symtab_and_line sal;
       struct symbol *sym;
 
-      if (frame_id_eq (get_frame_id (frame), tp->control.step_frame_id))
+      if (get_frame_id (frame) == tp->control.step_frame_id)
 	break;
       if (get_frame_type (frame) != INLINE_FRAME)
 	break;
@@ -6576,8 +6576,8 @@ handle_signal_stop (struct execution_control_state *ecs)
 	  && (pc_in_thread_step_range (ecs->event_thread->stop_pc (),
 				       ecs->event_thread)
 	      || ecs->event_thread->control.step_range_end == 1)
-	  && frame_id_eq (get_stack_frame_id (frame),
-			  ecs->event_thread->control.step_stack_frame_id)
+	  && (get_stack_frame_id (frame)
+	      == ecs->event_thread->control.step_stack_frame_id)
 	  && ecs->event_thread->control.step_resume_breakpoint == NULL)
 	{
 	  /* The inferior is about to take a signal that will take it
@@ -6744,8 +6744,7 @@ process_event_stop_test (struct execution_control_state *ecs)
 	  {
 	    struct frame_id current_id
 	      = get_frame_id (get_current_frame ());
-	    if (frame_id_eq (current_id,
-			     ecs->event_thread->initiating_frame))
+	    if (current_id == ecs->event_thread->initiating_frame)
 	      {
 		/* Case 2.  Fall through.  */
 	      }
@@ -6918,8 +6917,7 @@ process_event_stop_test (struct execution_control_state *ecs)
   if (pc_in_thread_step_range (ecs->event_thread->stop_pc (),
 			       ecs->event_thread)
       && (execution_direction != EXEC_REVERSE
-	  || frame_id_eq (get_frame_id (frame),
-			  ecs->event_thread->control.step_frame_id)))
+	  || get_frame_id (frame) == ecs->event_thread->control.step_frame_id))
     {
       infrun_debug_printf
 	("stepping inside range [%s-%s]",
@@ -7053,7 +7051,7 @@ process_event_stop_test (struct execution_control_state *ecs)
      previous frame's ID is sufficient - but it is a common case and
      cheaper than checking the previous frame's ID.
 
-     NOTE: frame_id_eq will never report two invalid frame IDs as
+     NOTE: frame_id::operator== will never report two invalid frame IDs as
      being equal, so to get into this block, both the current and
      previous frame must have valid frame IDs.  */
   /* The outer_frame_id check is a heuristic to detect stepping
@@ -7063,14 +7061,14 @@ process_event_stop_test (struct execution_control_state *ecs)
      "outermost" function.  This could be fixed by marking
      outermost frames as !stack_p,code_p,special_p.  Then the
      initial outermost frame, before sp was valid, would
-     have code_addr == &_start.  See the comment in frame_id_eq
+     have code_addr == &_start.  See the comment in frame_id::operator==
      for more.  */
-  if (!frame_id_eq (get_stack_frame_id (frame),
-		    ecs->event_thread->control.step_stack_frame_id)
-      && (frame_id_eq (frame_unwind_caller_id (get_current_frame ()),
-		       ecs->event_thread->control.step_stack_frame_id)
-	  && (!frame_id_eq (ecs->event_thread->control.step_stack_frame_id,
-			    outer_frame_id)
+  if ((get_stack_frame_id (frame)
+       != ecs->event_thread->control.step_stack_frame_id)
+      && ((frame_unwind_caller_id (get_current_frame ())
+	   == ecs->event_thread->control.step_stack_frame_id)
+	  && ((ecs->event_thread->control.step_stack_frame_id
+	       != outer_frame_id)
 	      || (ecs->event_thread->control.step_start_function
 		  != find_pc_function (ecs->event_thread->stop_pc ())))))
     {
@@ -7327,8 +7325,8 @@ process_event_stop_test (struct execution_control_state *ecs)
      frame machinery detected some skipped call sites, we have entered
      a new inline function.  */
 
-  if (frame_id_eq (get_frame_id (get_current_frame ()),
-		   ecs->event_thread->control.step_frame_id)
+  if ((get_frame_id (get_current_frame ())
+       == ecs->event_thread->control.step_frame_id)
       && inline_skipped_frames (ecs->event_thread))
     {
       infrun_debug_printf ("stepped into inlined function");
@@ -7376,8 +7374,8 @@ process_event_stop_test (struct execution_control_state *ecs)
      through a more inlined call beyond its call site.  */
 
   if (get_frame_type (get_current_frame ()) == INLINE_FRAME
-      && !frame_id_eq (get_frame_id (get_current_frame ()),
-		       ecs->event_thread->control.step_frame_id)
+      && (get_frame_id (get_current_frame ())
+	  != ecs->event_thread->control.step_frame_id)
       && stepped_in_from (get_current_frame (),
 			  ecs->event_thread->control.step_frame_id))
     {
@@ -7409,8 +7407,8 @@ process_event_stop_test (struct execution_control_state *ecs)
 	  end_stepping_range (ecs);
 	  return;
 	}
-      else if (frame_id_eq (get_frame_id (get_current_frame ()),
-                           ecs->event_thread->control.step_frame_id))
+      else if (get_frame_id (get_current_frame ())
+               == ecs->event_thread->control.step_frame_id)
 	{
 	  /* We are not at the start of a statement, and we have not changed
 	     frame.
@@ -8467,8 +8465,8 @@ print_stop_location (const target_waitstatus &ws)
 	 should) carry around the function and does (or should) use
 	 that when doing a frame comparison.  */
       if (tp->control.stop_step
-	  && frame_id_eq (tp->control.step_frame_id,
-			  get_frame_id (get_current_frame ()))
+	  && (tp->control.step_frame_id
+	      == get_frame_id (get_current_frame ()))
 	  && (tp->control.step_start_function
 	      == find_pc_function (tp->stop_pc ())))
 	{
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index 0fe204dbc66..40c1345404d 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -729,7 +729,7 @@ parse_frame_specification (const char *frame_exp)
        fid != NULL;
        fid = get_prev_frame (fid))
     {
-      if (frame_id_eq (id, get_frame_id (fid)))
+      if (id == get_frame_id (fid))
 	{
 	  struct frame_info *prev_frame;
 
@@ -737,7 +737,7 @@ parse_frame_specification (const char *frame_exp)
 	    {
 	      prev_frame = get_prev_frame (fid);
 	      if (!prev_frame
-		  || !frame_id_eq (id, get_frame_id (prev_frame)))
+		  || id != get_frame_id (prev_frame))
 		break;
 	      fid = prev_frame;
 	    }
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 68868e49e99..ee2e9acf634 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -2003,7 +2003,7 @@ struct user_selected_context
        reports not-equal, we only do the equality test if we have something
        other than the innermost frame selected.  */
     if (current_frame_level != -1
-	&& !frame_id_eq (current_frame_id, m_previous_frame_id))
+	&& current_frame_id != m_previous_frame_id)
       return true;
 
     /* Nothing changed!  */
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index c80096f6810..2d476114b35 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -207,7 +207,7 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
 	  else
 	    {
 	      frame_id = get_frame_id (prev_frame);
-	      if (frame_id_eq (frame_id, null_frame_id))
+	      if (frame_id == null_frame_id)
 		PyErr_SetString (PyExc_ValueError,
 				 _("Invalid ID for the `frame' object."));
 	    }
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 9a28c36c1cc..9b3a0ac142b 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -704,7 +704,7 @@ frapy_richcompare (PyObject *self, PyObject *other, int op)
   frame_object *other_frame = (frame_object *) other;
 
   if (self_frame->frame_id_is_next == other_frame->frame_id_is_next
-      && frame_id_eq (self_frame->frame_id, other_frame->frame_id))
+      && self_frame->frame_id == other_frame->frame_id)
     result = Py_EQ;
   else
     result = Py_NE;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 3a56925f63e..bc1411ecb3f 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -2033,10 +2033,8 @@ record_btrace_start_replaying (struct thread_info *tp)
       frame_id = get_thread_current_frame_id (tp);
 
       /* Check if we need to update any stepping-related frame id's.  */
-      upd_step_frame_id = frame_id_eq (frame_id,
-				       tp->control.step_frame_id);
-      upd_step_stack_frame_id = frame_id_eq (frame_id,
-					     tp->control.step_stack_frame_id);
+      upd_step_frame_id = (frame_id == tp->control.step_frame_id);
+      upd_step_stack_frame_id = (frame_id == tp->control.step_stack_frame_id);
 
       /* We start replaying at the end of the branch trace.  This corresponds
 	 to the current instruction.  */
diff --git a/gdb/stack.c b/gdb/stack.c
index 80801ccdb01..6e0f58565fe 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -3252,7 +3252,7 @@ find_frame_for_address (CORE_ADDR address)
        fid != NULL;
        fid = get_prev_frame (fid))
     {
-      if (frame_id_eq (id, get_frame_id (fid)))
+      if (id == get_frame_id (fid))
 	{
 	  struct frame_info *prev_frame;
 
@@ -3260,7 +3260,7 @@ find_frame_for_address (CORE_ADDR address)
 	    {
 	      prev_frame = get_prev_frame (fid);
 	      if (!prev_frame
-		  || !frame_id_eq (id, get_frame_id (prev_frame)))
+		  || id != get_frame_id (prev_frame))
 		break;
 	      fid = prev_frame;
 	    }
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 75ac0cef3b0..98f1563a89a 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -2190,8 +2190,7 @@ tfind_1 (enum trace_find_type type, int num,
 	 function and it's arguments) -- otherwise we'll just show the
 	 new source line.  */
 
-      if (frame_id_eq (old_frame_id,
-		       get_frame_id (get_current_frame ())))
+      if (old_frame_id == get_frame_id (get_current_frame ()))
 	print_what = SRC_LINE;
       else
 	print_what = SRC_AND_LOC;
diff --git a/gdb/value.c b/gdb/value.c
index 557e22154eb..3a0cac741e4 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -4004,7 +4004,7 @@ value_fetch_lazy_register (struct value *val)
 	 in this situation.  */
       if (VALUE_LVAL (new_val) == lval_register
 	  && value_lazy (new_val)
-	  && frame_id_eq (VALUE_NEXT_FRAME_ID (new_val), next_frame_id))
+	  && VALUE_NEXT_FRAME_ID (new_val) == next_frame_id)
 	internal_error (__FILE__, __LINE__,
 			_("infinite loop while fetching a register"));
     }
-- 
2.37.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 2/5] Introduce frame_info_ptr smart pointer class
  2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 1/5] Remove frame_id_eq Bruno Larsen
@ 2022-08-30 10:08 ` Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 3/5] Change GDB to use frame_info_ptr Bruno Larsen
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-08-30 10:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: blarsen, Tom Tromey

From: Tom Tromey <tom@tromey.com>

This adds frame_info_ptr, a smart pointer class.  Every instance of
the class is kept on an intrusive list.  When reinit_frame_cache is
called, the list is traversed and all the pointers are invalidated.
This should help catch the typical GDB bug of keeping a frame_info
pointer alive where a frame ID was needed instead.

Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
---
 gdb/frame-info.h | 179 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/frame.c      |   6 ++
 gdb/frame.h      |   2 +
 3 files changed, 187 insertions(+)
 create mode 100644 gdb/frame-info.h

diff --git a/gdb/frame-info.h b/gdb/frame-info.h
new file mode 100644
index 00000000000..195aa5ccf03
--- /dev/null
+++ b/gdb/frame-info.h
@@ -0,0 +1,179 @@
+/* Frame info pointer
+
+   Copyright (C) 2022 Free Software Foundation, 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/>.  */
+
+#ifndef GDB_FRAME_INFO_H
+#define GDB_FRAME_INFO_H
+
+#include "gdbsupport/intrusive_list.h"
+
+struct frame_info;
+
+extern void reinit_frame_cache ();
+
+/* A wrapper for "frame_info *".  frame_info objects are invalidated
+   whenever reinit_frame_cache is called.  This class arranges to
+   invalidate the pointer when appropriate.  This is done to help
+   detect a GDB bug that was relatively common.
+
+   A small amount of code must still operate on raw pointers, so a
+   "get" method is provided.  However, you should normally not use
+   this in new code.  */
+
+class frame_info_ptr : public intrusive_list_node<frame_info_ptr>
+{
+public:
+  /* Create a frame_info_ptr from a raw pointer.  */
+  explicit frame_info_ptr (struct frame_info *ptr)
+    : m_ptr (ptr)
+  {
+    frame_list.push_back (*this);
+  }
+
+  /* Create a null frame_info_ptr.  */
+  frame_info_ptr ()
+  {
+    frame_list.push_back (*this);
+  }
+
+  frame_info_ptr (std::nullptr_t)
+  {
+    frame_list.push_back (*this);
+  }
+
+  frame_info_ptr (const frame_info_ptr &other)
+    : m_ptr (other.m_ptr)
+  {
+    frame_list.push_back (*this);
+  }
+
+  frame_info_ptr (frame_info_ptr &&other)
+    : m_ptr (other.m_ptr)
+  {
+    other.m_ptr = nullptr;
+    frame_list.push_back (*this);
+  }
+
+  ~frame_info_ptr ()
+  {
+    frame_list.erase (frame_list.iterator_to (*this));
+  }
+
+  frame_info_ptr &operator= (const frame_info_ptr &other)
+  {
+    m_ptr = other.m_ptr;
+    return *this;
+  }
+
+  frame_info_ptr &operator= (std::nullptr_t)
+  {
+    m_ptr = nullptr;
+    return *this;
+  }
+
+  frame_info_ptr &operator= (frame_info_ptr &&other)
+  {
+    m_ptr = other.m_ptr;
+    other.m_ptr = nullptr;
+    return *this;
+  }
+
+  frame_info *operator-> () const
+  {
+    return m_ptr;
+  }
+
+  /* Fetch the underlying pointer.  Note that new code should
+     generally not use this -- avoid it if at all possible.  */
+  frame_info *get () const
+  {
+    return m_ptr;
+  }
+
+  /* This exists for compatibility with pre-existing code that checked
+     a "frame_info *" using "!".  */
+  bool operator! () const
+  {
+    return m_ptr == nullptr;
+  }
+
+  /* This exists for compatibility with pre-existing code that checked
+     a "frame_info *" like "if (ptr)".  */
+  explicit operator bool () const
+  {
+    return m_ptr != nullptr;
+  }
+
+  /* Invalidate this pointer.  */
+  void invalidate ()
+  {
+    m_ptr = nullptr;
+  }
+
+private:
+
+  /* The underlying pointer.  */
+  frame_info *m_ptr = nullptr;
+
+
+  /* All frame_info_ptr objects are kept on an intrusive list.
+     This keeps their construction and destruction costs
+     reasonably small.  */
+  static intrusive_list<frame_info_ptr> frame_list;
+
+  /* A friend so it can invalidate the pointers.  */
+  friend void reinit_frame_cache ();
+};
+
+static inline bool
+operator== (const frame_info *self, const frame_info_ptr &other)
+{
+  return self == other.get ();
+}
+
+static inline bool
+operator== (const frame_info_ptr &self, const frame_info_ptr &other)
+{
+  return self.get () == other.get ();
+}
+
+static inline bool
+operator== (const frame_info_ptr &self, const frame_info *other)
+{
+  return self.get () == other;
+}
+
+static inline bool
+operator!= (const frame_info *self, const frame_info_ptr &other)
+{
+  return self != other.get ();
+}
+
+static inline bool
+operator!= (const frame_info_ptr &self, const frame_info_ptr &other)
+{
+  return self.get () != other.get ();
+}
+
+static inline bool
+operator!= (const frame_info_ptr &self, const frame_info *other)
+{
+  return self.get () != other;
+}
+
+#endif /* GDB_FRAME_INFO_H */
diff --git a/gdb/frame.c b/gdb/frame.c
index c0cf3d585bf..7c31da53729 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -56,6 +56,9 @@ static struct frame_info *sentinel_frame;
 /* Number of calls to reinit_frame_cache.  */
 static unsigned int frame_cache_generation = 0;
 
+/* See frame-info.h.  */
+intrusive_list<frame_info_ptr> frame_info_ptr::frame_list;
+
 /* See frame.h.  */
 
 unsigned int
@@ -2006,6 +2009,9 @@ reinit_frame_cache (void)
   select_frame (NULL);
   frame_stash_invalidate ();
 
+  for (frame_info_ptr &iter : frame_info_ptr::frame_list)
+    iter.invalidate ();
+
   frame_debug_printf ("generation=%d", frame_cache_generation);
 }
 
diff --git a/gdb/frame.h b/gdb/frame.h
index 75bb3bd2aa0..9ad2599331f 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -20,6 +20,8 @@
 #if !defined (FRAME_H)
 #define FRAME_H 1
 
+#include "frame-info.h"
+
 /* The following is the intended naming schema for frame functions.
    It isn't 100% consistent, but it is approaching that.  Frame naming
    schema:
-- 
2.37.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 3/5] Change GDB to use frame_info_ptr
  2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 1/5] Remove frame_id_eq Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 2/5] Introduce frame_info_ptr smart pointer class Bruno Larsen
@ 2022-08-30 10:08 ` Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 4/5] Continue making GDB " Bruno Larsen
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-08-30 10:08 UTC (permalink / raw)
  To: gdb-patches; +Cc: blarsen, Tom Tromey

From: Tom Tromey <tom@tromey.com>

This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:

sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
    issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
    problems.

The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did

Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
---
 gdb/aarch64-fbsd-tdep.c     |  2 +-
 gdb/aarch64-linux-tdep.c    |  2 +-
 gdb/aarch64-tdep.c          | 34 ++++++-------
 gdb/ada-lang.c              | 10 ++--
 gdb/ada-lang.h              |  4 +-
 gdb/alpha-linux-tdep.c      |  2 +-
 gdb/alpha-mdebug-tdep.c     | 16 +++----
 gdb/alpha-netbsd-tdep.c     |  2 +-
 gdb/alpha-obsd-tdep.c       |  2 +-
 gdb/alpha-tdep.c            | 22 ++++-----
 gdb/alpha-tdep.h            |  2 +-
 gdb/amd64-darwin-tdep.c     |  2 +-
 gdb/amd64-fbsd-tdep.c       |  2 +-
 gdb/amd64-linux-tdep.c      |  6 +--
 gdb/amd64-netbsd-tdep.c     |  4 +-
 gdb/amd64-obsd-tdep.c       | 12 ++---
 gdb/amd64-sol2-tdep.c       |  2 +-
 gdb/amd64-tdep.c            | 34 ++++++-------
 gdb/amd64-tdep.h            |  2 +-
 gdb/amd64-windows-tdep.c    | 12 ++---
 gdb/arc-linux-tdep.c        |  4 +-
 gdb/arc-tdep.c              | 20 ++++----
 gdb/arc-tdep.h              |  4 +-
 gdb/arch-utils.c            |  6 +--
 gdb/arch-utils.h            |  8 ++--
 gdb/arm-fbsd-tdep.c         |  2 +-
 gdb/arm-linux-tdep.c        | 14 +++---
 gdb/arm-obsd-tdep.c         |  2 +-
 gdb/arm-tdep.c              | 62 ++++++++++++------------
 gdb/arm-tdep.h              |  4 +-
 gdb/arm-wince-tdep.c        |  2 +-
 gdb/avr-tdep.c              | 14 +++---
 gdb/ax-gdb.c                |  2 +-
 gdb/bfin-linux-tdep.c       |  2 +-
 gdb/bfin-tdep.c             | 12 ++---
 gdb/blockframe.c            |  8 ++--
 gdb/bpf-tdep.c              |  8 ++--
 gdb/break-catch-throw.c     |  2 +-
 gdb/breakpoint.c            | 18 +++----
 gdb/c-lang.c                |  2 +-
 gdb/cp-abi.c                |  2 +-
 gdb/cp-abi.h                |  6 +--
 gdb/cris-tdep.c             | 36 +++++++-------
 gdb/csky-linux-tdep.c       |  2 +-
 gdb/csky-tdep.c             | 22 ++++-----
 gdb/defs.h                  |  2 +-
 gdb/dtrace-probe.c          |  4 +-
 gdb/dummy-frame.c           |  8 ++--
 gdb/dummy-frame.h           |  2 +-
 gdb/elfread.c               |  2 +-
 gdb/eval.c                  |  2 +-
 gdb/extension-priv.h        |  2 +-
 gdb/extension.c             |  2 +-
 gdb/extension.h             |  4 +-
 gdb/gcore.c                 |  2 +-
 gdb/gdbarch-components.py   | 30 ++++++------
 gdb/gdbarch-gen.h           | 60 +++++++++++------------
 gdb/gdbarch-selftests.c     |  2 +-
 gdb/gdbarch.c               | 30 ++++++------
 gdb/gdbtypes.h              |  5 +-
 gdb/gnu-v3-abi.c            |  2 +-
 gdb/h8300-tdep.c            | 12 ++---
 gdb/hppa-bsd-tdep.c         |  2 +-
 gdb/hppa-linux-tdep.c       |  8 ++--
 gdb/hppa-netbsd-tdep.c      |  4 +-
 gdb/hppa-tdep.c             | 32 ++++++-------
 gdb/hppa-tdep.h             |  8 ++--
 gdb/jit.c                   | 12 ++---
 gdb/language.c              |  6 +--
 gdb/language.h              |  8 ++--
 gdb/lm32-tdep.c             |  8 ++--
 gdb/loongarch-linux-tdep.c  |  4 +-
 gdb/loongarch-tdep.c        |  8 ++--
 gdb/loongarch-tdep.h        |  2 +-
 gdb/m32c-tdep.c             | 10 ++--
 gdb/m32r-linux-tdep.c       | 14 +++---
 gdb/m32r-tdep.c             |  8 ++--
 gdb/m68hc11-tdep.c          | 16 +++----
 gdb/m68k-linux-tdep.c       | 12 ++---
 gdb/m68k-tdep.c             | 18 +++----
 gdb/m68k-tdep.h             |  2 +-
 gdb/macroscope.c            |  2 +-
 gdb/mep-tdep.c              |  8 ++--
 gdb/microblaze-linux-tdep.c |  4 +-
 gdb/microblaze-tdep.c       | 10 ++--
 gdb/minsyms.c               |  2 +-
 gdb/mips-fbsd-tdep.c        |  4 +-
 gdb/mips-linux-tdep.c       | 22 ++++-----
 gdb/mips-netbsd-tdep.c      |  2 +-
 gdb/mips-sde-tdep.c         | 12 ++---
 gdb/mips-tdep.c             | 96 ++++++++++++++++++-------------------
 gdb/mips-tdep.h             |  2 +-
 gdb/mips64-obsd-tdep.c      |  2 +-
 gdb/mn10300-linux-tdep.c    |  4 +-
 gdb/mn10300-tdep.c          |  8 ++--
 gdb/moxie-tdep.c            |  8 ++--
 gdb/msp430-tdep.c           | 10 ++--
 gdb/nds32-tdep.c            | 20 ++++----
 gdb/nios2-linux-tdep.c      |  4 +-
 gdb/nios2-tdep.c            | 22 ++++-----
 gdb/nios2-tdep.h            |  2 +-
 gdb/objc-lang.c             | 10 ++--
 gdb/observable.h            |  2 +-
 gdb/or1k-linux-tdep.c       |  4 +-
 gdb/or1k-tdep.c             | 12 ++---
 gdb/ppc-fbsd-tdep.c         |  8 ++--
 gdb/ppc-linux-tdep.c        | 12 ++---
 gdb/ppc-netbsd-tdep.c       |  2 +-
 gdb/ppc-obsd-tdep.c         |  8 ++--
 gdb/ppc-tdep.h              |  4 +-
 gdb/ppc64-tdep.c            | 20 ++++----
 gdb/ppc64-tdep.h            |  4 +-
 gdb/printcmd.c              |  4 +-
 gdb/probe.c                 |  4 +-
 gdb/probe.h                 |  4 +-
 gdb/record-btrace.c         | 26 +++++-----
 gdb/riscv-fbsd-tdep.c       |  2 +-
 gdb/riscv-linux-tdep.c      |  6 +--
 gdb/riscv-tdep.c            | 12 ++---
 gdb/riscv-tdep.h            |  2 +-
 gdb/rl78-tdep.c             | 12 ++---
 gdb/rs6000-aix-tdep.c       | 10 ++--
 gdb/rs6000-tdep.c           | 34 ++++++-------
 gdb/rx-tdep.c               | 16 +++----
 gdb/tic6x-linux-tdep.c      |  4 +-
 gdb/tic6x-tdep.c            | 22 ++++-----
 gdb/tic6x-tdep.h            |  2 +-
 gdb/tilegx-linux-tdep.c     |  2 +-
 gdb/tilegx-tdep.c           | 12 ++---
 gdb/top.c                   |  2 +-
 gdb/tracepoint.c            |  2 +-
 gdb/trad-frame.c            | 10 ++--
 gdb/trad-frame.h            | 10 ++--
 gdb/tramp-frame.c           | 10 ++--
 gdb/tramp-frame.h           |  6 +--
 gdb/user-regs.c             |  4 +-
 gdb/user-regs.h             |  6 +--
 gdb/xstormy16-tdep.c        | 12 ++---
 gdb/xtensa-tdep.c           | 22 ++++-----
 gdb/z80-tdep.c              |  6 +--
 140 files changed, 693 insertions(+), 692 deletions(-)

diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index 4a6b4115234..f37729a4d01 100644
--- a/gdb/aarch64-fbsd-tdep.c
+++ b/gdb/aarch64-fbsd-tdep.c
@@ -80,7 +80,7 @@ static const struct regcache_map_entry aarch64_fbsd_fpregmap[] =
 
 static void
 aarch64_fbsd_sigframe_init (const struct tramp_frame *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 15773c75da8..0954e219a25 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -283,7 +283,7 @@ aarch64_linux_restore_vreg (struct trad_frame_cache *cache, int num_regs,
 
 static void
 aarch64_linux_sigframe_init (const struct tramp_frame *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index f747ebda1ab..add3b186611 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -250,7 +250,7 @@ class instruction_reader : public abstract_instruction_reader
 
 static CORE_ADDR
 aarch64_frame_unmask_lr (aarch64_gdbarch_tdep *tdep,
-			 struct frame_info *this_frame, CORE_ADDR addr)
+			 frame_info_ptr this_frame, CORE_ADDR addr)
 {
   if (tdep->has_pauth ()
       && frame_unwind_register_unsigned (this_frame,
@@ -270,7 +270,7 @@ aarch64_frame_unmask_lr (aarch64_gdbarch_tdep *tdep,
 /* Implement the "get_pc_address_flags" gdbarch method.  */
 
 static std::string
-aarch64_get_pc_address_flags (frame_info *frame, CORE_ADDR pc)
+aarch64_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc)
 {
   if (pc != 0 && get_frame_pc_masked (frame))
     return "PAC";
@@ -969,7 +969,7 @@ aarch64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    cache CACHE.  */
 
 static void
-aarch64_scan_prologue (struct frame_info *this_frame,
+aarch64_scan_prologue (frame_info_ptr this_frame,
 		       struct aarch64_prologue_cache *cache)
 {
   CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
@@ -1023,7 +1023,7 @@ aarch64_scan_prologue (struct frame_info *this_frame,
    not available.  */
 
 static void
-aarch64_make_prologue_cache_1 (struct frame_info *this_frame,
+aarch64_make_prologue_cache_1 (frame_info_ptr this_frame,
 			       struct aarch64_prologue_cache *cache)
 {
   CORE_ADDR unwound_fp;
@@ -1058,7 +1058,7 @@ aarch64_make_prologue_cache_1 (struct frame_info *this_frame,
    *THIS_CACHE.  */
 
 static struct aarch64_prologue_cache *
-aarch64_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
+aarch64_make_prologue_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct aarch64_prologue_cache *cache;
 
@@ -1085,7 +1085,7 @@ aarch64_make_prologue_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the "stop_reason" frame_unwind method.  */
 
 static enum unwind_stop_reason
-aarch64_prologue_frame_unwind_stop_reason (struct frame_info *this_frame,
+aarch64_prologue_frame_unwind_stop_reason (frame_info_ptr this_frame,
 					   void **this_cache)
 {
   struct aarch64_prologue_cache *cache
@@ -1111,7 +1111,7 @@ aarch64_prologue_frame_unwind_stop_reason (struct frame_info *this_frame,
    PC and the caller's SP when we were called.  */
 
 static void
-aarch64_prologue_this_id (struct frame_info *this_frame,
+aarch64_prologue_this_id (frame_info_ptr this_frame,
 			  void **this_cache, struct frame_id *this_id)
 {
   struct aarch64_prologue_cache *cache
@@ -1126,7 +1126,7 @@ aarch64_prologue_this_id (struct frame_info *this_frame,
 /* Implement the "prev_register" frame_unwind method.  */
 
 static struct value *
-aarch64_prologue_prev_register (struct frame_info *this_frame,
+aarch64_prologue_prev_register (frame_info_ptr this_frame,
 				void **this_cache, int prev_regnum)
 {
   struct aarch64_prologue_cache *cache
@@ -1192,7 +1192,7 @@ static frame_unwind aarch64_prologue_unwind =
    *THIS_CACHE.  */
 
 static struct aarch64_prologue_cache *
-aarch64_make_stub_cache (struct frame_info *this_frame, void **this_cache)
+aarch64_make_stub_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct aarch64_prologue_cache *cache;
 
@@ -1222,7 +1222,7 @@ aarch64_make_stub_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the "stop_reason" frame_unwind method.  */
 
 static enum unwind_stop_reason
-aarch64_stub_frame_unwind_stop_reason (struct frame_info *this_frame,
+aarch64_stub_frame_unwind_stop_reason (frame_info_ptr this_frame,
 				       void **this_cache)
 {
   struct aarch64_prologue_cache *cache
@@ -1237,7 +1237,7 @@ aarch64_stub_frame_unwind_stop_reason (struct frame_info *this_frame,
 /* Our frame ID for a stub frame is the current SP and LR.  */
 
 static void
-aarch64_stub_this_id (struct frame_info *this_frame,
+aarch64_stub_this_id (frame_info_ptr this_frame,
 		      void **this_cache, struct frame_id *this_id)
 {
   struct aarch64_prologue_cache *cache
@@ -1253,7 +1253,7 @@ aarch64_stub_this_id (struct frame_info *this_frame,
 
 static int
 aarch64_stub_unwind_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   CORE_ADDR addr_in_block;
@@ -1284,7 +1284,7 @@ static frame_unwind aarch64_stub_unwind =
 /* Return the frame base address of *THIS_FRAME.  */
 
 static CORE_ADDR
-aarch64_normal_frame_base (struct frame_info *this_frame, void **this_cache)
+aarch64_normal_frame_base (frame_info_ptr this_frame, void **this_cache)
 {
   struct aarch64_prologue_cache *cache
     = aarch64_make_prologue_cache (this_frame, this_cache);
@@ -1305,7 +1305,7 @@ static frame_base aarch64_normal_base =
    *THIS_FRAME.  */
 
 static struct value *
-aarch64_dwarf2_prev_register (struct frame_info *this_frame,
+aarch64_dwarf2_prev_register (frame_info_ptr this_frame,
 			      void **this_cache, int regnum)
 {
   gdbarch *arch = get_frame_arch (this_frame);
@@ -1333,7 +1333,7 @@ static const unsigned char op_lit1 = DW_OP_lit1;
 static void
 aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			       struct dwarf2_frame_state_reg *reg,
-			       struct frame_info *this_frame)
+			       frame_info_ptr this_frame)
 {
   aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch);
 
@@ -2533,7 +2533,7 @@ aarch64_return_value (struct gdbarch *gdbarch, struct value *func_value,
 /* Implement the "get_longjmp_target" gdbarch method.  */
 
 static int
-aarch64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+aarch64_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
   gdb_byte buf[X_REGISTER_SIZE];
@@ -2884,7 +2884,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
 /* Callback function for user_reg_add.  */
 
 static struct value *
-value_of_aarch64_user_reg (struct frame_info *frame, const void *baton)
+value_of_aarch64_user_reg (frame_info_ptr frame, const void *baton)
 {
   const int *reg_p = (const int *) baton;
 
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index d49baf99005..ab545aee632 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11841,7 +11841,7 @@ ada_exception_support_info_sniffer (void)
    to most users.  */
 
 static int
-is_known_support_routine (struct frame_info *frame)
+is_known_support_routine (frame_info_ptr frame)
 {
   enum language func_lang;
   int i;
@@ -11900,7 +11900,7 @@ is_known_support_routine (struct frame_info *frame)
    part of the Ada run-time, starting from FI and moving upward.  */
 
 void
-ada_find_printable_frame (struct frame_info *fi)
+ada_find_printable_frame (frame_info_ptr fi)
 {
   for (; fi != NULL; fi = get_prev_frame (fi))
     {
@@ -11934,7 +11934,7 @@ static CORE_ADDR
 ada_unhandled_exception_name_addr_from_raise (void)
 {
   int frame_level;
-  struct frame_info *fi;
+  frame_info_ptr fi;
   struct ada_inferior_data *data = get_ada_inferior_data (current_inferior ());
 
   /* To determine the name of this exception, we need to select
@@ -13049,7 +13049,7 @@ ada_add_standard_exceptions (compiled_regex *preg,
 
 static void
 ada_add_exceptions_from_frame (compiled_regex *preg,
-			       struct frame_info *frame,
+			       frame_info_ptr frame,
 			       std::vector<ada_exc_info> *exceptions)
 {
   const struct block *block = get_frame_block (frame, 0);
@@ -13478,7 +13478,7 @@ class ada_language : public language_defn
 
   struct value *read_var_value (struct symbol *var,
 				const struct block *var_block,
-				struct frame_info *frame) const override
+				frame_info_ptr frame) const override
   {
     /* The only case where default_read_var_value is not sufficient
        is when VAR is a renaming...  */
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 0dcdb56c198..df648c2297e 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -20,7 +20,7 @@
 #if !defined (ADA_LANG_H)
 #define ADA_LANG_H 1
 
-struct frame_info;
+class frame_info_ptr;
 struct inferior;
 struct type_print_options;
 struct parser_state;
@@ -334,7 +334,7 @@ extern enum ada_renaming_category ada_parse_renaming (struct symbol *,
 						      const char **,
 						      int *, const char **);
 
-extern void ada_find_printable_frame (struct frame_info *fi);
+extern void ada_find_printable_frame (frame_info_ptr fi);
 
 extern char *ada_breakpoint_rewrite (char *, int *);
 
diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c
index c103aafc1ff..3a6a9aea160 100644
--- a/gdb/alpha-linux-tdep.c
+++ b/gdb/alpha-linux-tdep.c
@@ -126,7 +126,7 @@ alpha_linux_pc_in_sigtramp (struct gdbarch *gdbarch,
 }
 
 static CORE_ADDR
-alpha_linux_sigcontext_addr (struct frame_info *this_frame)
+alpha_linux_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc;
diff --git a/gdb/alpha-mdebug-tdep.c b/gdb/alpha-mdebug-tdep.c
index 10169c76c37..01f84f7fc3e 100644
--- a/gdb/alpha-mdebug-tdep.c
+++ b/gdb/alpha-mdebug-tdep.c
@@ -187,7 +187,7 @@ struct alpha_mdebug_unwind_cache
    and store the resulting register save locations in the structure.  */
 
 static struct alpha_mdebug_unwind_cache *
-alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame, 
+alpha_mdebug_frame_unwind_cache (frame_info_ptr this_frame, 
 				 void **this_prologue_cache)
 {
   struct alpha_mdebug_unwind_cache *info;
@@ -264,7 +264,7 @@ alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-alpha_mdebug_frame_this_id (struct frame_info *this_frame,
+alpha_mdebug_frame_this_id (frame_info_ptr this_frame,
 			    void **this_prologue_cache,
 			    struct frame_id *this_id)
 {
@@ -277,7 +277,7 @@ alpha_mdebug_frame_this_id (struct frame_info *this_frame,
 /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
 
 static struct value *
-alpha_mdebug_frame_prev_register (struct frame_info *this_frame,
+alpha_mdebug_frame_prev_register (frame_info_ptr this_frame,
 				  void **this_prologue_cache, int regnum)
 {
   struct alpha_mdebug_unwind_cache *info
@@ -308,7 +308,7 @@ alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc)
 
 static int
 alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
-			    struct frame_info *this_frame,
+			    frame_info_ptr this_frame,
 			    void **this_cache)
 {
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
@@ -345,7 +345,7 @@ static const struct frame_unwind alpha_mdebug_frame_unwind =
 };
 
 static CORE_ADDR
-alpha_mdebug_frame_base_address (struct frame_info *this_frame,
+alpha_mdebug_frame_base_address (frame_info_ptr this_frame,
 				 void **this_prologue_cache)
 {
   struct alpha_mdebug_unwind_cache *info
@@ -355,7 +355,7 @@ alpha_mdebug_frame_base_address (struct frame_info *this_frame,
 }
 
 static CORE_ADDR
-alpha_mdebug_frame_locals_address (struct frame_info *this_frame,
+alpha_mdebug_frame_locals_address (frame_info_ptr this_frame,
 				   void **this_prologue_cache)
 {
   struct alpha_mdebug_unwind_cache *info
@@ -365,7 +365,7 @@ alpha_mdebug_frame_locals_address (struct frame_info *this_frame,
 }
 
 static CORE_ADDR
-alpha_mdebug_frame_args_address (struct frame_info *this_frame,
+alpha_mdebug_frame_args_address (frame_info_ptr this_frame,
 				 void **this_prologue_cache)
 {
   struct alpha_mdebug_unwind_cache *info
@@ -382,7 +382,7 @@ static const struct frame_base alpha_mdebug_frame_base = {
 };
 
 static const struct frame_base *
-alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame)
+alpha_mdebug_frame_base_sniffer (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
   struct mdebug_extra_func_info *proc_desc;
diff --git a/gdb/alpha-netbsd-tdep.c b/gdb/alpha-netbsd-tdep.c
index 72d7019377f..ae2deca2c85 100644
--- a/gdb/alpha-netbsd-tdep.c
+++ b/gdb/alpha-netbsd-tdep.c
@@ -235,7 +235,7 @@ alphanbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
 }
 
 static CORE_ADDR
-alphanbsd_sigcontext_addr (struct frame_info *frame)
+alphanbsd_sigcontext_addr (frame_info_ptr frame)
 {
   /* FIXME: This is not correct for all versions of NetBSD/alpha.
      We will probably need to disassemble the trampoline to figure
diff --git a/gdb/alpha-obsd-tdep.c b/gdb/alpha-obsd-tdep.c
index c0d672c3f72..41c376c6503 100644
--- a/gdb/alpha-obsd-tdep.c
+++ b/gdb/alpha-obsd-tdep.c
@@ -69,7 +69,7 @@ alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch,
 }
 
 static CORE_ADDR
-alphaobsd_sigcontext_addr (struct frame_info *this_frame)
+alphaobsd_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 44efc8e4bbb..426fdf60fb4 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -238,7 +238,7 @@ alpha_convert_register_p (struct gdbarch *gdbarch, int regno,
 }
 
 static int
-alpha_register_to_value (struct frame_info *frame, int regnum,
+alpha_register_to_value (frame_info_ptr frame, int regnum,
 			 struct type *valtype, gdb_byte *out,
 			int *optimizedp, int *unavailablep)
 {
@@ -265,7 +265,7 @@ alpha_register_to_value (struct frame_info *frame, int regnum,
 }
 
 static void
-alpha_value_to_register (struct frame_info *frame, int regnum,
+alpha_value_to_register (frame_info_ptr frame, int regnum,
 			 struct type *valtype, const gdb_byte *in)
 {
   gdb_byte out[ALPHA_REGISTER_SIZE];
@@ -848,7 +848,7 @@ alpha_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
    into the "pc".  This routine returns true on success.  */
 
 static int
-alpha_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+alpha_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   alpha_gdbarch_tdep *tdep = gdbarch_tdep<alpha_gdbarch_tdep> (gdbarch);
@@ -879,7 +879,7 @@ struct alpha_sigtramp_unwind_cache
 };
 
 static struct alpha_sigtramp_unwind_cache *
-alpha_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
+alpha_sigtramp_frame_unwind_cache (frame_info_ptr this_frame,
 				   void **this_prologue_cache)
 {
   struct alpha_sigtramp_unwind_cache *info;
@@ -920,7 +920,7 @@ alpha_sigtramp_register_address (struct gdbarch *gdbarch,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-alpha_sigtramp_frame_this_id (struct frame_info *this_frame,
+alpha_sigtramp_frame_this_id (frame_info_ptr this_frame,
 			      void **this_prologue_cache,
 			      struct frame_id *this_id)
 {
@@ -962,7 +962,7 @@ alpha_sigtramp_frame_this_id (struct frame_info *this_frame,
 /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
 
 static struct value *
-alpha_sigtramp_frame_prev_register (struct frame_info *this_frame,
+alpha_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				    void **this_prologue_cache, int regnum)
 {
   struct alpha_sigtramp_unwind_cache *info
@@ -987,7 +987,7 @@ alpha_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 alpha_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1229,7 +1229,7 @@ alpha_heuristic_analyze_probing_loop (struct gdbarch *gdbarch, CORE_ADDR *pc,
 }
 
 static struct alpha_heuristic_unwind_cache *
-alpha_heuristic_frame_unwind_cache (struct frame_info *this_frame,
+alpha_heuristic_frame_unwind_cache (frame_info_ptr this_frame,
 				    void **this_prologue_cache,
 				    CORE_ADDR start_pc)
 {
@@ -1406,7 +1406,7 @@ alpha_heuristic_frame_unwind_cache (struct frame_info *this_frame,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-alpha_heuristic_frame_this_id (struct frame_info *this_frame,
+alpha_heuristic_frame_this_id (frame_info_ptr this_frame,
 			       void **this_prologue_cache,
 			       struct frame_id *this_id)
 {
@@ -1419,7 +1419,7 @@ alpha_heuristic_frame_this_id (struct frame_info *this_frame,
 /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
 
 static struct value *
-alpha_heuristic_frame_prev_register (struct frame_info *this_frame,
+alpha_heuristic_frame_prev_register (frame_info_ptr this_frame,
 				     void **this_prologue_cache, int regnum)
 {
   struct alpha_heuristic_unwind_cache *info
@@ -1446,7 +1446,7 @@ static const struct frame_unwind alpha_heuristic_frame_unwind =
 };
 
 static CORE_ADDR
-alpha_heuristic_frame_base_address (struct frame_info *this_frame,
+alpha_heuristic_frame_base_address (frame_info_ptr this_frame,
 				    void **this_prologue_cache)
 {
   struct alpha_heuristic_unwind_cache *info
diff --git a/gdb/alpha-tdep.h b/gdb/alpha-tdep.h
index bc4a8407249..c12d7ec92ae 100644
--- a/gdb/alpha-tdep.h
+++ b/gdb/alpha-tdep.h
@@ -81,7 +81,7 @@ struct alpha_gdbarch_tdep : gdbarch_tdep_base
 
   /* Translate a signal handler stack base address into the address of
      the sigcontext structure for that signal handler.  */
-  CORE_ADDR (*sigcontext_addr) (struct frame_info *) = nullptr;
+  CORE_ADDR (*sigcontext_addr) (frame_info_ptr ) = nullptr;
 
   /* Does the PC fall in a signal trampoline.  */
   /* NOTE: cagney/2004-04-30: Do not copy/clone this code.  Instead
diff --git a/gdb/amd64-darwin-tdep.c b/gdb/amd64-darwin-tdep.c
index 7fc35536bc6..af3bad9af9b 100644
--- a/gdb/amd64-darwin-tdep.c
+++ b/gdb/amd64-darwin-tdep.c
@@ -75,7 +75,7 @@ const int amd64_darwin_thread_state_num_regs =
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-amd64_darwin_sigcontext_addr (struct frame_info *this_frame)
+amd64_darwin_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c
index 8e40283d838..960bb0b5942 100644
--- a/gdb/amd64-fbsd-tdep.c
+++ b/gdb/amd64-fbsd-tdep.c
@@ -169,7 +169,7 @@ const struct regset amd64_fbsd_segbases_regset =
 
 static void
 amd64_fbsd_sigframe_init (const struct tramp_frame *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func)
 {
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 35703a36785..07c1669f91e 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -133,7 +133,7 @@ static const gdb_byte amd64_x32_linux_sigtramp_code[] =
    the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-amd64_linux_sigtramp_start (struct frame_info *this_frame)
+amd64_linux_sigtramp_start (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch;
   const gdb_byte *sigtramp_code;
@@ -175,7 +175,7 @@ amd64_linux_sigtramp_start (struct frame_info *this_frame)
    routine.  */
 
 static int
-amd64_linux_sigtramp_p (struct frame_info *this_frame)
+amd64_linux_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -201,7 +201,7 @@ amd64_linux_sigtramp_p (struct frame_info *this_frame)
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-amd64_linux_sigcontext_addr (struct frame_info *this_frame)
+amd64_linux_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/amd64-netbsd-tdep.c b/gdb/amd64-netbsd-tdep.c
index 59d723caa55..ec6906c12fb 100644
--- a/gdb/amd64-netbsd-tdep.c
+++ b/gdb/amd64-netbsd-tdep.c
@@ -35,7 +35,7 @@
    routine.  */
 
 static int
-amd64nbsd_sigtramp_p (struct frame_info *this_frame)
+amd64nbsd_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -48,7 +48,7 @@ amd64nbsd_sigtramp_p (struct frame_info *this_frame)
    return the address of the associated mcontext structure.  */
 
 static CORE_ADDR
-amd64nbsd_mcontext_addr (struct frame_info *this_frame)
+amd64nbsd_mcontext_addr (frame_info_ptr this_frame)
 {
   CORE_ADDR addr;
 
diff --git a/gdb/amd64-obsd-tdep.c b/gdb/amd64-obsd-tdep.c
index f0bc7c474a6..22cf7f5d6c2 100644
--- a/gdb/amd64-obsd-tdep.c
+++ b/gdb/amd64-obsd-tdep.c
@@ -45,7 +45,7 @@ static const int amd64obsd_page_size = 4096;
    routine.  */
 
 static int
-amd64obsd_sigtramp_p (struct frame_info *this_frame)
+amd64obsd_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
@@ -98,7 +98,7 @@ amd64obsd_sigtramp_p (struct frame_info *this_frame)
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-amd64obsd_sigcontext_addr (struct frame_info *this_frame)
+amd64obsd_sigcontext_addr (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   ULONGEST offset = (pc & (amd64obsd_page_size - 1));
@@ -315,7 +315,7 @@ amd64obsd_collect_uthread (const struct regcache *regcache,
 #define amd64obsd_tf_reg_offset amd64obsd_sc_reg_offset
 
 static struct trad_frame_cache *
-amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+amd64obsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -362,7 +362,7 @@ amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-amd64obsd_trapframe_this_id (struct frame_info *this_frame,
+amd64obsd_trapframe_this_id (frame_info_ptr this_frame,
 			     void **this_cache, struct frame_id *this_id)
 {
   struct trad_frame_cache *cache =
@@ -372,7 +372,7 @@ amd64obsd_trapframe_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-amd64obsd_trapframe_prev_register (struct frame_info *this_frame,
+amd64obsd_trapframe_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   struct trad_frame_cache *cache =
@@ -383,7 +383,7 @@ amd64obsd_trapframe_prev_register (struct frame_info *this_frame,
 
 static int
 amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   ULONGEST cs;
diff --git a/gdb/amd64-sol2-tdep.c b/gdb/amd64-sol2-tdep.c
index ce96eb045ec..f62240fcd55 100644
--- a/gdb/amd64-sol2-tdep.c
+++ b/gdb/amd64-sol2-tdep.c
@@ -67,7 +67,7 @@ static int amd64_sol2_gregset_reg_offset[] = {
    'mcontext_t' that contains the saved set of machine registers.  */
 
 static CORE_ADDR
-amd64_sol2_mcontext_addr (struct frame_info *this_frame)
+amd64_sol2_mcontext_addr (frame_info_ptr this_frame)
 {
   CORE_ADDR sp, ucontext_addr;
 
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index d89e06d27cb..b396651d12b 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -2560,7 +2560,7 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 /* Normal frames.  */
 
 static void
-amd64_frame_cache_1 (struct frame_info *this_frame,
+amd64_frame_cache_1 (frame_info_ptr this_frame,
 		     struct amd64_frame_cache *cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2629,7 +2629,7 @@ amd64_frame_cache_1 (struct frame_info *this_frame,
 }
 
 static struct amd64_frame_cache *
-amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
+amd64_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct amd64_frame_cache *cache;
 
@@ -2653,7 +2653,7 @@ amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static enum unwind_stop_reason
-amd64_frame_unwind_stop_reason (struct frame_info *this_frame,
+amd64_frame_unwind_stop_reason (frame_info_ptr this_frame,
 				void **this_cache)
 {
   struct amd64_frame_cache *cache =
@@ -2670,7 +2670,7 @@ amd64_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static void
-amd64_frame_this_id (struct frame_info *this_frame, void **this_cache,
+amd64_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		     struct frame_id *this_id)
 {
   struct amd64_frame_cache *cache =
@@ -2688,7 +2688,7 @@ amd64_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-amd64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+amd64_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			   int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2742,7 +2742,7 @@ amd64_gen_return_address (struct gdbarch *gdbarch,
    on both platforms.  */
 
 static struct amd64_frame_cache *
-amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+amd64_sigtramp_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
@@ -2782,7 +2782,7 @@ amd64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static enum unwind_stop_reason
-amd64_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
+amd64_sigtramp_frame_unwind_stop_reason (frame_info_ptr this_frame,
 					 void **this_cache)
 {
   struct amd64_frame_cache *cache =
@@ -2795,7 +2795,7 @@ amd64_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static void
-amd64_sigtramp_frame_this_id (struct frame_info *this_frame,
+amd64_sigtramp_frame_this_id (frame_info_ptr this_frame,
 			      void **this_cache, struct frame_id *this_id)
 {
   struct amd64_frame_cache *cache =
@@ -2813,7 +2813,7 @@ amd64_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-amd64_sigtramp_frame_prev_register (struct frame_info *this_frame,
+amd64_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				    void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
@@ -2824,7 +2824,7 @@ amd64_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 amd64_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      void **this_cache)
 {
   gdbarch *arch = get_frame_arch (this_frame);
@@ -2866,7 +2866,7 @@ static const struct frame_unwind amd64_sigtramp_frame_unwind =
 \f
 
 static CORE_ADDR
-amd64_frame_base_address (struct frame_info *this_frame, void **this_cache)
+amd64_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct amd64_frame_cache *cache =
     amd64_frame_cache (this_frame, this_cache);
@@ -2911,7 +2911,7 @@ amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 static int
 amd64_epilogue_frame_sniffer (const struct frame_unwind *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      void **this_prologue_cache)
 {
   if (frame_relative_level (this_frame) == 0)
@@ -2922,7 +2922,7 @@ amd64_epilogue_frame_sniffer (const struct frame_unwind *self,
 }
 
 static struct amd64_frame_cache *
-amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+amd64_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -2963,7 +2963,7 @@ amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static enum unwind_stop_reason
-amd64_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
+amd64_epilogue_frame_unwind_stop_reason (frame_info_ptr this_frame,
 					 void **this_cache)
 {
   struct amd64_frame_cache *cache
@@ -2976,7 +2976,7 @@ amd64_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static void
-amd64_epilogue_frame_this_id (struct frame_info *this_frame,
+amd64_epilogue_frame_this_id (frame_info_ptr this_frame,
 			      void **this_cache,
 			      struct frame_id *this_id)
 {
@@ -3001,7 +3001,7 @@ static const struct frame_unwind amd64_epilogue_frame_unwind =
 };
 
 static struct frame_id
-amd64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+amd64_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR fp;
 
@@ -3064,7 +3064,7 @@ const struct regset amd64_fpregset =
    success.  */
 
 static int
-amd64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+amd64_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   gdb_byte buf[8];
   CORE_ADDR jb_addr;
diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h
index c18766e71c4..df85c60c19c 100644
--- a/gdb/amd64-tdep.h
+++ b/gdb/amd64-tdep.h
@@ -22,7 +22,7 @@
 #define AMD64_TDEP_H
 
 struct gdbarch;
-struct frame_info;
+class frame_info_ptr;
 struct regcache;
 
 #include "i386-tdep.h"
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index a9aef0bab88..180e54fb9a8 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -513,7 +513,7 @@ pc_in_range (CORE_ADDR pc, const struct amd64_windows_frame_cache *cache)
    Return 1 if an epilogue sequence was recognized, 0 otherwise.  */
 
 static int
-amd64_windows_frame_decode_epilogue (struct frame_info *this_frame,
+amd64_windows_frame_decode_epilogue (frame_info_ptr this_frame,
 				     struct amd64_windows_frame_cache *cache)
 {
   /* According to MSDN an epilogue "must consist of either an add RSP,constant
@@ -693,7 +693,7 @@ amd64_windows_frame_decode_epilogue (struct frame_info *this_frame,
 /* Decode and execute unwind insns at UNWIND_INFO.  */
 
 static void
-amd64_windows_frame_decode_insns (struct frame_info *this_frame,
+amd64_windows_frame_decode_insns (frame_info_ptr this_frame,
 				  struct amd64_windows_frame_cache *cache,
 				  CORE_ADDR unwind_info)
 {
@@ -1073,7 +1073,7 @@ amd64_windows_find_unwind_info (struct gdbarch *gdbarch, CORE_ADDR pc,
    for THIS_FRAME.  */
 
 static struct amd64_windows_frame_cache *
-amd64_windows_frame_cache (struct frame_info *this_frame, void **this_cache)
+amd64_windows_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -1118,7 +1118,7 @@ amd64_windows_frame_cache (struct frame_info *this_frame, void **this_cache)
    using the standard Windows x64 SEH info.  */
 
 static struct value *
-amd64_windows_frame_prev_register (struct frame_info *this_frame,
+amd64_windows_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1164,7 +1164,7 @@ amd64_windows_frame_prev_register (struct frame_info *this_frame,
    the standard Windows x64 SEH info.  */
 
 static void
-amd64_windows_frame_this_id (struct frame_info *this_frame, void **this_cache,
+amd64_windows_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		   struct frame_id *this_id)
 {
   struct amd64_windows_frame_cache *cache =
@@ -1230,7 +1230,7 @@ amd64_windows_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Check Win64 DLL jmp trampolines and find jump destination.  */
 
 static CORE_ADDR
-amd64_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+amd64_windows_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   CORE_ADDR destination = 0;
   struct gdbarch *gdbarch = get_frame_arch (frame);
diff --git a/gdb/arc-linux-tdep.c b/gdb/arc-linux-tdep.c
index d72bdaf24ac..da7f4758c19 100644
--- a/gdb/arc-linux-tdep.c
+++ b/gdb/arc-linux-tdep.c
@@ -159,7 +159,7 @@ static const int arc_linux_core_reg_offsets[] = {
    Returns TRUE if this is a sigtramp frame.  */
 
 static bool
-arc_linux_is_sigtramp (struct frame_info *this_frame)
+arc_linux_is_sigtramp (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -257,7 +257,7 @@ arc_linux_is_sigtramp (struct frame_info *this_frame)
    etc) in GDB hardcode values.  */
 
 static CORE_ADDR
-arc_linux_sigcontext_addr (struct frame_info *this_frame)
+arc_linux_sigcontext_addr (frame_info_ptr this_frame)
 {
   const int ucontext_offset = 0x80;
   const int sigcontext_offset = 0x14;
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 11e0551266e..2a145f837aa 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -997,7 +997,7 @@ arc_store_return_value (struct gdbarch *gdbarch, struct type *type,
 /* Implement the "get_longjmp_target" gdbarch method.  */
 
 static int
-arc_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+arc_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   arc_debug_printf ("called");
 
@@ -1061,7 +1061,7 @@ arc_return_value (struct gdbarch *gdbarch, struct value *function,
    frame pointer.  */
 
 static CORE_ADDR
-arc_frame_base_address (struct frame_info *this_frame, void **prologue_cache)
+arc_frame_base_address (frame_info_ptr this_frame, void **prologue_cache)
 {
   return (CORE_ADDR) get_frame_register_unsigned (this_frame, ARC_FP_REGNUM);
 }
@@ -1642,7 +1642,7 @@ arc_print_frame_cache (struct gdbarch *gdbarch, const char *message,
 /* Frame unwinder for normal frames.  */
 
 static struct arc_frame_cache *
-arc_make_frame_cache (struct frame_info *this_frame)
+arc_make_frame_cache (frame_info_ptr this_frame)
 {
   arc_debug_printf ("called");
 
@@ -1709,7 +1709,7 @@ arc_make_frame_cache (struct frame_info *this_frame)
 /* Implement the "this_id" frame_unwind method.  */
 
 static void
-arc_frame_this_id (struct frame_info *this_frame, void **this_cache,
+arc_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		   struct frame_id *this_id)
 {
   arc_debug_printf ("called");
@@ -1754,7 +1754,7 @@ arc_frame_this_id (struct frame_info *this_frame, void **this_cache,
 /* Implement the "prev_register" frame_unwind method.  */
 
 static struct value *
-arc_frame_prev_register (struct frame_info *this_frame,
+arc_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_cache, int regnum)
 {
   if (*this_cache == NULL)
@@ -1791,7 +1791,7 @@ arc_frame_prev_register (struct frame_info *this_frame,
 static void
 arc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			   struct dwarf2_frame_state_reg *reg,
-			   struct frame_info *info)
+			   frame_info_ptr info)
 {
   if (regnum == gdbarch_pc_regnum (gdbarch))
     /* The return address column.  */
@@ -1805,7 +1805,7 @@ arc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
     from within signal handlers.  */
 
 static struct arc_frame_cache *
-arc_make_sigtramp_frame_cache (struct frame_info *this_frame)
+arc_make_sigtramp_frame_cache (frame_info_ptr this_frame)
 {
   arc_debug_printf ("called");
 
@@ -1844,7 +1844,7 @@ arc_make_sigtramp_frame_cache (struct frame_info *this_frame)
    frames.  */
 
 static void
-arc_sigtramp_frame_this_id (struct frame_info *this_frame,
+arc_sigtramp_frame_this_id (frame_info_ptr this_frame,
 			    void **this_cache, struct frame_id *this_id)
 {
   arc_debug_printf ("called");
@@ -1863,7 +1863,7 @@ arc_sigtramp_frame_this_id (struct frame_info *this_frame,
 /* Get a register from a signal handler frame.  */
 
 static struct value *
-arc_sigtramp_frame_prev_register (struct frame_info *this_frame,
+arc_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				  void **this_cache, int regnum)
 {
   arc_debug_printf ("regnum = %d", regnum);
@@ -1881,7 +1881,7 @@ arc_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 arc_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			    struct frame_info *this_frame,
+			    frame_info_ptr this_frame,
 			    void **this_cache)
 {
   arc_debug_printf ("called");
diff --git a/gdb/arc-tdep.h b/gdb/arc-tdep.h
index eba435f62f0..56e0c49ae71 100644
--- a/gdb/arc-tdep.h
+++ b/gdb/arc-tdep.h
@@ -131,10 +131,10 @@ struct arc_gdbarch_tdep : gdbarch_tdep_base
   bool has_hw_loops = false;
 
   /* Detect sigtramp.  */
-  bool (*is_sigtramp) (struct frame_info *) = nullptr;
+  bool (*is_sigtramp) (frame_info_ptr ) = nullptr;
 
   /* Get address of sigcontext for sigtramp.  */
-  CORE_ADDR (*sigcontext_addr) (struct frame_info *) = nullptr;
+  CORE_ADDR (*sigcontext_addr) (frame_info_ptr ) = nullptr;
 
   /* Offset of registers in `struct sigcontext'.  */
   const int *sc_reg_offset = nullptr;
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index 9c6b9268a69..6f7b5b1fd01 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -132,7 +132,7 @@ default_get_memtag (struct gdbarch *gdbarch, struct value *address,
 }
 
 CORE_ADDR
-generic_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+generic_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   return 0;
 }
@@ -158,7 +158,7 @@ generic_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 int
 default_code_of_frame_writable (struct gdbarch *gdbarch,
-				struct frame_info *frame)
+				frame_info_ptr frame)
 {
   return 1;
 }
@@ -1077,7 +1077,7 @@ default_type_align (struct gdbarch *gdbarch, struct type *type)
 /* See arch-utils.h.  */
 
 std::string
-default_get_pc_address_flags (frame_info *frame, CORE_ADDR pc)
+default_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc)
 {
   return "";
 }
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
index f850e5fd6e7..f6229f434fd 100644
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -22,7 +22,7 @@
 
 #include "gdbarch.h"
 
-struct frame_info;
+class frame_info_ptr;
 struct minimal_symbol;
 struct type;
 struct gdbarch_info;
@@ -154,7 +154,7 @@ struct value *default_get_memtag (struct gdbarch *gdbarch,
 				  struct value *address,
 				  memtag_type tag_type);
 
-extern CORE_ADDR generic_skip_trampoline_code (struct frame_info *frame,
+extern CORE_ADDR generic_skip_trampoline_code (frame_info_ptr frame,
 					       CORE_ADDR pc);
 
 extern CORE_ADDR generic_skip_solib_resolver (struct gdbarch *gdbarch,
@@ -167,7 +167,7 @@ extern int generic_stack_frame_destroyed_p (struct gdbarch *gdbarch,
 					    CORE_ADDR pc);
 
 extern int default_code_of_frame_writable (struct gdbarch *gdbarch,
-					   struct frame_info *frame);
+					   frame_info_ptr frame);
 
 /* By default, registers are not convertible.  */
 extern int generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
@@ -291,7 +291,7 @@ extern ULONGEST default_type_align (struct gdbarch *gdbarch,
 				    struct type *type);
 
 /* Default implementation of gdbarch get_pc_address_flags method.  */
-extern std::string default_get_pc_address_flags (frame_info *frame,
+extern std::string default_get_pc_address_flags (frame_info_ptr frame,
 						 CORE_ADDR pc);
 
 /* Default implementation of gdbarch read_core_file_mappings method.  */
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index 61c8f0cecad..dabbceb743a 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -97,7 +97,7 @@ static const struct regcache_map_entry arm_fbsd_vfpregmap[] =
 
 static void
 arm_fbsd_sigframe_init (const struct tramp_frame *self,
-			struct frame_info *this_frame,
+			frame_info_ptr this_frame,
 			struct trad_frame_cache *this_cache,
 			CORE_ADDR func)
 {
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 1feb69fe6dd..86ab5794b37 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -277,7 +277,7 @@ static struct arm_get_next_pcs_ops arm_linux_get_next_pcs_ops = {
 };
 
 static void
-arm_linux_sigtramp_cache (struct frame_info *this_frame,
+arm_linux_sigtramp_cache (frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func, int regs_offset)
 {
@@ -300,7 +300,7 @@ arm_linux_sigtramp_cache (struct frame_info *this_frame,
 /* See arm-linux.h for stack layout details.  */
 static void
 arm_linux_sigreturn_init (const struct tramp_frame *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func)
 {
@@ -320,7 +320,7 @@ arm_linux_sigreturn_init (const struct tramp_frame *self,
 
 static void
 arm_linux_rt_sigreturn_init (const struct tramp_frame *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func)
 {
@@ -343,7 +343,7 @@ arm_linux_rt_sigreturn_init (const struct tramp_frame *self,
 
 static void
 arm_linux_restart_syscall_init (const struct tramp_frame *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				struct trad_frame_cache *this_cache,
 				CORE_ADDR func)
 {
@@ -755,7 +755,7 @@ arm_linux_core_read_description (struct gdbarch *gdbarch,
    will return to ARM or Thumb code.  Return 0 if it is not a
    rt_sigreturn/sigreturn syscall.  */
 static int
-arm_linux_sigreturn_return_addr (struct frame_info *frame,
+arm_linux_sigreturn_return_addr (frame_info_ptr frame,
 				 unsigned long svc_number,
 				 CORE_ADDR *pc, int *is_thumb)
 {
@@ -975,7 +975,7 @@ arm_linux_copy_svc (struct gdbarch *gdbarch, struct regcache *regs,
 {
   CORE_ADDR return_to = 0;
 
-  struct frame_info *frame;
+  frame_info_ptr frame;
   unsigned int svc_number = displaced_read_reg (regs, dsc, 7);
   int is_sigreturn = 0;
   int is_thumb;
@@ -1687,7 +1687,7 @@ arm_linux_syscall_record (struct regcache *regcache, unsigned long svc_number)
 /* Implement the skip_trampoline_code gdbarch method.  */
 
 static CORE_ADDR
-arm_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+arm_linux_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   CORE_ADDR target_pc = arm_skip_stub (frame, pc);
 
diff --git a/gdb/arm-obsd-tdep.c b/gdb/arm-obsd-tdep.c
index 634c76b7561..697f0756112 100644
--- a/gdb/arm-obsd-tdep.c
+++ b/gdb/arm-obsd-tdep.c
@@ -30,7 +30,7 @@
 
 static void
 armobsd_sigframe_init (const struct tramp_frame *self,
-		       struct frame_info *this_frame,
+		       frame_info_ptr this_frame,
 		       struct trad_frame_cache *cache,
 		       CORE_ADDR func)
 {
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index cf8b610a381..f7fe19d13c0 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -329,7 +329,7 @@ reconstruct_t_bit(struct gdbarch *gdbarch, CORE_ADDR lr, ULONGEST psr)
 static inline void
 arm_cache_init_sp (int regnum, CORE_ADDR* member,
 				      struct arm_prologue_cache *cache,
-				      struct frame_info *frame)
+				      frame_info_ptr frame)
 {
   CORE_ADDR val = get_frame_register_unsigned (frame, regnum);
   if (val == cache->sp)
@@ -352,7 +352,7 @@ arm_cache_init (struct arm_prologue_cache *cache, struct gdbarch *gdbarch)
 /* Similar to the previous function, but extracts GDBARCH from FRAME.  */
 
 static void
-arm_cache_init (struct arm_prologue_cache *cache, struct frame_info *frame)
+arm_cache_init (struct arm_prologue_cache *cache, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
@@ -578,7 +578,7 @@ arm_is_thumb (struct regcache *regcache)
    frame.  */
 
 int
-arm_frame_is_thumb (struct frame_info *frame)
+arm_frame_is_thumb (frame_info_ptr frame)
 {
   /* Check the architecture of FRAME.  */
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -2119,7 +2119,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
 }
 
 static void
-arm_scan_prologue (struct frame_info *this_frame,
+arm_scan_prologue (frame_info_ptr this_frame,
 		   struct arm_prologue_cache *cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2216,7 +2216,7 @@ arm_scan_prologue (struct frame_info *this_frame,
 }
 
 static struct arm_prologue_cache *
-arm_make_prologue_cache (struct frame_info *this_frame)
+arm_make_prologue_cache (frame_info_ptr this_frame)
 {
   int reg;
   struct arm_prologue_cache *cache;
@@ -2250,7 +2250,7 @@ arm_make_prologue_cache (struct frame_info *this_frame)
 /* Implementation of the stop_reason hook for arm_prologue frames.  */
 
 static enum unwind_stop_reason
-arm_prologue_unwind_stop_reason (struct frame_info *this_frame,
+arm_prologue_unwind_stop_reason (frame_info_ptr this_frame,
 				 void **this_cache)
 {
   struct arm_prologue_cache *cache;
@@ -2278,7 +2278,7 @@ arm_prologue_unwind_stop_reason (struct frame_info *this_frame,
    and the caller's SP when we were called.  */
 
 static void
-arm_prologue_this_id (struct frame_info *this_frame,
+arm_prologue_this_id (frame_info_ptr this_frame,
 		      void **this_cache,
 		      struct frame_id *this_id)
 {
@@ -2306,7 +2306,7 @@ arm_prologue_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-arm_prologue_prev_register (struct frame_info *this_frame,
+arm_prologue_prev_register (frame_info_ptr this_frame,
 			    void **this_cache,
 			    int prev_regnum)
 {
@@ -2702,7 +2702,7 @@ arm_find_exidx_entry (CORE_ADDR memaddr, CORE_ADDR *start)
    for the ARM Architecture" document.  */
 
 static struct arm_prologue_cache *
-arm_exidx_fill_cache (struct frame_info *this_frame, gdb_byte *entry)
+arm_exidx_fill_cache (frame_info_ptr this_frame, gdb_byte *entry)
 {
   CORE_ADDR vsp = 0;
   int vsp_valid = 0;
@@ -3000,7 +3000,7 @@ arm_exidx_fill_cache (struct frame_info *this_frame, gdb_byte *entry)
 
 static int
 arm_exidx_unwind_sniffer (const struct frame_unwind *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -3099,7 +3099,7 @@ struct frame_unwind arm_exidx_unwind = {
 };
 
 static struct arm_prologue_cache *
-arm_make_epilogue_frame_cache (struct frame_info *this_frame)
+arm_make_epilogue_frame_cache (frame_info_ptr this_frame)
 {
   struct arm_prologue_cache *cache;
   int reg;
@@ -3131,7 +3131,7 @@ arm_make_epilogue_frame_cache (struct frame_info *this_frame)
    'struct frame_uwnind' for epilogue unwinder.  */
 
 static void
-arm_epilogue_frame_this_id (struct frame_info *this_frame,
+arm_epilogue_frame_this_id (frame_info_ptr this_frame,
 			    void **this_cache,
 			    struct frame_id *this_id)
 {
@@ -3159,7 +3159,7 @@ arm_epilogue_frame_this_id (struct frame_info *this_frame,
    'struct frame_uwnind' for epilogue unwinder.  */
 
 static struct value *
-arm_epilogue_frame_prev_register (struct frame_info *this_frame,
+arm_epilogue_frame_prev_register (frame_info_ptr this_frame,
 				  void **this_cache, int regnum)
 {
   if (*this_cache == NULL)
@@ -3178,7 +3178,7 @@ static int thumb_stack_frame_destroyed_p (struct gdbarch *gdbarch,
 
 static int
 arm_epilogue_frame_sniffer (const struct frame_unwind *self,
-			    struct frame_info *this_frame,
+			    frame_info_ptr this_frame,
 			    void **this_prologue_cache)
 {
   if (frame_relative_level (this_frame) == 0)
@@ -3235,7 +3235,7 @@ static const struct frame_unwind arm_epilogue_frame_unwind =
    The trampoline 'bx r2' doesn't belong to main.  */
 
 static CORE_ADDR
-arm_skip_bx_reg (struct frame_info *frame, CORE_ADDR pc)
+arm_skip_bx_reg (frame_info_ptr frame, CORE_ADDR pc)
 {
   /* The heuristics of recognizing such trampoline is that FRAME is
      executing in Thumb mode and the instruction on PC is 'bx Rm'.  */
@@ -3267,7 +3267,7 @@ arm_skip_bx_reg (struct frame_info *frame, CORE_ADDR pc)
 }
 
 static struct arm_prologue_cache *
-arm_make_stub_cache (struct frame_info *this_frame)
+arm_make_stub_cache (frame_info_ptr this_frame)
 {
   struct arm_prologue_cache *cache;
 
@@ -3286,7 +3286,7 @@ arm_make_stub_cache (struct frame_info *this_frame)
 /* Our frame ID for a stub frame is the current SP and LR.  */
 
 static void
-arm_stub_this_id (struct frame_info *this_frame,
+arm_stub_this_id (frame_info_ptr this_frame,
 		  void **this_cache,
 		  struct frame_id *this_id)
 {
@@ -3304,7 +3304,7 @@ arm_stub_this_id (struct frame_info *this_frame,
 
 static int
 arm_stub_unwind_sniffer (const struct frame_unwind *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   CORE_ADDR addr_in_block;
@@ -3342,7 +3342,7 @@ struct frame_unwind arm_stub_unwind = {
    returned.  */
 
 static struct arm_prologue_cache *
-arm_m_exception_cache (struct frame_info *this_frame)
+arm_m_exception_cache (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
@@ -3644,7 +3644,7 @@ arm_m_exception_cache (struct frame_info *this_frame)
    'struct frame_uwnind'.  */
 
 static void
-arm_m_exception_this_id (struct frame_info *this_frame,
+arm_m_exception_this_id (frame_info_ptr this_frame,
 			 void **this_cache,
 			 struct frame_id *this_id)
 {
@@ -3665,7 +3665,7 @@ arm_m_exception_this_id (struct frame_info *this_frame,
    'struct frame_uwnind'.  */
 
 static struct value *
-arm_m_exception_prev_register (struct frame_info *this_frame,
+arm_m_exception_prev_register (frame_info_ptr this_frame,
 			       void **this_cache,
 			       int prev_regnum)
 {
@@ -3730,7 +3730,7 @@ arm_m_exception_prev_register (struct frame_info *this_frame,
 
 static int
 arm_m_exception_unwind_sniffer (const struct frame_unwind *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -3757,7 +3757,7 @@ struct frame_unwind arm_m_exception_unwind =
 };
 
 static CORE_ADDR
-arm_normal_frame_base (struct frame_info *this_frame, void **this_cache)
+arm_normal_frame_base (frame_info_ptr this_frame, void **this_cache)
 {
   struct arm_prologue_cache *cache;
 
@@ -3778,7 +3778,7 @@ struct frame_base arm_normal_base = {
 };
 
 static struct value *
-arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache,
+arm_dwarf2_prev_register (frame_info_ptr this_frame, void **this_cache,
 			  int regnum)
 {
   struct gdbarch * gdbarch = get_frame_arch (this_frame);
@@ -4661,7 +4661,7 @@ print_fpu_flags (struct ui_file *file, int flags)
    (if present) or emulator.  */
 static void
 arm_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
-		      struct frame_info *frame, const char *args)
+		      frame_info_ptr frame, const char *args)
 {
   unsigned long status = get_frame_register_unsigned (frame, ARM_FPS_REGNUM);
   int type;
@@ -5005,7 +5005,7 @@ static const unsigned char op_lit0 = DW_OP_lit0;
 static void
 arm_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			   struct dwarf2_frame_state_reg *reg,
-			   struct frame_info *this_frame)
+			   frame_info_ptr this_frame)
 {
   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
 
@@ -9050,7 +9050,7 @@ arm_return_value (struct gdbarch *gdbarch, struct value *function,
 
 
 static int
-arm_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+arm_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
@@ -9122,7 +9122,7 @@ arm_is_sgstubs_section (struct obj_section *sec)
    return the target PC.  Otherwise return 0.  */
 
 CORE_ADDR
-arm_skip_stub (struct frame_info *frame, CORE_ADDR pc)
+arm_skip_stub (frame_info_ptr frame, CORE_ADDR pc)
 {
   const char *name;
   int namelen;
@@ -9671,7 +9671,7 @@ arm_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache,
 }
 
 static struct value *
-value_of_arm_user_reg (struct frame_info *frame, const void *baton)
+value_of_arm_user_reg (frame_info_ptr frame, const void *baton)
 {
   const int *reg_p = (const int *) baton;
   return value_of_register (*reg_p, frame);
@@ -9765,7 +9765,7 @@ arm_register_g_packet_guesses (struct gdbarch *gdbarch)
 /* Implement the code_of_frame_writable gdbarch method.  */
 
 static int
-arm_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame)
+arm_code_of_frame_writable (struct gdbarch *gdbarch, frame_info_ptr frame)
 {
   arm_gdbarch_tdep *tdep = gdbarch_tdep<arm_gdbarch_tdep> (gdbarch);
 
@@ -9793,7 +9793,7 @@ arm_gnu_triplet_regexp (struct gdbarch *gdbarch)
 /* Implement the "get_pc_address_flags" gdbarch method.  */
 
 static std::string
-arm_get_pc_address_flags (frame_info *frame, CORE_ADDR pc)
+arm_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc)
 {
   if (get_frame_pc_masked (frame))
     return "PAC";
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 67dd1151da4..47b0270c5c2 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -279,7 +279,7 @@ extern void
 		       arm_displaced_step_copy_insn_closure *dsc, int regno,
 		       ULONGEST val, enum pc_write_style write_pc);
 
-CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR);
+CORE_ADDR arm_skip_stub (frame_info_ptr , CORE_ADDR);
 
 ULONGEST arm_get_next_pcs_read_memory_unsigned_integer (CORE_ADDR memaddr,
 							int len,
@@ -292,7 +292,7 @@ int arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self);
 
 std::vector<CORE_ADDR> arm_software_single_step (struct regcache *);
 int arm_is_thumb (struct regcache *regcache);
-int arm_frame_is_thumb (struct frame_info *frame);
+int arm_frame_is_thumb (frame_info_ptr frame);
 
 extern void arm_displaced_step_fixup (struct gdbarch *,
 				      displaced_step_copy_insn_closure *,
diff --git a/gdb/arm-wince-tdep.c b/gdb/arm-wince-tdep.c
index 5063b308809..6ec3c04b5a8 100644
--- a/gdb/arm-wince-tdep.c
+++ b/gdb/arm-wince-tdep.c
@@ -36,7 +36,7 @@ static const gdb_byte arm_wince_thumb_le_breakpoint[] = { 0xfe, 0xdf };
 #define ARM_WINCE_JB_PC			10
 
 static CORE_ADDR
-arm_pe_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+arm_pe_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index 357f5bb8f2d..1e9d9442909 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -981,7 +981,7 @@ avr_return_value (struct gdbarch *gdbarch, struct value *function,
    for it IS the sp for the next frame.  */
 
 static struct avr_unwind_cache *
-avr_frame_unwind_cache (struct frame_info *this_frame,
+avr_frame_unwind_cache (frame_info_ptr this_frame,
 			void **this_prologue_cache)
 {
   CORE_ADDR start_pc, current_pc;
@@ -1061,7 +1061,7 @@ avr_frame_unwind_cache (struct frame_info *this_frame,
 }
 
 static CORE_ADDR
-avr_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+avr_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   ULONGEST pc;
 
@@ -1071,7 +1071,7 @@ avr_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 }
 
 static CORE_ADDR
-avr_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+avr_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   ULONGEST sp;
 
@@ -1084,7 +1084,7 @@ avr_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-avr_frame_this_id (struct frame_info *this_frame,
+avr_frame_this_id (frame_info_ptr this_frame,
 		   void **this_prologue_cache,
 		   struct frame_id *this_id)
 {
@@ -1109,7 +1109,7 @@ avr_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-avr_frame_prev_register (struct frame_info *this_frame,
+avr_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_prologue_cache, int regnum)
 {
   struct avr_unwind_cache *info
@@ -1168,7 +1168,7 @@ static const struct frame_unwind avr_frame_unwind = {
 };
 
 static CORE_ADDR
-avr_frame_base_address (struct frame_info *this_frame, void **this_cache)
+avr_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct avr_unwind_cache *info
     = avr_frame_unwind_cache (this_frame, this_cache);
@@ -1188,7 +1188,7 @@ static const struct frame_base avr_frame_base = {
    save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */
 
 static struct frame_id
-avr_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+avr_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   ULONGEST base;
 
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 1fccfde559e..ab94c2128f2 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2569,7 +2569,7 @@ maint_agent_eval_command (const char *exp, int from_tty)
 static void
 maint_agent_printf_command (const char *cmdrest, int from_tty)
 {
-  struct frame_info *fi = get_current_frame ();	/* need current scope */
+  frame_info_ptr fi = get_current_frame ();	/* need current scope */
   const char *format_start, *format_end;
 
   /* We don't deal with overlay debugging at the moment.  We need to
diff --git a/gdb/bfin-linux-tdep.c b/gdb/bfin-linux-tdep.c
index 6c4023da9f5..873cb017e82 100644
--- a/gdb/bfin-linux-tdep.c
+++ b/gdb/bfin-linux-tdep.c
@@ -95,7 +95,7 @@ static const int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] =
 
 static void
 bfin_linux_sigframe_init (const struct tramp_frame *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func)
 {
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index f232e22c37c..d3b3d7f86f1 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -288,7 +288,7 @@ bfin_alloc_frame_cache (void)
 }
 
 static struct bfin_frame_cache *
-bfin_frame_cache (struct frame_info *this_frame, void **this_cache)
+bfin_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct bfin_frame_cache *cache;
   int i;
@@ -340,7 +340,7 @@ bfin_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-bfin_frame_this_id (struct frame_info *this_frame,
+bfin_frame_this_id (frame_info_ptr this_frame,
 		    void **this_cache,
 		    struct frame_id *this_id)
 {
@@ -355,7 +355,7 @@ bfin_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-bfin_frame_prev_register (struct frame_info *this_frame,
+bfin_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_cache,
 			  int regnum)
 {
@@ -726,7 +726,7 @@ bfin_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
 }
 
 static CORE_ADDR
-bfin_frame_base_address (struct frame_info *this_frame, void **this_cache)
+bfin_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
 
@@ -734,7 +734,7 @@ bfin_frame_base_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static CORE_ADDR
-bfin_frame_local_address (struct frame_info *this_frame, void **this_cache)
+bfin_frame_local_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
 
@@ -742,7 +742,7 @@ bfin_frame_local_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static CORE_ADDR
-bfin_frame_args_address (struct frame_info *this_frame, void **this_cache)
+bfin_frame_args_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache);
 
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 47772f3b1a6..a7c9e143751 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -52,7 +52,7 @@
    slot instruction.  */
 
 const struct block *
-get_frame_block (struct frame_info *frame, CORE_ADDR *addr_in_block)
+get_frame_block (frame_info_ptr frame, CORE_ADDR *addr_in_block)
 {
   CORE_ADDR pc;
   const struct block *bl;
@@ -115,7 +115,7 @@ get_pc_function_start (CORE_ADDR pc)
 /* Return the symbol for the function executing in frame FRAME.  */
 
 struct symbol *
-get_frame_function (struct frame_info *frame)
+get_frame_function (frame_info_ptr frame)
 {
   const struct block *bl = get_frame_block (frame, 0);
 
@@ -460,13 +460,13 @@ find_gnu_ifunc_target_type (CORE_ADDR resolver_funaddr)
    at least as old as the selected frame. Return NULL if there is no
    such frame.  If BLOCK is NULL, just return NULL.  */
 
-struct frame_info *
+frame_info_ptr
 block_innermost_frame (const struct block *block)
 {
   if (block == NULL)
     return NULL;
 
-  frame_info *frame = get_selected_frame ();
+  frame_info_ptr frame = get_selected_frame ();
   while (frame != NULL)
     {
       const struct block *frame_block = get_frame_block (frame, NULL);
diff --git a/gdb/bpf-tdep.c b/gdb/bpf-tdep.c
index a5df478063c..fee85f0ec04 100644
--- a/gdb/bpf-tdep.c
+++ b/gdb/bpf-tdep.c
@@ -155,7 +155,7 @@ bpf_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 /* Given THIS_FRAME, return its ID.  */
 
 static void
-bpf_frame_this_id (struct frame_info *this_frame,
+bpf_frame_this_id (frame_info_ptr this_frame,
 		   void **this_prologue_cache,
 		   struct frame_id *this_id)
 {
@@ -166,7 +166,7 @@ bpf_frame_this_id (struct frame_info *this_frame,
 /* Return the reason why we can't unwind past THIS_FRAME.  */
 
 static enum unwind_stop_reason
-bpf_frame_unwind_stop_reason (struct frame_info *this_frame,
+bpf_frame_unwind_stop_reason (frame_info_ptr this_frame,
 			      void **this_cache)
 {
   return UNWIND_OUTERMOST;
@@ -175,7 +175,7 @@ bpf_frame_unwind_stop_reason (struct frame_info *this_frame,
 /* Ask THIS_FRAME to unwind its register.  */
 
 static struct value *
-bpf_frame_prev_register (struct frame_info *this_frame,
+bpf_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_prologue_cache, int regnum)
 {
   return frame_unwind_got_register (this_frame, regnum, regnum);
@@ -236,7 +236,7 @@ bpf_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
 /* Assuming THIS_FRAME is a dummy frame, return its frame ID.  */
 
 static struct frame_id
-bpf_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+bpf_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR sp = get_frame_register_unsigned (this_frame,
 					      gdbarch_sp_regnum (gdbarch));
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index 2eb24f3b76c..6557ee71449 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -133,7 +133,7 @@ is_exception_catchpoint (breakpoint *bp)
 static void
 fetch_probe_arguments (struct value **arg0, struct value **arg1)
 {
-  struct frame_info *frame = get_selected_frame (_("No frame selected"));
+  frame_info_ptr frame = get_selected_frame (_("No frame selected"));
   CORE_ADDR pc = get_frame_pc (frame);
   struct bound_probe pc_probe;
   unsigned n_args;
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 5397dee6733..592ee64f9cd 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1948,7 +1948,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
     within_current_scope = 1;
   else
     {
-      struct frame_info *fi = get_current_frame ();
+      frame_info_ptr fi = get_current_frame ();
       struct gdbarch *frame_arch = get_frame_arch (fi);
       CORE_ADDR frame_pc = get_frame_pc (fi);
 
@@ -4975,7 +4975,7 @@ static wp_check_result
 watchpoint_check (bpstat *bs)
 {
   struct watchpoint *b;
-  struct frame_info *fr;
+  frame_info_ptr fr;
   int within_current_scope;
 
   /* BS is built from an existing struct breakpoint.  */
@@ -4992,7 +4992,7 @@ watchpoint_check (bpstat *bs)
     within_current_scope = 1;
   else
     {
-      struct frame_info *frame = get_current_frame ();
+      frame_info_ptr frame = get_current_frame ();
       struct gdbarch *frame_arch = get_frame_arch (frame);
       CORE_ADDR frame_pc = get_frame_pc (frame);
 
@@ -5379,7 +5379,7 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
 	select_frame (get_current_frame ());
       else
 	{
-	  struct frame_info *frame;
+	  frame_info_ptr frame;
 
 	  /* For local watchpoint expressions, which particular
 	     instance of a local is being watched matters, so we
@@ -7450,9 +7450,9 @@ check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
 	   original dummy frame, hence frame_id_inner can't be used.  See
 	   the comments on frame_id_inner for more details.  */
 	bool unwind_finished_unexpectedly = false;
-	for (struct frame_info *fi = get_current_frame (); fi != nullptr; )
+	for (frame_info_ptr fi = get_current_frame (); fi != nullptr; )
 	  {
-	    struct frame_info *prev = get_prev_frame (fi);
+	    frame_info_ptr prev = get_prev_frame (fi);
 	    if (prev == nullptr)
 	      {
 		/* FI is the last stack frame.  Why did this frame not
@@ -10049,7 +10049,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
   if (*tok)
     error (_("Junk at end of command."));
 
-  frame_info *wp_frame = block_innermost_frame (exp_valid_block);
+  frame_info_ptr wp_frame = block_innermost_frame (exp_valid_block);
 
   /* Save this because create_internal_breakpoint below invalidates
      'wp_frame'.  */
@@ -10440,7 +10440,7 @@ until_break_fsm::do_async_reply_reason ()
 void
 until_break_command (const char *arg, int from_tty, int anywhere)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *frame_gdbarch;
   struct frame_id stack_frame_id;
   struct frame_id caller_frame_id;
@@ -13510,7 +13510,7 @@ insert_single_step_breakpoints (struct gdbarch *gdbarch)
 
   if (!next_pcs.empty ())
     {
-      struct frame_info *frame = get_current_frame ();
+      frame_info_ptr frame = get_current_frame ();
       const address_space *aspace = get_frame_address_space (frame);
 
       for (CORE_ADDR pc : next_pcs)
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 87373085f24..a4fdc55b092 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -975,7 +975,7 @@ class cplus_language : public language_defn
 
   /* See language.h.  */
 
-  CORE_ADDR skip_trampoline (struct frame_info *fi,
+  CORE_ADDR skip_trampoline (frame_info_ptr fi,
 			     CORE_ADDR pc) const override
   {
     return cplus_skip_trampoline (fi, pc);
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
index f9ba559f12c..f10117491ec 100644
--- a/gdb/cp-abi.c
+++ b/gdb/cp-abi.c
@@ -152,7 +152,7 @@ cplus_make_method_ptr (struct type *type, gdb_byte *contents,
 }
 
 CORE_ADDR
-cplus_skip_trampoline (struct frame_info *frame,
+cplus_skip_trampoline (frame_info_ptr frame,
 		       CORE_ADDR stop_pc)
 {
   if (current_cp_abi.skip_trampoline == NULL)
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h
index c53b02d509c..bc85f6dc187 100644
--- a/gdb/cp-abi.h
+++ b/gdb/cp-abi.h
@@ -27,7 +27,7 @@ struct fn_field;
 struct type;
 struct value;
 struct ui_file;
-struct frame_info;
+class frame_info_ptr;
 
 /* The functions here that attempt to determine what sort of thing a
    mangled name refers to may well be revised in the future.  It would
@@ -204,7 +204,7 @@ extern std::string cplus_typename_from_type_info (struct value *value);
    address of the routine we are thunking to and continue to there
    instead.  */
 
-CORE_ADDR cplus_skip_trampoline (struct frame_info *frame,
+CORE_ADDR cplus_skip_trampoline (frame_info_ptr frame,
 				 CORE_ADDR stop_pc);
 
 /* Return a struct that provides pass-by-reference information
@@ -247,7 +247,7 @@ struct cp_abi_ops
   struct type *(*get_typeid_type) (struct gdbarch *gdbarch);
   struct type *(*get_type_from_type_info) (struct value *value);
   std::string (*get_typename_from_type_info) (struct value *value);
-  CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
+  CORE_ADDR (*skip_trampoline) (frame_info_ptr , CORE_ADDR);
   struct language_pass_by_ref_info (*pass_by_reference) (struct type *type);
 };
 
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index 73110d97f2f..3019d32965c 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -193,7 +193,7 @@ static const unsigned short rt_sigtramp_code[] =
    the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-cris_sigtramp_start (struct frame_info *this_frame)
+cris_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[SIGTRAMP_LEN];
@@ -221,7 +221,7 @@ cris_sigtramp_start (struct frame_info *this_frame)
    the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-cris_rt_sigtramp_start (struct frame_info *this_frame)
+cris_rt_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[SIGTRAMP_LEN];
@@ -249,7 +249,7 @@ cris_rt_sigtramp_start (struct frame_info *this_frame)
    return the address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-cris_sigcontext_addr (struct frame_info *this_frame)
+cris_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -309,7 +309,7 @@ struct cris_unwind_cache
 };
 
 static struct cris_unwind_cache *
-cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
+cris_sigtramp_frame_unwind_cache (frame_info_ptr this_frame,
 				  void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -402,7 +402,7 @@ cris_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
 }
 
 static void
-cris_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
+cris_sigtramp_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			     struct frame_id *this_id)
 {
   struct cris_unwind_cache *cache =
@@ -412,10 +412,10 @@ cris_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
 
 /* Forward declaration.  */
 
-static struct value *cris_frame_prev_register (struct frame_info *this_frame,
+static struct value *cris_frame_prev_register (frame_info_ptr this_frame,
 					       void **this_cache, int regnum);
 static struct value *
-cris_sigtramp_frame_prev_register (struct frame_info *this_frame,
+cris_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
@@ -425,7 +425,7 @@ cris_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 cris_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_cache)
 {
   if (cris_sigtramp_start (this_frame) 
@@ -448,7 +448,7 @@ static const struct frame_unwind cris_sigtramp_frame_unwind =
 
 static int
 crisv32_single_step_through_delay (struct gdbarch *gdbarch,
-				   struct frame_info *this_frame)
+				   frame_info_ptr this_frame)
 {
   cris_gdbarch_tdep *tdep = gdbarch_tdep<cris_gdbarch_tdep> (gdbarch);
   ULONGEST erp;
@@ -645,11 +645,11 @@ static void set_cris_dwarf2_cfi (const char *ignore_args, int from_tty,
 				 struct cmd_list_element *c);
 
 static CORE_ADDR cris_scan_prologue (CORE_ADDR pc, 
-				     struct frame_info *this_frame,
+				     frame_info_ptr this_frame,
 				     struct cris_unwind_cache *info);
 
 static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc, 
-					struct frame_info *this_frame,
+					frame_info_ptr this_frame,
 					struct cris_unwind_cache *info);
 
 /* When arguments must be pushed onto the stack, they go on in reverse
@@ -692,7 +692,7 @@ pop_stack_item (struct cris_stack_item *si)
    for it IS the sp for the next frame.  */
 
 static struct cris_unwind_cache *
-cris_frame_unwind_cache (struct frame_info *this_frame,
+cris_frame_unwind_cache (frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -729,7 +729,7 @@ cris_frame_unwind_cache (struct frame_info *this_frame,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-cris_frame_this_id (struct frame_info *this_frame,
+cris_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache,
 		    struct frame_id *this_id)
 {
@@ -755,7 +755,7 @@ cris_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-cris_frame_prev_register (struct frame_info *this_frame,
+cris_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct cris_unwind_cache *info
@@ -912,7 +912,7 @@ static const struct frame_unwind cris_frame_unwind =
 };
 
 static CORE_ADDR
-cris_frame_base_address (struct frame_info *this_frame, void **this_cache)
+cris_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct cris_unwind_cache *info
     = cris_frame_unwind_cache (this_frame, this_cache);
@@ -1004,7 +1004,7 @@ static const struct frame_base cris_frame_base =
    determine that it is a prologue (1).  */
 
 static CORE_ADDR 
-cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
+cris_scan_prologue (CORE_ADDR pc, frame_info_ptr this_frame,
 		    struct cris_unwind_cache *info)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1287,7 +1287,7 @@ cris_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
 }
 
 static CORE_ADDR 
-crisv32_scan_prologue (CORE_ADDR pc, struct frame_info *this_frame,
+crisv32_scan_prologue (CORE_ADDR pc, frame_info_ptr this_frame,
 		    struct cris_unwind_cache *info)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1755,7 +1755,7 @@ cris_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 static void
 cris_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			    struct dwarf2_frame_state_reg *reg,
-			    struct frame_info *this_frame)
+			    frame_info_ptr this_frame)
 {
   /* The return address column.  */
   if (regnum == gdbarch_pc_regnum (gdbarch))
diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
index ae5d2bba33c..ef6c45f6008 100644
--- a/gdb/csky-linux-tdep.c
+++ b/gdb/csky-linux-tdep.c
@@ -310,7 +310,7 @@ csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
 static void
 csky_linux_rt_sigreturn_init (const struct tramp_frame *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      struct trad_frame_cache *this_cache,
 			      CORE_ADDR func)
 {
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index 01d4a0f28cb..0cd3de0ce5f 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -950,7 +950,7 @@ csky_analyze_prologue (struct gdbarch *gdbarch,
 		       CORE_ADDR start_pc,
 		       CORE_ADDR limit_pc,
 		       CORE_ADDR end_pc,
-		       struct frame_info *this_frame,
+		       frame_info_ptr this_frame,
 		       struct csky_unwind_cache *this_cache,
 		       lr_type_t lr_type)
 {
@@ -2250,7 +2250,7 @@ csky_analyze_lr_type (struct gdbarch *gdbarch,
 /* Heuristic unwinder.  */
 
 static struct csky_unwind_cache *
-csky_frame_unwind_cache (struct frame_info *this_frame)
+csky_frame_unwind_cache (frame_info_ptr this_frame)
 {
   CORE_ADDR prologue_start, prologue_end, func_end, prev_pc, block_addr;
   struct csky_unwind_cache *cache;
@@ -2309,7 +2309,7 @@ csky_frame_unwind_cache (struct frame_info *this_frame)
 /* Implement the this_id function for the normal unwinder.  */
 
 static void
-csky_frame_this_id (struct frame_info *this_frame,
+csky_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache, struct frame_id *this_id)
 {
   struct csky_unwind_cache *cache;
@@ -2330,7 +2330,7 @@ csky_frame_this_id (struct frame_info *this_frame,
 /* Implement the prev_register function for the normal unwinder.  */
 
 static struct value *
-csky_frame_prev_register (struct frame_info *this_frame,
+csky_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct csky_unwind_cache *cache;
@@ -2362,7 +2362,7 @@ static const struct frame_unwind csky_unwind_cache = {
 
 static int
 csky_stub_unwind_sniffer (const struct frame_unwind *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   CORE_ADDR addr_in_block;
@@ -2377,7 +2377,7 @@ csky_stub_unwind_sniffer (const struct frame_unwind *self,
 }
 
 static struct csky_unwind_cache *
-csky_make_stub_cache (struct frame_info *this_frame)
+csky_make_stub_cache (frame_info_ptr this_frame)
 {
   struct csky_unwind_cache *cache;
 
@@ -2389,7 +2389,7 @@ csky_make_stub_cache (struct frame_info *this_frame)
 }
 
 static void
-csky_stub_this_id (struct frame_info *this_frame,
+csky_stub_this_id (frame_info_ptr this_frame,
 		  void **this_cache,
 		  struct frame_id *this_id)
 {
@@ -2404,7 +2404,7 @@ csky_stub_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-csky_stub_prev_register (struct frame_info *this_frame,
+csky_stub_prev_register (frame_info_ptr this_frame,
 			    void **this_cache,
 			    int prev_regnum)
 {
@@ -2444,7 +2444,7 @@ static frame_unwind csky_stub_unwind = {
    for the normal unwinder.  */
 
 static CORE_ADDR
-csky_frame_base_address (struct frame_info *this_frame, void **this_cache)
+csky_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct csky_unwind_cache *cache;
 
@@ -2467,7 +2467,7 @@ static const struct frame_base csky_frame_base = {
 static void
 csky_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			    struct dwarf2_frame_state_reg *reg,
-			    struct frame_info *this_frame)
+			    frame_info_ptr this_frame)
 {
   if (regnum == gdbarch_pc_regnum (gdbarch))
     reg->how = DWARF2_FRAME_REG_RA;
@@ -2594,7 +2594,7 @@ csky_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dw_reg)
 
 static void
 csky_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
-			   struct frame_info *frame, int regnum, int all)
+			   frame_info_ptr frame, int regnum, int all)
 {
   /* Call default print_registers_info function.  */
   default_print_registers_info (gdbarch, file, frame, regnum, all);
diff --git a/gdb/defs.h b/gdb/defs.h
index e5b6c7878b1..0d9a39a59d0 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -284,7 +284,7 @@ enum return_value_convention
 
 struct symtab;
 struct breakpoint;
-struct frame_info;
+class frame_info_ptr;
 struct gdbarch;
 struct value;
 
diff --git a/gdb/dtrace-probe.c b/gdb/dtrace-probe.c
index b1f6ce5039c..44f3de22a01 100644
--- a/gdb/dtrace-probe.c
+++ b/gdb/dtrace-probe.c
@@ -129,7 +129,7 @@ class dtrace_probe : public probe
 
   /* See probe.h.  */
   struct value *evaluate_argument (unsigned n,
-				   struct frame_info *frame) override;
+				   frame_info_ptr frame) override;
 
   /* See probe.h.  */
   void compile_to_ax (struct agent_expr *aexpr,
@@ -709,7 +709,7 @@ dtrace_probe::can_evaluate_arguments () const
 
 struct value *
 dtrace_probe::evaluate_argument (unsigned n,
-				 struct frame_info *frame)
+				 frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = this->get_gdbarch ();
   struct dtrace_probe_arg *arg;
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index 2fef6eae562..42c4bf23431 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -288,7 +288,7 @@ struct dummy_frame_cache
 
 static int
 dummy_frame_sniffer (const struct frame_unwind *self,
-		     struct frame_info *this_frame,
+		     frame_info_ptr this_frame,
 		     void **this_prologue_cache)
 {
   /* When unwinding a normal frame, the stack structure is determined
@@ -334,7 +334,7 @@ dummy_frame_sniffer (const struct frame_unwind *self,
    register value is taken from the local copy of the register buffer.  */
 
 static struct value *
-dummy_frame_prev_register (struct frame_info *this_frame,
+dummy_frame_prev_register (frame_info_ptr this_frame,
 			   void **this_prologue_cache,
 			   int regnum)
 {
@@ -364,7 +364,7 @@ dummy_frame_prev_register (struct frame_info *this_frame,
    dummy cache is located and saved in THIS_PROLOGUE_CACHE.  */
 
 static void
-dummy_frame_this_id (struct frame_info *this_frame,
+dummy_frame_this_id (frame_info_ptr this_frame,
 		     void **this_prologue_cache,
 		     struct frame_id *this_id)
 {
@@ -390,7 +390,7 @@ const struct frame_unwind dummy_frame_unwind =
 /* See dummy-frame.h.  */
 
 struct frame_id
-default_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+default_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR sp, pc;
 
diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h
index 80111f0a4db..213881e4eab 100644
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -78,6 +78,6 @@ extern int find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor,
    for THIS_FRAME assuming that the frame is a dummy frame.  */
 
 extern struct frame_id default_dummy_id (struct gdbarch *gdbarch,
-					 struct frame_info *this_frame);
+					 frame_info_ptr this_frame);
 
 #endif /* !defined (DUMMY_FRAME_H)  */
diff --git a/gdb/elfread.c b/gdb/elfread.c
index e8b4a8e9177..6979c6f3ff7 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -930,7 +930,7 @@ static void
 elf_gnu_ifunc_resolver_stop (code_breakpoint *b)
 {
   struct breakpoint *b_return;
-  struct frame_info *prev_frame = get_prev_frame (get_current_frame ());
+  frame_info_ptr prev_frame = get_prev_frame (get_current_frame ());
   struct frame_id prev_frame_id = get_stack_frame_id (prev_frame);
   CORE_ADDR prev_pc = get_frame_pc (prev_frame);
   int thread_id = inferior_thread ()->global_num;
diff --git a/gdb/eval.c b/gdb/eval.c
index ce1d883aa86..f5fbf545ec4 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1099,7 +1099,7 @@ eval_op_var_entry_value (struct type *expect_type, struct expression *exp,
     error (_("Symbol \"%s\" does not have any specific entry value"),
 	   sym->print_name ());
 
-  struct frame_info *frame = get_selected_frame (NULL);
+  frame_info_ptr frame = get_selected_frame (NULL);
   return SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry (sym, frame);
 }
 
diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h
index 7c74e721c57..50e9337af6e 100644
--- a/gdb/extension-priv.h
+++ b/gdb/extension-priv.h
@@ -179,7 +179,7 @@ struct extension_language_ops
      or SCR_BT_COMPLETED on success.  */
   enum ext_lang_bt_status (*apply_frame_filter)
     (const struct extension_language_defn *,
-     struct frame_info *frame, frame_filter_flags flags,
+     frame_info_ptr frame, frame_filter_flags flags,
      enum ext_lang_frame_args args_type,
      struct ui_out *out, int frame_low, int frame_high);
 
diff --git a/gdb/extension.c b/gdb/extension.c
index 5a805bea00e..8cbd80f45d5 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -524,7 +524,7 @@ apply_ext_lang_val_pretty_printer (struct value *val,
    rather than trying filters in other extension languages.  */
 
 enum ext_lang_bt_status
-apply_ext_lang_frame_filter (struct frame_info *frame,
+apply_ext_lang_frame_filter (frame_info_ptr frame,
 			     frame_filter_flags flags,
 			     enum ext_lang_frame_args args_type,
 			     struct ui_out *out,
diff --git a/gdb/extension.h b/gdb/extension.h
index 47839ea50be..72cff218f5b 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -26,7 +26,7 @@
 
 struct breakpoint;
 struct command_line;
-struct frame_info;
+class frame_info_ptr;
 struct language_defn;
 struct objfile;
 struct extension_language_defn;
@@ -291,7 +291,7 @@ extern int apply_ext_lang_val_pretty_printer
    const struct language_defn *language);
 
 extern enum ext_lang_bt_status apply_ext_lang_frame_filter
-  (struct frame_info *frame, frame_filter_flags flags,
+  (frame_info_ptr frame, frame_filter_flags flags,
    enum ext_lang_frame_args args_type,
    struct ui_out *out, int frame_low, int frame_high);
 
diff --git a/gdb/gcore.c b/gdb/gcore.c
index 519007714e5..ede78534bd8 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -198,7 +198,7 @@ default_gcore_target (void)
 static int
 derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
 {
-  struct frame_info *fi, *tmp_fi;
+  frame_info_ptr fi, tmp_fi;
 
   gdb_assert (bottom);
   gdb_assert (top);
diff --git a/gdb/gdbarch-components.py b/gdb/gdbarch-components.py
index 71aa5991fbe..ae115580ffa 100644
--- a/gdb/gdbarch-components.py
+++ b/gdb/gdbarch-components.py
@@ -590,7 +590,7 @@ frame.
 """,
     type="struct frame_id",
     name="dummy_id",
-    params=[("struct frame_info *", "this_frame")],
+    params=[("frame_info_ptr ", "this_frame")],
     predefault="default_dummy_id",
     invalid=False,
 )
@@ -653,7 +653,7 @@ Return true if the code of FRAME is writable.
 """,
     type="int",
     name="code_of_frame_writable",
-    params=[("struct frame_info *", "frame")],
+    params=[("frame_info_ptr ", "frame")],
     predefault="default_code_of_frame_writable",
     invalid=False,
 )
@@ -663,7 +663,7 @@ Method(
     name="print_registers_info",
     params=[
         ("struct ui_file *", "file"),
-        ("struct frame_info *", "frame"),
+        ("frame_info_ptr ", "frame"),
         ("int", "regnum"),
         ("int", "all"),
     ],
@@ -676,7 +676,7 @@ Method(
     name="print_float_info",
     params=[
         ("struct ui_file *", "file"),
-        ("struct frame_info *", "frame"),
+        ("frame_info_ptr ", "frame"),
         ("const char *", "args"),
     ],
     predefault="default_print_float_info",
@@ -688,7 +688,7 @@ Method(
     name="print_vector_info",
     params=[
         ("struct ui_file *", "file"),
-        ("struct frame_info *", "frame"),
+        ("frame_info_ptr ", "frame"),
         ("const char *", "args"),
     ],
     predicate=True,
@@ -732,7 +732,7 @@ FRAME corresponds to the longjmp frame.
 """,
     type="int",
     name="get_longjmp_target",
-    params=[("struct frame_info *", "frame"), ("CORE_ADDR *", "pc")],
+    params=[("frame_info_ptr ", "frame"), ("CORE_ADDR *", "pc")],
     predicate=True,
     invalid=True,
 )
@@ -755,7 +755,7 @@ Function(
     type="int",
     name="register_to_value",
     params=[
-        ("struct frame_info *", "frame"),
+        ("frame_info_ptr ", "frame"),
         ("int", "regnum"),
         ("struct type *", "type"),
         ("gdb_byte *", "buf"),
@@ -769,7 +769,7 @@ Function(
     type="void",
     name="value_to_register",
     params=[
-        ("struct frame_info *", "frame"),
+        ("frame_info_ptr ", "frame"),
         ("int", "regnum"),
         ("struct type *", "type"),
         ("const gdb_byte *", "buf"),
@@ -1042,7 +1042,7 @@ Value(
 Method(
     type="CORE_ADDR",
     name="unwind_pc",
-    params=[("struct frame_info *", "next_frame")],
+    params=[("frame_info_ptr ", "next_frame")],
     predefault="default_unwind_pc",
     invalid=False,
 )
@@ -1050,7 +1050,7 @@ Method(
 Method(
     type="CORE_ADDR",
     name="unwind_sp",
-    params=[("struct frame_info *", "next_frame")],
+    params=[("frame_info_ptr ", "next_frame")],
     predefault="default_unwind_sp",
     invalid=False,
 )
@@ -1062,7 +1062,7 @@ frame-base.  Enable frame-base before frame-unwind.
 """,
     type="int",
     name="frame_num_args",
-    params=[("struct frame_info *", "frame")],
+    params=[("frame_info_ptr ", "frame")],
     predicate=True,
     invalid=True,
 )
@@ -1237,7 +1237,7 @@ further single-step is needed before the instruction finishes.
 """,
     type="int",
     name="single_step_through_delay",
-    params=[("struct frame_info *", "frame")],
+    params=[("frame_info_ptr ", "frame")],
     predicate=True,
     invalid=True,
 )
@@ -1257,7 +1257,7 @@ disassembler.  Perhaps objdump can handle it?
 Function(
     type="CORE_ADDR",
     name="skip_trampoline_code",
-    params=[("struct frame_info *", "frame"), ("CORE_ADDR", "pc")],
+    params=[("frame_info_ptr ", "frame"), ("CORE_ADDR", "pc")],
     predefault="generic_skip_trampoline_code",
     invalid=False,
 )
@@ -1472,7 +1472,7 @@ Fetch the pointer to the ith function argument.
     type="CORE_ADDR",
     name="fetch_pointer_argument",
     params=[
-        ("struct frame_info *", "frame"),
+        ("frame_info_ptr ", "frame"),
         ("int", "argi"),
         ("struct type *", "type"),
     ],
@@ -2633,7 +2633,7 @@ Return a string containing any flags for the given PC in the given FRAME.
 """,
     type="std::string",
     name="get_pc_address_flags",
-    params=[("frame_info *", "frame"), ("CORE_ADDR", "pc")],
+    params=[("frame_info_ptr ", "frame"), ("CORE_ADDR", "pc")],
     predefault="default_get_pc_address_flags",
     invalid=False,
 )
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 0504962e50d..19dd80ee5f0 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -309,8 +309,8 @@ extern void set_gdbarch_register_type (struct gdbarch *gdbarch, gdbarch_register
    should match the address at which the breakpoint was set in the dummy
    frame. */
 
-typedef struct frame_id (gdbarch_dummy_id_ftype) (struct gdbarch *gdbarch, struct frame_info *this_frame);
-extern struct frame_id gdbarch_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame);
+typedef struct frame_id (gdbarch_dummy_id_ftype) (struct gdbarch *gdbarch, frame_info_ptr this_frame);
+extern struct frame_id gdbarch_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame);
 extern void set_gdbarch_dummy_id (struct gdbarch *gdbarch, gdbarch_dummy_id_ftype *dummy_id);
 
 /* Implement DUMMY_ID and PUSH_DUMMY_CALL, then delete
@@ -336,22 +336,22 @@ extern void set_gdbarch_push_dummy_code (struct gdbarch *gdbarch, gdbarch_push_d
 
 /* Return true if the code of FRAME is writable. */
 
-typedef int (gdbarch_code_of_frame_writable_ftype) (struct gdbarch *gdbarch, struct frame_info *frame);
-extern int gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame);
+typedef int (gdbarch_code_of_frame_writable_ftype) (struct gdbarch *gdbarch, frame_info_ptr frame);
+extern int gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, frame_info_ptr frame);
 extern void set_gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, gdbarch_code_of_frame_writable_ftype *code_of_frame_writable);
 
-typedef void (gdbarch_print_registers_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all);
-extern void gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all);
+typedef void (gdbarch_print_registers_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, int regnum, int all);
+extern void gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, int regnum, int all);
 extern void set_gdbarch_print_registers_info (struct gdbarch *gdbarch, gdbarch_print_registers_info_ftype *print_registers_info);
 
-typedef void (gdbarch_print_float_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
-extern void gdbarch_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
+typedef void (gdbarch_print_float_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, const char *args);
+extern void gdbarch_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, const char *args);
 extern void set_gdbarch_print_float_info (struct gdbarch *gdbarch, gdbarch_print_float_info_ftype *print_float_info);
 
 extern bool gdbarch_print_vector_info_p (struct gdbarch *gdbarch);
 
-typedef void (gdbarch_print_vector_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
-extern void gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args);
+typedef void (gdbarch_print_vector_info_ftype) (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, const char *args);
+extern void gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, const char *args);
 extern void set_gdbarch_print_vector_info (struct gdbarch *gdbarch, gdbarch_print_vector_info_ftype *print_vector_info);
 
 /* MAP a GDB RAW register number onto a simulator register number.  See
@@ -376,8 +376,8 @@ extern void set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, gdbarch_
 
 extern bool gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch);
 
-typedef int (gdbarch_get_longjmp_target_ftype) (struct frame_info *frame, CORE_ADDR *pc);
-extern int gdbarch_get_longjmp_target (struct gdbarch *gdbarch, struct frame_info *frame, CORE_ADDR *pc);
+typedef int (gdbarch_get_longjmp_target_ftype) (frame_info_ptr frame, CORE_ADDR *pc);
+extern int gdbarch_get_longjmp_target (struct gdbarch *gdbarch, frame_info_ptr frame, CORE_ADDR *pc);
 extern void set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch, gdbarch_get_longjmp_target_ftype *get_longjmp_target);
 
 extern int gdbarch_believe_pcc_promotion (struct gdbarch *gdbarch);
@@ -387,12 +387,12 @@ typedef int (gdbarch_convert_register_p_ftype) (struct gdbarch *gdbarch, int reg
 extern int gdbarch_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type);
 extern void set_gdbarch_convert_register_p (struct gdbarch *gdbarch, gdbarch_convert_register_p_ftype *convert_register_p);
 
-typedef int (gdbarch_register_to_value_ftype) (struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep);
-extern int gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep);
+typedef int (gdbarch_register_to_value_ftype) (frame_info_ptr frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep);
+extern int gdbarch_register_to_value (struct gdbarch *gdbarch, frame_info_ptr frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep);
 extern void set_gdbarch_register_to_value (struct gdbarch *gdbarch, gdbarch_register_to_value_ftype *register_to_value);
 
-typedef void (gdbarch_value_to_register_ftype) (struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf);
-extern void gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf);
+typedef void (gdbarch_value_to_register_ftype) (frame_info_ptr frame, int regnum, struct type *type, const gdb_byte *buf);
+extern void gdbarch_value_to_register (struct gdbarch *gdbarch, frame_info_ptr frame, int regnum, struct type *type, const gdb_byte *buf);
 extern void set_gdbarch_value_to_register (struct gdbarch *gdbarch, gdbarch_value_to_register_ftype *value_to_register);
 
 /* Construct a value representing the contents of register REGNUM in
@@ -561,12 +561,12 @@ extern void set_gdbarch_get_thread_local_address (struct gdbarch *gdbarch, gdbar
 extern CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch);
 extern void set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, CORE_ADDR frame_args_skip);
 
-typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame);
-extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame);
+typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, frame_info_ptr next_frame);
+extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame);
 extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc);
 
-typedef CORE_ADDR (gdbarch_unwind_sp_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame);
-extern CORE_ADDR gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame);
+typedef CORE_ADDR (gdbarch_unwind_sp_ftype) (struct gdbarch *gdbarch, frame_info_ptr next_frame);
+extern CORE_ADDR gdbarch_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame);
 extern void set_gdbarch_unwind_sp (struct gdbarch *gdbarch, gdbarch_unwind_sp_ftype *unwind_sp);
 
 /* DEPRECATED_FRAME_LOCALS_ADDRESS as been replaced by the per-frame
@@ -574,8 +574,8 @@ extern void set_gdbarch_unwind_sp (struct gdbarch *gdbarch, gdbarch_unwind_sp_ft
 
 extern bool gdbarch_frame_num_args_p (struct gdbarch *gdbarch);
 
-typedef int (gdbarch_frame_num_args_ftype) (struct frame_info *frame);
-extern int gdbarch_frame_num_args (struct gdbarch *gdbarch, struct frame_info *frame);
+typedef int (gdbarch_frame_num_args_ftype) (frame_info_ptr frame);
+extern int gdbarch_frame_num_args (struct gdbarch *gdbarch, frame_info_ptr frame);
 extern void set_gdbarch_frame_num_args (struct gdbarch *gdbarch, gdbarch_frame_num_args_ftype *frame_num_args);
 
 extern bool gdbarch_frame_align_p (struct gdbarch *gdbarch);
@@ -687,8 +687,8 @@ extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_s
 
 extern bool gdbarch_single_step_through_delay_p (struct gdbarch *gdbarch);
 
-typedef int (gdbarch_single_step_through_delay_ftype) (struct gdbarch *gdbarch, struct frame_info *frame);
-extern int gdbarch_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame);
+typedef int (gdbarch_single_step_through_delay_ftype) (struct gdbarch *gdbarch, frame_info_ptr frame);
+extern int gdbarch_single_step_through_delay (struct gdbarch *gdbarch, frame_info_ptr frame);
 extern void set_gdbarch_single_step_through_delay (struct gdbarch *gdbarch, gdbarch_single_step_through_delay_ftype *single_step_through_delay);
 
 /* FIXME: cagney/2003-08-28: Need to find a better way of selecting the
@@ -698,8 +698,8 @@ typedef int (gdbarch_print_insn_ftype) (bfd_vma vma, struct disassemble_info *in
 extern int gdbarch_print_insn (struct gdbarch *gdbarch, bfd_vma vma, struct disassemble_info *info);
 extern void set_gdbarch_print_insn (struct gdbarch *gdbarch, gdbarch_print_insn_ftype *print_insn);
 
-typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (struct frame_info *frame, CORE_ADDR pc);
-extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, struct frame_info *frame, CORE_ADDR pc);
+typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (frame_info_ptr frame, CORE_ADDR pc);
+extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, frame_info_ptr frame, CORE_ADDR pc);
 extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype *skip_trampoline_code);
 
 /* If in_solib_dynsym_resolve_code() returns true, and SKIP_SOLIB_RESOLVER
@@ -841,8 +841,8 @@ extern void set_gdbarch_register_reggroup_p (struct gdbarch *gdbarch, gdbarch_re
 
 extern bool gdbarch_fetch_pointer_argument_p (struct gdbarch *gdbarch);
 
-typedef CORE_ADDR (gdbarch_fetch_pointer_argument_ftype) (struct frame_info *frame, int argi, struct type *type);
-extern CORE_ADDR gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, struct frame_info *frame, int argi, struct type *type);
+typedef CORE_ADDR (gdbarch_fetch_pointer_argument_ftype) (frame_info_ptr frame, int argi, struct type *type);
+extern CORE_ADDR gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, frame_info_ptr frame, int argi, struct type *type);
 extern void set_gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument);
 
 /* Iterate over all supported register notes in a core file.  For each
@@ -1618,8 +1618,8 @@ extern void set_gdbarch_type_align (struct gdbarch *gdbarch, gdbarch_type_align_
 
 /* Return a string containing any flags for the given PC in the given FRAME. */
 
-typedef std::string (gdbarch_get_pc_address_flags_ftype) (frame_info *frame, CORE_ADDR pc);
-extern std::string gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info *frame, CORE_ADDR pc);
+typedef std::string (gdbarch_get_pc_address_flags_ftype) (frame_info_ptr frame, CORE_ADDR pc);
+extern std::string gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info_ptr frame, CORE_ADDR pc);
 extern void set_gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, gdbarch_get_pc_address_flags_ftype *get_pc_address_flags);
 
 /* Read core file mappings */
diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c
index 198346bddec..800a3ecb308 100644
--- a/gdb/gdbarch-selftests.c
+++ b/gdb/gdbarch-selftests.c
@@ -71,7 +71,7 @@ register_to_value_test (struct gdbarch *gdbarch)
 
   scoped_mock_context<test_target_ops> mockctx (gdbarch);
 
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
   const int num_regs = gdbarch_num_cooked_regs (gdbarch);
 
   /* Test gdbarch methods register_to_value and value_to_register with
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 0edae7f6f0a..6620d0b2a13 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -2259,7 +2259,7 @@ set_gdbarch_register_type (struct gdbarch *gdbarch,
 }
 
 struct frame_id
-gdbarch_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+gdbarch_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->dummy_id != NULL);
@@ -2358,7 +2358,7 @@ set_gdbarch_push_dummy_code (struct gdbarch *gdbarch,
 }
 
 int
-gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, struct frame_info *frame)
+gdbarch_code_of_frame_writable (struct gdbarch *gdbarch, frame_info_ptr frame)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->code_of_frame_writable != NULL);
@@ -2375,7 +2375,7 @@ set_gdbarch_code_of_frame_writable (struct gdbarch *gdbarch,
 }
 
 void
-gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, int regnum, int all)
+gdbarch_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, int regnum, int all)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->print_registers_info != NULL);
@@ -2392,7 +2392,7 @@ set_gdbarch_print_registers_info (struct gdbarch *gdbarch,
 }
 
 void
-gdbarch_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args)
+gdbarch_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, const char *args)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->print_float_info != NULL);
@@ -2416,7 +2416,7 @@ gdbarch_print_vector_info_p (struct gdbarch *gdbarch)
 }
 
 void
-gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, struct frame_info *frame, const char *args)
+gdbarch_print_vector_info (struct gdbarch *gdbarch, struct ui_file *file, frame_info_ptr frame, const char *args)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->print_vector_info != NULL);
@@ -2491,7 +2491,7 @@ gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch)
 }
 
 int
-gdbarch_get_longjmp_target (struct gdbarch *gdbarch, struct frame_info *frame, CORE_ADDR *pc)
+gdbarch_get_longjmp_target (struct gdbarch *gdbarch, frame_info_ptr frame, CORE_ADDR *pc)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->get_longjmp_target != NULL);
@@ -2542,7 +2542,7 @@ set_gdbarch_convert_register_p (struct gdbarch *gdbarch,
 }
 
 int
-gdbarch_register_to_value (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep)
+gdbarch_register_to_value (struct gdbarch *gdbarch, frame_info_ptr frame, int regnum, struct type *type, gdb_byte *buf, int *optimizedp, int *unavailablep)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->register_to_value != NULL);
@@ -2559,7 +2559,7 @@ set_gdbarch_register_to_value (struct gdbarch *gdbarch,
 }
 
 void
-gdbarch_value_to_register (struct gdbarch *gdbarch, struct frame_info *frame, int regnum, struct type *type, const gdb_byte *buf)
+gdbarch_value_to_register (struct gdbarch *gdbarch, frame_info_ptr frame, int regnum, struct type *type, const gdb_byte *buf)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->value_to_register != NULL);
@@ -3016,7 +3016,7 @@ set_gdbarch_frame_args_skip (struct gdbarch *gdbarch,
 }
 
 CORE_ADDR
-gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+gdbarch_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->unwind_pc != NULL);
@@ -3033,7 +3033,7 @@ set_gdbarch_unwind_pc (struct gdbarch *gdbarch,
 }
 
 CORE_ADDR
-gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+gdbarch_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->unwind_sp != NULL);
@@ -3057,7 +3057,7 @@ gdbarch_frame_num_args_p (struct gdbarch *gdbarch)
 }
 
 int
-gdbarch_frame_num_args (struct gdbarch *gdbarch, struct frame_info *frame)
+gdbarch_frame_num_args (struct gdbarch *gdbarch, frame_info_ptr frame)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->frame_num_args != NULL);
@@ -3316,7 +3316,7 @@ gdbarch_single_step_through_delay_p (struct gdbarch *gdbarch)
 }
 
 int
-gdbarch_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame)
+gdbarch_single_step_through_delay (struct gdbarch *gdbarch, frame_info_ptr frame)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->single_step_through_delay != NULL);
@@ -3350,7 +3350,7 @@ set_gdbarch_print_insn (struct gdbarch *gdbarch,
 }
 
 CORE_ADDR
-gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, struct frame_info *frame, CORE_ADDR pc)
+gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, frame_info_ptr frame, CORE_ADDR pc)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->skip_trampoline_code != NULL);
@@ -3674,7 +3674,7 @@ gdbarch_fetch_pointer_argument_p (struct gdbarch *gdbarch)
 }
 
 CORE_ADDR
-gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, struct frame_info *frame, int argi, struct type *type)
+gdbarch_fetch_pointer_argument (struct gdbarch *gdbarch, frame_info_ptr frame, int argi, struct type *type)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->fetch_pointer_argument != NULL);
@@ -5331,7 +5331,7 @@ set_gdbarch_type_align (struct gdbarch *gdbarch,
 }
 
 std::string
-gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info *frame, CORE_ADDR pc)
+gdbarch_get_pc_address_flags (struct gdbarch *gdbarch, frame_info_ptr frame, CORE_ADDR pc)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->get_pc_address_flags != NULL);
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 8ffcafc6a29..303e2b2e6b2 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -56,6 +56,7 @@
 #include "dwarf2.h"
 #include "gdbsupport/gdb_obstack.h"
 #include "gmp-utils.h"
+#include "frame-info.h"
 
 /* Forward declarations for prototypes.  */
 struct field;
@@ -1877,7 +1878,7 @@ struct call_site_target
 
   void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
 			       const struct call_site *call_site,
-			       struct frame_info *caller_frame,
+			       frame_info_ptr caller_frame,
 			       iterate_ftype callback) const;
 
 private:
@@ -1984,7 +1985,7 @@ struct call_site
        throw NO_ENTRY_VALUE_ERROR.  */
 
     void iterate_over_addresses (struct gdbarch *call_site_gdbarch,
-				 struct frame_info *caller_frame,
+				 frame_info_ptr caller_frame,
 				 call_site_target::iterate_ftype callback)
       const
     {
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 61666f2353c..be4b6d1461c 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -1215,7 +1215,7 @@ gnuv3_get_type_from_type_info (struct value *type_info_ptr)
    of the routine we are thunking to and continue to there instead.  */
 
 static CORE_ADDR 
-gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
+gnuv3_skip_trampoline (frame_info_ptr frame, CORE_ADDR stop_pc)
 {
   CORE_ADDR real_stop_pc, method_stop_pc, func_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index c4d9824ffda..e85e90b60a1 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -404,7 +404,7 @@ h8300_analyze_prologue (struct gdbarch *gdbarch,
 }
 
 static struct h8300_frame_cache *
-h8300_frame_cache (struct frame_info *this_frame, void **this_cache)
+h8300_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct h8300_frame_cache *cache;
@@ -466,7 +466,7 @@ h8300_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-h8300_frame_this_id (struct frame_info *this_frame, void **this_cache,
+h8300_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		     struct frame_id *this_id)
 {
   struct h8300_frame_cache *cache =
@@ -480,7 +480,7 @@ h8300_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-h8300_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+h8300_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			   int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -511,7 +511,7 @@ static const struct frame_unwind h8300_frame_unwind = {
 };
 
 static CORE_ADDR
-h8300_frame_base_address (struct frame_info *this_frame, void **this_cache)
+h8300_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct h8300_frame_cache *cache = h8300_frame_cache (this_frame, this_cache);
   return cache->base;
@@ -997,7 +997,7 @@ h8300sx_register_name (struct gdbarch *gdbarch, int regno)
 
 static void
 h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
-		      struct frame_info *frame, int regno)
+		      frame_info_ptr frame, int regno)
 {
   LONGEST rval;
   const char *name = gdbarch_register_name (gdbarch, regno);
@@ -1074,7 +1074,7 @@ h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
 
 static void
 h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
-			    struct frame_info *frame, int regno, int cpregs)
+			    frame_info_ptr frame, int regno, int cpregs)
 {
   if (regno < 0)
     {
diff --git a/gdb/hppa-bsd-tdep.c b/gdb/hppa-bsd-tdep.c
index c405511529d..458c22085d7 100644
--- a/gdb/hppa-bsd-tdep.c
+++ b/gdb/hppa-bsd-tdep.c
@@ -107,7 +107,7 @@ hppabsd_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 static void
 hppabsd_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			       struct dwarf2_frame_state_reg *reg,
-			       struct frame_info *this_frame)
+			       frame_info_ptr this_frame)
 {
   if (regnum == HPPA_PCOQ_HEAD_REGNUM)
     reg->how = DWARF2_FRAME_REG_RA;
diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c
index f17d2ae6b02..2a1aa6c24b3 100644
--- a/gdb/hppa-linux-tdep.c
+++ b/gdb/hppa-linux-tdep.c
@@ -193,7 +193,7 @@ struct hppa_linux_sigtramp_unwind_cache
 };
 
 static struct hppa_linux_sigtramp_unwind_cache *
-hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
+hppa_linux_sigtramp_frame_unwind_cache (frame_info_ptr this_frame,
 					void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -268,7 +268,7 @@ hppa_linux_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
 }
 
 static void
-hppa_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+hppa_linux_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				   void **this_prologue_cache,
 				   struct frame_id *this_id)
 {
@@ -278,7 +278,7 @@ hppa_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-hppa_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+hppa_linux_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					 void **this_prologue_cache,
 					 int regnum)
 {
@@ -296,7 +296,7 @@ hppa_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
    we can find the beginning of the struct rt_sigframe.  */
 static int
 hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
diff --git a/gdb/hppa-netbsd-tdep.c b/gdb/hppa-netbsd-tdep.c
index 8b1a03b462e..3c5364cb370 100644
--- a/gdb/hppa-netbsd-tdep.c
+++ b/gdb/hppa-netbsd-tdep.c
@@ -64,7 +64,7 @@ static int hppanbsd_mc_reg_offset[] =
 };
 
 static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *,
-					 struct frame_info *,
+					 frame_info_ptr ,
 					 struct trad_frame_cache *,
 					 CORE_ADDR);
 
@@ -99,7 +99,7 @@ static const struct tramp_frame hppanbsd_sigtramp_si4 =
 
 static void
 hppanbsd_sigtramp_cache_init (const struct tramp_frame *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 91f9cecdcbc..2f8b4e4b8ce 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -1834,7 +1834,7 @@ hppa_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Return an unwind entry that falls within the frame's code block.  */
 
 static struct unwind_table_entry *
-hppa_find_unwind_entry_in_block (struct frame_info *this_frame)
+hppa_find_unwind_entry_in_block (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
 
@@ -1855,7 +1855,7 @@ struct hppa_frame_cache
 };
 
 static struct hppa_frame_cache *
-hppa_frame_cache (struct frame_info *this_frame, void **this_cache)
+hppa_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -2256,7 +2256,7 @@ hppa_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-hppa_frame_this_id (struct frame_info *this_frame, void **this_cache,
+hppa_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct hppa_frame_cache *info;
@@ -2269,7 +2269,7 @@ hppa_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-hppa_frame_prev_register (struct frame_info *this_frame,
+hppa_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_cache, int regnum)
 {
   struct hppa_frame_cache *info = hppa_frame_cache (this_frame, this_cache);
@@ -2280,7 +2280,7 @@ hppa_frame_prev_register (struct frame_info *this_frame,
 
 static int
 hppa_frame_unwind_sniffer (const struct frame_unwind *self,
-			   struct frame_info *this_frame, void **this_cache)
+			   frame_info_ptr this_frame, void **this_cache)
 {
   if (hppa_find_unwind_entry_in_block (this_frame))
     return 1;
@@ -2308,7 +2308,7 @@ static const struct frame_unwind hppa_frame_unwind =
    identify the stack and pc for the frame.  */
 
 static struct hppa_frame_cache *
-hppa_fallback_frame_cache (struct frame_info *this_frame, void **this_cache)
+hppa_fallback_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -2381,7 +2381,7 @@ hppa_fallback_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-hppa_fallback_frame_this_id (struct frame_info *this_frame, void **this_cache,
+hppa_fallback_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			     struct frame_id *this_id)
 {
   struct hppa_frame_cache *info = 
@@ -2391,7 +2391,7 @@ hppa_fallback_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-hppa_fallback_frame_prev_register (struct frame_info *this_frame,
+hppa_fallback_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   struct hppa_frame_cache *info
@@ -2420,7 +2420,7 @@ struct hppa_stub_unwind_cache
 };
 
 static struct hppa_stub_unwind_cache *
-hppa_stub_frame_unwind_cache (struct frame_info *this_frame,
+hppa_stub_frame_unwind_cache (frame_info_ptr this_frame,
 			      void **this_cache)
 {
   struct hppa_stub_unwind_cache *info;
@@ -2441,7 +2441,7 @@ hppa_stub_frame_unwind_cache (struct frame_info *this_frame,
 }
 
 static void
-hppa_stub_frame_this_id (struct frame_info *this_frame,
+hppa_stub_frame_this_id (frame_info_ptr this_frame,
 			 void **this_prologue_cache,
 			 struct frame_id *this_id)
 {
@@ -2453,7 +2453,7 @@ hppa_stub_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-hppa_stub_frame_prev_register (struct frame_info *this_frame,
+hppa_stub_frame_prev_register (frame_info_ptr this_frame,
 			       void **this_prologue_cache, int regnum)
 {
   struct hppa_stub_unwind_cache *info
@@ -2468,7 +2468,7 @@ hppa_stub_frame_prev_register (struct frame_info *this_frame,
 
 static int
 hppa_stub_unwind_sniffer (const struct frame_unwind *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  void **this_cache)
 {
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
@@ -2494,7 +2494,7 @@ static const struct frame_unwind hppa_stub_frame_unwind = {
 };
 
 CORE_ADDR
-hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+hppa_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   ULONGEST ipsw;
   CORE_ADDR pc;
@@ -2711,7 +2711,7 @@ hppa_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
 /* Get the ARGIth function argument for the current function.  */
 
 static CORE_ADDR
-hppa_fetch_pointer_argument (struct frame_info *frame, int argi, 
+hppa_fetch_pointer_argument (frame_info_ptr frame, int argi, 
 			     struct type *type)
 {
   return get_frame_register_unsigned (frame, HPPA_R0_REGNUM + 26 - argi);
@@ -2742,7 +2742,7 @@ hppa_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 }
 
 struct value *
-hppa_frame_prev_register_helper (struct frame_info *this_frame,
+hppa_frame_prev_register_helper (frame_info_ptr this_frame,
 				 trad_frame_saved_reg saved_regs[],
 				 int regnum)
 {
@@ -2920,7 +2920,7 @@ hppa_in_solib_call_trampoline (struct gdbarch *gdbarch, CORE_ADDR pc)
    systems: $$dyncall, import stubs and PLT stubs.  */
 
 CORE_ADDR
-hppa_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+hppa_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *func_ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
diff --git a/gdb/hppa-tdep.h b/gdb/hppa-tdep.h
index c2c9e0e0b5e..d0e0d4d6a3a 100644
--- a/gdb/hppa-tdep.h
+++ b/gdb/hppa-tdep.h
@@ -109,7 +109,7 @@ struct hppa_gdbarch_tdep : gdbarch_tdep_base
      not interested in them.  If we detect that we are returning to a stub,
      adjust the pc to the real caller.  This improves the behavior of commands
      that traverse frames such as "up" and "finish".  */
-  void (*unwind_adjust_stub) (struct frame_info *this_frame, CORE_ADDR base,
+  void (*unwind_adjust_stub) (frame_info_ptr this_frame, CORE_ADDR base,
 			      trad_frame_saved_reg *saved_regs) = nullptr;
 
   /* These are solib-dependent methods.  They are really HPUX only, but
@@ -201,14 +201,14 @@ int hppa_extract_14 (unsigned);
 CORE_ADDR hppa_symbol_address(const char *sym);
 
 extern struct value *
-  hppa_frame_prev_register_helper (struct frame_info *this_frame,
+  hppa_frame_prev_register_helper (frame_info_ptr this_frame,
 				   trad_frame_saved_reg *saved_regs,
 				   int regnum);
 
 extern CORE_ADDR hppa_read_pc (struct regcache *regcache);
 extern void hppa_write_pc (struct regcache *regcache, CORE_ADDR pc);
 extern CORE_ADDR hppa_unwind_pc (struct gdbarch *gdbarch,
-				 struct frame_info *next_frame);
+				 frame_info_ptr next_frame);
 
 extern struct bound_minimal_symbol
   hppa_lookup_stub_minimal_symbol (const char *name,
@@ -216,6 +216,6 @@ extern struct bound_minimal_symbol
 
 extern int hppa_in_solib_call_trampoline (struct gdbarch *gdbarch,
 					  CORE_ADDR pc);
-extern CORE_ADDR hppa_skip_trampoline_code (struct frame_info *, CORE_ADDR pc);
+extern CORE_ADDR hppa_skip_trampoline_code (frame_info_ptr , CORE_ADDR pc);
 
 #endif  /* hppa-tdep.h */
diff --git a/gdb/jit.c b/gdb/jit.c
index 6d8acc40225..12d6d83e26c 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -930,7 +930,7 @@ struct jit_unwind_private
   std::unique_ptr<detached_regcache> regcache;
 
   /* The frame being unwound.  */
-  struct frame_info *this_frame;
+  frame_info_ptr this_frame;
 };
 
 /* Sets the value of a particular register in this frame.  */
@@ -991,7 +991,7 @@ jit_unwind_reg_get_impl (struct gdb_unwind_callbacks *cb, int regnum)
    saved register value.  */
 
 static void
-jit_dealloc_cache (struct frame_info *this_frame, void *cache)
+jit_dealloc_cache (frame_info *this_frame, void *cache)
 {
   struct jit_unwind_private *priv_data = (struct jit_unwind_private *) cache;
   delete priv_data;
@@ -1007,7 +1007,7 @@ jit_dealloc_cache (struct frame_info *this_frame, void *cache)
 
 static int
 jit_frame_sniffer (const struct frame_unwind *self,
-		   struct frame_info *this_frame, void **cache)
+		   frame_info_ptr this_frame, void **cache)
 {
   struct jit_unwind_private *priv_data;
   struct gdb_unwind_callbacks callbacks;
@@ -1042,7 +1042,7 @@ jit_frame_sniffer (const struct frame_unwind *self,
 
   jit_debug_printf ("Could not unwind frame using JIT reader.");
 
-  jit_dealloc_cache (this_frame, *cache);
+  jit_dealloc_cache (this_frame.get (), *cache);
   *cache = NULL;
 
   return 0;
@@ -1053,7 +1053,7 @@ jit_frame_sniffer (const struct frame_unwind *self,
    the loaded plugin.  */
 
 static void
-jit_frame_this_id (struct frame_info *this_frame, void **cache,
+jit_frame_this_id (frame_info_ptr this_frame, void **cache,
 		   struct frame_id *this_id)
 {
   struct jit_unwind_private priv;
@@ -1082,7 +1082,7 @@ jit_frame_this_id (struct frame_info *this_frame, void **cache,
    the register from the cache.  */
 
 static struct value *
-jit_frame_prev_register (struct frame_info *this_frame, void **cache, int reg)
+jit_frame_prev_register (frame_info_ptr this_frame, void **cache, int reg)
 {
   struct jit_unwind_private *priv = (struct jit_unwind_private *) *cache;
   struct gdbarch *gdbarch;
diff --git a/gdb/language.c b/gdb/language.c
index bc784a8ec79..a94e5db0a46 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -125,7 +125,7 @@ show_language_command (struct ui_file *file, int from_tty,
 
   if (has_stack_frames ())
     {
-      struct frame_info *frame;
+      frame_info_ptr frame;
 
       frame = get_selected_frame (NULL);
       flang = get_frame_language (frame);
@@ -160,7 +160,7 @@ set_language_command (const char *ignore,
 	      language_mode = language_mode_auto;
 	      try
 		{
-		  struct frame_info *frame;
+		  frame_info_ptr frame;
 
 		  frame = get_selected_frame (NULL);
 		  flang = get_frame_language (frame);
@@ -533,7 +533,7 @@ add_set_language_command ()
    Return the result from the first that returns non-zero, or 0 if all
    `fail'.  */
 CORE_ADDR 
-skip_language_trampoline (struct frame_info *frame, CORE_ADDR pc)
+skip_language_trampoline (frame_info_ptr frame, CORE_ADDR pc)
 {
   for (const auto &lang : language_defn::languages)
     {
diff --git a/gdb/language.h b/gdb/language.h
index c6812c52634..6482f371e22 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -30,7 +30,7 @@
 /* Forward decls for prototypes.  */
 struct value;
 struct objfile;
-struct frame_info;
+class frame_info_ptr;
 struct ui_file;
 struct value_print_options;
 struct type_print_options;
@@ -321,7 +321,7 @@ struct language_defn
 
   virtual struct value *read_var_value (struct symbol *var,
 					const struct block *var_block,
-					struct frame_info *frame) const;
+					frame_info_ptr frame) const;
 
   /* Return information about whether TYPE should be passed
      (and returned) by reference at the language level.  The default
@@ -464,7 +464,7 @@ struct language_defn
      If that PC falls in a trampoline belonging to this language, return
      the address of the first pc in the real function, or 0 if it isn't a
      language tramp for this language.  */
-  virtual CORE_ADDR skip_trampoline (struct frame_info *fi, CORE_ADDR pc) const
+  virtual CORE_ADDR skip_trampoline (frame_info_ptr fi, CORE_ADDR pc) const
   {
     return (CORE_ADDR) 0;
   }
@@ -782,7 +782,7 @@ extern const char *language_str (enum language);
 
 /* Check for a language-specific trampoline.  */
 
-extern CORE_ADDR skip_language_trampoline (struct frame_info *, CORE_ADDR pc);
+extern CORE_ADDR skip_language_trampoline (frame_info_ptr , CORE_ADDR pc);
 
 /* Return demangled language symbol, or NULL.  */
 extern gdb::unique_xmalloc_ptr<char> language_demangle
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index 4cbff537fab..46c0b1e0be1 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -377,7 +377,7 @@ lm32_return_value (struct gdbarch *gdbarch, struct value *function,
    for it IS the sp for the next frame.  */
 
 static struct lm32_frame_cache *
-lm32_frame_cache (struct frame_info *this_frame, void **this_prologue_cache)
+lm32_frame_cache (frame_info_ptr this_frame, void **this_prologue_cache)
 {
   CORE_ADDR current_pc;
   ULONGEST prev_sp;
@@ -423,7 +423,7 @@ lm32_frame_cache (struct frame_info *this_frame, void **this_prologue_cache)
 }
 
 static void
-lm32_frame_this_id (struct frame_info *this_frame, void **this_cache,
+lm32_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct lm32_frame_cache *cache = lm32_frame_cache (this_frame, this_cache);
@@ -436,7 +436,7 @@ lm32_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-lm32_frame_prev_register (struct frame_info *this_frame,
+lm32_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct lm32_frame_cache *info;
@@ -456,7 +456,7 @@ static const struct frame_unwind lm32_frame_unwind = {
 };
 
 static CORE_ADDR
-lm32_frame_base_address (struct frame_info *this_frame, void **this_cache)
+lm32_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct lm32_frame_cache *info = lm32_frame_cache (this_frame, this_cache);
 
diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c
index 883245bec7e..f4559b65b33 100644
--- a/gdb/loongarch-linux-tdep.c
+++ b/gdb/loongarch-linux-tdep.c
@@ -222,7 +222,7 @@ const struct regset loongarch_fpregset =
 
 static void
 loongarch_linux_rt_sigframe_init (const struct tramp_frame *self,
-				  struct frame_info *this_frame,
+				  frame_info_ptr this_frame,
 				  struct trad_frame_cache *this_cache,
 				  CORE_ADDR func)
 {
@@ -284,7 +284,7 @@ loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
    instruction to be executed.  */
 
 static CORE_ADDR
-loongarch_linux_syscall_next_pc (struct frame_info *frame)
+loongarch_linux_syscall_next_pc (frame_info_ptr frame)
 {
   const CORE_ADDR pc = get_frame_pc (frame);
   ULONGEST a7 = get_frame_register_unsigned (frame, LOONGARCH_A7_REGNUM);
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
index e63ff01854d..40d989bf193 100644
--- a/gdb/loongarch-tdep.c
+++ b/gdb/loongarch-tdep.c
@@ -112,7 +112,7 @@ loongarch_insn_is_sc (insn_t insn)
 
 static CORE_ADDR
 loongarch_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
-			 CORE_ADDR limit_pc, struct frame_info *this_frame,
+			 CORE_ADDR limit_pc, frame_info_ptr this_frame,
 			 struct trad_frame_cache *this_cache)
 {
   CORE_ADDR cur_pc = start_pc, prologue_end = 0;
@@ -397,7 +397,7 @@ loongarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
 /* Generate, or return the cached frame cache for frame unwinder.  */
 
 static struct trad_frame_cache *
-loongarch_frame_cache (struct frame_info *this_frame, void **this_cache)
+loongarch_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct trad_frame_cache *cache;
   CORE_ADDR pc;
@@ -419,7 +419,7 @@ loongarch_frame_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the this_id callback for frame unwinder.  */
 
 static void
-loongarch_frame_this_id (struct frame_info *this_frame, void **prologue_cache,
+loongarch_frame_this_id (frame_info_ptr this_frame, void **prologue_cache,
 			 struct frame_id *this_id)
 {
   struct trad_frame_cache *info;
@@ -431,7 +431,7 @@ loongarch_frame_this_id (struct frame_info *this_frame, void **prologue_cache,
 /* Implement the prev_register callback for frame unwinder.  */
 
 static struct value *
-loongarch_frame_prev_register (struct frame_info *this_frame,
+loongarch_frame_prev_register (frame_info_ptr this_frame,
 			       void **prologue_cache, int regnum)
 {
   struct trad_frame_cache *info;
diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h
index c5527f7d148..42fe1f617a9 100644
--- a/gdb/loongarch-tdep.h
+++ b/gdb/loongarch-tdep.h
@@ -38,7 +38,7 @@ struct loongarch_gdbarch_tdep : gdbarch_tdep_base
   struct loongarch_gdbarch_features abi_features;
 
   /* Return the expected next PC if FRAME is stopped at a syscall instruction.  */
-  CORE_ADDR (*syscall_next_pc) (struct frame_info *frame) = nullptr;
+  CORE_ADDR (*syscall_next_pc) (frame_info_ptr frame) = nullptr;
 };
 
 #endif /* LOONGARCH_TDEP_H  */
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 30f716b6969..dec52aa4f20 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -1851,7 +1851,7 @@ m32c_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR ip)
 /* Stack unwinding.  */
 
 static struct m32c_prologue *
-m32c_analyze_frame_prologue (struct frame_info *this_frame,
+m32c_analyze_frame_prologue (frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   if (! *this_prologue_cache)
@@ -1875,7 +1875,7 @@ m32c_analyze_frame_prologue (struct frame_info *this_frame,
 
 
 static CORE_ADDR
-m32c_frame_base (struct frame_info *this_frame,
+m32c_frame_base (frame_info_ptr this_frame,
 		void **this_prologue_cache)
 {
   struct m32c_prologue *p
@@ -1915,7 +1915,7 @@ m32c_frame_base (struct frame_info *this_frame,
 
 
 static void
-m32c_this_id (struct frame_info *this_frame,
+m32c_this_id (frame_info_ptr this_frame,
 	      void **this_prologue_cache,
 	      struct frame_id *this_id)
 {
@@ -1928,7 +1928,7 @@ m32c_this_id (struct frame_info *this_frame,
 
 
 static struct value *
-m32c_prev_register (struct frame_info *this_frame,
+m32c_prev_register (frame_info_ptr this_frame,
 		    void **this_prologue_cache, int regnum)
 {
   gdbarch *arch = get_frame_arch (this_frame);
@@ -2306,7 +2306,7 @@ m32c_return_value (struct gdbarch *gdbarch,
    code sequence seems more fragile.  */
 
 static CORE_ADDR
-m32c_skip_trampoline_code (struct frame_info *frame, CORE_ADDR stop_pc)
+m32c_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR stop_pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   m32c_gdbarch_tdep *tdep = gdbarch_tdep<m32c_gdbarch_tdep> (gdbarch);
diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c
index 6606a64afa1..7174a10b021 100644
--- a/gdb/m32r-linux-tdep.c
+++ b/gdb/m32r-linux-tdep.c
@@ -85,7 +85,7 @@ static const gdb_byte linux_sigtramp_code[] = {
    the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-m32r_linux_sigtramp_start (CORE_ADDR pc, struct frame_info *this_frame)
+m32r_linux_sigtramp_start (CORE_ADDR pc, frame_info_ptr this_frame)
 {
   gdb_byte buf[4];
 
@@ -133,7 +133,7 @@ static const gdb_byte linux_rt_sigtramp_code[] = {
    of the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *this_frame)
+m32r_linux_rt_sigtramp_start (CORE_ADDR pc, frame_info_ptr this_frame)
 {
   gdb_byte buf[4];
 
@@ -173,7 +173,7 @@ m32r_linux_rt_sigtramp_start (CORE_ADDR pc, struct frame_info *this_frame)
 
 static int
 m32r_linux_pc_in_sigtramp (CORE_ADDR pc, const char *name,
-			   struct frame_info *this_frame)
+			   frame_info_ptr this_frame)
 {
   /* If we have NAME, we can optimize the search.  The trampolines are
      named __restore and __restore_rt.  However, they aren't dynamically
@@ -223,7 +223,7 @@ struct m32r_frame_cache
 };
 
 static struct m32r_frame_cache *
-m32r_linux_sigtramp_frame_cache (struct frame_info *this_frame,
+m32r_linux_sigtramp_frame_cache (frame_info_ptr this_frame,
 				 void **this_cache)
 {
   struct m32r_frame_cache *cache;
@@ -266,7 +266,7 @@ m32r_linux_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-m32r_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+m32r_linux_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				   void **this_cache,
 				   struct frame_id *this_id)
 {
@@ -277,7 +277,7 @@ m32r_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-m32r_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+m32r_linux_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					 void **this_cache, int regnum)
 {
   struct m32r_frame_cache *cache =
@@ -288,7 +288,7 @@ m32r_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index 3ad4c8de6bf..54a94c45d5a 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -519,7 +519,7 @@ struct m32r_unwind_cache
    for it IS the sp for the next frame.  */
 
 static struct m32r_unwind_cache *
-m32r_frame_unwind_cache (struct frame_info *this_frame,
+m32r_frame_unwind_cache (frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   CORE_ADDR pc, scan_limit;
@@ -796,7 +796,7 @@ m32r_return_value (struct gdbarch *gdbarch, struct value *function,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-m32r_frame_this_id (struct frame_info *this_frame,
+m32r_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache, struct frame_id *this_id)
 {
   struct m32r_unwind_cache *info
@@ -826,7 +826,7 @@ m32r_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-m32r_frame_prev_register (struct frame_info *this_frame,
+m32r_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct m32r_unwind_cache *info
@@ -845,7 +845,7 @@ static const struct frame_unwind m32r_frame_unwind = {
 };
 
 static CORE_ADDR
-m32r_frame_base_address (struct frame_info *this_frame, void **this_cache)
+m32r_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct m32r_unwind_cache *info
     = m32r_frame_unwind_cache (this_frame, this_cache);
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 7ea1f9a5b91..2ef70814a0b 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -780,7 +780,7 @@ m68hc11_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    for it IS the sp for the next frame.  */
 
 static struct m68hc11_unwind_cache *
-m68hc11_frame_unwind_cache (struct frame_info *this_frame,
+m68hc11_frame_unwind_cache (frame_info_ptr this_frame,
 			    void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -877,7 +877,7 @@ m68hc11_frame_unwind_cache (struct frame_info *this_frame,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-m68hc11_frame_this_id (struct frame_info *this_frame,
+m68hc11_frame_this_id (frame_info_ptr this_frame,
 		       void **this_prologue_cache,
 		       struct frame_id *this_id)
 {
@@ -902,7 +902,7 @@ m68hc11_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-m68hc11_frame_prev_register (struct frame_info *this_frame,
+m68hc11_frame_prev_register (frame_info_ptr this_frame,
 			     void **this_prologue_cache, int regnum)
 {
   struct value *value;
@@ -950,7 +950,7 @@ static const struct frame_unwind m68hc11_frame_unwind = {
 };
 
 static CORE_ADDR
-m68hc11_frame_base_address (struct frame_info *this_frame, void **this_cache)
+m68hc11_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct m68hc11_unwind_cache *info
     = m68hc11_frame_unwind_cache (this_frame, this_cache);
@@ -959,7 +959,7 @@ m68hc11_frame_base_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static CORE_ADDR
-m68hc11_frame_args_address (struct frame_info *this_frame, void **this_cache)
+m68hc11_frame_args_address (frame_info_ptr this_frame, void **this_cache)
 {
   CORE_ADDR addr;
   struct m68hc11_unwind_cache *info
@@ -986,7 +986,7 @@ static const struct frame_base m68hc11_frame_base = {
    save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */
 
 static struct frame_id
-m68hc11_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+m68hc11_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   ULONGEST tos;
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -1000,7 +1000,7 @@ m68hc11_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 /* Get and print the register from the given frame.  */
 static void
 m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
-			struct frame_info *frame, int regno)
+			frame_info_ptr frame, int regno)
 {
   LONGEST rval;
 
@@ -1087,7 +1087,7 @@ m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
 /* Same as 'info reg' but prints the registers in a different way.  */
 static void
 m68hc11_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
-			      struct frame_info *frame, int regno, int cpregs)
+			      frame_info_ptr frame, int regno, int cpregs)
 {
   if (regno >= 0)
     {
diff --git a/gdb/m68k-linux-tdep.c b/gdb/m68k-linux-tdep.c
index 28401d3ecc6..9c6a41609ed 100644
--- a/gdb/m68k-linux-tdep.c
+++ b/gdb/m68k-linux-tdep.c
@@ -61,7 +61,7 @@
    non-RT and RT signal trampolines.  */
 
 static int
-m68k_linux_pc_in_sigtramp (struct frame_info *this_frame)
+m68k_linux_pc_in_sigtramp (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -219,7 +219,7 @@ m68k_linux_inferior_created (inferior *inf)
 }
 
 static struct m68k_linux_sigtramp_info
-m68k_linux_get_sigtramp_info (struct frame_info *this_frame)
+m68k_linux_get_sigtramp_info (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -248,7 +248,7 @@ m68k_linux_get_sigtramp_info (struct frame_info *this_frame)
 /* Signal trampolines.  */
 
 static struct trad_frame_cache *
-m68k_linux_sigtramp_frame_cache (struct frame_info *this_frame,
+m68k_linux_sigtramp_frame_cache (frame_info_ptr this_frame,
 				 void **this_cache)
 {
   struct frame_id this_id;
@@ -286,7 +286,7 @@ m68k_linux_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-m68k_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+m68k_linux_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				   void **this_cache,
 				   struct frame_id *this_id)
 {
@@ -296,7 +296,7 @@ m68k_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-m68k_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+m68k_linux_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					 void **this_cache,
 					 int regnum)
 {
@@ -308,7 +308,7 @@ m68k_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   void **this_prologue_cache)
 {
   return m68k_linux_pc_in_sigtramp (this_frame);
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index 9e59f5904c3..adb63d67a72 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -205,7 +205,7 @@ m68k_convert_register_p (struct gdbarch *gdbarch,
    return its contents in TO.  */
 
 static int
-m68k_register_to_value (struct frame_info *frame, int regnum,
+m68k_register_to_value (frame_info_ptr frame, int regnum,
 			struct type *type, gdb_byte *to,
 			int *optimizedp, int *unavailablep)
 {
@@ -232,7 +232,7 @@ m68k_register_to_value (struct frame_info *frame, int regnum,
    REGNUM in frame FRAME.  */
 
 static void
-m68k_value_to_register (struct frame_info *frame, int regnum,
+m68k_value_to_register (frame_info_ptr frame, int regnum,
 			struct type *type, const gdb_byte *from)
 {
   gdb_byte to[M68K_MAX_REGISTER_SIZE];
@@ -901,7 +901,7 @@ m68k_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 }
 
 static CORE_ADDR
-m68k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+m68k_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_byte buf[8];
 
@@ -912,7 +912,7 @@ m68k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Normal frames.  */
 
 static struct m68k_frame_cache *
-m68k_frame_cache (struct frame_info *this_frame, void **this_cache)
+m68k_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -977,7 +977,7 @@ m68k_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-m68k_frame_this_id (struct frame_info *this_frame, void **this_cache,
+m68k_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct m68k_frame_cache *cache = m68k_frame_cache (this_frame, this_cache);
@@ -991,7 +991,7 @@ m68k_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-m68k_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+m68k_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			  int regnum)
 {
   struct m68k_frame_cache *cache = m68k_frame_cache (this_frame, this_cache);
@@ -1020,7 +1020,7 @@ static const struct frame_unwind m68k_frame_unwind =
 };
 \f
 static CORE_ADDR
-m68k_frame_base_address (struct frame_info *this_frame, void **this_cache)
+m68k_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct m68k_frame_cache *cache = m68k_frame_cache (this_frame, this_cache);
 
@@ -1036,7 +1036,7 @@ static const struct frame_base m68k_frame_base =
 };
 
 static struct frame_id
-m68k_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+m68k_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR fp;
 
@@ -1053,7 +1053,7 @@ m68k_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
    This routine returns true on success.  */
 
 static int
-m68k_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+m68k_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   gdb_byte *buf;
   CORE_ADDR sp, jb_addr;
diff --git a/gdb/m68k-tdep.h b/gdb/m68k-tdep.h
index 785e3fdb84f..e22d624adaa 100644
--- a/gdb/m68k-tdep.h
+++ b/gdb/m68k-tdep.h
@@ -22,7 +22,7 @@
 
 #include "gdbarch.h"
 
-struct frame_info;
+class frame_info_ptr;
 
 /* Register numbers of various important registers.  */
 
diff --git a/gdb/macroscope.c b/gdb/macroscope.c
index fe7f10e296a..c5fd91e6fd1 100644
--- a/gdb/macroscope.c
+++ b/gdb/macroscope.c
@@ -100,7 +100,7 @@ default_macro_scope (void)
 {
   struct symtab_and_line sal;
   gdb::unique_xmalloc_ptr<struct macro_scope> ms;
-  struct frame_info *frame;
+  frame_info_ptr frame;
   CORE_ADDR pc;
 
   /* If there's a selected frame, use its PC.  */
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 170b4b07460..cd54f6b462d 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -1910,7 +1910,7 @@ typedef BP_MANIPULATION (mep_break_insn) mep_breakpoint;
 
 
 static struct mep_prologue *
-mep_analyze_frame_prologue (struct frame_info *this_frame,
+mep_analyze_frame_prologue (frame_info_ptr this_frame,
 			    void **this_prologue_cache)
 {
   if (! *this_prologue_cache)
@@ -1940,7 +1940,7 @@ mep_analyze_frame_prologue (struct frame_info *this_frame,
 /* Given the next frame and a prologue cache, return this frame's
    base.  */
 static CORE_ADDR
-mep_frame_base (struct frame_info *this_frame,
+mep_frame_base (frame_info_ptr this_frame,
 		void **this_prologue_cache)
 {
   struct mep_prologue *p
@@ -1968,7 +1968,7 @@ mep_frame_base (struct frame_info *this_frame,
 
 
 static void
-mep_frame_this_id (struct frame_info *this_frame,
+mep_frame_this_id (frame_info_ptr this_frame,
 		   void **this_prologue_cache,
 		   struct frame_id *this_id)
 {
@@ -1978,7 +1978,7 @@ mep_frame_this_id (struct frame_info *this_frame,
 
 
 static struct value *
-mep_frame_prev_register (struct frame_info *this_frame,
+mep_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_prologue_cache, int regnum)
 {
   struct mep_prologue *p
diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
index daa7ddf7e4d..768889a7480 100644
--- a/gdb/microblaze-linux-tdep.c
+++ b/gdb/microblaze-linux-tdep.c
@@ -62,7 +62,7 @@ microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
 }
 
 static void
-microblaze_linux_sigtramp_cache (struct frame_info *next_frame,
+microblaze_linux_sigtramp_cache (frame_info_ptr next_frame,
 				 struct trad_frame_cache *this_cache,
 				 CORE_ADDR func, LONGEST offset,
 				 int bias)
@@ -90,7 +90,7 @@ microblaze_linux_sigtramp_cache (struct frame_info *next_frame,
 
 static void
 microblaze_linux_sighandler_cache_init (const struct tramp_frame *self,
-					struct frame_info *next_frame,
+					frame_info_ptr next_frame,
 					struct trad_frame_cache *this_cache,
 					CORE_ADDR func)
 {
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index 3d5dd669341..479ea6899d7 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -368,7 +368,7 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
 }
 
 static CORE_ADDR
-microblaze_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+microblaze_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_byte buf[4];
   CORE_ADDR pc;
@@ -417,7 +417,7 @@ microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 /* Normal frames.  */
 
 static struct microblaze_frame_cache *
-microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
+microblaze_frame_cache (frame_info_ptr next_frame, void **this_cache)
 {
   struct microblaze_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
@@ -443,7 +443,7 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
 }
 
 static void
-microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache,
+microblaze_frame_this_id (frame_info_ptr next_frame, void **this_cache,
 		       struct frame_id *this_id)
 {
   struct microblaze_frame_cache *cache =
@@ -457,7 +457,7 @@ microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache,
 }
 
 static struct value *
-microblaze_frame_prev_register (struct frame_info *this_frame,
+microblaze_frame_prev_register (frame_info_ptr this_frame,
 				 void **this_cache, int regnum)
 {
   struct microblaze_frame_cache *cache =
@@ -490,7 +490,7 @@ static const struct frame_unwind microblaze_frame_unwind =
 };
 \f
 static CORE_ADDR
-microblaze_frame_base_address (struct frame_info *next_frame,
+microblaze_frame_base_address (frame_info_ptr next_frame,
 			       void **this_cache)
 {
   struct microblaze_frame_cache *cache =
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index c6abec81ce2..0da615564b6 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -1538,7 +1538,7 @@ lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
    a duplicate function in case this matters someday.  */
 
 CORE_ADDR
-find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
+find_solib_trampoline_target (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct minimal_symbol *tsymbol = lookup_solib_trampoline_symbol_by_pc (pc);
 
diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index 05043d93e74..eae53108c03 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -275,7 +275,7 @@ mips_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
 static void
 mips_fbsd_sigframe_init (const struct tramp_frame *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 struct trad_frame_cache *cache,
 			 CORE_ADDR func)
 {
@@ -367,7 +367,7 @@ static const struct tramp_frame mips_fbsd_sigframe =
 
 static void
 mips64_fbsd_sigframe_init (const struct tramp_frame *self,
-			   struct frame_info *this_frame,
+			   frame_info_ptr this_frame,
 			   struct trad_frame_cache *cache,
 			   CORE_ADDR func)
 {
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index ca313a28279..e7c1800a876 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -93,7 +93,7 @@ enum
 #define MIPS_LINUX_JB_PC 0
 
 static int
-mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+mips_linux_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -246,7 +246,7 @@ mips_fill_gregset_wrapper (const struct regset *regset,
 #define MIPS64_LINUX_JB_PC 0
 
 static int
-mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+mips64_linux_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -713,21 +713,21 @@ mips_linux_skip_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
    efficient way, but simplest.  First, declare all the unwinders.  */
 
 static void mips_linux_o32_sigframe_init (const struct tramp_frame *self,
-					  struct frame_info *this_frame,
+					  frame_info_ptr this_frame,
 					  struct trad_frame_cache *this_cache,
 					  CORE_ADDR func);
 
 static void mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
-					     struct frame_info *this_frame,
+					     frame_info_ptr this_frame,
 					     struct trad_frame_cache *this_cache,
 					     CORE_ADDR func);
 
 static int mips_linux_sigframe_validate (const struct tramp_frame *self,
-					 struct frame_info *this_frame,
+					 frame_info_ptr this_frame,
 					 CORE_ADDR *pc);
 
 static int micromips_linux_sigframe_validate (const struct tramp_frame *self,
-					      struct frame_info *this_frame,
+					      frame_info_ptr this_frame,
 					      CORE_ADDR *pc);
 
 #define MIPS_NR_LINUX 4000
@@ -958,7 +958,7 @@ static const struct tramp_frame micromips_linux_n64_rt_sigframe = {
 
 static void
 mips_linux_o32_sigframe_init (const struct tramp_frame *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      struct trad_frame_cache *this_cache,
 			      CORE_ADDR func)
 {
@@ -1153,7 +1153,7 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
 
 static void
 mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
-				 struct frame_info *this_frame,
+				 frame_info_ptr this_frame,
 				 struct trad_frame_cache *this_cache,
 				 CORE_ADDR func)
 {
@@ -1238,7 +1238,7 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
 
 static int
 mips_linux_sigframe_validate (const struct tramp_frame *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      CORE_ADDR *pc)
 {
   return mips_pc_is_mips (*pc);
@@ -1248,7 +1248,7 @@ mips_linux_sigframe_validate (const struct tramp_frame *self,
 
 static int
 micromips_linux_sigframe_validate (const struct tramp_frame *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   CORE_ADDR *pc)
 {
   if (mips_pc_is_micromips (get_frame_arch (this_frame), *pc))
@@ -1293,7 +1293,7 @@ mips_linux_restart_reg_p (struct gdbarch *gdbarch)
    instruction to be executed.  */
 
 static CORE_ADDR
-mips_linux_syscall_next_pc (struct frame_info *frame)
+mips_linux_syscall_next_pc (frame_info_ptr frame)
 {
   CORE_ADDR pc = get_frame_pc (frame);
   ULONGEST v0 = get_frame_register_unsigned (frame, MIPS_V0_REGNUM);
diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c
index 2179ca0bf5a..c13e1fd0802 100644
--- a/gdb/mips-netbsd-tdep.c
+++ b/gdb/mips-netbsd-tdep.c
@@ -254,7 +254,7 @@ static const unsigned char sigtramp_retcode_mipseb[RETCODE_SIZE] =
 					 NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch))
 
 static int
-mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+mipsnbsd_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/mips-sde-tdep.c b/gdb/mips-sde-tdep.c
index de8e726d64f..7d69effd704 100644
--- a/gdb/mips-sde-tdep.c
+++ b/gdb/mips-sde-tdep.c
@@ -34,7 +34,7 @@
    in the SDE frame unwinder.  */
 
 static struct trad_frame_cache *
-mips_sde_frame_cache (struct frame_info *this_frame, void **this_cache)
+mips_sde_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   const struct mips_regnum *regs = mips_regnum (gdbarch);
@@ -122,7 +122,7 @@ mips_sde_frame_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the this_id function for the SDE frame unwinder.  */
 
 static void
-mips_sde_frame_this_id (struct frame_info *this_frame, void **this_cache,
+mips_sde_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			struct frame_id *this_id)
 {
   struct trad_frame_cache *this_trad_cache
@@ -134,7 +134,7 @@ mips_sde_frame_this_id (struct frame_info *this_frame, void **this_cache,
 /* Implement the prev_register function for the SDE frame unwinder.  */
 
 static struct value *
-mips_sde_frame_prev_register (struct frame_info *this_frame,
+mips_sde_frame_prev_register (frame_info_ptr this_frame,
 			      void **this_cache,
 			      int prev_regnum)
 {
@@ -148,7 +148,7 @@ mips_sde_frame_prev_register (struct frame_info *this_frame,
 
 static int
 mips_sde_frame_sniffer (const struct frame_unwind *self,
-			struct frame_info *this_frame,
+			frame_info_ptr this_frame,
 			void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -177,7 +177,7 @@ static const struct frame_unwind mips_sde_frame_unwind =
    for the normal unwinder.  */
 
 static CORE_ADDR
-mips_sde_frame_base_address (struct frame_info *this_frame, void **this_cache)
+mips_sde_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct trad_frame_cache *this_trad_cache
     = mips_sde_frame_cache (this_frame, this_cache);
@@ -194,7 +194,7 @@ static const struct frame_base mips_sde_frame_base =
 };
 
 static const struct frame_base *
-mips_sde_frame_base_sniffer (struct frame_info *this_frame)
+mips_sde_frame_base_sniffer (frame_info_ptr this_frame)
 {
   if (mips_sde_frame_sniffer (&mips_sde_frame_unwind, this_frame, NULL))
     return &mips_sde_frame_base;
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 98270268584..a7ae5ef45ca 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -74,7 +74,7 @@ static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
 					     CORE_ADDR addr, int mustbe32);
 
 static void mips_print_float_info (struct gdbarch *, struct ui_file *,
-				   struct frame_info *, const char *);
+				   frame_info_ptr , const char *);
 
 /* A useful bit in the CP0 status register (MIPS_PS_REGNUM).  */
 /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip.  */
@@ -560,7 +560,7 @@ mips_xfer_register (struct gdbarch *gdbarch, struct regcache *regcache,
    physical 64-bit registers, but should treat them as 32-bit registers.  */
 
 static int
-mips2_fp_compat (struct frame_info *frame)
+mips2_fp_compat (frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
@@ -942,7 +942,7 @@ mips_convert_register_p (struct gdbarch *gdbarch,
 }
 
 static int
-mips_register_to_value (struct frame_info *frame, int regnum,
+mips_register_to_value (frame_info_ptr frame, int regnum,
 			struct type *type, gdb_byte *to,
 			int *optimizedp, int *unavailablep)
 {
@@ -984,7 +984,7 @@ mips_register_to_value (struct frame_info *frame, int regnum,
 }
 
 static void
-mips_value_to_register (struct frame_info *frame, int regnum,
+mips_value_to_register (frame_info_ptr frame, int regnum,
 			struct type *type, const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1407,7 +1407,7 @@ mips_read_pc (readable_regcache *regcache)
 }
 
 static CORE_ADDR
-mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+mips_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   CORE_ADDR pc;
 
@@ -1429,7 +1429,7 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 }
 
 static CORE_ADDR
-mips_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+mips_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   return frame_unwind_register_signed
 	   (next_frame, gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM);
@@ -1441,7 +1441,7 @@ mips_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
    breakpoint.  */
 
 static struct frame_id
-mips_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+mips_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   return frame_id_build
 	   (get_frame_register_signed (this_frame,
@@ -2524,7 +2524,7 @@ mips16_get_imm (unsigned short prev_inst,	/* previous instruction */
 static CORE_ADDR
 mips16_scan_prologue (struct gdbarch *gdbarch,
 		      CORE_ADDR start_pc, CORE_ADDR limit_pc,
-		      struct frame_info *this_frame,
+		      frame_info_ptr this_frame,
 		      struct mips_frame_cache *this_cache)
 {
   int prev_non_prologue_insn = 0;
@@ -2860,7 +2860,7 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
    mips_insn32 unwinder.  */
 
 static struct mips_frame_cache *
-mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
+mips_insn16_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct mips_frame_cache *cache;
@@ -2896,7 +2896,7 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-mips_insn16_frame_this_id (struct frame_info *this_frame, void **this_cache,
+mips_insn16_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			   struct frame_id *this_id)
 {
   struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
@@ -2908,7 +2908,7 @@ mips_insn16_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-mips_insn16_frame_prev_register (struct frame_info *this_frame,
+mips_insn16_frame_prev_register (frame_info_ptr this_frame,
 				 void **this_cache, int regnum)
 {
   struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
@@ -2918,7 +2918,7 @@ mips_insn16_frame_prev_register (struct frame_info *this_frame,
 
 static int
 mips_insn16_frame_sniffer (const struct frame_unwind *self,
-			   struct frame_info *this_frame, void **this_cache)
+			   frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -2939,7 +2939,7 @@ static const struct frame_unwind mips_insn16_frame_unwind =
 };
 
 static CORE_ADDR
-mips_insn16_frame_base_address (struct frame_info *this_frame,
+mips_insn16_frame_base_address (frame_info_ptr this_frame,
 				void **this_cache)
 {
   struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
@@ -2956,7 +2956,7 @@ static const struct frame_base mips_insn16_frame_base =
 };
 
 static const struct frame_base *
-mips_insn16_frame_base_sniffer (struct frame_info *this_frame)
+mips_insn16_frame_base_sniffer (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -2985,7 +2985,7 @@ micromips_decode_imm9 (int imm)
 static CORE_ADDR
 micromips_scan_prologue (struct gdbarch *gdbarch,
 			 CORE_ADDR start_pc, CORE_ADDR limit_pc,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 struct mips_frame_cache *this_cache)
 {
   CORE_ADDR end_prologue_addr;
@@ -3294,7 +3294,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
    mips_insn32 unwinder.  Likewise MIPS16 and the mips_insn16 unwinder. */
 
 static struct mips_frame_cache *
-mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache)
+mips_micro_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct mips_frame_cache *cache;
@@ -3331,7 +3331,7 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-mips_micro_frame_this_id (struct frame_info *this_frame, void **this_cache,
+mips_micro_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			  struct frame_id *this_id)
 {
   struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
@@ -3343,7 +3343,7 @@ mips_micro_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-mips_micro_frame_prev_register (struct frame_info *this_frame,
+mips_micro_frame_prev_register (frame_info_ptr this_frame,
 				void **this_cache, int regnum)
 {
   struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
@@ -3353,7 +3353,7 @@ mips_micro_frame_prev_register (struct frame_info *this_frame,
 
 static int
 mips_micro_frame_sniffer (const struct frame_unwind *self,
-			  struct frame_info *this_frame, void **this_cache)
+			  frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -3375,7 +3375,7 @@ static const struct frame_unwind mips_micro_frame_unwind =
 };
 
 static CORE_ADDR
-mips_micro_frame_base_address (struct frame_info *this_frame,
+mips_micro_frame_base_address (frame_info_ptr this_frame,
 			       void **this_cache)
 {
   struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
@@ -3392,7 +3392,7 @@ static const struct frame_base mips_micro_frame_base =
 };
 
 static const struct frame_base *
-mips_micro_frame_base_sniffer (struct frame_info *this_frame)
+mips_micro_frame_base_sniffer (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -3430,7 +3430,7 @@ reset_saved_regs (struct gdbarch *gdbarch, struct mips_frame_cache *this_cache)
 static CORE_ADDR
 mips32_scan_prologue (struct gdbarch *gdbarch,
 		      CORE_ADDR start_pc, CORE_ADDR limit_pc,
-		      struct frame_info *this_frame,
+		      frame_info_ptr this_frame,
 		      struct mips_frame_cache *this_cache)
 {
   int prev_non_prologue_insn;
@@ -3675,7 +3675,7 @@ mips32_scan_prologue (struct gdbarch *gdbarch,
    unwinder.  Likewise microMIPS and the mips_micro unwinder. */
 
 static struct mips_frame_cache *
-mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
+mips_insn32_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct mips_frame_cache *cache;
@@ -3712,7 +3712,7 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-mips_insn32_frame_this_id (struct frame_info *this_frame, void **this_cache,
+mips_insn32_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			   struct frame_id *this_id)
 {
   struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
@@ -3724,7 +3724,7 @@ mips_insn32_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-mips_insn32_frame_prev_register (struct frame_info *this_frame,
+mips_insn32_frame_prev_register (frame_info_ptr this_frame,
 				 void **this_cache, int regnum)
 {
   struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
@@ -3734,7 +3734,7 @@ mips_insn32_frame_prev_register (struct frame_info *this_frame,
 
 static int
 mips_insn32_frame_sniffer (const struct frame_unwind *self,
-			   struct frame_info *this_frame, void **this_cache)
+			   frame_info_ptr this_frame, void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   if (mips_pc_is_mips (pc))
@@ -3754,7 +3754,7 @@ static const struct frame_unwind mips_insn32_frame_unwind =
 };
 
 static CORE_ADDR
-mips_insn32_frame_base_address (struct frame_info *this_frame,
+mips_insn32_frame_base_address (frame_info_ptr this_frame,
 				void **this_cache)
 {
   struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
@@ -3771,7 +3771,7 @@ static const struct frame_base mips_insn32_frame_base =
 };
 
 static const struct frame_base *
-mips_insn32_frame_base_sniffer (struct frame_info *this_frame)
+mips_insn32_frame_base_sniffer (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   if (mips_pc_is_mips (pc))
@@ -3781,7 +3781,7 @@ mips_insn32_frame_base_sniffer (struct frame_info *this_frame)
 }
 
 static struct trad_frame_cache *
-mips_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
+mips_stub_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   CORE_ADDR pc;
   CORE_ADDR start_addr;
@@ -3816,7 +3816,7 @@ mips_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-mips_stub_frame_this_id (struct frame_info *this_frame, void **this_cache,
+mips_stub_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			 struct frame_id *this_id)
 {
   struct trad_frame_cache *this_trad_cache
@@ -3825,7 +3825,7 @@ mips_stub_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-mips_stub_frame_prev_register (struct frame_info *this_frame,
+mips_stub_frame_prev_register (frame_info_ptr this_frame,
 			       void **this_cache, int regnum)
 {
   struct trad_frame_cache *this_trad_cache
@@ -3835,7 +3835,7 @@ mips_stub_frame_prev_register (struct frame_info *this_frame,
 
 static int
 mips_stub_frame_sniffer (const struct frame_unwind *self,
-			 struct frame_info *this_frame, void **this_cache)
+			 frame_info_ptr this_frame, void **this_cache)
 {
   gdb_byte dummy[4];
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
@@ -3871,7 +3871,7 @@ static const struct frame_unwind mips_stub_frame_unwind =
 };
 
 static CORE_ADDR
-mips_stub_frame_base_address (struct frame_info *this_frame,
+mips_stub_frame_base_address (frame_info_ptr this_frame,
 			      void **this_cache)
 {
   struct trad_frame_cache *this_trad_cache
@@ -3888,7 +3888,7 @@ static const struct frame_base mips_stub_frame_base =
 };
 
 static const struct frame_base *
-mips_stub_frame_base_sniffer (struct frame_info *this_frame)
+mips_stub_frame_base_sniffer (frame_info_ptr this_frame)
 {
   if (mips_stub_frame_sniffer (&mips_stub_frame_unwind, this_frame, NULL))
     return &mips_stub_frame_base;
@@ -6252,7 +6252,7 @@ mips_o64_return_value (struct gdbarch *gdbarch, struct value *function,
    into rare_buffer.  */
 
 static void
-mips_read_fp_register_single (struct frame_info *frame, int regno,
+mips_read_fp_register_single (frame_info_ptr frame, int regno,
 			      gdb_byte *rare_buffer)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -6286,7 +6286,7 @@ mips_read_fp_register_single (struct frame_info *frame, int regno,
    register.  */
 
 static void
-mips_read_fp_register_double (struct frame_info *frame, int regno,
+mips_read_fp_register_double (frame_info_ptr frame, int regno,
 			      gdb_byte *rare_buffer)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -6325,7 +6325,7 @@ mips_read_fp_register_double (struct frame_info *frame, int regno,
 }
 
 static void
-mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
+mips_print_fp_register (struct ui_file *file, frame_info_ptr frame,
 			int regnum)
 {				/* Do values for FP (float) regs.  */
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -6390,7 +6390,7 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
 }
 
 static void
-mips_print_register (struct ui_file *file, struct frame_info *frame,
+mips_print_register (struct ui_file *file, frame_info_ptr frame,
 		     int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -6445,7 +6445,7 @@ print_fpu_flags (struct ui_file *file, int flags)
 
 static void
 mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
-		      struct frame_info *frame, const char *args)
+		      frame_info_ptr frame, const char *args)
 {
   int fcsr = mips_regnum (gdbarch)->fp_control_status;
   enum mips_fpu_type type = mips_get_fpu_type (gdbarch);
@@ -6512,7 +6512,7 @@ mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
    Print regs in pretty columns.  */
 
 static int
-print_fp_register_row (struct ui_file *file, struct frame_info *frame,
+print_fp_register_row (struct ui_file *file, frame_info_ptr frame,
 		       int regnum)
 {
   gdb_printf (file, " ");
@@ -6525,7 +6525,7 @@ print_fp_register_row (struct ui_file *file, struct frame_info *frame,
 /* Print a row's worth of GP (int) registers, with name labels above.  */
 
 static int
-print_gp_register_row (struct ui_file *file, struct frame_info *frame,
+print_gp_register_row (struct ui_file *file, frame_info_ptr frame,
 		       int start_regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -6628,7 +6628,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
 
 static void
 mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
-			   struct frame_info *frame, int regnum, int all)
+			   frame_info_ptr frame, int regnum, int all)
 {
   if (regnum != -1)		/* Do one specified register.  */
     {
@@ -6660,7 +6660,7 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
 
 static int
 mips_single_step_through_delay (struct gdbarch *gdbarch,
-				struct frame_info *frame)
+				frame_info_ptr frame)
 {
   CORE_ADDR pc = get_frame_pc (frame);
   enum mips_isa isa;
@@ -7565,7 +7565,7 @@ mips_is_stub_mode (const char *mode)
    The limit on the search is arbitrarily set to 20 instructions.  FIXME.  */
 
 static CORE_ADDR
-mips_get_mips16_fn_stub_pc (struct frame_info *frame, CORE_ADDR pc)
+mips_get_mips16_fn_stub_pc (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -7688,7 +7688,7 @@ mips_get_mips16_fn_stub_pc (struct frame_info *frame, CORE_ADDR pc)
    gory details.  */
 
 static CORE_ADDR
-mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+mips_skip_mips16_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   CORE_ADDR start_addr;
@@ -7816,7 +7816,7 @@ mips_in_return_stub (struct gdbarch *gdbarch, CORE_ADDR pc, const char *name)
    so that $t9 has the correct value at function entry.  */
 
 static CORE_ADDR
-mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+mips_skip_pic_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -7869,7 +7869,7 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 }
 
 static CORE_ADDR
-mips_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+mips_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   CORE_ADDR requested_pc = pc;
   CORE_ADDR target_pc;
@@ -8073,7 +8073,7 @@ mips_register_g_packet_guesses (struct gdbarch *gdbarch)
 }
 
 static struct value *
-value_of_mips_user_reg (struct frame_info *frame, const void *baton)
+value_of_mips_user_reg (frame_info_ptr frame, const void *baton)
 {
   const int *reg_p = (const int *) baton;
   return value_of_register (*reg_p, frame);
diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h
index 24ed678a521..5d9a52490c4 100644
--- a/gdb/mips-tdep.h
+++ b/gdb/mips-tdep.h
@@ -125,7 +125,7 @@ struct mips_gdbarch_tdep : gdbarch_tdep_base
 
   /* Return the expected next PC if FRAME is stopped at a syscall
      instruction.  */
-  CORE_ADDR (*syscall_next_pc) (struct frame_info *frame) = nullptr;
+  CORE_ADDR (*syscall_next_pc) (frame_info_ptr frame) = nullptr;
 };
 
 /* Register numbers of various important registers.  */
diff --git a/gdb/mips64-obsd-tdep.c b/gdb/mips64-obsd-tdep.c
index 8fe2834f23a..450e302f004 100644
--- a/gdb/mips64-obsd-tdep.c
+++ b/gdb/mips64-obsd-tdep.c
@@ -77,7 +77,7 @@ mips64obsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
 static void
 mips64obsd_sigframe_init (const struct tramp_frame *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  struct trad_frame_cache *cache,
 			  CORE_ADDR func)
 {
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index 4fb59123b58..b6111d431b7 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -464,7 +464,7 @@ am33_iterate_over_regset_sections (struct gdbarch *gdbarch,
 \f
 static void
 am33_linux_sigframe_cache_init (const struct tramp_frame *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				struct trad_frame_cache *this_cache,
 				CORE_ADDR func);
 
@@ -607,7 +607,7 @@ struct sigcontext {
 
 static void
 am33_linux_sigframe_cache_init (const struct tramp_frame *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				struct trad_frame_cache *this_cache,
 				CORE_ADDR func)
 {
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 22511d894d4..e00697310d9 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -1046,7 +1046,7 @@ mn10300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    use the current frame PC as the limit, then
    invoke mn10300_analyze_prologue and return its result.  */
 static struct mn10300_prologue *
-mn10300_analyze_frame_prologue (struct frame_info *this_frame,
+mn10300_analyze_frame_prologue (frame_info_ptr this_frame,
 			   void **this_prologue_cache)
 {
   if (!*this_prologue_cache)
@@ -1075,7 +1075,7 @@ mn10300_analyze_frame_prologue (struct frame_info *this_frame,
 /* Given the next frame and a prologue cache, return this frame's
    base.  */
 static CORE_ADDR
-mn10300_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
+mn10300_frame_base (frame_info_ptr this_frame, void **this_prologue_cache)
 {
   struct mn10300_prologue *p
     = mn10300_analyze_frame_prologue (this_frame, this_prologue_cache);
@@ -1099,7 +1099,7 @@ mn10300_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
 }
 
 static void
-mn10300_frame_this_id (struct frame_info *this_frame,
+mn10300_frame_this_id (frame_info_ptr this_frame,
 		       void **this_prologue_cache,
 		       struct frame_id *this_id)
 {
@@ -1110,7 +1110,7 @@ mn10300_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-mn10300_frame_prev_register (struct frame_info *this_frame,
+mn10300_frame_prev_register (frame_info_ptr this_frame,
 			     void **this_prologue_cache, int regnum)
 {
   struct mn10300_prologue *p
diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
index f5cf501cea0..c5ce6913353 100644
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -516,7 +516,7 @@ moxie_alloc_frame_cache (void)
 /* Populate a moxie_frame_cache object for this_frame.  */
 
 static struct moxie_frame_cache *
-moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
+moxie_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct moxie_frame_cache *cache;
   CORE_ADDR current_pc;
@@ -553,7 +553,7 @@ moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-moxie_frame_this_id (struct frame_info *this_frame,
+moxie_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache, struct frame_id *this_id)
 {
   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
@@ -569,7 +569,7 @@ moxie_frame_this_id (struct frame_info *this_frame,
 /* Get the value of register regnum in the previous stack frame.  */
 
 static struct value *
-moxie_frame_prev_register (struct frame_info *this_frame,
+moxie_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
@@ -600,7 +600,7 @@ static const struct frame_unwind moxie_frame_unwind = {
 /* Return the base address of this_frame.  */
 
 static CORE_ADDR
-moxie_frame_base_address (struct frame_info *this_frame, void **this_cache)
+moxie_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
 						       this_cache);
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index cf4106d1a34..d04fbf70c10 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -455,7 +455,7 @@ msp430_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    return that struct as the value of this function.  */
 
 static struct msp430_prologue *
-msp430_analyze_frame_prologue (struct frame_info *this_frame,
+msp430_analyze_frame_prologue (frame_info_ptr this_frame,
 			       void **this_prologue_cache)
 {
   if (!*this_prologue_cache)
@@ -483,7 +483,7 @@ msp430_analyze_frame_prologue (struct frame_info *this_frame,
 /* Given a frame and a prologue cache, return this frame's base.  */
 
 static CORE_ADDR
-msp430_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
+msp430_frame_base (frame_info_ptr this_frame, void **this_prologue_cache)
 {
   struct msp430_prologue *p
     = msp430_analyze_frame_prologue (this_frame, this_prologue_cache);
@@ -495,7 +495,7 @@ msp430_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
 /* Implement the "frame_this_id" method for unwinding frames.  */
 
 static void
-msp430_this_id (struct frame_info *this_frame,
+msp430_this_id (frame_info_ptr this_frame,
 		void **this_prologue_cache, struct frame_id *this_id)
 {
   *this_id = frame_id_build (msp430_frame_base (this_frame,
@@ -506,7 +506,7 @@ msp430_this_id (struct frame_info *this_frame,
 /* Implement the "frame_prev_register" method for unwinding frames.  */
 
 static struct value *
-msp430_prev_register (struct frame_info *this_frame,
+msp430_prev_register (frame_info_ptr this_frame,
 		      void **this_prologue_cache, int regnum)
 {
   struct msp430_prologue *p
@@ -802,7 +802,7 @@ msp430_in_return_stub (struct gdbarch *gdbarch, CORE_ADDR pc,
 
 /* Implement the "skip_trampoline_code" gdbarch method.  */
 static CORE_ADDR
-msp430_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+msp430_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct bound_minimal_symbol bms;
   const char *stub_name;
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index 11bfd2d1f54..82e68cd09c5 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -265,7 +265,7 @@ static const struct
    register.  */
 
 static struct value *
-value_of_nds32_reg (struct frame_info *frame, const void *baton)
+value_of_nds32_reg (frame_info_ptr frame, const void *baton)
 {
   return value_of_register ((int) (intptr_t) baton, frame);
 }
@@ -901,7 +901,7 @@ nds32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    a pointer to the current nds32_frame_cache in *THIS_CACHE.  */
 
 static struct nds32_frame_cache *
-nds32_frame_cache (struct frame_info *this_frame, void **this_cache)
+nds32_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct nds32_frame_cache *cache;
@@ -952,7 +952,7 @@ nds32_frame_cache (struct frame_info *this_frame, void **this_cache)
    PC and the caller's SP when we were called.  */
 
 static void
-nds32_frame_this_id (struct frame_info *this_frame,
+nds32_frame_this_id (frame_info_ptr this_frame,
 		     void **this_cache, struct frame_id *this_id)
 {
   struct nds32_frame_cache *cache = nds32_frame_cache (this_frame, this_cache);
@@ -967,7 +967,7 @@ nds32_frame_this_id (struct frame_info *this_frame,
 /* Implement the "prev_register" frame_unwind method.  */
 
 static struct value *
-nds32_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+nds32_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			   int regnum)
 {
   struct nds32_frame_cache *cache = nds32_frame_cache (this_frame, this_cache);
@@ -1001,7 +1001,7 @@ static const struct frame_unwind nds32_frame_unwind =
 /* Return the frame base address of *THIS_FRAME.  */
 
 static CORE_ADDR
-nds32_frame_base_address (struct frame_info *this_frame, void **this_cache)
+nds32_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct nds32_frame_cache *cache = nds32_frame_cache (this_frame, this_cache);
 
@@ -1287,7 +1287,7 @@ nds32_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR addr)
 
 static int
 nds32_epilogue_frame_sniffer (const struct frame_unwind *self,
-			      struct frame_info *this_frame, void **this_cache)
+			      frame_info_ptr this_frame, void **this_cache)
 {
   if (frame_relative_level (this_frame) == 0)
     return nds32_stack_frame_destroyed_p (get_frame_arch (this_frame),
@@ -1302,7 +1302,7 @@ nds32_epilogue_frame_sniffer (const struct frame_unwind *self,
    *THIS_CACHE.  */
 
 static struct nds32_frame_cache *
-nds32_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+nds32_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct nds32_frame_cache *cache;
@@ -1334,7 +1334,7 @@ nds32_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the "this_id" frame_unwind method.  */
 
 static void
-nds32_epilogue_frame_this_id (struct frame_info *this_frame,
+nds32_epilogue_frame_this_id (frame_info_ptr this_frame,
 			      void **this_cache, struct frame_id *this_id)
 {
   struct nds32_frame_cache *cache
@@ -1350,7 +1350,7 @@ nds32_epilogue_frame_this_id (struct frame_info *this_frame,
 /* Implement the "prev_register" frame_unwind method.  */
 
 static struct value *
-nds32_epilogue_frame_prev_register (struct frame_info *this_frame,
+nds32_epilogue_frame_prev_register (frame_info_ptr this_frame,
 				    void **this_cache, int regnum)
 {
   struct nds32_frame_cache *cache
@@ -1827,7 +1827,7 @@ nds32_return_value (struct gdbarch *gdbarch, struct value *func_type,
 /* Implement the "get_longjmp_target" gdbarch method.  */
 
 static int
-nds32_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+nds32_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   gdb_byte buf[4];
   CORE_ADDR jb_addr;
diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c
index da69638b20b..5a03cbc1773 100644
--- a/gdb/nios2-linux-tdep.c
+++ b/gdb/nios2-linux-tdep.c
@@ -134,7 +134,7 @@ nios2_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
 static void
 nios2_linux_rt_sigreturn_init (const struct tramp_frame *self,
-			       struct frame_info *next_frame,
+			       frame_info_ptr next_frame,
 			       struct trad_frame_cache *this_cache,
 			       CORE_ADDR func)
 {
@@ -187,7 +187,7 @@ static struct tramp_frame nios2_r2_linux_rt_sigreturn_tramp_frame =
    instruction to be executed.  */
 
 static CORE_ADDR
-nios2_linux_syscall_next_pc (struct frame_info *frame,
+nios2_linux_syscall_next_pc (frame_info_ptr frame,
 			     const struct nios2_opcode *op)
 {
   CORE_ADDR pc = get_frame_pc (frame);
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
index 0bad229b44a..b1e76779fe4 100644
--- a/gdb/nios2-tdep.c
+++ b/gdb/nios2-tdep.c
@@ -1189,7 +1189,7 @@ static CORE_ADDR
 nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
 			const CORE_ADDR current_pc,
 			struct nios2_unwind_cache *cache,
-			struct frame_info *this_frame)
+			frame_info_ptr this_frame)
 {
   /* Maximum number of possibly-prologue instructions to check.
      Note that this number should not be too large, else we can
@@ -1880,7 +1880,7 @@ nios2_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 /* Implement the unwind_pc gdbarch method.  */
 
 static CORE_ADDR
-nios2_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+nios2_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_byte buf[4];
 
@@ -1893,7 +1893,7 @@ nios2_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
    *THIS_PROLOGUE_CACHE first.  */
 
 static struct nios2_unwind_cache *
-nios2_frame_unwind_cache (struct frame_info *this_frame,
+nios2_frame_unwind_cache (frame_info_ptr this_frame,
 			  void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1920,7 +1920,7 @@ nios2_frame_unwind_cache (struct frame_info *this_frame,
 /* Implement the this_id function for the normal unwinder.  */
 
 static void
-nios2_frame_this_id (struct frame_info *this_frame, void **this_cache,
+nios2_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		     struct frame_id *this_id)
 {
   struct nios2_unwind_cache *cache =
@@ -1936,7 +1936,7 @@ nios2_frame_this_id (struct frame_info *this_frame, void **this_cache,
 /* Implement the prev_register function for the normal unwinder.  */
 
 static struct value *
-nios2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+nios2_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			   int regnum)
 {
   struct nios2_unwind_cache *cache =
@@ -1966,7 +1966,7 @@ nios2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
    for the normal unwinder.  */
 
 static CORE_ADDR
-nios2_frame_base_address (struct frame_info *this_frame, void **this_cache)
+nios2_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct nios2_unwind_cache *info
     = nios2_frame_unwind_cache (this_frame, this_cache);
@@ -2000,7 +2000,7 @@ static const struct frame_base nios2_frame_base =
    in the stub unwinder.  */
 
 static struct trad_frame_cache *
-nios2_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
+nios2_stub_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   CORE_ADDR pc;
   CORE_ADDR start_addr;
@@ -2033,7 +2033,7 @@ nios2_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the this_id function for the stub unwinder.  */
 
 static void
-nios2_stub_frame_this_id (struct frame_info *this_frame, void **this_cache,
+nios2_stub_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			  struct frame_id *this_id)
 {
   struct trad_frame_cache *this_trad_cache
@@ -2045,7 +2045,7 @@ nios2_stub_frame_this_id (struct frame_info *this_frame, void **this_cache,
 /* Implement the prev_register function for the stub unwinder.  */
 
 static struct value *
-nios2_stub_frame_prev_register (struct frame_info *this_frame,
+nios2_stub_frame_prev_register (frame_info_ptr this_frame,
 				void **this_cache, int regnum)
 {
   struct trad_frame_cache *this_trad_cache
@@ -2061,7 +2061,7 @@ nios2_stub_frame_prev_register (struct frame_info *this_frame,
 
 static int
 nios2_stub_frame_sniffer (const struct frame_unwind *self,
-			  struct frame_info *this_frame, void **cache)
+			  frame_info_ptr this_frame, void **cache)
 {
   gdb_byte dummy[4];
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
@@ -2218,7 +2218,7 @@ nios2_software_single_step (struct regcache *regcache)
 /* Implement the get_longjump_target gdbarch method.  */
 
 static int
-nios2_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+nios2_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   nios2_gdbarch_tdep *tdep = gdbarch_tdep<nios2_gdbarch_tdep> (gdbarch);
diff --git a/gdb/nios2-tdep.h b/gdb/nios2-tdep.h
index cbf2599f5c0..e9aa4129eb9 100644
--- a/gdb/nios2-tdep.h
+++ b/gdb/nios2-tdep.h
@@ -73,7 +73,7 @@ struct nios2_gdbarch_tdep : gdbarch_tdep_base
 {
   /* Assumes FRAME is stopped at a syscall (trap) instruction; returns
      the expected next PC.  */
-  CORE_ADDR (*syscall_next_pc) (struct frame_info *frame,
+  CORE_ADDR (*syscall_next_pc) (frame_info_ptr frame,
 				const struct nios2_opcode *op) = nullptr;
 
   /* Returns true if PC points to a kernel helper function.  */
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 4429d4a7d44..1a1d6215475 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -275,7 +275,7 @@ class objc_language : public language_defn
 
   /* See language.h.  */
 
-  CORE_ADDR skip_trampoline (struct frame_info *frame,
+  CORE_ADDR skip_trampoline (frame_info_ptr frame,
 			     CORE_ADDR stop_pc) const override
   {
     struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1458,7 +1458,7 @@ find_implementation (struct gdbarch *gdbarch,
 static int
 resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
 {
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
 
@@ -1480,7 +1480,7 @@ resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
 static int
 resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
 {
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
 
@@ -1502,7 +1502,7 @@ resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
 static int
 resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
 {
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
 
@@ -1530,7 +1530,7 @@ resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
 static int
 resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
 {
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
 
diff --git a/gdb/observable.h b/gdb/observable.h
index 796bf2a43c6..1103c5c98a6 100644
--- a/gdb/observable.h
+++ b/gdb/observable.h
@@ -233,7 +233,7 @@ extern observable<ptid_t /* thread */, CORE_ADDR /* address */>
     inferior_call_post;
 
 /* A register in the inferior has been modified by the gdb user.  */
-extern observable<struct frame_info */* frame */, int /* regnum */>
+extern observable<frame_info_ptr /* frame */, int /* regnum */>
     register_changed;
 
 /* The user-selected inferior, thread and/or frame has changed.  The
diff --git a/gdb/or1k-linux-tdep.c b/gdb/or1k-linux-tdep.c
index 10f76680d8c..750b3d84288 100644
--- a/gdb/or1k-linux-tdep.c
+++ b/gdb/or1k-linux-tdep.c
@@ -62,7 +62,7 @@ or1k_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 /* Signal trampoline support.  */
 
 static void or1k_linux_sigframe_init (const struct tramp_frame *self,
-				       struct frame_info *this_frame,
+				       frame_info_ptr this_frame,
 				       struct trad_frame_cache *this_cache,
 				       CORE_ADDR func);
 
@@ -116,7 +116,7 @@ static const struct tramp_frame or1k_linux_sigframe = {
 
 static void
 or1k_linux_sigframe_init (const struct tramp_frame *self,
-			   struct frame_info *this_frame,
+			   frame_info_ptr this_frame,
 			   struct trad_frame_cache *this_cache,
 			   CORE_ADDR func)
 {
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index 360a7cb36c1..5f55c4e007e 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -379,7 +379,7 @@ or1k_delay_slot_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 static int
 or1k_single_step_through_delay (struct gdbarch *gdbarch,
-				struct frame_info *this_frame)
+				frame_info_ptr this_frame)
 {
   ULONGEST val;
   CORE_ADDR ppc;
@@ -559,7 +559,7 @@ or1k_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 /* Implement the unwind_pc gdbarch method.  */
 
 static CORE_ADDR
-or1k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+or1k_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   CORE_ADDR pc;
 
@@ -579,7 +579,7 @@ or1k_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Implement the unwind_sp gdbarch method.  */
 
 static CORE_ADDR
-or1k_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+or1k_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   CORE_ADDR sp;
 
@@ -890,7 +890,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    Reportedly, this is only valid for frames less than 0x7fff in size.  */
 
 static struct trad_frame_cache *
-or1k_frame_cache (struct frame_info *this_frame, void **prologue_cache)
+or1k_frame_cache (frame_info_ptr this_frame, void **prologue_cache)
 {
   struct gdbarch *gdbarch;
   struct trad_frame_cache *info;
@@ -1103,7 +1103,7 @@ or1k_frame_cache (struct frame_info *this_frame, void **prologue_cache)
 /* Implement the this_id function for the stub unwinder.  */
 
 static void
-or1k_frame_this_id (struct frame_info *this_frame,
+or1k_frame_this_id (frame_info_ptr this_frame,
 		    void **prologue_cache, struct frame_id *this_id)
 {
   struct trad_frame_cache *info = or1k_frame_cache (this_frame,
@@ -1115,7 +1115,7 @@ or1k_frame_this_id (struct frame_info *this_frame,
 /* Implement the prev_register function for the stub unwinder.  */
 
 static struct value *
-or1k_frame_prev_register (struct frame_info *this_frame,
+or1k_frame_prev_register (frame_info_ptr this_frame,
 			  void **prologue_cache, int regnum)
 {
   struct trad_frame_cache *info = or1k_frame_cache (this_frame,
diff --git a/gdb/ppc-fbsd-tdep.c b/gdb/ppc-fbsd-tdep.c
index f5b482921a7..497d82810a7 100644
--- a/gdb/ppc-fbsd-tdep.c
+++ b/gdb/ppc-fbsd-tdep.c
@@ -150,7 +150,7 @@ static const int ppcfbsd_sigreturn_offset[] = {
 
 static int
 ppcfbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -197,7 +197,7 @@ ppcfbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
 }
 
 static struct trad_frame_cache *
-ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+ppcfbsd_sigtramp_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
@@ -243,7 +243,7 @@ ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-ppcfbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ppcfbsd_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				void **this_cache, struct frame_id *this_id)
 {
   struct trad_frame_cache *cache =
@@ -253,7 +253,7 @@ ppcfbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-ppcfbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ppcfbsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				      void **this_cache, int regnum)
 {
   struct trad_frame_cache *cache =
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index beef4bd393c..bbb3e6fd1a6 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -328,7 +328,7 @@ powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
    stub sequence.  */
 
 static CORE_ADDR
-ppc_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+ppc_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   unsigned int insnbuf[POWERPC32_PLT_CHECK_LEN];
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1159,7 +1159,7 @@ ppc_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 }
 
 static void
-ppc_linux_sigtramp_cache (struct frame_info *this_frame,
+ppc_linux_sigtramp_cache (frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func, LONGEST offset,
 			  int bias)
@@ -1231,7 +1231,7 @@ ppc_linux_sigtramp_cache (struct frame_info *this_frame,
 
 static void
 ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
-				  struct frame_info *this_frame,
+				  frame_info_ptr this_frame,
 				  struct trad_frame_cache *this_cache,
 				  CORE_ADDR func)
 {
@@ -1243,7 +1243,7 @@ ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
 
 static void
 ppc64_linux_sigaction_cache_init (const struct tramp_frame *self,
-				  struct frame_info *this_frame,
+				  frame_info_ptr this_frame,
 				  struct trad_frame_cache *this_cache,
 				  CORE_ADDR func)
 {
@@ -1255,7 +1255,7 @@ ppc64_linux_sigaction_cache_init (const struct tramp_frame *self,
 
 static void
 ppc32_linux_sighandler_cache_init (const struct tramp_frame *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   struct trad_frame_cache *this_cache,
 				   CORE_ADDR func)
 {
@@ -1267,7 +1267,7 @@ ppc32_linux_sighandler_cache_init (const struct tramp_frame *self,
 
 static void
 ppc64_linux_sighandler_cache_init (const struct tramp_frame *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   struct trad_frame_cache *this_cache,
 				   CORE_ADDR func)
 {
diff --git a/gdb/ppc-netbsd-tdep.c b/gdb/ppc-netbsd-tdep.c
index d8dc494979a..e9fb660fee2 100644
--- a/gdb/ppc-netbsd-tdep.c
+++ b/gdb/ppc-netbsd-tdep.c
@@ -97,7 +97,7 @@ extern const struct tramp_frame ppcnbsd2_sigtramp;
 
 static void
 ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
diff --git a/gdb/ppc-obsd-tdep.c b/gdb/ppc-obsd-tdep.c
index 90fb5e3a399..7436532d846 100644
--- a/gdb/ppc-obsd-tdep.c
+++ b/gdb/ppc-obsd-tdep.c
@@ -117,7 +117,7 @@ static const int ppcobsd_sigreturn_offset[] = {
 
 static int
 ppcobsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -158,7 +158,7 @@ ppcobsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
 }
 
 static struct trad_frame_cache *
-ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+ppcobsd_sigtramp_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
@@ -212,7 +212,7 @@ ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-ppcobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+ppcobsd_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				void **this_cache, struct frame_id *this_id)
 {
   struct trad_frame_cache *cache =
@@ -222,7 +222,7 @@ ppcobsd_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-ppcobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ppcobsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				      void **this_cache, int regnum)
 {
   struct trad_frame_cache *cache =
diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h
index 44f63b145c6..34b250849b9 100644
--- a/gdb/ppc-tdep.h
+++ b/gdb/ppc-tdep.h
@@ -23,7 +23,7 @@
 #include "gdbarch.h"
 
 struct gdbarch;
-struct frame_info;
+class frame_info_ptr;
 struct value;
 struct regcache;
 struct type;
@@ -420,7 +420,7 @@ struct ppc_insn_pattern
   int optional;                 /* If non-zero, this insn may be absent.  */
 };
 
-extern int ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
+extern int ppc_insns_match_pattern (frame_info_ptr frame, CORE_ADDR pc,
 				    const struct ppc_insn_pattern *pattern,
 				    unsigned int *insns);
 extern CORE_ADDR ppc_insn_d_field (unsigned int insn);
diff --git a/gdb/ppc64-tdep.c b/gdb/ppc64-tdep.c
index 0437ca7e3f3..b3ae2329e7b 100644
--- a/gdb/ppc64-tdep.c
+++ b/gdb/ppc64-tdep.c
@@ -85,7 +85,7 @@
    Return the function's entry point.  */
 
 static CORE_ADDR
-ppc64_plt_entry_point (struct frame_info *frame, CORE_ADDR plt_off)
+ppc64_plt_entry_point (frame_info_ptr frame, CORE_ADDR plt_off)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -108,7 +108,7 @@ ppc64_plt_entry_point (struct frame_info *frame, CORE_ADDR plt_off)
 }
 
 static CORE_ADDR
-ppc64_plt_pcrel_entry_point (struct frame_info *frame, CORE_ADDR plt_off,
+ppc64_plt_pcrel_entry_point (frame_info_ptr frame, CORE_ADDR plt_off,
 			     CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -546,7 +546,7 @@ static const struct ppc_insn_pattern ppc64_standard_linkage12[] =
    dynamic linker lazy symbol resolution stubs.)  */
 
 static CORE_ADDR
-ppc64_standard_linkage1_target (struct frame_info *frame, unsigned int *insn)
+ppc64_standard_linkage1_target (frame_info_ptr frame, unsigned int *insn)
 {
   CORE_ADDR plt_off = ((ppc_insn_d_field (insn[0]) << 16)
 		       + ppc_insn_ds_field (insn[2]));
@@ -555,7 +555,7 @@ ppc64_standard_linkage1_target (struct frame_info *frame, unsigned int *insn)
 }
 
 static CORE_ADDR
-ppc64_standard_linkage2_target (struct frame_info *frame, unsigned int *insn)
+ppc64_standard_linkage2_target (frame_info_ptr frame, unsigned int *insn)
 {
   CORE_ADDR plt_off = ((ppc_insn_d_field (insn[1]) << 16)
 		       + ppc_insn_ds_field (insn[3]));
@@ -564,7 +564,7 @@ ppc64_standard_linkage2_target (struct frame_info *frame, unsigned int *insn)
 }
 
 static CORE_ADDR
-ppc64_standard_linkage3_target (struct frame_info *frame, unsigned int *insn)
+ppc64_standard_linkage3_target (frame_info_ptr frame, unsigned int *insn)
 {
   CORE_ADDR plt_off = ppc_insn_ds_field (insn[1]);
 
@@ -572,7 +572,7 @@ ppc64_standard_linkage3_target (struct frame_info *frame, unsigned int *insn)
 }
 
 static CORE_ADDR
-ppc64_standard_linkage4_target (struct frame_info *frame, unsigned int *insn)
+ppc64_standard_linkage4_target (frame_info_ptr frame, unsigned int *insn)
 {
   CORE_ADDR plt_off = ((ppc_insn_d_field (insn[1]) << 16)
 		       + ppc_insn_ds_field (insn[2]));
@@ -581,7 +581,7 @@ ppc64_standard_linkage4_target (struct frame_info *frame, unsigned int *insn)
 }
 
 static CORE_ADDR
-ppc64_pcrel_linkage1_target (struct frame_info *frame, unsigned int *insn,
+ppc64_pcrel_linkage1_target (frame_info_ptr frame, unsigned int *insn,
 			     CORE_ADDR pc)
 {
   /* insn[0] is for the std instruction.  */
@@ -591,7 +591,7 @@ ppc64_pcrel_linkage1_target (struct frame_info *frame, unsigned int *insn,
 }
 
 static CORE_ADDR
-ppc64_pcrel_linkage2_target (struct frame_info *frame, unsigned int *insn,
+ppc64_pcrel_linkage2_target (frame_info_ptr frame, unsigned int *insn,
 			     CORE_ADDR pc)
 {
   CORE_ADDR plt_off;
@@ -611,7 +611,7 @@ ppc64_pcrel_linkage2_target (struct frame_info *frame, unsigned int *insn,
    check whether we are in the middle of a PLT stub.  */
 
 static CORE_ADDR
-ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc)
+ppc64_skip_trampoline_code_1 (frame_info_ptr frame, CORE_ADDR pc)
 {
 #define MAX(a,b) ((a) > (b) ? (a) : (b))
   unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1),
@@ -707,7 +707,7 @@ ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc)
    ppc_elfv2_skip_entrypoint.  */
 
 CORE_ADDR
-ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+ppc64_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
diff --git a/gdb/ppc64-tdep.h b/gdb/ppc64-tdep.h
index 943d5fbc194..f519fe63463 100644
--- a/gdb/ppc64-tdep.h
+++ b/gdb/ppc64-tdep.h
@@ -21,10 +21,10 @@
 #define PPC64_TDEP_H
 
 struct gdbarch;
-struct frame_info;
+class frame_info_ptr;
 struct target_ops;
 
-extern CORE_ADDR ppc64_skip_trampoline_code (struct frame_info *frame,
+extern CORE_ADDR ppc64_skip_trampoline_code (frame_info_ptr frame,
 					     CORE_ADDR pc);
 
 extern CORE_ADDR ppc64_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index ce3dd3882d9..66b43b4c8e0 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -749,7 +749,7 @@ pc_prefix (CORE_ADDR addr)
 {
   if (has_stack_frames ())
     {
-      struct frame_info *frame;
+      frame_info_ptr frame;
       CORE_ADDR pc;
 
       frame = get_selected_frame (NULL);
@@ -2380,7 +2380,7 @@ clear_dangling_display_expressions (struct objfile *objfile)
 
 void
 print_variable_and_value (const char *name, struct symbol *var,
-			  struct frame_info *frame,
+			  frame_info_ptr frame,
 			  struct ui_file *stream, int indent)
 {
 
diff --git a/gdb/probe.c b/gdb/probe.c
index ad7af77f722..ec8845219fa 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -683,7 +683,7 @@ disable_probes_command (const char *arg, int from_tty)
 /* See comments in probe.h.  */
 
 struct value *
-probe_safe_evaluate_at_pc (struct frame_info *frame, unsigned n)
+probe_safe_evaluate_at_pc (frame_info_ptr frame, unsigned n)
 {
   struct bound_probe probe;
   unsigned n_args;
@@ -801,7 +801,7 @@ static struct value *
 compute_probe_arg (struct gdbarch *arch, struct internalvar *ivar,
 		   void *data)
 {
-  struct frame_info *frame = get_selected_frame (_("No frame selected"));
+  frame_info_ptr frame = get_selected_frame (_("No frame selected"));
   CORE_ADDR pc = get_frame_pc (frame);
   int sel = (int) (uintptr_t) data;
   struct bound_probe pc_probe;
diff --git a/gdb/probe.h b/gdb/probe.h
index fe933154663..598f43a238e 100644
--- a/gdb/probe.h
+++ b/gdb/probe.h
@@ -143,7 +143,7 @@ class probe
      corresponding to it.  The argument number is represented N.
      This function can throw an exception.  */
   virtual struct value *evaluate_argument (unsigned n,
-					   struct frame_info *frame) = 0;
+					   frame_info_ptr frame) = 0;
 
   /* Compile the Nth argument of the probe to an agent expression.
      The argument number is represented by N.  */
@@ -301,7 +301,7 @@ extern struct cmd_list_element **info_probes_cmdlist_get (void);
    probe at that location, or if the probe does not have enough arguments,
    this returns NULL.  */
 
-extern struct value *probe_safe_evaluate_at_pc (struct frame_info *frame,
+extern struct value *probe_safe_evaluate_at_pc (frame_info_ptr frame,
 						unsigned n);
 
 #endif /* !defined (PROBE_H) */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index bc1411ecb3f..c0679a35f92 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1605,7 +1605,7 @@ struct btrace_frame_cache
   struct thread_info *tp;
 
   /* The frame info.  */
-  struct frame_info *frame;
+  frame_info *frame;
 
   /* The branch trace function segment.  */
   const struct btrace_function *bfun;
@@ -1642,13 +1642,13 @@ bfcache_eq (const void *arg1, const void *arg2)
 /* Create a new btrace frame cache.  */
 
 static struct btrace_frame_cache *
-bfcache_new (struct frame_info *frame)
+bfcache_new (frame_info_ptr frame)
 {
   struct btrace_frame_cache *cache;
   void **slot;
 
   cache = FRAME_OBSTACK_ZALLOC (struct btrace_frame_cache);
-  cache->frame = frame;
+  cache->frame = frame.get ();
 
   slot = htab_find_slot (bfcache, cache, INSERT);
   gdb_assert (*slot == NULL);
@@ -1660,13 +1660,13 @@ bfcache_new (struct frame_info *frame)
 /* Extract the branch trace function from a branch trace frame.  */
 
 static const struct btrace_function *
-btrace_get_frame_function (struct frame_info *frame)
+btrace_get_frame_function (frame_info_ptr frame)
 {
   const struct btrace_frame_cache *cache;
   struct btrace_frame_cache pattern;
   void **slot;
 
-  pattern.frame = frame;
+  pattern.frame = frame.get ();
 
   slot = htab_find_slot (bfcache, &pattern, NO_INSERT);
   if (slot == NULL)
@@ -1679,7 +1679,7 @@ btrace_get_frame_function (struct frame_info *frame)
 /* Implement stop_reason method for record_btrace_frame_unwind.  */
 
 static enum unwind_stop_reason
-record_btrace_frame_unwind_stop_reason (struct frame_info *this_frame,
+record_btrace_frame_unwind_stop_reason (frame_info_ptr this_frame,
 					void **this_cache)
 {
   const struct btrace_frame_cache *cache;
@@ -1698,7 +1698,7 @@ record_btrace_frame_unwind_stop_reason (struct frame_info *this_frame,
 /* Implement this_id method for record_btrace_frame_unwind.  */
 
 static void
-record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
+record_btrace_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			     struct frame_id *this_id)
 {
   const struct btrace_frame_cache *cache;
@@ -1728,7 +1728,7 @@ record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
 /* Implement prev_register method for record_btrace_frame_unwind.  */
 
 static struct value *
-record_btrace_frame_prev_register (struct frame_info *this_frame,
+record_btrace_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache,
 				   int regnum)
 {
@@ -1774,13 +1774,13 @@ record_btrace_frame_prev_register (struct frame_info *this_frame,
 
 static int
 record_btrace_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_cache)
 {
   const struct btrace_function *bfun;
   struct btrace_frame_cache *cache;
   struct thread_info *tp;
-  struct frame_info *next;
+  frame_info_ptr next;
 
   /* THIS_FRAME does not contain a reference to its thread.  */
   tp = inferior_thread ();
@@ -1829,13 +1829,13 @@ record_btrace_frame_sniffer (const struct frame_unwind *self,
 
 static int
 record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
-				      struct frame_info *this_frame,
+				      frame_info_ptr this_frame,
 				      void **this_cache)
 {
   const struct btrace_function *bfun, *callee;
   struct btrace_frame_cache *cache;
   struct btrace_call_iterator it;
-  struct frame_info *next;
+  frame_info_ptr next;
   struct thread_info *tinfo;
 
   next = get_next_frame (this_frame);
@@ -1868,7 +1868,7 @@ record_btrace_tailcall_frame_sniffer (const struct frame_unwind *self,
 }
 
 static void
-record_btrace_frame_dealloc_cache (struct frame_info *self, void *this_cache)
+record_btrace_frame_dealloc_cache (frame_info *self, void *this_cache)
 {
   struct btrace_frame_cache *cache;
   void **slot;
diff --git a/gdb/riscv-fbsd-tdep.c b/gdb/riscv-fbsd-tdep.c
index 7efd833a94b..5b66a9c582e 100644
--- a/gdb/riscv-fbsd-tdep.c
+++ b/gdb/riscv-fbsd-tdep.c
@@ -108,7 +108,7 @@ riscv_fbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
 
 static void
 riscv_fbsd_sigframe_init (const struct tramp_frame *self,
-			  struct frame_info *this_frame,
+			  frame_info_ptr this_frame,
 			  struct trad_frame_cache *this_cache,
 			  CORE_ADDR func)
 {
diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c
index 5bda2e5c824..e736e3b9b26 100644
--- a/gdb/riscv-linux-tdep.c
+++ b/gdb/riscv-linux-tdep.c
@@ -86,7 +86,7 @@ riscv_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
 /* Signal trampoline support.  */
 
 static void riscv_linux_sigframe_init (const struct tramp_frame *self,
-				       struct frame_info *this_frame,
+				       frame_info_ptr this_frame,
 				       struct trad_frame_cache *this_cache,
 				       CORE_ADDR func);
 
@@ -125,7 +125,7 @@ static const struct tramp_frame riscv_linux_sigframe = {
 
 static void
 riscv_linux_sigframe_init (const struct tramp_frame *self,
-			   struct frame_info *this_frame,
+			   frame_info_ptr this_frame,
 			   struct trad_frame_cache *this_cache,
 			   CORE_ADDR func)
 {
@@ -163,7 +163,7 @@ riscv_linux_sigframe_init (const struct tramp_frame *self,
    instruction to be executed.  */
 
 static CORE_ADDR
-riscv_linux_syscall_next_pc (struct frame_info *frame)
+riscv_linux_syscall_next_pc (frame_info_ptr frame)
 {
   const CORE_ADDR pc = get_frame_pc (frame);
   const ULONGEST a7 = get_frame_register_unsigned (frame, RISCV_A7_REGNUM);
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 2d41be96b20..7ce54ac2bef 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -134,7 +134,7 @@ static const reggroup *csr_reggroup = nullptr;
 /* Callback function for user_reg_add.  */
 
 static struct value *
-value_of_riscv_user_reg (struct frame_info *frame, const void *baton)
+value_of_riscv_user_reg (frame_info_ptr frame, const void *baton)
 {
   const int *reg_p = (const int *) baton;
   return value_of_register (*reg_p, frame);
@@ -1028,7 +1028,7 @@ riscv_register_type (struct gdbarch *gdbarch, int regnum)
 static void
 riscv_print_one_register_info (struct gdbarch *gdbarch,
 			       struct ui_file *file,
-			       struct frame_info *frame,
+			       frame_info_ptr frame,
 			       int regnum)
 {
   const char *name = gdbarch_register_name (gdbarch, regnum);
@@ -1356,7 +1356,7 @@ riscv_register_reggroup_p (struct gdbarch  *gdbarch, int regnum,
 static void
 riscv_print_registers_info (struct gdbarch *gdbarch,
 			    struct ui_file *file,
-			    struct frame_info *frame,
+			    frame_info_ptr frame,
 			    int regnum, int print_all)
 {
   if (regnum != -1)
@@ -3320,7 +3320,7 @@ riscv_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
    unwinder.  */
 
 static struct riscv_unwind_cache *
-riscv_frame_cache (struct frame_info *this_frame, void **this_cache)
+riscv_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   CORE_ADDR pc, start_addr;
   struct riscv_unwind_cache *cache;
@@ -3381,7 +3381,7 @@ riscv_frame_cache (struct frame_info *this_frame, void **this_cache)
 /* Implement the this_id callback for RiscV frame unwinder.  */
 
 static void
-riscv_frame_this_id (struct frame_info *this_frame,
+riscv_frame_this_id (frame_info_ptr this_frame,
 		     void **prologue_cache,
 		     struct frame_id *this_id)
 {
@@ -3402,7 +3402,7 @@ riscv_frame_this_id (struct frame_info *this_frame,
 /* Implement the prev_register callback for RiscV frame unwinder.  */
 
 static struct value *
-riscv_frame_prev_register (struct frame_info *this_frame,
+riscv_frame_prev_register (frame_info_ptr this_frame,
 			   void **prologue_cache,
 			   int regnum)
 {
diff --git a/gdb/riscv-tdep.h b/gdb/riscv-tdep.h
index 826a002ef92..95f1ea68c68 100644
--- a/gdb/riscv-tdep.h
+++ b/gdb/riscv-tdep.h
@@ -106,7 +106,7 @@ struct riscv_gdbarch_tdep : gdbarch_tdep_base
 
   /* Return the expected next PC assuming FRAME is stopped at a syscall
      instruction.  */
-  CORE_ADDR (*syscall_next_pc) (struct frame_info *frame) = nullptr;
+  CORE_ADDR (*syscall_next_pc) (frame_info_ptr frame) = nullptr;
 };
 
 
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index be668bfa6fe..0b27a311203 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -1078,7 +1078,7 @@ rl78_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Implement the "unwind_pc" gdbarch method.  */
 
 static CORE_ADDR
-rl78_unwind_pc (struct gdbarch *arch, struct frame_info *next_frame)
+rl78_unwind_pc (struct gdbarch *arch, frame_info_ptr next_frame)
 {
   return rl78_addr_bits_remove
 	   (arch, frame_unwind_register_unsigned (next_frame,
@@ -1091,7 +1091,7 @@ rl78_unwind_pc (struct gdbarch *arch, struct frame_info *next_frame)
    return that struct as the value of this function.  */
 
 static struct rl78_prologue *
-rl78_analyze_frame_prologue (struct frame_info *this_frame,
+rl78_analyze_frame_prologue (frame_info_ptr this_frame,
 			   void **this_prologue_cache)
 {
   if (!*this_prologue_cache)
@@ -1118,7 +1118,7 @@ rl78_analyze_frame_prologue (struct frame_info *this_frame,
 /* Given a frame and a prologue cache, return this frame's base.  */
 
 static CORE_ADDR
-rl78_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
+rl78_frame_base (frame_info_ptr this_frame, void **this_prologue_cache)
 {
   struct rl78_prologue *p
     = rl78_analyze_frame_prologue (this_frame, this_prologue_cache);
@@ -1130,7 +1130,7 @@ rl78_frame_base (struct frame_info *this_frame, void **this_prologue_cache)
 /* Implement the "frame_this_id" method for unwinding frames.  */
 
 static void
-rl78_this_id (struct frame_info *this_frame,
+rl78_this_id (frame_info_ptr this_frame,
 	      void **this_prologue_cache, struct frame_id *this_id)
 {
   *this_id = frame_id_build (rl78_frame_base (this_frame,
@@ -1141,7 +1141,7 @@ rl78_this_id (struct frame_info *this_frame,
 /* Implement the "frame_prev_register" method for unwinding frames.  */
 
 static struct value *
-rl78_prev_register (struct frame_info *this_frame,
+rl78_prev_register (frame_info_ptr this_frame,
 		    void **this_prologue_cache, int regnum)
 {
   struct rl78_prologue *p
@@ -1315,7 +1315,7 @@ rl78_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
 /* Implement the "dummy_id" gdbarch method.  */
 
 static struct frame_id
-rl78_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+rl78_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   return
     frame_id_build (rl78_make_data_address
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index 41384993c26..d322e83263f 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -69,7 +69,7 @@
 #define AIX_TEXT_SEGMENT_BASE 0x10000000
 
 static struct trad_frame_cache *
-aix_sighandle_frame_cache (struct frame_info *this_frame,
+aix_sighandle_frame_cache (frame_info_ptr this_frame,
 			   void **this_cache)
 {
   LONGEST backchain;
@@ -125,7 +125,7 @@ aix_sighandle_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-aix_sighandle_frame_this_id (struct frame_info *this_frame,
+aix_sighandle_frame_this_id (frame_info_ptr this_frame,
 			     void **this_prologue_cache,
 			     struct frame_id *this_id)
 {
@@ -135,7 +135,7 @@ aix_sighandle_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-aix_sighandle_frame_prev_register (struct frame_info *this_frame,
+aix_sighandle_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_prologue_cache, int regnum)
 {
   struct trad_frame_cache *this_trad_cache
@@ -145,7 +145,7 @@ aix_sighandle_frame_prev_register (struct frame_info *this_frame,
 
 static int
 aix_sighandle_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -744,7 +744,7 @@ branch_dest (struct regcache *regcache, int opcode, int instr,
 	     execution will return to the saved PC in the frame.  */
 	  if (dest < AIX_TEXT_SEGMENT_BASE)
 	    {
-	      struct frame_info *frame = get_current_frame ();
+	      frame_info_ptr frame = get_current_frame ();
 
 	      dest = read_memory_unsigned_integer
 		(get_frame_base (frame) + SIG_FRAME_PC_OFFSET,
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index cccc8872da9..decd5628899 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -743,7 +743,7 @@ insn_changes_sp_or_jumps (unsigned long insn)
 	   limit for the size of an epilogue.  */
 
 static int
-rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm,
+rs6000_in_function_epilogue_frame_p (frame_info_ptr curfrm,
 				     struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
@@ -816,7 +816,7 @@ rs6000_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 /* Get the ith function argument for the current function.  */
 static CORE_ADDR
-rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, 
+rs6000_fetch_pointer_argument (frame_info_ptr frame, int argi, 
 			       struct type *type)
 {
   return get_frame_register_unsigned (frame, 3 + argi);
@@ -2307,7 +2307,7 @@ rs6000_in_solib_return_trampoline (struct gdbarch *gdbarch,
    code that should be skipped.  */
 
 static CORE_ADDR
-rs6000_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+rs6000_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
@@ -2670,7 +2670,7 @@ rs6000_convert_register_p (struct gdbarch *gdbarch, int regnum,
 }
 
 static int
-rs6000_register_to_value (struct frame_info *frame,
+rs6000_register_to_value (frame_info_ptr frame,
 			  int regnum,
 			  struct type *type,
 			  gdb_byte *to,
@@ -2695,7 +2695,7 @@ rs6000_register_to_value (struct frame_info *frame,
 }
 
 static void
-rs6000_value_to_register (struct frame_info *frame,
+rs6000_value_to_register (frame_info_ptr frame,
 			  int regnum,
 			  struct type *type,
 			  const gdb_byte *from)
@@ -3557,7 +3557,7 @@ struct rs6000_frame_cache
 };
 
 static struct rs6000_frame_cache *
-rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
+rs6000_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct rs6000_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -3750,7 +3750,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache,
+rs6000_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		      struct frame_id *this_id)
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
@@ -3770,7 +3770,7 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-rs6000_frame_prev_register (struct frame_info *this_frame,
+rs6000_frame_prev_register (frame_info_ptr this_frame,
 			    void **this_cache, int regnum)
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
@@ -3793,7 +3793,7 @@ static const struct frame_unwind rs6000_frame_unwind =
    SP is restored and prev-PC is stored in LR.  */
 
 static struct rs6000_frame_cache *
-rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+rs6000_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct rs6000_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -3833,7 +3833,7 @@ rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
    Return the frame ID of an epilogue frame.  */
 
 static void
-rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
+rs6000_epilogue_frame_this_id (frame_info_ptr this_frame,
 			       void **this_cache, struct frame_id *this_id)
 {
   CORE_ADDR pc;
@@ -3851,7 +3851,7 @@ rs6000_epilogue_frame_this_id (struct frame_info *this_frame,
    Return the register value of REGNUM in previous frame.  */
 
 static struct value *
-rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
+rs6000_epilogue_frame_prev_register (frame_info_ptr this_frame,
 				     void **this_cache, int regnum)
 {
   struct rs6000_frame_cache *info =
@@ -3864,7 +3864,7 @@ rs6000_epilogue_frame_prev_register (struct frame_info *this_frame,
 
 static int
 rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
-			       struct frame_info *this_frame,
+			       frame_info_ptr this_frame,
 			       void **this_prologue_cache)
 {
   if (frame_relative_level (this_frame) == 0)
@@ -3890,7 +3890,7 @@ static const struct frame_unwind rs6000_epilogue_frame_unwind =
 \f
 
 static CORE_ADDR
-rs6000_frame_base_address (struct frame_info *this_frame, void **this_cache)
+rs6000_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame,
 							this_cache);
@@ -3905,7 +3905,7 @@ static const struct frame_base rs6000_frame_base = {
 };
 
 static const struct frame_base *
-rs6000_frame_base_sniffer (struct frame_info *this_frame)
+rs6000_frame_base_sniffer (frame_info_ptr this_frame)
 {
   return &rs6000_frame_base;
 }
@@ -3916,7 +3916,7 @@ rs6000_frame_base_sniffer (struct frame_info *this_frame)
 static void
 ppc_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			    struct dwarf2_frame_state_reg *reg,
-			    struct frame_info *this_frame)
+			    frame_info_ptr this_frame)
 {
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
 
@@ -8510,7 +8510,7 @@ show_powerpc_exact_watchpoints (struct ui_file *file, int from_tty,
 /* Read a PPC instruction from memory.  */
 
 static unsigned int
-read_insn (struct frame_info *frame, CORE_ADDR pc)
+read_insn (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -8532,7 +8532,7 @@ read_insn (struct frame_info *frame, CORE_ADDR pc)
    necessarily the i'th instruction in memory.  */
 
 int
-ppc_insns_match_pattern (struct frame_info *frame, CORE_ADDR pc,
+ppc_insns_match_pattern (frame_info_ptr frame, CORE_ADDR pc,
 			 const struct ppc_insn_pattern *pattern,
 			 unsigned int *insns)
 {
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index 989d90096bd..7367325c8d3 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -382,7 +382,7 @@ rx_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
    return that struct as the value of this function.  */
 
 static struct rx_prologue *
-rx_analyze_frame_prologue (struct frame_info *this_frame,
+rx_analyze_frame_prologue (frame_info_ptr this_frame,
 			   enum rx_frame_type frame_type,
 			   void **this_prologue_cache)
 {
@@ -411,7 +411,7 @@ rx_analyze_frame_prologue (struct frame_info *this_frame,
    instruction.  */
 
 static enum rx_frame_type
-rx_frame_type (struct frame_info *this_frame, void **this_cache)
+rx_frame_type (frame_info_ptr this_frame, void **this_cache)
 {
   const char *name;
   CORE_ADDR pc, start_pc, lim_pc;
@@ -465,7 +465,7 @@ rx_frame_type (struct frame_info *this_frame, void **this_cache)
    base.  */
 
 static CORE_ADDR
-rx_frame_base (struct frame_info *this_frame, void **this_cache)
+rx_frame_base (frame_info_ptr this_frame, void **this_cache)
 {
   enum rx_frame_type frame_type = rx_frame_type (this_frame, this_cache);
   struct rx_prologue *p
@@ -492,7 +492,7 @@ rx_frame_base (struct frame_info *this_frame, void **this_cache)
 /* Implement the "frame_this_id" method for unwinding frames.  */
 
 static void
-rx_frame_this_id (struct frame_info *this_frame, void **this_cache,
+rx_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		  struct frame_id *this_id)
 {
   *this_id = frame_id_build (rx_frame_base (this_frame, this_cache),
@@ -502,7 +502,7 @@ rx_frame_this_id (struct frame_info *this_frame, void **this_cache,
 /* Implement the "frame_prev_register" method for unwinding frames.  */
 
 static struct value *
-rx_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+rx_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			int regnum)
 {
   enum rx_frame_type frame_type = rx_frame_type (this_frame, this_cache);
@@ -576,7 +576,7 @@ exception_frame_p (enum rx_frame_type frame_type)
 
 static int
 rx_frame_sniffer_common (const struct frame_unwind *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 void **this_cache,
 			 int (*sniff_p)(enum rx_frame_type) )
 {
@@ -609,7 +609,7 @@ rx_frame_sniffer_common (const struct frame_unwind *self,
 
 static int
 rx_frame_sniffer (const struct frame_unwind *self,
-		  struct frame_info *this_frame,
+		  frame_info_ptr this_frame,
 		  void **this_cache)
 {
   return rx_frame_sniffer_common (self, this_frame, this_cache,
@@ -620,7 +620,7 @@ rx_frame_sniffer (const struct frame_unwind *self,
 
 static int
 rx_exception_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_cache)
 {
   return rx_frame_sniffer_common (self, this_frame, this_cache,
diff --git a/gdb/tic6x-linux-tdep.c b/gdb/tic6x-linux-tdep.c
index b2422d1ccc0..0452da1eb21 100644
--- a/gdb/tic6x-linux-tdep.c
+++ b/gdb/tic6x-linux-tdep.c
@@ -78,7 +78,7 @@ tic6x_register_sigcontext_offset (unsigned int regnum, struct gdbarch *gdbarch)
 
 static void
 tic6x_linux_rt_sigreturn_init (const struct tramp_frame *self,
-			       struct frame_info *this_frame,
+			       frame_info_ptr this_frame,
 			       struct trad_frame_cache *this_cache,
 			       CORE_ADDR func)
 {
@@ -148,7 +148,7 @@ static struct tramp_frame tic6x_linux_rt_sigreturn_tramp_frame =
    instruction to be executed.  */
 
 static CORE_ADDR
-tic6x_linux_syscall_next_pc (struct frame_info *frame)
+tic6x_linux_syscall_next_pc (frame_info_ptr frame)
 {
   ULONGEST syscall_number = get_frame_register_unsigned (frame,
 							 TIC6X_B0_REGNUM);
diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c
index b7efcf18576..b6798f2b0a1 100644
--- a/gdb/tic6x-tdep.c
+++ b/gdb/tic6x-tdep.c
@@ -145,7 +145,7 @@ static CORE_ADDR
 tic6x_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
 			const CORE_ADDR current_pc,
 			struct tic6x_unwind_cache *cache,
-			struct frame_info *this_frame)
+			frame_info_ptr this_frame)
 {
   unsigned int src_reg, base_reg, dst_reg;
   int i;
@@ -343,7 +343,7 @@ tic6x_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
 static void
 tic6x_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			     struct dwarf2_frame_state_reg *reg,
-			     struct frame_info *this_frame)
+			     frame_info_ptr this_frame)
 {
   /* Mark the PC as the destination for the return address.  */
   if (regnum == gdbarch_pc_regnum (gdbarch))
@@ -368,7 +368,7 @@ tic6x_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 /* This is the implementation of gdbarch method unwind_pc.  */
 
 static CORE_ADDR
-tic6x_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+tic6x_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_byte buf[8];
 
@@ -379,7 +379,7 @@ tic6x_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Frame base handling.  */
 
 static struct tic6x_unwind_cache*
-tic6x_frame_unwind_cache (struct frame_info *this_frame,
+tic6x_frame_unwind_cache (frame_info_ptr this_frame,
 			  void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -407,7 +407,7 @@ tic6x_frame_unwind_cache (struct frame_info *this_frame,
 }
 
 static void
-tic6x_frame_this_id (struct frame_info *this_frame, void **this_cache,
+tic6x_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		     struct frame_id *this_id)
 {
   struct tic6x_unwind_cache *cache =
@@ -421,7 +421,7 @@ tic6x_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-tic6x_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+tic6x_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			   int regnum)
 {
   struct tic6x_unwind_cache *cache =
@@ -448,7 +448,7 @@ tic6x_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 }
 
 static CORE_ADDR
-tic6x_frame_base_address (struct frame_info *this_frame, void **this_cache)
+tic6x_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct tic6x_unwind_cache *info
     = tic6x_frame_unwind_cache (this_frame, this_cache);
@@ -476,7 +476,7 @@ static const struct frame_base tic6x_frame_base =
 
 
 static struct tic6x_unwind_cache *
-tic6x_make_stub_cache (struct frame_info *this_frame)
+tic6x_make_stub_cache (frame_info_ptr this_frame)
 {
   struct tic6x_unwind_cache *cache;
 
@@ -492,7 +492,7 @@ tic6x_make_stub_cache (struct frame_info *this_frame)
 }
 
 static void
-tic6x_stub_this_id (struct frame_info *this_frame, void **this_cache,
+tic6x_stub_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct tic6x_unwind_cache *cache;
@@ -506,7 +506,7 @@ tic6x_stub_this_id (struct frame_info *this_frame, void **this_cache,
 
 static int
 tic6x_stub_unwind_sniffer (const struct frame_unwind *self,
-			   struct frame_info *this_frame,
+			   frame_info_ptr this_frame,
 			   void **this_prologue_cache)
 {
   CORE_ADDR addr_in_block;
@@ -1108,7 +1108,7 @@ tic6x_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* This is the implementation of gdbarch method get_longjmp_target.  */
 
 static int
-tic6x_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+tic6x_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/tic6x-tdep.h b/gdb/tic6x-tdep.h
index ebfd6e686fa..d50715e24da 100644
--- a/gdb/tic6x-tdep.h
+++ b/gdb/tic6x-tdep.h
@@ -50,7 +50,7 @@ struct tic6x_gdbarch_tdep : gdbarch_tdep_base
 {
   /* Return the expected next PC if FRAME is stopped at a syscall
      instruction.  */
-  CORE_ADDR (*syscall_next_pc) (struct frame_info *frame) = nullptr;
+  CORE_ADDR (*syscall_next_pc) (frame_info_ptr frame) = nullptr;
 
   const gdb_byte *breakpoint = nullptr; /* Breakpoint instruction.  */
 
diff --git a/gdb/tilegx-linux-tdep.c b/gdb/tilegx-linux-tdep.c
index 0bb2366925a..ef38436801f 100644
--- a/gdb/tilegx-linux-tdep.c
+++ b/gdb/tilegx-linux-tdep.c
@@ -34,7 +34,7 @@
 
 static void
 tilegx_linux_sigframe_init (const struct tramp_frame *self,
-			    struct frame_info *this_frame,
+			    frame_info_ptr this_frame,
 			    struct trad_frame_cache *this_cache,
 			    CORE_ADDR func)
 {
diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c
index 9668aa80b53..c66df75cb54 100644
--- a/gdb/tilegx-tdep.c
+++ b/gdb/tilegx-tdep.c
@@ -366,7 +366,7 @@ static CORE_ADDR
 tilegx_analyze_prologue (struct gdbarch* gdbarch,
 			 CORE_ADDR start_addr, CORE_ADDR end_addr,
 			 struct tilegx_frame_cache *cache,
-			 struct frame_info *next_frame)
+			 frame_info_ptr next_frame)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR next_addr;
@@ -778,7 +778,7 @@ tilegx_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* This is the implementation of gdbarch method get_longjmp_target.  */
 
 static int
-tilegx_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+tilegx_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -837,7 +837,7 @@ typedef BP_MANIPULATION (tilegx_break_insn) tilegx_breakpoint;
 /* Normal frames.  */
 
 static struct tilegx_frame_cache *
-tilegx_frame_cache (struct frame_info *this_frame, void **this_cache)
+tilegx_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct tilegx_frame_cache *cache;
@@ -868,7 +868,7 @@ tilegx_frame_cache (struct frame_info *this_frame, void **this_cache)
 /* Retrieve the value of REGNUM in FRAME.  */
 
 static struct value*
-tilegx_frame_prev_register (struct frame_info *this_frame,
+tilegx_frame_prev_register (frame_info_ptr this_frame,
 			    void **this_cache,
 			    int regnum)
 {
@@ -882,7 +882,7 @@ tilegx_frame_prev_register (struct frame_info *this_frame,
 /* Build frame id.  */
 
 static void
-tilegx_frame_this_id (struct frame_info *this_frame, void **this_cache,
+tilegx_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		      struct frame_id *this_id)
 {
   struct tilegx_frame_cache *info =
@@ -896,7 +896,7 @@ tilegx_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static CORE_ADDR
-tilegx_frame_base_address (struct frame_info *this_frame, void **this_cache)
+tilegx_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct tilegx_frame_cache *cache =
     tilegx_frame_cache (this_frame, this_cache);
diff --git a/gdb/top.c b/gdb/top.c
index 453fa236db1..c54b6cbda0c 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -498,7 +498,7 @@ void
 check_frame_language_change (void)
 {
   static int warned = 0;
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   /* First make sure that a new frame has been selected, in case the
      command or the hooks changed the program state.  */
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 98f1563a89a..76c077a018a 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -206,7 +206,7 @@ set_tracepoint_num (int num)
    the traceframe context (line, function, file).  */
 
 static void
-set_traceframe_context (struct frame_info *trace_frame)
+set_traceframe_context (frame_info_ptr trace_frame)
 {
   CORE_ADDR trace_pc;
   struct symbol *traceframe_fun;
diff --git a/gdb/trad-frame.c b/gdb/trad-frame.c
index 9d4f23a851f..82d910942e6 100644
--- a/gdb/trad-frame.c
+++ b/gdb/trad-frame.c
@@ -29,14 +29,14 @@
 
 struct trad_frame_cache
 {
-  struct frame_info *this_frame;
+  frame_info_ptr this_frame;
   CORE_ADDR this_base;
   trad_frame_saved_reg *prev_regs;
   struct frame_id this_id;
 };
 
 struct trad_frame_cache *
-trad_frame_cache_zalloc (struct frame_info *this_frame)
+trad_frame_cache_zalloc (frame_info_ptr this_frame)
 {
   struct trad_frame_cache *this_trad_cache;
 
@@ -83,7 +83,7 @@ trad_frame_alloc_saved_regs (struct gdbarch *gdbarch)
    for all potential instruction sequences).  */
 
 trad_frame_saved_reg *
-trad_frame_alloc_saved_regs (struct frame_info *this_frame)
+trad_frame_alloc_saved_regs (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
 
@@ -184,7 +184,7 @@ trad_frame_set_reg_value_bytes (struct trad_frame_cache *this_trad_cache,
 
 
 struct value *
-trad_frame_get_prev_register (struct frame_info *this_frame,
+trad_frame_get_prev_register (frame_info_ptr this_frame,
 			      trad_frame_saved_reg this_saved_regs[],
 			      int regnum)
 {
@@ -209,7 +209,7 @@ trad_frame_get_prev_register (struct frame_info *this_frame,
 
 struct value *
 trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 int regnum)
 {
   return trad_frame_get_prev_register (this_frame, this_trad_cache->prev_regs,
diff --git a/gdb/trad-frame.h b/gdb/trad-frame.h
index 09a8133d362..190f4098b5d 100644
--- a/gdb/trad-frame.h
+++ b/gdb/trad-frame.h
@@ -22,7 +22,7 @@
 
 #include "frame.h"		/* For "struct frame_id".  */
 
-struct frame_info;
+class frame_info_ptr;
 struct regcache_map_entry;
 struct trad_frame_cache;
 
@@ -31,7 +31,7 @@ struct trad_frame_cache;
    The entire cache is populated in a single pass and then generic
    routines are used to extract the various cache values.  */
 
-struct trad_frame_cache *trad_frame_cache_zalloc (struct frame_info *);
+struct trad_frame_cache *trad_frame_cache_zalloc (frame_info_ptr );
 
 /* This frame's ID.  */
 void trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
@@ -59,7 +59,7 @@ void trad_frame_set_reg_value_bytes (struct trad_frame_cache *this_trad_cache,
 				     gdb::array_view<const gdb_byte> bytes);
 
 struct value *trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
-				       struct frame_info *this_frame,
+				       frame_info_ptr this_frame,
 				       int regnum);
 
 /* Describes the kind of encoding a stored register has.  */
@@ -194,12 +194,12 @@ void trad_frame_reset_saved_regs (struct gdbarch *gdbarch,
 				  trad_frame_saved_reg *regs);
 
 /* Return a freshly allocated (and initialized) trad_frame array.  */
-trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct frame_info *);
+trad_frame_saved_reg *trad_frame_alloc_saved_regs (frame_info_ptr );
 trad_frame_saved_reg *trad_frame_alloc_saved_regs (struct gdbarch *);
 
 /* Given the trad_frame info, return the location of the specified
    register.  */
-struct value *trad_frame_get_prev_register (struct frame_info *this_frame,
+struct value *trad_frame_get_prev_register (frame_info_ptr this_frame,
 					    trad_frame_saved_reg this_saved_regs[],
 					    int regnum);
 
diff --git a/gdb/tramp-frame.c b/gdb/tramp-frame.c
index 04f81804624..f5926dc1ee7 100644
--- a/gdb/tramp-frame.c
+++ b/gdb/tramp-frame.c
@@ -40,7 +40,7 @@ struct tramp_frame_cache
 };
 
 static struct trad_frame_cache *
-tramp_frame_cache (struct frame_info *this_frame,
+tramp_frame_cache (frame_info_ptr this_frame,
 		   void **this_cache)
 {
   struct tramp_frame_cache *tramp_cache
@@ -58,7 +58,7 @@ tramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-tramp_frame_this_id (struct frame_info *this_frame,
+tramp_frame_this_id (frame_info_ptr this_frame,
 		     void **this_cache,
 		     struct frame_id *this_id)
 {
@@ -69,7 +69,7 @@ tramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-tramp_frame_prev_register (struct frame_info *this_frame,
+tramp_frame_prev_register (frame_info_ptr this_frame,
 			   void **this_cache,
 			   int prev_regnum)
 {
@@ -81,7 +81,7 @@ tramp_frame_prev_register (struct frame_info *this_frame,
 
 static CORE_ADDR
 tramp_frame_start (const struct tramp_frame *tramp,
-		   struct frame_info *this_frame, CORE_ADDR pc)
+		   frame_info_ptr this_frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -121,7 +121,7 @@ tramp_frame_start (const struct tramp_frame *tramp,
 
 static int
 tramp_frame_sniffer (const struct frame_unwind *self,
-		     struct frame_info *this_frame,
+		     frame_info_ptr this_frame,
 		     void **this_cache)
 {
   const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
diff --git a/gdb/tramp-frame.h b/gdb/tramp-frame.h
index 94af6f2db0e..4e7dcb68eaa 100644
--- a/gdb/tramp-frame.h
+++ b/gdb/tramp-frame.h
@@ -23,7 +23,7 @@
 #include "frame.h"		/* For "enum frame_type".  */
 
 struct trad_frame;
-struct frame_info;
+class frame_info_ptr;
 struct trad_frame_cache;
 
 /* A trampoline consists of a small sequence of instructions placed at
@@ -66,7 +66,7 @@ struct tramp_frame
   /* Initialize a trad-frame cache corresponding to the tramp-frame.
      FUNC is the address of the instruction TRAMP[0] in memory.  */
   void (*init) (const struct tramp_frame *self,
-		struct frame_info *this_frame,
+		frame_info_ptr this_frame,
 		struct trad_frame_cache *this_cache,
 		CORE_ADDR func);
   /* Return non-zero if the tramp-frame is valid for the PC requested.
@@ -74,7 +74,7 @@ struct tramp_frame
      sequence against if required.  If this is NULL, then the tramp-frame
      is valid for any PC.  */
   int (*validate) (const struct tramp_frame *self,
-		   struct frame_info *this_frame,
+		   frame_info_ptr this_frame,
 		   CORE_ADDR *pc);
 };
 
diff --git a/gdb/user-regs.c b/gdb/user-regs.c
index 05bb04ef2ed..e3b4f78d6a0 100644
--- a/gdb/user-regs.c
+++ b/gdb/user-regs.c
@@ -44,7 +44,7 @@ struct user_reg
   /* Avoid the "read" symbol name as it conflicts with a preprocessor symbol
      in the NetBSD header for Stack Smashing Protection, that wraps the read(2)
      syscall.  */
-  struct value *(*xread) (struct frame_info * frame, const void *baton);
+  struct value *(*xread) (frame_info_ptr  frame, const void *baton);
   const void *baton;
   struct user_reg *next;
 };
@@ -207,7 +207,7 @@ user_reg_map_regnum_to_name (struct gdbarch *gdbarch, int regnum)
 }
 
 struct value *
-value_of_user_reg (int regnum, struct frame_info *frame)
+value_of_user_reg (int regnum, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   int maxregs = gdbarch_num_cooked_regs (gdbarch);
diff --git a/gdb/user-regs.h b/gdb/user-regs.h
index 2b393ab917a..10eaf59e197 100644
--- a/gdb/user-regs.h
+++ b/gdb/user-regs.h
@@ -38,7 +38,7 @@
    of assumed to be read-only.  Should it, for instance, return a
    register descriptor that contains all the relevant access methods.  */
 
-struct frame_info;
+class frame_info_ptr;
 struct gdbarch;
 
 /* Given an architecture, map a user visible register name onto its
@@ -56,9 +56,9 @@ extern const char *user_reg_map_regnum_to_name (struct gdbarch *gdbarch,
    bytes as, at the time the register is being added, the type needed
    to describe the register has not bee initialized.  */
 
-typedef struct value *(user_reg_read_ftype) (struct frame_info *frame,
+typedef struct value *(user_reg_read_ftype) (frame_info_ptr frame,
 					     const void *baton);
-extern struct value *value_of_user_reg (int regnum, struct frame_info *frame);
+extern struct value *value_of_user_reg (int regnum, frame_info_ptr frame);
 
 /* Add a builtin register (present in all architectures).  */
 extern void user_reg_add_builtin (const char *name,
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index c0fe5dab1cb..4296902305e 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -311,7 +311,7 @@ static CORE_ADDR
 xstormy16_analyze_prologue (struct gdbarch *gdbarch,
 			    CORE_ADDR start_addr, CORE_ADDR end_addr,
 			    struct xstormy16_frame_cache *cache,
-			    struct frame_info *this_frame)
+			    frame_info_ptr this_frame)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR next_addr;
@@ -588,7 +588,7 @@ xstormy16_find_jmp_table_entry (struct gdbarch *gdbarch, CORE_ADDR faddr)
 }
 
 static CORE_ADDR
-xstormy16_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+xstormy16_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   CORE_ADDR tmp = xstormy16_resolve_jmp_table_entry (gdbarch, pc);
@@ -660,7 +660,7 @@ xstormy16_alloc_frame_cache (void)
 }
 
 static struct xstormy16_frame_cache *
-xstormy16_frame_cache (struct frame_info *this_frame, void **this_cache)
+xstormy16_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct xstormy16_frame_cache *cache;
@@ -696,7 +696,7 @@ xstormy16_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static struct value *
-xstormy16_frame_prev_register (struct frame_info *this_frame, 
+xstormy16_frame_prev_register (frame_info_ptr this_frame, 
 			       void **this_cache, int regnum)
 {
   struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
@@ -714,7 +714,7 @@ xstormy16_frame_prev_register (struct frame_info *this_frame,
 }
 
 static void
-xstormy16_frame_this_id (struct frame_info *this_frame, void **this_cache,
+xstormy16_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			 struct frame_id *this_id)
 {
   struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
@@ -728,7 +728,7 @@ xstormy16_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static CORE_ADDR
-xstormy16_frame_base_address (struct frame_info *this_frame, void **this_cache)
+xstormy16_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
 							       this_cache);
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index f881870e244..08675973ab7 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -1029,13 +1029,13 @@ xtensa_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
 
 
 static CORE_ADDR
-xtensa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+xtensa_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_byte buf[8];
   CORE_ADDR pc;
 
   DEBUGTRACE ("xtensa_unwind_pc (next_frame = %s)\n", 
-		host_address_to_string (next_frame));
+		host_address_to_string (next_frame.get ()));
 
   frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf);
   pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
@@ -1047,7 +1047,7 @@ xtensa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 
 
 static struct frame_id
-xtensa_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+xtensa_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR pc, fp;
   xtensa_gdbarch_tdep *tdep = gdbarch_tdep<xtensa_gdbarch_tdep> (gdbarch);
@@ -1220,16 +1220,16 @@ xtensa_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR current_pc)
 	cache->prev_sp = SP of the previous frame.  */
 
 static void
-call0_frame_cache (struct frame_info *this_frame,
+call0_frame_cache (frame_info_ptr this_frame,
 		   xtensa_frame_cache_t *cache, CORE_ADDR pc);
 
 static void
-xtensa_window_interrupt_frame_cache (struct frame_info *this_frame,
+xtensa_window_interrupt_frame_cache (frame_info_ptr this_frame,
 				     xtensa_frame_cache_t *cache,
 				     CORE_ADDR pc);
 
 static struct xtensa_frame_cache *
-xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
+xtensa_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   xtensa_frame_cache_t *cache;
   CORE_ADDR ra, wb, ws, pc, sp, ps;
@@ -1395,7 +1395,7 @@ This message will not be repeated in this session.\n"));
 
 
 static void
-xtensa_frame_this_id (struct frame_info *this_frame,
+xtensa_frame_this_id (frame_info_ptr this_frame,
 		      void **this_cache,
 		      struct frame_id *this_id)
 {
@@ -1409,7 +1409,7 @@ xtensa_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-xtensa_frame_prev_register (struct frame_info *this_frame,
+xtensa_frame_prev_register (frame_info_ptr this_frame,
 			    void **this_cache,
 			    int regnum)
 {
@@ -1512,7 +1512,7 @@ xtensa_unwind =
 };
 
 static CORE_ADDR
-xtensa_frame_base_address (struct frame_info *this_frame, void **this_cache)
+xtensa_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct xtensa_frame_cache *cache =
     xtensa_frame_cache (this_frame, this_cache);
@@ -2548,7 +2548,7 @@ call0_analyze_prologue (struct gdbarch *gdbarch,
 /* Initialize frame cache for the current frame in CALL0 ABI.  */
 
 static void
-call0_frame_cache (struct frame_info *this_frame,
+call0_frame_cache (frame_info_ptr this_frame,
 		   xtensa_frame_cache_t *cache, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2897,7 +2897,7 @@ execute_code (struct gdbarch *gdbarch, CORE_ADDR current_pc, CORE_ADDR wb)
 /* Handle Window Overflow / Underflow exception frames.  */
 
 static void
-xtensa_window_interrupt_frame_cache (struct frame_info *this_frame,
+xtensa_window_interrupt_frame_cache (frame_info_ptr this_frame,
 				     xtensa_frame_cache_t *cache,
 				     CORE_ADDR pc)
 {
diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c
index 1ab375c5014..fb456e5192b 100644
--- a/gdb/z80-tdep.c
+++ b/gdb/z80-tdep.c
@@ -555,7 +555,7 @@ z80_return_value (struct gdbarch *gdbarch, struct value *function,
 
 /* function unwinds current stack frame and returns next one */
 static struct z80_unwind_cache *
-z80_frame_unwind_cache (struct frame_info *this_frame,
+z80_frame_unwind_cache (frame_info_ptr this_frame,
 			void **this_prologue_cache)
 {
   CORE_ADDR start_pc, current_pc;
@@ -658,7 +658,7 @@ z80_frame_unwind_cache (struct frame_info *this_frame,
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 static void
-z80_frame_this_id (struct frame_info *this_frame, void **this_cache,
+z80_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		   struct frame_id *this_id)
 {
   struct frame_id id;
@@ -682,7 +682,7 @@ z80_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-z80_frame_prev_register (struct frame_info *this_frame,
+z80_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_prologue_cache, int regnum)
 {
   struct z80_unwind_cache *info
-- 
2.37.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 4/5] Continue making GDB use frame_info_ptr
  2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
                   ` (2 preceding siblings ...)
  2022-08-30 10:08 ` [PATCH v4 3/5] Change GDB to use frame_info_ptr Bruno Larsen
@ 2022-08-30 10:08 ` Bruno Larsen
  2022-08-30 10:08 ` [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr Bruno Larsen
  2022-09-13  8:06 ` [Ping][PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
  5 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-08-30 10:08 UTC (permalink / raw)
  To: gdb-patches

This commit only exists to make my emails be smaller than 500Kb. It is
going to be squashed into the former commit.
---
 gdb/arm-tdep.c                      |   2 +-
 gdb/cli/cli-cmds.c                  |   2 +-
 gdb/compile/compile-c-symbols.c     |   2 +-
 gdb/compile/compile-cplus-symbols.c |   2 +-
 gdb/compile/compile-loc2c.c         |   2 +-
 gdb/dwarf2/expr.c                   |  20 +-
 gdb/dwarf2/expr.h                   |   6 +-
 gdb/dwarf2/frame-tailcall.c         |  41 ++--
 gdb/dwarf2/frame-tailcall.h         |   6 +-
 gdb/dwarf2/frame.c                  |  39 ++--
 gdb/dwarf2/frame.h                  |  12 +-
 gdb/dwarf2/loc.c                    |  38 ++--
 gdb/dwarf2/loc.h                    |   8 +-
 gdb/f-valprint.c                    |   2 +-
 gdb/findvar.c                       |  26 +--
 gdb/frame-base.c                    |   8 +-
 gdb/frame-base.h                    |  12 +-
 gdb/frame-unwind.c                  |  24 +--
 gdb/frame-unwind.h                  |  36 ++--
 gdb/frame.c                         | 290 ++++++++++++++--------------
 gdb/frame.h                         | 152 +++++++--------
 gdb/frv-linux-tdep.c                |  10 +-
 gdb/frv-tdep.c                      |  10 +-
 gdb/ft32-tdep.c                     |   8 +-
 gdb/guile/scm-frame.c               |   2 +-
 gdb/i386-bsd-tdep.c                 |   2 +-
 gdb/i386-darwin-tdep.c              |   4 +-
 gdb/i386-darwin-tdep.h              |   2 +-
 gdb/i386-fbsd-tdep.c                |   2 +-
 gdb/i386-gnu-tdep.c                 |   6 +-
 gdb/i386-linux-tdep.c               |  10 +-
 gdb/i386-netbsd-tdep.c              |   4 +-
 gdb/i386-nto-tdep.c                 |   4 +-
 gdb/i386-obsd-tdep.c                |  10 +-
 gdb/i386-sol2-tdep.c                |   2 +-
 gdb/i386-tdep.c                     |  54 +++---
 gdb/i386-tdep.h                     |  10 +-
 gdb/i386-windows-tdep.c             |   2 +-
 gdb/i387-tdep.c                     |   6 +-
 gdb/i387-tdep.h                     |   8 +-
 gdb/ia64-libunwind-tdep.c           |  12 +-
 gdb/ia64-libunwind-tdep.h           |  12 +-
 gdb/ia64-tdep.c                     |  50 ++---
 gdb/ia64-tdep.h                     |   4 +-
 gdb/infcall.c                       |   4 +-
 gdb/infcmd.c                        |  28 +--
 gdb/inferior.h                      |   6 +-
 gdb/infrun.c                        |  32 +--
 gdb/infrun.h                        |   4 +-
 gdb/inline-frame.c                  |  14 +-
 gdb/inline-frame.h                  |   4 +-
 gdb/iq2000-tdep.c                   |  10 +-
 gdb/mi/mi-cmd-stack.c               |  22 +--
 gdb/mi/mi-main.c                    |  10 +-
 gdb/python/py-event.h               |   2 +-
 gdb/python/py-finishbreakpoint.c    |   4 +-
 gdb/python/py-frame.c               |  42 ++--
 gdb/python/py-framefilter.c         |  22 +--
 gdb/python/py-inferior.c            |   2 +-
 gdb/python/py-infevents.c           |   4 +-
 gdb/python/py-symbol.c              |   6 +-
 gdb/python/py-unwind.c              |  12 +-
 gdb/python/python-internal.h        |   6 +-
 gdb/s12z-tdep.c                     |  10 +-
 gdb/s390-linux-tdep.c               |   8 +-
 gdb/s390-tdep.c                     |  38 ++--
 gdb/s390-tdep.h                     |   2 +-
 gdb/sentinel-frame.c                |   6 +-
 gdb/sh-linux-tdep.c                 |   6 +-
 gdb/sh-tdep.c                       |  16 +-
 gdb/skip.c                          |   2 +-
 gdb/sol2-tdep.c                     |   2 +-
 gdb/sol2-tdep.h                     |   2 +-
 gdb/solib-svr4.c                    |   4 +-
 gdb/sparc-linux-tdep.c              |   6 +-
 gdb/sparc-netbsd-tdep.c             |  12 +-
 gdb/sparc-obsd-tdep.c               |   8 +-
 gdb/sparc-sol2-tdep.c               |   8 +-
 gdb/sparc-tdep.c                    |  20 +-
 gdb/sparc-tdep.h                    |  12 +-
 gdb/sparc64-fbsd-tdep.c             |   8 +-
 gdb/sparc64-linux-tdep.c            |   8 +-
 gdb/sparc64-netbsd-tdep.c           |  10 +-
 gdb/sparc64-obsd-tdep.c             |  16 +-
 gdb/sparc64-sol2-tdep.c             |   8 +-
 gdb/sparc64-tdep.c                  |  10 +-
 gdb/sparc64-tdep.h                  |   4 +-
 gdb/stack.c                         | 104 +++++-----
 gdb/stack.h                         |   4 +-
 gdb/stap-probe.c                    |   4 +-
 gdb/std-regs.c                      |   8 +-
 gdb/symfile.h                       |   2 +-
 gdb/symtab.h                        |  10 +-
 gdb/tui/tui-disasm.c                |   2 +-
 gdb/tui/tui-disasm.h                |   2 +-
 gdb/tui/tui-hooks.c                 |   6 +-
 gdb/tui/tui-regs.c                  |   8 +-
 gdb/tui/tui-regs.h                  |   4 +-
 gdb/tui/tui-source.c                |   4 +-
 gdb/tui/tui-source.h                |   2 +-
 gdb/tui/tui-stack.c                 |   4 +-
 gdb/tui/tui-stack.h                 |   4 +-
 gdb/tui/tui-winsource.c             |   4 +-
 gdb/tui/tui-winsource.h             |   2 +-
 gdb/v850-tdep.c                     |  10 +-
 gdb/valops.c                        |  10 +-
 gdb/value.c                         |   4 +-
 gdb/value.h                         |  16 +-
 gdb/varobj.c                        |   8 +-
 gdb/vax-tdep.c                      |  14 +-
 110 files changed, 832 insertions(+), 828 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index f7fe19d13c0..23151331954 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3876,7 +3876,7 @@ arm_dwarf2_prev_register (frame_info_ptr this_frame, void **this_cache,
       if (override_with_sp_value)
 	{
 	  /* Use value of SP from previous frame.  */
-	  struct frame_info *prev_frame = get_prev_frame (this_frame);
+	  frame_info_ptr prev_frame = get_prev_frame (this_frame);
 	  if (prev_frame)
 	    val = get_frame_register_unsigned (prev_frame, ARM_SP_REGNUM);
 	  else
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 18fb6e6d869..fde648afa54 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -1466,7 +1466,7 @@ print_disassembly (struct gdbarch *gdbarch, const char *name,
 static void
 disassemble_current_function (gdb_disassembly_flags flags)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *gdbarch;
   CORE_ADDR low, high, pc;
   const char *name;
diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index e1f94ec2907..f043ba751e6 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -144,7 +144,7 @@ convert_one_symbol (compile_c_instance *context,
 	     by their name.  */
 	  {
 	    struct value *val;
-	    struct frame_info *frame = NULL;
+	    frame_info_ptr frame = NULL;
 
 	    if (symbol_read_needs_frame (sym.symbol))
 	      {
diff --git a/gdb/compile/compile-cplus-symbols.c b/gdb/compile/compile-cplus-symbols.c
index ef2a1f57603..4d3f1602322 100644
--- a/gdb/compile/compile-cplus-symbols.c
+++ b/gdb/compile/compile-cplus-symbols.c
@@ -138,7 +138,7 @@ convert_one_symbol (compile_cplus_instance *instance,
 	     by their name.  */
 	  {
 	    struct value *val;
-	    struct frame_info *frame = nullptr;
+	    frame_info_ptr frame = nullptr;
 
 	    if (symbol_read_needs_frame (sym.symbol))
 	      {
diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c
index 3ce0bfab45f..3864228ef37 100644
--- a/gdb/compile/compile-loc2c.c
+++ b/gdb/compile/compile-loc2c.c
@@ -633,7 +633,7 @@ do_compile_dwarf_expr_to_c (int indent, string_file *stream,
      offset by hand seemed too hackish.  */
   if (is_tls)
     {
-      struct frame_info *frame = get_selected_frame (NULL);
+      frame_info_ptr frame = get_selected_frame (NULL);
       struct value *val;
 
       if (frame == NULL)
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 3549745df04..e16f3c2bcbb 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -49,7 +49,7 @@ static const registry<gdbarch>::key<dwarf_gdbarch_types> dwarf_arch_cookie;
 /* Ensure that a FRAME is defined, throw an exception otherwise.  */
 
 static void
-ensure_have_frame (frame_info *frame, const char *op_name)
+ensure_have_frame (frame_info_ptr frame, const char *op_name)
 {
   if (frame == nullptr)
     throw_error (GENERIC_ERROR,
@@ -78,7 +78,7 @@ bits_to_bytes (ULONGEST start, ULONGEST n_bits)
 /* See expr.h.  */
 
 CORE_ADDR
-read_addr_from_reg (frame_info *frame, int reg)
+read_addr_from_reg (frame_info_ptr frame, int reg)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg);
@@ -112,7 +112,7 @@ static piece_closure *
 allocate_piece_closure (dwarf2_per_cu_data *per_cu,
 			dwarf2_per_objfile *per_objfile,
 			std::vector<dwarf_expr_piece> &&pieces,
-			frame_info *frame)
+			frame_info_ptr frame)
 {
   piece_closure *c = new piece_closure;
 
@@ -208,7 +208,7 @@ rw_pieced_value (value *v, value *from, bool check_optimized)
 	{
 	case DWARF_VALUE_REGISTER:
 	  {
-	    frame_info *frame = frame_find_by_id (c->frame_id);
+	    frame_info_ptr frame = frame_find_by_id (c->frame_id);
 	    gdbarch *arch = get_frame_arch (frame);
 	    int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
 	    ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
@@ -550,7 +550,7 @@ indirect_pieced_value (value *value)
     }
 
   gdb_assert (piece != NULL && c->per_cu != nullptr);
-  frame_info *frame = get_selected_frame (_("No frame selected."));
+  frame_info_ptr frame = get_selected_frame (_("No frame selected."));
 
   /* This is an offset requested by GDB, such as value subscripts.
      However, due to how synthetic pointers are implemented, this is
@@ -585,7 +585,7 @@ coerce_pieced_ref (const value *value)
     {
       const piece_closure *closure
 	= (piece_closure *) value_computed_closure (value);
-      frame_info *frame
+      frame_info_ptr frame
 	= get_selected_frame (_("No frame selected."));
 
       /* gdb represents synthetic pointers as pieced values with a single
@@ -675,7 +675,7 @@ sect_variable_value (sect_offset sect_off,
     }
 
   struct type *type = lookup_pointer_type (die_type);
-  frame_info *frame = get_selected_frame (_("No frame selected."));
+  frame_info_ptr frame = get_selected_frame (_("No frame selected."));
   return indirect_synthetic_pointer (sect_off, 0, per_cu, per_objfile, frame,
 				     type, true);
 }
@@ -811,7 +811,7 @@ dwarf_expr_context::dwarf_call (cu_offset die_cu_off)
 {
   ensure_have_per_cu (this->m_per_cu, "DW_OP_call");
 
-  frame_info *frame = this->m_frame;
+  frame_info_ptr frame = this->m_frame;
 
   auto get_pc_from_frame = [frame] ()
     {
@@ -866,7 +866,7 @@ dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind,
 
   dwarf2_per_cu_data *caller_per_cu;
   dwarf2_per_objfile *caller_per_objfile;
-  frame_info *caller_frame = get_prev_frame (this->m_frame);
+  frame_info_ptr caller_frame = get_prev_frame (this->m_frame);
   call_site_parameter *parameter
     = dwarf_expr_reg_to_entry_parameter (this->m_frame, kind, kind_u,
 					 &caller_per_cu,
@@ -1065,7 +1065,7 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
 
 value *
 dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len, bool as_lval,
-			      dwarf2_per_cu_data *per_cu, frame_info *frame,
+			      dwarf2_per_cu_data *per_cu, frame_info_ptr frame,
 			      const struct property_addr_info *addr_info,
 			      struct type *type, struct type *subobj_type,
 			      LONGEST subobj_offset)
diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h
index 4ce9b734f77..6078dce0abc 100644
--- a/gdb/dwarf2/expr.h
+++ b/gdb/dwarf2/expr.h
@@ -137,7 +137,7 @@ struct dwarf_expr_context
      The ADDR_INFO property can be specified to override the range of
      memory addresses with the passed in buffer.  */
   value *evaluate (const gdb_byte *addr, size_t len, bool as_lval,
-		   dwarf2_per_cu_data *per_cu, frame_info *frame,
+		   dwarf2_per_cu_data *per_cu, frame_info_ptr frame,
 		   const struct property_addr_info *addr_info = nullptr,
 		   struct type *type = nullptr,
 		   struct type *subobj_type = nullptr,
@@ -196,7 +196,7 @@ struct dwarf_expr_context
   dwarf2_per_objfile *m_per_objfile;
 
   /* Frame information used for the evaluation.  */
-  frame_info *m_frame = nullptr;
+  frame_info_ptr m_frame = nullptr;
 
   /* Compilation unit used for the evaluation.  */
   dwarf2_per_cu_data *m_per_cu = nullptr;
@@ -256,7 +256,7 @@ struct dwarf_expr_context
 
 /* Return the value of register number REG (a DWARF register number),
    read as an address in a given FRAME.  */
-CORE_ADDR read_addr_from_reg (frame_info *frame, int reg);
+CORE_ADDR read_addr_from_reg (frame_info_ptr frame, int reg);
 
 void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
 				     const char *);
diff --git a/gdb/dwarf2/frame-tailcall.c b/gdb/dwarf2/frame-tailcall.c
index 7f30a0d3126..a1e43cc18ed 100644
--- a/gdb/dwarf2/frame-tailcall.c
+++ b/gdb/dwarf2/frame-tailcall.c
@@ -39,7 +39,7 @@ static htab_t cache_htab;
 struct tailcall_cache
 {
   /* It must be the first one of this struct.  It is the furthest callee.  */
-  struct frame_info *next_bottom_frame;
+  frame_info *next_bottom_frame;
 
   /* Reference count.  The whole chain of virtual tail call frames shares one
      tailcall_cache.  */
@@ -90,12 +90,12 @@ cache_eq (const void *arg1, const void *arg2)
    tailcall_cache.  */
 
 static struct tailcall_cache *
-cache_new_ref1 (struct frame_info *next_bottom_frame)
+cache_new_ref1 (frame_info_ptr next_bottom_frame)
 {
   struct tailcall_cache *cache = XCNEW (struct tailcall_cache);
   void **slot;
 
-  cache->next_bottom_frame = next_bottom_frame;
+  cache->next_bottom_frame = next_bottom_frame.get ();
   cache->refc = 1;
 
   slot = htab_find_slot (cache_htab, cache, INSERT);
@@ -137,7 +137,7 @@ cache_unref (struct tailcall_cache *cache)
    return 0.  */
 
 static int
-frame_is_tailcall (struct frame_info *fi)
+frame_is_tailcall (frame_info_ptr fi)
 {
   return frame_unwinder_is (fi, &dwarf2_tailcall_frame_unwind);
 }
@@ -146,9 +146,10 @@ frame_is_tailcall (struct frame_info *fi)
    call chain.  Otherwise return NULL.  No new reference is created.  */
 
 static struct tailcall_cache *
-cache_find (struct frame_info *fi)
+cache_find (frame_info_ptr fi)
 {
   struct tailcall_cache *cache;
+  struct tailcall_cache search;
   void **slot;
 
   while (frame_is_tailcall (fi))
@@ -157,7 +158,9 @@ cache_find (struct frame_info *fi)
       gdb_assert (fi != NULL);
     }
 
-  slot = htab_find_slot (cache_htab, &fi, NO_INSERT);
+  search.next_bottom_frame = fi.get();
+  search.refc = 1;
+  slot = htab_find_slot (cache_htab, &search, NO_INSERT);
   if (slot == NULL)
     return NULL;
 
@@ -170,11 +173,11 @@ cache_find (struct frame_info *fi)
    If THIS_FRAME is CACHE-> NEXT_BOTTOM_FRAME return -1.  */
 
 static int
-existing_next_levels (struct frame_info *this_frame,
+existing_next_levels (frame_info_ptr this_frame,
 		      struct tailcall_cache *cache)
 {
   int retval = (frame_relative_level (this_frame)
-		- frame_relative_level (cache->next_bottom_frame) - 1);
+		- frame_relative_level (frame_info_ptr (cache->next_bottom_frame)) - 1);
 
   gdb_assert (retval >= -1);
 
@@ -207,11 +210,11 @@ pretended_chain_levels (struct call_site_chain *chain)
    Specific virtual tail call frames are tracked by INLINE_DEPTH.  */
 
 static void
-tailcall_frame_this_id (struct frame_info *this_frame, void **this_cache,
+tailcall_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			struct frame_id *this_id)
 {
   struct tailcall_cache *cache = (struct tailcall_cache *) *this_cache;
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
 
   /* Tail call does not make sense for a sentinel frame.  */
   next_frame = get_next_frame (this_frame);
@@ -229,7 +232,7 @@ tailcall_frame_this_id (struct frame_info *this_frame, void **this_cache,
    CACHE.  */
 
 static CORE_ADDR
-pretend_pc (struct frame_info *this_frame, struct tailcall_cache *cache)
+pretend_pc (frame_info_ptr this_frame, struct tailcall_cache *cache)
 {
   int next_levels = existing_next_levels (this_frame, cache);
   struct call_site_chain *chain = cache->chain;
@@ -261,7 +264,7 @@ pretend_pc (struct frame_info *this_frame, struct tailcall_cache *cache)
    frames unwind the NULL case differently.  */
 
 struct value *
-dwarf2_tailcall_prev_register_first (struct frame_info *this_frame,
+dwarf2_tailcall_prev_register_first (frame_info_ptr this_frame,
 				     void **tailcall_cachep, int regnum)
 {
   struct gdbarch *this_gdbarch = get_frame_arch (this_frame);
@@ -291,7 +294,7 @@ dwarf2_tailcall_prev_register_first (struct frame_info *this_frame,
    dwarf2_tailcall_prev_register_first.  */
 
 static struct value *
-tailcall_frame_prev_register (struct frame_info *this_frame,
+tailcall_frame_prev_register (frame_info_ptr this_frame,
 			       void **this_cache, int regnum)
 {
   struct tailcall_cache *cache = (struct tailcall_cache *) *this_cache;
@@ -313,9 +316,9 @@ tailcall_frame_prev_register (struct frame_info *this_frame,
 
 static int
 tailcall_frame_sniffer (const struct frame_unwind *self,
-			 struct frame_info *this_frame, void **this_cache)
+			 frame_info_ptr this_frame, void **this_cache)
 {
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
   int next_levels;
   struct tailcall_cache *cache;
 
@@ -360,7 +363,7 @@ tailcall_frame_sniffer (const struct frame_unwind *self,
    address pushed on the stack.  */
 
 void
-dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
+dwarf2_tailcall_sniffer_first (frame_info_ptr this_frame,
 			       void **tailcall_cachep,
 			       const LONGEST *entry_cfa_sp_offsetp)
 {
@@ -444,7 +447,7 @@ dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
    TAILCALL_FRAME.  */
 
 static void
-tailcall_frame_dealloc_cache (struct frame_info *self, void *this_cache)
+tailcall_frame_dealloc_cache (frame_info *self, void *this_cache)
 {
   struct tailcall_cache *cache = (struct tailcall_cache *) this_cache;
 
@@ -455,12 +458,12 @@ tailcall_frame_dealloc_cache (struct frame_info *self, void *this_cache)
    call frames have gdbarch of the bottom (callee) frame.  */
 
 static struct gdbarch *
-tailcall_frame_prev_arch (struct frame_info *this_frame,
+tailcall_frame_prev_arch (frame_info_ptr this_frame,
 			  void **this_prologue_cache)
 {
   struct tailcall_cache *cache = (struct tailcall_cache *) *this_prologue_cache;
 
-  return get_frame_arch (cache->next_bottom_frame);
+  return get_frame_arch (frame_info_ptr (cache->next_bottom_frame));
 }
 
 /* Virtual tail call frame unwinder if dwarf2_tailcall_sniffer_first finds
diff --git a/gdb/dwarf2/frame-tailcall.h b/gdb/dwarf2/frame-tailcall.h
index e55a59dfbc2..c849bfb070e 100644
--- a/gdb/dwarf2/frame-tailcall.h
+++ b/gdb/dwarf2/frame-tailcall.h
@@ -20,18 +20,18 @@
 #ifndef DWARF2_FRAME_TAILCALL_H
 #define DWARF2_FRAME_TAILCALL_H 1
 
-struct frame_info;
+class frame_info_ptr;
 struct frame_unwind;
 
 /* The tail call frame unwinder.  */
 
 extern void
-  dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
+  dwarf2_tailcall_sniffer_first (frame_info_ptr this_frame,
 				 void **tailcall_cachep,
 				 const LONGEST *entry_cfa_sp_offsetp);
 
 extern struct value *
-  dwarf2_tailcall_prev_register_first (struct frame_info *this_frame,
+  dwarf2_tailcall_prev_register_first (frame_info_ptr this_frame,
 				       void **tailcall_cachep, int regnum);
 
 extern const struct frame_unwind dwarf2_tailcall_frame_unwind;
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 0e681f006cd..83565ea7c99 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -226,7 +226,7 @@ register %s (#%d) at %s"),
 
 static CORE_ADDR
 execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
-		  struct frame_info *this_frame, CORE_ADDR initial,
+		  frame_info_ptr this_frame, CORE_ADDR initial,
 		  int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
 {
   dwarf_expr_context ctx (per_objfile, addr_size);
@@ -583,17 +583,17 @@ execute_cfa_program_test (struct gdbarch *gdbarch)
 static void dwarf2_frame_default_init_reg (struct gdbarch *gdbarch,
 					   int regnum,
 					   struct dwarf2_frame_state_reg *reg,
-					   struct frame_info *this_frame);
+					   frame_info_ptr this_frame);
 
 struct dwarf2_frame_ops
 {
   /* Pre-initialize the register state REG for register REGNUM.  */
   void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *,
-		    struct frame_info *)
+		    frame_info_ptr)
     = dwarf2_frame_default_init_reg;
 
   /* Check whether the THIS_FRAME is a signal trampoline.  */
-  int (*signal_frame_p) (struct gdbarch *, struct frame_info *) = nullptr;
+  int (*signal_frame_p) (struct gdbarch *, frame_info_ptr) = nullptr;
 
   /* Convert .eh_frame register number to DWARF register number, or
      adjust .debug_frame register number.  */
@@ -619,7 +619,7 @@ get_frame_ops (struct gdbarch *gdbarch)
 static void
 dwarf2_frame_default_init_reg (struct gdbarch *gdbarch, int regnum,
 			       struct dwarf2_frame_state_reg *reg,
-			       struct frame_info *this_frame)
+			       frame_info_ptr this_frame)
 {
   /* If we have a register that acts as a program counter, mark it as
      a destination for the return address.  If we have a register that
@@ -660,7 +660,7 @@ void
 dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
 			   void (*init_reg) (struct gdbarch *, int,
 					     struct dwarf2_frame_state_reg *,
-					     struct frame_info *))
+					     frame_info_ptr ))
 {
   struct dwarf2_frame_ops *ops = get_frame_ops (gdbarch);
 
@@ -672,7 +672,7 @@ dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
 static void
 dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 		       struct dwarf2_frame_state_reg *reg,
-		       struct frame_info *this_frame)
+		       frame_info_ptr this_frame)
 {
   struct dwarf2_frame_ops *ops = get_frame_ops (gdbarch);
 
@@ -685,7 +685,7 @@ dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 void
 dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
 				 int (*signal_frame_p) (struct gdbarch *,
-							struct frame_info *))
+							frame_info_ptr ))
 {
   struct dwarf2_frame_ops *ops = get_frame_ops (gdbarch);
 
@@ -697,7 +697,7 @@ dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
 
 static int
 dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch,
-			     struct frame_info *this_frame)
+			     frame_info_ptr this_frame)
 {
   struct dwarf2_frame_ops *ops = get_frame_ops (gdbarch);
 
@@ -866,7 +866,7 @@ struct dwarf2_frame_cache
 };
 
 static struct dwarf2_frame_cache *
-dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
+dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   const int num_regs = gdbarch_num_cooked_regs (gdbarch);
@@ -1095,7 +1095,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
 }
 
 static enum unwind_stop_reason
-dwarf2_frame_unwind_stop_reason (struct frame_info *this_frame,
+dwarf2_frame_unwind_stop_reason (frame_info_ptr this_frame,
 				 void **this_cache)
 {
   struct dwarf2_frame_cache *cache
@@ -1111,7 +1111,7 @@ dwarf2_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static void
-dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache,
+dwarf2_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		      struct frame_id *this_id)
 {
   struct dwarf2_frame_cache *cache =
@@ -1126,7 +1126,7 @@ dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+dwarf2_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			    int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1226,9 +1226,10 @@ dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
    call frames chain.  */
 
 static void
-dwarf2_frame_dealloc_cache (struct frame_info *self, void *this_cache)
+dwarf2_frame_dealloc_cache (frame_info *self, void *this_cache)
 {
-  struct dwarf2_frame_cache *cache = dwarf2_frame_cache (self, &this_cache);
+  struct dwarf2_frame_cache *cache
+      = dwarf2_frame_cache (frame_info_ptr (self), &this_cache);
 
   if (cache->tailcall_cache)
     dwarf2_tailcall_frame_unwind.dealloc_cache (self, cache->tailcall_cache);
@@ -1236,7 +1237,7 @@ dwarf2_frame_dealloc_cache (struct frame_info *self, void *this_cache)
 
 static int
 dwarf2_frame_sniffer (const struct frame_unwind *self,
-		      struct frame_info *this_frame, void **this_cache)
+		      frame_info_ptr this_frame, void **this_cache)
 {
   if (!dwarf2_frame_unwinders_enabled_p)
     return 0;
@@ -1312,7 +1313,7 @@ dwarf2_append_unwinders (struct gdbarch *gdbarch)
    response to the "info frame" command.  */
 
 static CORE_ADDR
-dwarf2_frame_base_address (struct frame_info *this_frame, void **this_cache)
+dwarf2_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct dwarf2_frame_cache *cache =
     dwarf2_frame_cache (this_frame, this_cache);
@@ -1329,7 +1330,7 @@ static const struct frame_base dwarf2_frame_base =
 };
 
 const struct frame_base *
-dwarf2_frame_base_sniffer (struct frame_info *this_frame)
+dwarf2_frame_base_sniffer (frame_info_ptr this_frame)
 {
   CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
 
@@ -1344,7 +1345,7 @@ dwarf2_frame_base_sniffer (struct frame_info *this_frame)
    DW_OP_call_frame_cfa.  */
 
 CORE_ADDR
-dwarf2_frame_cfa (struct frame_info *this_frame)
+dwarf2_frame_cfa (frame_info_ptr this_frame)
 {
   if (frame_unwinder_is (this_frame, &record_btrace_tailcall_frame_unwind)
       || frame_unwinder_is (this_frame, &record_btrace_frame_unwind))
diff --git a/gdb/dwarf2/frame.h b/gdb/dwarf2/frame.h
index 04ec1e06c48..653156fa509 100644
--- a/gdb/dwarf2/frame.h
+++ b/gdb/dwarf2/frame.h
@@ -23,7 +23,7 @@
 #define DWARF2_FRAME_H 1
 
 struct gdbarch;
-struct frame_info;
+class frame_info_ptr;
 struct dwarf2_per_cu_data;
 struct agent_expr;
 struct axs_value;
@@ -78,7 +78,7 @@ struct dwarf2_frame_state_reg
       const gdb_byte *start;
       ULONGEST len;
     } exp;
-    struct value *(*fn) (struct frame_info *this_frame, void **this_cache,
+    struct value *(*fn) (frame_info_ptr this_frame, void **this_cache,
 			 int regnum);
   } loc;
   enum dwarf2_frame_reg_rule how;
@@ -208,7 +208,7 @@ extern bool dwarf2_frame_unwinders_enabled_p;
 extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
 				       void (*init_reg) (struct gdbarch *, int,
 					     struct dwarf2_frame_state_reg *,
-					     struct frame_info *));
+					     frame_info_ptr ));
 
 /* Set the architecture-specific signal trampoline recognition
    function for GDBARCH to SIGNAL_FRAME_P.  */
@@ -216,7 +216,7 @@ extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
 extern void
   dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
 				   int (*signal_frame_p) (struct gdbarch *,
-							  struct frame_info *));
+							  frame_info_ptr ));
 
 /* Set the architecture-specific adjustment of .eh_frame and .debug_frame
    register numbers.  */
@@ -234,11 +234,11 @@ void dwarf2_append_unwinders (struct gdbarch *gdbarch);
    NULL if it can't be handled by the DWARF CFI frame unwinder.  */
 
 extern const struct frame_base *
-  dwarf2_frame_base_sniffer (struct frame_info *this_frame);
+  dwarf2_frame_base_sniffer (frame_info_ptr this_frame);
 
 /* Compute the DWARF CFA for a frame.  */
 
-CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame);
+CORE_ADDR dwarf2_frame_cfa (frame_info_ptr this_frame);
 
 /* Find the CFA information for PC.
 
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index bf0df613f24..c6cf26e75cd 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -48,7 +48,7 @@
 #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, bool as_lval = true);
 
@@ -488,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;
@@ -545,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;
@@ -638,7 +638,7 @@ void
 call_site_target::iterate_over_addresses
      (struct gdbarch *call_site_gdbarch,
       const struct call_site *call_site,
-      struct frame_info *caller_frame,
+      frame_info_ptr caller_frame,
       iterate_ftype callback) const
 {
   switch (m_loc_kind)
@@ -1126,7 +1126,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,
@@ -1134,7 +1134,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.  */
@@ -1251,7 +1251,7 @@ 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)
 {
@@ -1333,13 +1333,13 @@ static const struct lval_funcs entry_data_value_funcs =
    cannot resolve the parameter for any reason.  */
 
 static struct value *
-value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
+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);
+  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;
@@ -1389,7 +1389,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;
@@ -1450,7 +1450,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.  */
@@ -1490,7 +1490,7 @@ 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,
@@ -1555,7 +1555,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
    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, bool as_lval)
@@ -1578,7 +1578,7 @@ dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
 
 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,
 			   gdb::array_view<CORE_ADDR> push_values,
@@ -1639,7 +1639,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
 
 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,
 			  gdb::array_view<CORE_ADDR> push_values)
@@ -3044,7 +3044,7 @@ 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);
@@ -3062,7 +3062,7 @@ 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);
@@ -3877,7 +3877,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);
@@ -3902,7 +3902,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);
diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h
index a9834d32066..d6709f2e342 100644
--- a/gdb/dwarf2/loc.h
+++ b/gdb/dwarf2/loc.h
@@ -65,7 +65,7 @@ value *compute_var_value (const char *name);
    otherwise.  */
 
 struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
-  (struct frame_info *frame, enum call_site_parameter_kind kind,
+  (frame_info_ptr frame, enum call_site_parameter_kind kind,
    union call_site_parameter_u kind_u, dwarf2_per_cu_data **per_cu_return,
    dwarf2_per_objfile **per_objfile_return);
 
@@ -76,7 +76,7 @@ struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
    be a value or a location description.  */
 
 struct value *dwarf2_evaluate_loc_desc (struct type *type,
-					struct frame_info *frame,
+					frame_info_ptr frame,
 					const gdb_byte *data,
 					size_t size,
 					dwarf2_per_cu_data *per_cu,
@@ -120,7 +120,7 @@ struct property_addr_info
    bottom of the stack.  */
 
 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,
 			       gdb::array_view<CORE_ADDR> push_values = {});
@@ -293,7 +293,7 @@ extern void invalid_synthetic_pointer ();
 
 extern 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,
+   dwarf2_per_objfile *per_objfile, frame_info_ptr frame,
    struct type *type, bool resolve_abstract_p = false);
 
 #endif /* DWARF2LOC_H */
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 6a3f83c2194..e1ab8a3a760 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -662,7 +662,7 @@ info_common_command_for_block (const struct block *block, const char *comname,
 static void
 info_common_command (const char *comname, int from_tty)
 {
-  struct frame_info *fi;
+  frame_info_ptr fi;
   const struct block *block;
   int values_printed = 0;
 
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 36c094534be..5c6eea0778c 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -259,7 +259,7 @@ copy_integer_to_size (gdb_byte *dest, int dest_size, const gdb_byte *source,
    determined by register_type ().  */
 
 struct value *
-value_of_register (int regnum, struct frame_info *frame)
+value_of_register (int regnum, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct value *reg_val;
@@ -279,11 +279,11 @@ value_of_register (int regnum, struct frame_info *frame)
    determined by register_type ().  The value is not fetched.  */
 
 struct value *
-value_of_register_lazy (struct frame_info *frame, int regnum)
+value_of_register_lazy (frame_info_ptr frame, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct value *reg_val;
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
 
   gdb_assert (regnum < gdbarch_num_cooked_regs (gdbarch));
 
@@ -403,8 +403,8 @@ symbol_read_needs_frame (struct symbol *sym)
    the static links points to and return it.  Return NULL if we could not find
    such a frame.   */
 
-static struct frame_info *
-follow_static_link (struct frame_info *frame,
+static frame_info_ptr
+follow_static_link (frame_info_ptr frame,
 		    const struct dynamic_prop *static_link)
 {
   CORE_ADDR upper_frame_base;
@@ -446,9 +446,9 @@ follow_static_link (struct frame_info *frame,
    For backward compatibility purposes (with old compilers), we then look for
    the first frame that can host it.  */
 
-static struct frame_info *
+static frame_info_ptr
 get_hosting_frame (struct symbol *var, const struct block *var_block,
-		   struct frame_info *frame)
+		   frame_info_ptr frame)
 {
   const struct block *frame_block = NULL;
 
@@ -559,7 +559,7 @@ get_hosting_frame (struct symbol *var, const struct block *var_block,
 struct value *
 language_defn::read_var_value (struct symbol *var,
 			       const struct block *var_block,
-			       struct frame_info *frame) const
+			       frame_info_ptr frame) const
 {
   struct value *v;
   struct type *type = var->type ();
@@ -781,7 +781,7 @@ language_defn::read_var_value (struct symbol *var,
 
 struct value *
 read_var_value (struct symbol *var, const struct block *var_block,
-		struct frame_info *frame)
+		frame_info_ptr frame)
 {
   const struct language_defn *lang = language_def (var->language ());
 
@@ -798,7 +798,7 @@ default_value_from_register (struct gdbarch *gdbarch, struct type *type,
 {
   int len = TYPE_LENGTH (type);
   struct value *value = allocate_value (type);
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   VALUE_LVAL (value) = lval_register;
   frame = frame_find_by_id (frame_id);
@@ -834,7 +834,7 @@ default_value_from_register (struct gdbarch *gdbarch, struct type *type,
    complete resulting value as optimized out.  */
 
 void
-read_frame_register_value (struct value *value, struct frame_info *frame)
+read_frame_register_value (struct value *value, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   LONGEST offset = 0;
@@ -874,7 +874,7 @@ read_frame_register_value (struct value *value, struct frame_info *frame)
 /* Return a value of type TYPE, stored in register REGNUM, in frame FRAME.  */
 
 struct value *
-value_from_register (struct type *type, int regnum, struct frame_info *frame)
+value_from_register (struct type *type, int regnum, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *type1 = check_typedef (type);
@@ -924,7 +924,7 @@ value_from_register (struct type *type, int regnum, struct frame_info *frame)
    Will abort if register value is not available.  */
 
 CORE_ADDR
-address_from_register (int regnum, struct frame_info *frame)
+address_from_register (int regnum, frame_info_ptr frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct type *type = builtin_type (gdbarch)->builtin_data_ptr;
diff --git a/gdb/frame-base.c b/gdb/frame-base.c
index 06c6af4b8c7..fb577df5143 100644
--- a/gdb/frame-base.c
+++ b/gdb/frame-base.c
@@ -29,19 +29,19 @@
    really need to override this.  */
 
 static CORE_ADDR
-default_frame_base_address (struct frame_info *this_frame, void **this_cache)
+default_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   return get_frame_base (this_frame); /* sigh! */
 }
 
 static CORE_ADDR
-default_frame_locals_address (struct frame_info *this_frame, void **this_cache)
+default_frame_locals_address (frame_info_ptr this_frame, void **this_cache)
 {
   return default_frame_base_address (this_frame, this_cache);
 }
 
 static CORE_ADDR
-default_frame_args_address (struct frame_info *this_frame, void **this_cache)
+default_frame_args_address (frame_info_ptr this_frame, void **this_cache)
 {
   return default_frame_base_address (this_frame, this_cache);
 }
@@ -99,7 +99,7 @@ frame_base_set_default (struct gdbarch *gdbarch,
 }
 
 const struct frame_base *
-frame_base_find_by_frame (struct frame_info *this_frame)
+frame_base_find_by_frame (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct frame_base_table *table = get_frame_base_table (gdbarch);
diff --git a/gdb/frame-base.h b/gdb/frame-base.h
index ba3d99cc02f..334a2e2c750 100644
--- a/gdb/frame-base.h
+++ b/gdb/frame-base.h
@@ -20,7 +20,7 @@
 #if !defined (FRAME_BASE_H)
 #define FRAME_BASE_H 1
 
-struct frame_info;
+class frame_info_ptr;
 struct frame_id;
 struct frame_unwind;
 struct frame_base;
@@ -42,17 +42,17 @@ struct regcache;
 
 /* A generic base address.  */
 
-typedef CORE_ADDR (frame_this_base_ftype) (struct frame_info *this_frame,
+typedef CORE_ADDR (frame_this_base_ftype) (frame_info_ptr this_frame,
 					   void **this_base_cache);
 
 /* The base address of the frame's local variables.  */
 
-typedef CORE_ADDR (frame_this_locals_ftype) (struct frame_info *this_frame,
+typedef CORE_ADDR (frame_this_locals_ftype) (frame_info_ptr this_frame,
 					     void **this_base_cache);
 
 /* The base address of the frame's arguments / parameters.  */
 
-typedef CORE_ADDR (frame_this_args_ftype) (struct frame_info *this_frame,
+typedef CORE_ADDR (frame_this_args_ftype) (frame_info_ptr this_frame,
 					   void **this_base_cache);
 
 struct frame_base
@@ -68,7 +68,7 @@ struct frame_base
 /* Given THIS frame, return the frame base methods for THIS frame,
    or NULL if it can't handle THIS frame.  */
 
-typedef const struct frame_base *(frame_base_sniffer_ftype) (struct frame_info *this_frame);
+typedef const struct frame_base *(frame_base_sniffer_ftype) (frame_info_ptr this_frame);
 
 /* Append a frame base sniffer to the list.  The sniffers are polled
    in the order that they are appended.  */
@@ -86,6 +86,6 @@ extern void frame_base_set_default (struct gdbarch *gdbarch,
 /* Iterate through the list of frame base handlers until one returns
    an implementation.  */
 
-extern const struct frame_base *frame_base_find_by_frame (struct frame_info *this_frame);
+extern const struct frame_base *frame_base_find_by_frame (frame_info_ptr this_frame);
 
 #endif
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 78e3f1d8bad..ed24e6e1747 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -121,7 +121,7 @@ frame_unwind_append_unwinder (struct gdbarch *gdbarch,
    unchanged and returns 0.  */
 
 static int
-frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
+frame_unwind_try_unwinder (frame_info_ptr this_frame, void **this_cache,
 			  const struct frame_unwind *unwinder)
 {
   int res = 0;
@@ -181,7 +181,7 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
    by this function.  Possibly initialize THIS_CACHE.  */
 
 void
-frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
+frame_unwind_find_by_frame (frame_info_ptr this_frame, void **this_cache)
 {
   FRAME_SCOPED_DEBUG_ENTER_EXIT;
   frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame));
@@ -215,7 +215,7 @@ frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
 
 int
 default_frame_sniffer (const struct frame_unwind *self,
-		       struct frame_info *this_frame,
+		       frame_info_ptr this_frame,
 		       void **this_prologue_cache)
 {
   return 1;
@@ -224,7 +224,7 @@ default_frame_sniffer (const struct frame_unwind *self,
 /* The default frame unwinder stop_reason callback.  */
 
 enum unwind_stop_reason
-default_frame_unwind_stop_reason (struct frame_info *this_frame,
+default_frame_unwind_stop_reason (frame_info_ptr this_frame,
 				  void **this_cache)
 {
   struct frame_id this_id = get_frame_id (this_frame);
@@ -238,7 +238,7 @@ default_frame_unwind_stop_reason (struct frame_info *this_frame,
 /* See frame-unwind.h.  */
 
 CORE_ADDR
-default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+default_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   int pc_regnum = gdbarch_pc_regnum (gdbarch);
   CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, pc_regnum);
@@ -249,7 +249,7 @@ default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* See frame-unwind.h.  */
 
 CORE_ADDR
-default_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+default_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   int sp_regnum = gdbarch_sp_regnum (gdbarch);
   return frame_unwind_register_unsigned (next_frame, sp_regnum);
@@ -261,7 +261,7 @@ default_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Return a value which indicates that FRAME did not save REGNUM.  */
 
 struct value *
-frame_unwind_got_optimized (struct frame_info *frame, int regnum)
+frame_unwind_got_optimized (frame_info_ptr frame, int regnum)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   struct type *type = register_type (gdbarch, regnum);
@@ -273,7 +273,7 @@ frame_unwind_got_optimized (struct frame_info *frame, int regnum)
    register NEW_REGNUM.  */
 
 struct value *
-frame_unwind_got_register (struct frame_info *frame,
+frame_unwind_got_register (frame_info_ptr frame,
 			   int regnum, int new_regnum)
 {
   return value_of_register_lazy (frame, new_regnum);
@@ -283,7 +283,7 @@ frame_unwind_got_register (struct frame_info *frame,
    ADDR.  */
 
 struct value *
-frame_unwind_got_memory (struct frame_info *frame, int regnum, CORE_ADDR addr)
+frame_unwind_got_memory (frame_info_ptr frame, int regnum, CORE_ADDR addr)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   struct value *v = value_at_lazy (register_type (gdbarch, regnum), addr);
@@ -296,7 +296,7 @@ frame_unwind_got_memory (struct frame_info *frame, int regnum, CORE_ADDR addr)
    REGNUM has a known constant (computed) value of VAL.  */
 
 struct value *
-frame_unwind_got_constant (struct frame_info *frame, int regnum,
+frame_unwind_got_constant (frame_info_ptr frame, int regnum,
 			   ULONGEST val)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
@@ -310,7 +310,7 @@ frame_unwind_got_constant (struct frame_info *frame, int regnum,
 }
 
 struct value *
-frame_unwind_got_bytes (struct frame_info *frame, int regnum, const gdb_byte *buf)
+frame_unwind_got_bytes (frame_info_ptr frame, int regnum, const gdb_byte *buf)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   struct value *reg_val;
@@ -326,7 +326,7 @@ frame_unwind_got_bytes (struct frame_info *frame, int regnum, const gdb_byte *bu
    CORE_ADDR to a target address if necessary.  */
 
 struct value *
-frame_unwind_got_address (struct frame_info *frame, int regnum,
+frame_unwind_got_address (frame_info_ptr frame, int regnum,
 			  CORE_ADDR addr)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index af79c808301..84c90fdd143 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -21,7 +21,7 @@
 #define FRAME_UNWIND_H 1
 
 struct frame_data;
-struct frame_info;
+class frame_info_ptr;
 struct frame_id;
 struct frame_unwind;
 struct gdbarch;
@@ -50,37 +50,37 @@ struct value;
    to set *THIS_PROLOGUE_CACHE to NULL.  */
 
 typedef int (frame_sniffer_ftype) (const struct frame_unwind *self,
-				   struct frame_info *this_frame,
+				   frame_info_ptr this_frame,
 				   void **this_prologue_cache);
 
 typedef enum unwind_stop_reason (frame_unwind_stop_reason_ftype)
-  (struct frame_info *this_frame, void **this_prologue_cache);
+  (frame_info_ptr this_frame, void **this_prologue_cache);
 
 /* A default frame sniffer which always accepts the frame.  Used by
    fallback prologue unwinders.  */
 
 int default_frame_sniffer (const struct frame_unwind *self,
-			   struct frame_info *this_frame,
+			   frame_info_ptr this_frame,
 			   void **this_prologue_cache);
 
 /* A default stop_reason callback which always claims the frame is
    unwindable.  */
 
 enum unwind_stop_reason
-  default_frame_unwind_stop_reason (struct frame_info *this_frame,
+  default_frame_unwind_stop_reason (frame_info_ptr this_frame,
 				    void **this_cache);
 
 /* A default unwind_pc callback that simply unwinds the register identified
    by GDBARCH_PC_REGNUM.  */
 
 extern CORE_ADDR default_unwind_pc (struct gdbarch *gdbarch,
-				    struct frame_info *next_frame);
+				    frame_info_ptr next_frame);
 
 /* A default unwind_sp callback that simply unwinds the register identified
    by GDBARCH_SP_REGNUM.  */
 
 extern CORE_ADDR default_unwind_sp (struct gdbarch *gdbarch,
-				    struct frame_info *next_frame);
+				    frame_info_ptr next_frame);
 
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    use THIS frame, and through it the NEXT frame's register unwind
@@ -105,7 +105,7 @@ extern CORE_ADDR default_unwind_sp (struct gdbarch *gdbarch,
    with the other unwind methods.  Memory for that cache should be
    allocated using FRAME_OBSTACK_ZALLOC().  */
 
-typedef void (frame_this_id_ftype) (struct frame_info *this_frame,
+typedef void (frame_this_id_ftype) (frame_info_ptr this_frame,
 				    void **this_prologue_cache,
 				    struct frame_id *this_id);
 
@@ -141,19 +141,19 @@ typedef void (frame_this_id_ftype) (struct frame_info *this_frame,
    allocated using FRAME_OBSTACK_ZALLOC().  */
 
 typedef struct value * (frame_prev_register_ftype)
-  (struct frame_info *this_frame, void **this_prologue_cache,
+  (frame_info_ptr this_frame, void **this_prologue_cache,
    int regnum);
 
 /* Deallocate extra memory associated with the frame cache if any.  */
 
-typedef void (frame_dealloc_cache_ftype) (struct frame_info *self,
+typedef void (frame_dealloc_cache_ftype) (frame_info *self,
 					  void *this_cache);
 
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    use THIS frame, and implicitly the NEXT frame's register unwind
    method, return PREV frame's architecture.  */
 
-typedef struct gdbarch *(frame_prev_arch_ftype) (struct frame_info *this_frame,
+typedef struct gdbarch *(frame_prev_arch_ftype) (frame_info_ptr this_frame,
 						 void **this_prologue_cache);
 
 struct frame_unwind
@@ -193,7 +193,7 @@ extern void frame_unwind_append_unwinder (struct gdbarch *gdbarch,
    unwinder implementation.  THIS_FRAME->UNWIND must be NULL, it will get set
    by this function.  Possibly initialize THIS_CACHE.  */
 
-extern void frame_unwind_find_by_frame (struct frame_info *this_frame,
+extern void frame_unwind_find_by_frame (frame_info_ptr this_frame,
 					void **this_cache);
 
 /* Helper functions for value-based register unwinding.  These return
@@ -201,39 +201,39 @@ extern void frame_unwind_find_by_frame (struct frame_info *this_frame,
 
 /* Return a value which indicates that FRAME did not save REGNUM.  */
 
-struct value *frame_unwind_got_optimized (struct frame_info *frame,
+struct value *frame_unwind_got_optimized (frame_info_ptr frame,
 					  int regnum);
 
 /* Return a value which indicates that FRAME copied REGNUM into
    register NEW_REGNUM.  */
 
-struct value *frame_unwind_got_register (struct frame_info *frame, int regnum,
+struct value *frame_unwind_got_register (frame_info_ptr frame, int regnum,
 					 int new_regnum);
 
 /* Return a value which indicates that FRAME saved REGNUM in memory at
    ADDR.  */
 
-struct value *frame_unwind_got_memory (struct frame_info *frame, int regnum,
+struct value *frame_unwind_got_memory (frame_info_ptr frame, int regnum,
 				       CORE_ADDR addr);
 
 /* Return a value which indicates that FRAME's saved version of
    REGNUM has a known constant (computed) value of VAL.  */
 
-struct value *frame_unwind_got_constant (struct frame_info *frame, int regnum,
+struct value *frame_unwind_got_constant (frame_info_ptr frame, int regnum,
 					 ULONGEST val);
 
 /* Return a value which indicates that FRAME's saved version of
    REGNUM has a known constant (computed) value which is stored
    inside BUF.  */
 
-struct value *frame_unwind_got_bytes (struct frame_info *frame, int regnum,
+struct value *frame_unwind_got_bytes (frame_info_ptr frame, int regnum,
 				      const gdb_byte *buf);
 
 /* Return a value which indicates that FRAME's saved version of REGNUM
    has a known constant (computed) value of ADDR.  Convert the
    CORE_ADDR to a target address if necessary.  */
 
-struct value *frame_unwind_got_address (struct frame_info *frame, int regnum,
+struct value *frame_unwind_got_address (frame_info_ptr frame, int regnum,
 					CORE_ADDR addr);
 
 #endif
diff --git a/gdb/frame.c b/gdb/frame.c
index 7c31da53729..1d13d319b83 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -51,7 +51,7 @@
    The current frame, which is the innermost frame, can be found at
    sentinel_frame->prev.  */
 
-static struct frame_info *sentinel_frame;
+static frame_info *sentinel_frame;
 
 /* Number of calls to reinit_frame_cache.  */
 static unsigned int frame_cache_generation = 0;
@@ -70,7 +70,7 @@ get_frame_cache_generation ()
 /* The values behind the global "set backtrace ..." settings.  */
 set_backtrace_options user_set_backtrace_options;
 
-static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
+static frame_info_ptr get_prev_frame_raw (frame_info_ptr this_frame);
 static const char *frame_stop_reason_symbol_string (enum unwind_stop_reason reason);
 
 /* Status of some values cached in the frame_info object.  */
@@ -195,7 +195,7 @@ struct frame_info
 /* See frame.h.  */
 
 void
-set_frame_previous_pc_masked (struct frame_info *frame)
+set_frame_previous_pc_masked (frame_info_ptr frame)
 {
   frame->prev_pc.masked = true;
 }
@@ -203,7 +203,7 @@ set_frame_previous_pc_masked (struct frame_info *frame)
 /* See frame.h.  */
 
 bool
-get_frame_pc_masked (const struct frame_info *frame)
+get_frame_pc_masked (frame_info_ptr frame)
 {
   gdb_assert (frame->next != nullptr);
   gdb_assert (frame->next->prev_pc.status == CC_VALUE);
@@ -225,7 +225,7 @@ static htab_t frame_stash;
 static hashval_t
 frame_addr_hash (const void *ap)
 {
-  const struct frame_info *frame = (const struct frame_info *) ap;
+  const frame_info *frame = (const frame_info *) ap;
   const struct frame_id f_id = frame->this_id.value;
   hashval_t hash = 0;
 
@@ -252,8 +252,8 @@ frame_addr_hash (const void *ap)
 static int
 frame_addr_hash_eq (const void *a, const void *b)
 {
-  const struct frame_info *f_entry = (const struct frame_info *) a;
-  const struct frame_info *f_element = (const struct frame_info *) b;
+  const frame_info *f_entry = (const frame_info *) a;
+  const frame_info *f_element = (const frame_info *) b;
 
   return f_entry->this_id.value == f_element->this_id.value;
 }
@@ -280,8 +280,8 @@ frame_stash_add (frame_info *frame)
   /* Do not try to stash the sentinel frame.  */
   gdb_assert (frame->level >= 0);
 
-  frame_info **slot = (struct frame_info **) htab_find_slot (frame_stash,
-							     frame, INSERT);
+  frame_info **slot = (frame_info **) htab_find_slot (frame_stash,
+						      frame, INSERT);
 
   /* If we already have a frame in the stack with the same id, we
      either have a stack cycle (corrupted stack?), or some bug
@@ -298,15 +298,15 @@ frame_stash_add (frame_info *frame)
    given frame ID.  If found, return that frame.  Otherwise return
    NULL.  */
 
-static struct frame_info *
+static frame_info_ptr 
 frame_stash_find (struct frame_id id)
 {
   struct frame_info dummy;
-  struct frame_info *frame;
+  frame_info *frame;
 
   dummy.this_id.value = id;
-  frame = (struct frame_info *) htab_find (frame_stash, &dummy);
-  return frame;
+  frame = (frame_info *) htab_find (frame_stash, &dummy);
+  return frame_info_ptr (frame);
 }
 
 /* Internal function to invalidate the frame stash by removing all
@@ -505,8 +505,8 @@ frame_info::to_string () const
    Return FRAME if FRAME is a non-artificial frame.
    Return NULL if FRAME is the start of an artificial-only chain.  */
 
-static struct frame_info *
-skip_artificial_frames (struct frame_info *frame)
+static frame_info_ptr 
+skip_artificial_frames (frame_info_ptr frame)
 {
   /* Note we use get_prev_frame_always, and not get_prev_frame.  The
      latter will truncate the frame chain, leading to this function
@@ -526,8 +526,8 @@ skip_artificial_frames (struct frame_info *frame)
   return frame;
 }
 
-struct frame_info *
-skip_unwritable_frames (struct frame_info *frame)
+frame_info_ptr 
+skip_unwritable_frames (frame_info_ptr frame)
 {
   while (gdbarch_code_of_frame_writable (get_frame_arch (frame), frame) == 0)
     {
@@ -541,8 +541,8 @@ skip_unwritable_frames (struct frame_info *frame)
 
 /* See frame.h.  */
 
-struct frame_info *
-skip_tailcall_frames (struct frame_info *frame)
+frame_info_ptr 
+skip_tailcall_frames (frame_info_ptr frame)
 {
   while (get_frame_type (frame) == TAILCALL_FRAME)
     {
@@ -560,7 +560,7 @@ skip_tailcall_frames (struct frame_info *frame)
    frame.  */
 
 static void
-compute_frame_id (struct frame_info *fi)
+compute_frame_id (frame_info_ptr fi)
 {
   FRAME_SCOPED_DEBUG_ENTER_EXIT;
 
@@ -606,7 +606,7 @@ compute_frame_id (struct frame_info *fi)
    frame.  */
 
 struct frame_id
-get_frame_id (struct frame_info *fi)
+get_frame_id (frame_info_ptr fi)
 {
   if (fi == NULL)
     return null_frame_id;
@@ -629,7 +629,7 @@ get_frame_id (struct frame_info *fi)
 
       /* Since this is the first frame in the chain, this should
 	 always succeed.  */
-      bool stashed = frame_stash_add (fi);
+      bool stashed = frame_stash_add (fi.get ());
       gdb_assert (stashed);
     }
 
@@ -637,15 +637,15 @@ get_frame_id (struct frame_info *fi)
 }
 
 struct frame_id
-get_stack_frame_id (struct frame_info *next_frame)
+get_stack_frame_id (frame_info_ptr next_frame)
 {
   return get_frame_id (skip_artificial_frames (next_frame));
 }
 
 struct frame_id
-frame_unwind_caller_id (struct frame_info *next_frame)
+frame_unwind_caller_id (frame_info_ptr next_frame)
 {
-  struct frame_info *this_frame;
+  frame_info_ptr this_frame;
 
   /* Use get_prev_frame_always, and not get_prev_frame.  The latter
      will truncate the frame chain, leading to this function
@@ -866,10 +866,10 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
   return inner;
 }
 
-struct frame_info *
+frame_info_ptr 
 frame_find_by_id (struct frame_id id)
 {
-  struct frame_info *frame, *prev_frame;
+  frame_info_ptr frame, prev_frame;
 
   /* ZERO denotes the null frame, let the caller decide what to do
      about it.  Should it instead return get_current_frame()?  */
@@ -878,7 +878,7 @@ frame_find_by_id (struct frame_id id)
 
   /* Check for the sentinel frame.  */
   if (id == sentinel_frame_id)
-    return sentinel_frame;
+    return frame_info_ptr (sentinel_frame);
 
   /* Try using the frame stash first.  Finding it there removes the need
      to perform the search by looping over all frames, which can be very
@@ -919,7 +919,7 @@ frame_find_by_id (struct frame_id id)
 }
 
 static CORE_ADDR
-frame_unwind_pc (struct frame_info *this_frame)
+frame_unwind_pc (frame_info_ptr this_frame)
 {
   if (this_frame->prev_pc.status == CC_UNKNOWN)
     {
@@ -994,7 +994,7 @@ frame_unwind_pc (struct frame_info *this_frame)
 }
 
 CORE_ADDR
-frame_unwind_caller_pc (struct frame_info *this_frame)
+frame_unwind_caller_pc (frame_info_ptr this_frame)
 {
   this_frame = skip_artificial_frames (this_frame);
 
@@ -1007,9 +1007,9 @@ frame_unwind_caller_pc (struct frame_info *this_frame)
 }
 
 bool
-get_frame_func_if_available (frame_info *this_frame, CORE_ADDR *pc)
+get_frame_func_if_available (frame_info_ptr this_frame, CORE_ADDR *pc)
 {
-  struct frame_info *next_frame = this_frame->next;
+  frame_info *next_frame = this_frame->next;
 
   if (next_frame->prev_func.status == CC_UNKNOWN)
     {
@@ -1050,7 +1050,7 @@ get_frame_func_if_available (frame_info *this_frame, CORE_ADDR *pc)
 }
 
 CORE_ADDR
-get_frame_func (struct frame_info *this_frame)
+get_frame_func (frame_info_ptr this_frame)
 {
   CORE_ADDR pc;
 
@@ -1061,7 +1061,7 @@ get_frame_func (struct frame_info *this_frame)
 }
 
 std::unique_ptr<readonly_detached_regcache>
-frame_save_as_regcache (struct frame_info *this_frame)
+frame_save_as_regcache (frame_info_ptr this_frame)
 {
   auto cooked_read = [this_frame] (int regnum, gdb_byte *buf)
     {
@@ -1078,9 +1078,9 @@ frame_save_as_regcache (struct frame_info *this_frame)
 }
 
 void
-frame_pop (struct frame_info *this_frame)
+frame_pop (frame_info_ptr this_frame)
 {
-  struct frame_info *prev_frame;
+  frame_info_ptr prev_frame;
 
   if (get_frame_type (this_frame) == DUMMY_FRAME)
     {
@@ -1127,7 +1127,7 @@ frame_pop (struct frame_info *this_frame)
 }
 
 void
-frame_register_unwind (frame_info *next_frame, int regnum,
+frame_register_unwind (frame_info_ptr next_frame, int regnum,
 		       int *optimizedp, int *unavailablep,
 		       enum lval_type *lvalp, CORE_ADDR *addrp,
 		       int *realnump, gdb_byte *bufferp)
@@ -1170,7 +1170,7 @@ frame_register_unwind (frame_info *next_frame, int regnum,
 }
 
 void
-frame_register (struct frame_info *frame, int regnum,
+frame_register (frame_info_ptr frame, int regnum,
 		int *optimizedp, int *unavailablep, enum lval_type *lvalp,
 		CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp)
 {
@@ -1185,12 +1185,12 @@ frame_register (struct frame_info *frame, int regnum,
   /* Obtain the register value by unwinding the register from the next
      (more inner frame).  */
   gdb_assert (frame != NULL && frame->next != NULL);
-  frame_register_unwind (frame->next, regnum, optimizedp, unavailablep,
-			 lvalp, addrp, realnump, bufferp);
+  frame_register_unwind (frame_info_ptr (frame->next), regnum, optimizedp,
+			 unavailablep, lvalp, addrp, realnump, bufferp);
 }
 
 void
-frame_unwind_register (frame_info *next_frame, int regnum, gdb_byte *buf)
+frame_unwind_register (frame_info_ptr next_frame, int regnum, gdb_byte *buf)
 {
   int optimized;
   int unavailable;
@@ -1210,14 +1210,14 @@ frame_unwind_register (frame_info *next_frame, int regnum, gdb_byte *buf)
 }
 
 void
-get_frame_register (struct frame_info *frame,
+get_frame_register (frame_info_ptr frame,
 		    int regnum, gdb_byte *buf)
 {
-  frame_unwind_register (frame->next, regnum, buf);
+  frame_unwind_register (frame_info_ptr (frame->next), regnum, buf);
 }
 
 struct value *
-frame_unwind_register_value (frame_info *next_frame, int regnum)
+frame_unwind_register_value (frame_info_ptr next_frame, int regnum)
 {
   FRAME_SCOPED_DEBUG_ENTER_EXIT;
 
@@ -1280,13 +1280,13 @@ frame_unwind_register_value (frame_info *next_frame, int regnum)
 }
 
 struct value *
-get_frame_register_value (struct frame_info *frame, int regnum)
+get_frame_register_value (frame_info_ptr frame, int regnum)
 {
-  return frame_unwind_register_value (frame->next, regnum);
+  return frame_unwind_register_value (frame_info_ptr (frame->next), regnum);
 }
 
 LONGEST
-frame_unwind_register_signed (frame_info *next_frame, int regnum)
+frame_unwind_register_signed (frame_info_ptr next_frame, int regnum)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (next_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -1312,13 +1312,13 @@ frame_unwind_register_signed (frame_info *next_frame, int regnum)
 }
 
 LONGEST
-get_frame_register_signed (struct frame_info *frame, int regnum)
+get_frame_register_signed (frame_info_ptr frame, int regnum)
 {
-  return frame_unwind_register_signed (frame->next, regnum);
+  return frame_unwind_register_signed (frame_info_ptr (frame->next), regnum);
 }
 
 ULONGEST
-frame_unwind_register_unsigned (frame_info *next_frame, int regnum)
+frame_unwind_register_unsigned (frame_info_ptr next_frame, int regnum)
 {
   struct gdbarch *gdbarch = frame_unwind_arch (next_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -1346,13 +1346,13 @@ frame_unwind_register_unsigned (frame_info *next_frame, int regnum)
 }
 
 ULONGEST
-get_frame_register_unsigned (struct frame_info *frame, int regnum)
+get_frame_register_unsigned (frame_info_ptr frame, int regnum)
 {
-  return frame_unwind_register_unsigned (frame->next, regnum);
+  return frame_unwind_register_unsigned (frame_info_ptr (frame->next), regnum);
 }
 
 bool
-read_frame_register_unsigned (frame_info *frame, int regnum,
+read_frame_register_unsigned (frame_info_ptr frame, int regnum,
 			      ULONGEST *val)
 {
   struct value *regval = get_frame_register_value (frame, regnum);
@@ -1373,7 +1373,7 @@ read_frame_register_unsigned (frame_info *frame, int regnum,
 }
 
 void
-put_frame_register (struct frame_info *frame, int regnum,
+put_frame_register (frame_info_ptr frame, int regnum,
 		    const gdb_byte *buf)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1411,7 +1411,7 @@ put_frame_register (struct frame_info *frame, int regnum,
    Returns 0 if the register value could not be found.  */
 
 bool
-deprecated_frame_register_read (frame_info *frame, int regnum,
+deprecated_frame_register_read (frame_info_ptr frame, int regnum,
 				gdb_byte *myaddr)
 {
   int optimized;
@@ -1427,7 +1427,7 @@ deprecated_frame_register_read (frame_info *frame, int regnum,
 }
 
 bool
-get_frame_register_bytes (frame_info *frame, int regnum,
+get_frame_register_bytes (frame_info_ptr frame, int regnum,
 			  CORE_ADDR offset,
 			  gdb::array_view<gdb_byte> buffer,
 			  int *optimizedp, int *unavailablep)
@@ -1485,8 +1485,9 @@ get_frame_register_bytes (frame_info *frame, int regnum,
 	}
       else
 	{
-	  struct value *value = frame_unwind_register_value (frame->next,
-							     regnum);
+	  struct value *value
+	    = frame_unwind_register_value (frame_info_ptr (frame->next),
+					   regnum);
 	  gdb_assert (value != NULL);
 	  *optimizedp = value_optimized_out (value);
 	  *unavailablep = !value_entirely_available (value);
@@ -1515,7 +1516,7 @@ get_frame_register_bytes (frame_info *frame, int regnum,
 }
 
 void
-put_frame_register_bytes (struct frame_info *frame, int regnum,
+put_frame_register_bytes (frame_info_ptr frame, int regnum,
 			  CORE_ADDR offset,
 			  gdb::array_view<const gdb_byte> buffer)
 {
@@ -1544,8 +1545,9 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 	}
       else
 	{
-	  struct value *value = frame_unwind_register_value (frame->next,
-							     regnum);
+	  struct value *value
+	    = frame_unwind_register_value (frame_info_ptr (frame->next),
+					   regnum);
 	  gdb_assert (value != NULL);
 
 	  memcpy ((char *) value_contents_writeable (value).data () + offset,
@@ -1564,10 +1566,10 @@ put_frame_register_bytes (struct frame_info *frame, int regnum,
 
 /* Create a sentinel frame.  */
 
-static struct frame_info *
+static frame_info *
 create_sentinel_frame (struct program_space *pspace, struct regcache *regcache)
 {
-  struct frame_info *frame = FRAME_OBSTACK_ZALLOC (struct frame_info);
+  frame_info *frame = FRAME_OBSTACK_ZALLOC (struct frame_info);
 
   frame->level = -1;
   frame->pspace = pspace;
@@ -1605,12 +1607,12 @@ frame_obstack_zalloc (unsigned long size)
   return data;
 }
 
-static struct frame_info *get_prev_frame_always_1 (struct frame_info *this_frame);
+static frame_info_ptr get_prev_frame_always_1 (frame_info_ptr this_frame);
 
-struct frame_info *
+frame_info_ptr 
 get_current_frame (void)
 {
-  struct frame_info *current_frame;
+  frame_info_ptr current_frame;
 
   /* First check, and report, the lack of registers.  Having GDB
      report "No stack!" or "No memory" when the target doesn't even
@@ -1642,7 +1644,7 @@ get_current_frame (void)
      want to leave with the current frame created and linked in --
      we should never end up with the sentinel frame as outermost
      frame.  */
-  current_frame = get_prev_frame_always_1 (sentinel_frame);
+  current_frame = get_prev_frame_always_1 (frame_info_ptr (sentinel_frame));
   gdb_assert (current_frame != NULL);
 
   return current_frame;
@@ -1673,7 +1675,7 @@ static int selected_frame_level = -1;
 
 /* The cached frame_info object pointing to the selected frame.
    Looked up on demand by get_selected_frame.  */
-static struct frame_info *selected_frame;
+static frame_info_ptr selected_frame;
 
 /* See frame.h.  */
 
@@ -1711,7 +1713,7 @@ restore_selected_frame (frame_id frame_id, int frame_level)
 void
 lookup_selected_frame (struct frame_id a_frame_id, int frame_level)
 {
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
   int count;
 
   /* This either means there was no selected frame, or the selected
@@ -1801,7 +1803,7 @@ has_stack_frames ()
 
 /* See frame.h.  */
 
-struct frame_info *
+frame_info_ptr 
 get_selected_frame (const char *message)
 {
   if (selected_frame == NULL)
@@ -1820,7 +1822,7 @@ get_selected_frame (const char *message)
    the inferior does not have a frame; in that case it will return
    NULL instead of calling error().  */
 
-struct frame_info *
+frame_info_ptr 
 deprecated_safe_get_selected_frame (void)
 {
   if (!has_stack_frames ())
@@ -1831,7 +1833,7 @@ deprecated_safe_get_selected_frame (void)
 /* Select frame FI (or NULL - to invalidate the selected frame).  */
 
 void
-select_frame (struct frame_info *fi)
+select_frame (frame_info_ptr fi)
 {
   selected_frame = fi;
   selected_frame_level = frame_relative_level (fi);
@@ -1905,10 +1907,10 @@ select_frame (struct frame_info *fi)
 /* Create an arbitrary (i.e. address specified by user) or innermost frame.
    Always returns a non-NULL value.  */
 
-struct frame_info *
+frame_info_ptr 
 create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
 {
-  struct frame_info *fi;
+  frame_info *fi;
 
   frame_debug_printf ("addr=%s, pc=%s", hex_string (addr), hex_string (pc));
 
@@ -1930,25 +1932,25 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
 
   /* Select/initialize both the unwind function and the frame's type
      based on the PC.  */
-  frame_unwind_find_by_frame (fi, &fi->prologue_cache);
+  frame_unwind_find_by_frame (frame_info_ptr (fi), &fi->prologue_cache);
 
   fi->this_id.p = frame_id_status::COMPUTED;
   fi->this_id.value = frame_id_build (addr, pc);
 
   frame_debug_printf ("  -> %s", fi->to_string ().c_str ());
 
-  return fi;
+  return frame_info_ptr (fi);
 }
 
 /* Return the frame that THIS_FRAME calls (NULL if THIS_FRAME is the
    innermost frame).  Be careful to not fall off the bottom of the
    frame chain and onto the sentinel frame.  */
 
-struct frame_info *
-get_next_frame (struct frame_info *this_frame)
+frame_info_ptr 
+get_next_frame (frame_info_ptr this_frame)
 {
   if (this_frame->level > 0)
-    return this_frame->next;
+    return frame_info_ptr (this_frame->next);
   else
     return NULL;
 }
@@ -1957,8 +1959,8 @@ get_next_frame (struct frame_info *this_frame)
    innermost (i.e. current) frame, return the sentinel frame.  Thus,
    unlike get_next_frame(), NULL will never be returned.  */
 
-struct frame_info *
-get_next_frame_sentinel_okay (struct frame_info *this_frame)
+frame_info_ptr 
+get_next_frame_sentinel_okay (frame_info_ptr this_frame)
 {
   gdb_assert (this_frame != NULL);
 
@@ -1969,7 +1971,7 @@ get_next_frame_sentinel_okay (struct frame_info *this_frame)
      is likely a coding error.  */
   gdb_assert (this_frame != sentinel_frame);
 
-  return this_frame->next;
+  return frame_info_ptr (this_frame->next);
 }
 
 /* Observer for the target_changed event.  */
@@ -1985,12 +1987,10 @@ frame_observer_target_changed (struct target_ops *target)
 void
 reinit_frame_cache (void)
 {
-  struct frame_info *fi;
-
   ++frame_cache_generation;
 
   /* Tear down all frame caches.  */
-  for (fi = sentinel_frame; fi != NULL; fi = fi->prev)
+  for (frame_info *fi = sentinel_frame; fi != NULL; fi = fi->prev)
     {
       if (fi->prologue_cache && fi->unwind->dealloc_cache)
 	fi->unwind->dealloc_cache (fi, fi->prologue_cache);
@@ -2020,7 +2020,7 @@ reinit_frame_cache (void)
    relative to this particular frame.  */
 
 static void
-frame_register_unwind_location (struct frame_info *this_frame, int regnum,
+frame_register_unwind_location (frame_info_ptr this_frame, int regnum,
 				int *optimizedp, enum lval_type *lvalp,
 				CORE_ADDR *addrp, int *realnump)
 {
@@ -2063,10 +2063,10 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum,
    then the frame_id of the inline frame, calculated based off the frame_id
    of the previous frame, should also be a duplicate.  */
 
-static struct frame_info *
-get_prev_frame_maybe_check_cycle (struct frame_info *this_frame)
+static frame_info_ptr 
+get_prev_frame_maybe_check_cycle (frame_info_ptr this_frame)
 {
-  struct frame_info *prev_frame = get_prev_frame_raw (this_frame);
+  frame_info_ptr prev_frame = get_prev_frame_raw (this_frame);
 
   /* Don't compute the frame id of the current frame yet.  Unwinding
      the sentinel frame can fail (e.g., if the thread is gone and we
@@ -2120,7 +2120,7 @@ get_prev_frame_maybe_check_cycle (struct frame_info *this_frame)
 	 PREV_FRAME into the cache; if PREV_FRAME is unique then we do want
 	 it in the cache, but if it is a duplicate and CYCLE_DETECTION_P is
 	 false, then we don't want to unlink it.  */
-      if (!frame_stash_add (prev_frame) && cycle_detection_p)
+      if (!frame_stash_add (prev_frame.get ()) && cycle_detection_p)
 	{
 	  /* Another frame with the same id was already in the stash.  We just
 	     detected a cycle.  */
@@ -2151,8 +2151,8 @@ get_prev_frame_maybe_check_cycle (struct frame_info *this_frame)
    TRY_CATCH block.  Return the frame that called THIS_FRAME or NULL if
    there is no such frame.  This may throw an exception.  */
 
-static struct frame_info *
-get_prev_frame_always_1 (struct frame_info *this_frame)
+static frame_info_ptr 
+get_prev_frame_always_1 (frame_info_ptr this_frame)
 {
   FRAME_SCOPED_DEBUG_ENTER_EXIT;
 
@@ -2178,7 +2178,7 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
 	frame_debug_printf
 	  ("  -> nullptr // %s // cached",
 	   frame_stop_reason_symbol_string (this_frame->stop_reason));
-      return this_frame->prev;
+      return frame_info_ptr (this_frame->prev);
     }
 
   /* If the frame unwinder hasn't been selected yet, we must do so
@@ -2236,9 +2236,9 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
      See the comment at frame_id_inner for details.  */
   if (get_frame_type (this_frame) == NORMAL_FRAME
       && this_frame->next->unwind->type == NORMAL_FRAME
-      && frame_id_inner (get_frame_arch (this_frame->next),
+      && frame_id_inner (get_frame_arch (frame_info_ptr (this_frame->next)),
 			 get_frame_id (this_frame),
-			 get_frame_id (this_frame->next)))
+			 get_frame_id (frame_info_ptr (this_frame->next))))
     {
       CORE_ADDR this_pc_in_block;
       struct minimal_symbol *morestack_msym;
@@ -2274,8 +2274,8 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
   if (this_frame->level > 0
       && gdbarch_pc_regnum (gdbarch) >= 0
       && get_frame_type (this_frame) == NORMAL_FRAME
-      && (get_frame_type (this_frame->next) == NORMAL_FRAME
-	  || get_frame_type (this_frame->next) == INLINE_FRAME))
+      && (get_frame_type (frame_info_ptr (this_frame->next)) == NORMAL_FRAME
+	  || get_frame_type (frame_info_ptr (this_frame->next)) == INLINE_FRAME))
     {
       int optimized, realnum, nrealnum;
       enum lval_type lval, nlval;
@@ -2307,10 +2307,10 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
    Unlike get_prev_frame, this function always tries to unwind the
    frame.  */
 
-struct frame_info *
-get_prev_frame_always (struct frame_info *this_frame)
+frame_info_ptr 
+get_prev_frame_always (frame_info_ptr this_frame)
 {
-  struct frame_info *prev_frame = NULL;
+  frame_info_ptr prev_frame = NULL;
 
   try
     {
@@ -2347,10 +2347,10 @@ get_prev_frame_always (struct frame_info *this_frame)
 /* Construct a new "struct frame_info" and link it previous to
    this_frame.  */
 
-static struct frame_info *
-get_prev_frame_raw (struct frame_info *this_frame)
+static frame_info_ptr 
+get_prev_frame_raw (frame_info_ptr this_frame)
 {
-  struct frame_info *prev_frame;
+  frame_info *prev_frame;
 
   /* Allocate the new frame but do not wire it in to the frame chain.
      Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along
@@ -2391,17 +2391,17 @@ get_prev_frame_raw (struct frame_info *this_frame)
 
   /* Link it in.  */
   this_frame->prev = prev_frame;
-  prev_frame->next = this_frame;
+  prev_frame->next = this_frame.get ();
 
   frame_debug_printf ("  -> %s", prev_frame->to_string ().c_str ());
 
-  return prev_frame;
+  return frame_info_ptr (prev_frame);
 }
 
 /* Debug routine to print a NULL frame being returned.  */
 
 static void
-frame_debug_got_null_frame (struct frame_info *this_frame,
+frame_debug_got_null_frame (frame_info_ptr this_frame,
 			    const char *reason)
 {
   if (frame_debug)
@@ -2416,7 +2416,7 @@ frame_debug_got_null_frame (struct frame_info *this_frame,
 /* Is this (non-sentinel) frame in the "main"() function?  */
 
 static bool
-inside_main_func (frame_info *this_frame)
+inside_main_func (frame_info_ptr this_frame)
 {
   if (current_program_space->symfile_object_file == nullptr)
     return false;
@@ -2453,7 +2453,7 @@ inside_main_func (frame_info *this_frame)
 /* Test whether THIS_FRAME is inside the process entry point function.  */
 
 static bool
-inside_entry_func (frame_info *this_frame)
+inside_entry_func (frame_info_ptr this_frame)
 {
   CORE_ADDR entry_point;
 
@@ -2472,8 +2472,8 @@ inside_entry_func (frame_info *this_frame)
    This function should not contain target-dependent tests, such as
    checking whether the program-counter is zero.  */
 
-struct frame_info *
-get_prev_frame (struct frame_info *this_frame)
+frame_info_ptr 
+get_prev_frame (frame_info_ptr this_frame)
 {
   FRAME_SCOPED_DEBUG_ENTER_EXIT;
 
@@ -2571,21 +2571,21 @@ get_prev_frame (struct frame_info *this_frame)
 }
 
 CORE_ADDR
-get_frame_pc (struct frame_info *frame)
+get_frame_pc (frame_info_ptr frame)
 {
   gdb_assert (frame->next != NULL);
-  return frame_unwind_pc (frame->next);
+  return frame_unwind_pc (frame_info_ptr (frame->next));
 }
 
 bool
-get_frame_pc_if_available (frame_info *frame, CORE_ADDR *pc)
+get_frame_pc_if_available (frame_info_ptr frame, CORE_ADDR *pc)
 {
 
   gdb_assert (frame->next != NULL);
 
   try
     {
-      *pc = frame_unwind_pc (frame->next);
+      *pc = frame_unwind_pc (frame_info_ptr (frame->next));
     }
   catch (const gdb_exception_error &ex)
     {
@@ -2601,12 +2601,12 @@ get_frame_pc_if_available (frame_info *frame, CORE_ADDR *pc)
 /* Return an address that falls within THIS_FRAME's code block.  */
 
 CORE_ADDR
-get_frame_address_in_block (struct frame_info *this_frame)
+get_frame_address_in_block (frame_info_ptr this_frame)
 {
   /* A draft address.  */
   CORE_ADDR pc = get_frame_pc (this_frame);
 
-  struct frame_info *next_frame = this_frame->next;
+  frame_info_ptr next_frame (this_frame->next);
 
   /* Calling get_frame_pc returns the resume address for THIS_FRAME.
      Normally the resume address is inside the body of the function
@@ -2648,7 +2648,7 @@ get_frame_address_in_block (struct frame_info *this_frame)
      "calling" normal function should not be adjusted either.  */
 
   while (get_frame_type (next_frame) == INLINE_FRAME)
-    next_frame = next_frame->next;
+    next_frame = frame_info_ptr (next_frame->next);
 
   if ((get_frame_type (next_frame) == NORMAL_FRAME
        || get_frame_type (next_frame) == TAILCALL_FRAME)
@@ -2661,7 +2661,7 @@ get_frame_address_in_block (struct frame_info *this_frame)
 }
 
 bool
-get_frame_address_in_block_if_available (frame_info *this_frame,
+get_frame_address_in_block_if_available (frame_info_ptr this_frame,
 					 CORE_ADDR *pc)
 {
 
@@ -2680,9 +2680,9 @@ get_frame_address_in_block_if_available (frame_info *this_frame,
 }
 
 symtab_and_line
-find_frame_sal (frame_info *frame)
+find_frame_sal (frame_info_ptr frame)
 {
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
   int notcurrent;
   CORE_ADDR pc;
 
@@ -2738,7 +2738,7 @@ find_frame_sal (frame_info *frame)
 /* Per "frame.h", return the ``address'' of the frame.  Code should
    really be using get_frame_id().  */
 CORE_ADDR
-get_frame_base (struct frame_info *fi)
+get_frame_base (frame_info_ptr fi)
 {
   return get_frame_id (fi).stack_addr;
 }
@@ -2746,7 +2746,7 @@ get_frame_base (struct frame_info *fi)
 /* High-level offsets into the frame.  Used by the debug info.  */
 
 CORE_ADDR
-get_frame_base_address (struct frame_info *fi)
+get_frame_base_address (frame_info_ptr fi)
 {
   if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
@@ -2760,7 +2760,7 @@ get_frame_base_address (struct frame_info *fi)
 }
 
 CORE_ADDR
-get_frame_locals_address (struct frame_info *fi)
+get_frame_locals_address (frame_info_ptr fi)
 {
   if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
@@ -2775,7 +2775,7 @@ get_frame_locals_address (struct frame_info *fi)
 }
 
 CORE_ADDR
-get_frame_args_address (struct frame_info *fi)
+get_frame_args_address (frame_info_ptr fi)
 {
   if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
@@ -2793,7 +2793,7 @@ get_frame_args_address (struct frame_info *fi)
    otherwise.  */
 
 bool
-frame_unwinder_is (frame_info *fi, const frame_unwind *unwinder)
+frame_unwinder_is (frame_info_ptr fi, const frame_unwind *unwinder)
 {
   if (fi->unwind == nullptr)
     frame_unwind_find_by_frame (fi, &fi->prologue_cache);
@@ -2805,7 +2805,7 @@ frame_unwinder_is (frame_info *fi, const frame_unwind *unwinder)
    or -1 for a NULL frame.  */
 
 int
-frame_relative_level (struct frame_info *fi)
+frame_relative_level (frame_info_ptr fi)
 {
   if (fi == NULL)
     return -1;
@@ -2814,7 +2814,7 @@ frame_relative_level (struct frame_info *fi)
 }
 
 enum frame_type
-get_frame_type (struct frame_info *frame)
+get_frame_type (frame_info_ptr frame)
 {
   if (frame->unwind == NULL)
     /* Initialize the frame's unwinder because that's what
@@ -2824,13 +2824,13 @@ get_frame_type (struct frame_info *frame)
 }
 
 struct program_space *
-get_frame_program_space (struct frame_info *frame)
+get_frame_program_space (frame_info_ptr frame)
 {
   return frame->pspace;
 }
 
 struct program_space *
-frame_unwind_program_space (struct frame_info *this_frame)
+frame_unwind_program_space (frame_info_ptr this_frame)
 {
   gdb_assert (this_frame);
 
@@ -2841,7 +2841,7 @@ frame_unwind_program_space (struct frame_info *this_frame)
 }
 
 const address_space *
-get_frame_address_space (struct frame_info *frame)
+get_frame_address_space (frame_info_ptr frame)
 {
   return frame->aspace;
 }
@@ -2849,14 +2849,14 @@ get_frame_address_space (struct frame_info *frame)
 /* Memory access methods.  */
 
 void
-get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr,
+get_frame_memory (frame_info_ptr this_frame, CORE_ADDR addr,
 		  gdb::array_view<gdb_byte> buffer)
 {
   read_memory (addr, buffer.data (), buffer.size ());
 }
 
 LONGEST
-get_frame_memory_signed (struct frame_info *this_frame, CORE_ADDR addr,
+get_frame_memory_signed (frame_info_ptr this_frame, CORE_ADDR addr,
 			 int len)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2866,7 +2866,7 @@ get_frame_memory_signed (struct frame_info *this_frame, CORE_ADDR addr,
 }
 
 ULONGEST
-get_frame_memory_unsigned (struct frame_info *this_frame, CORE_ADDR addr,
+get_frame_memory_unsigned (frame_info_ptr this_frame, CORE_ADDR addr,
 			   int len)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2876,7 +2876,7 @@ get_frame_memory_unsigned (struct frame_info *this_frame, CORE_ADDR addr,
 }
 
 bool
-safe_frame_unwind_memory (struct frame_info *this_frame,
+safe_frame_unwind_memory (frame_info_ptr this_frame,
 			  CORE_ADDR addr, gdb::array_view<gdb_byte> buffer)
 {
   /* NOTE: target_read_memory returns zero on success!  */
@@ -2886,13 +2886,13 @@ safe_frame_unwind_memory (struct frame_info *this_frame,
 /* Architecture methods.  */
 
 struct gdbarch *
-get_frame_arch (struct frame_info *this_frame)
+get_frame_arch (frame_info_ptr this_frame)
 {
-  return frame_unwind_arch (this_frame->next);
+  return frame_unwind_arch (frame_info_ptr (this_frame->next));
 }
 
 struct gdbarch *
-frame_unwind_arch (struct frame_info *next_frame)
+frame_unwind_arch (frame_info_ptr next_frame)
 {
   if (!next_frame->prev_arch.p)
     {
@@ -2918,7 +2918,7 @@ frame_unwind_arch (struct frame_info *next_frame)
 }
 
 struct gdbarch *
-frame_unwind_caller_arch (struct frame_info *next_frame)
+frame_unwind_caller_arch (frame_info_ptr next_frame)
 {
   next_frame = skip_artificial_frames (next_frame);
 
@@ -2933,7 +2933,7 @@ frame_unwind_caller_arch (struct frame_info *next_frame)
 /* Gets the language of FRAME.  */
 
 enum language
-get_frame_language (struct frame_info *frame)
+get_frame_language (frame_info_ptr frame)
 {
   CORE_ADDR pc = 0;
   bool pc_p = false;
@@ -2974,19 +2974,19 @@ get_frame_language (struct frame_info *frame)
 /* Stack pointer methods.  */
 
 CORE_ADDR
-get_frame_sp (struct frame_info *this_frame)
+get_frame_sp (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
 
   /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to
      operate on THIS_FRAME now.  */
-  return gdbarch_unwind_sp (gdbarch, this_frame->next);
+  return gdbarch_unwind_sp (gdbarch, frame_info_ptr (this_frame->next));
 }
 
 /* Return the reason why we can't unwind past FRAME.  */
 
 enum unwind_stop_reason
-get_frame_unwind_stop_reason (struct frame_info *frame)
+get_frame_unwind_stop_reason (frame_info_ptr frame)
 {
   /* Fill-in STOP_REASON.  */
   get_prev_frame_always (frame);
@@ -3014,7 +3014,7 @@ unwind_stop_reason_to_string (enum unwind_stop_reason reason)
 }
 
 const char *
-frame_stop_reason_string (struct frame_info *fi)
+frame_stop_reason_string (frame_info_ptr fi)
 {
   gdb_assert (fi->prev_p);
   gdb_assert (fi->prev == NULL);
@@ -3050,7 +3050,7 @@ frame_stop_reason_symbol_string (enum unwind_stop_reason reason)
    FRAME.  */
 
 void
-frame_cleanup_after_sniffer (struct frame_info *frame)
+frame_cleanup_after_sniffer (frame_info_ptr frame)
 {
   /* The sniffer should not allocate a prologue cache if it did not
      match this frame.  */
@@ -3080,7 +3080,7 @@ frame_cleanup_after_sniffer (struct frame_info *frame)
    frame_cleanup_after_sniffer.  */
 
 void
-frame_prepare_for_sniffer (struct frame_info *frame,
+frame_prepare_for_sniffer (frame_info_ptr frame,
 			   const struct frame_unwind *unwind)
 {
   gdb_assert (frame->unwind == NULL);
diff --git a/gdb/frame.h b/gdb/frame.h
index 9ad2599331f..759cd32c5e3 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -111,7 +111,7 @@ enum frame_id_stack_status
 
 /* The frame object.  */
 
-struct frame_info;
+class frame_info_ptr;
 
 /* The frame object's ID.  This provides a per-frame unique identifier
    that can be used to relocate a `struct frame_info' after a target
@@ -324,7 +324,7 @@ enum frame_type
 /* On demand, create the inner most frame using information found in
    the inferior.  If the inner most frame can't be created, throw an
    error.  */
-extern struct frame_info *get_current_frame (void);
+extern frame_info_ptr get_current_frame (void);
 
 /* Does the current target interface have enough state to be able to
    query the current inferior for frame info, and is the inferior in a
@@ -349,11 +349,11 @@ extern void reinit_frame_cache (void);
    It should instead, when a thread has previously had its frame
    selected (but not resumed) and the frame cache invalidated, find
    and then return that thread's previously selected frame.  */
-extern struct frame_info *get_selected_frame (const char *message = nullptr);
+extern frame_info_ptr get_selected_frame (const char *message = nullptr);
 
 /* Select a specific frame.  NULL implies re-select the inner most
    frame.  */
-extern void select_frame (struct frame_info *);
+extern void select_frame (frame_info_ptr );
 
 /* Save the frame ID and frame level of the selected frame in FRAME_ID
    and FRAME_LEVEL, to be restored later with restore_selected_frame.
@@ -385,23 +385,23 @@ extern void lookup_selected_frame (frame_id frame_id, int frame_level);
 
 /* Given a FRAME, return the next (more inner, younger) or previous
    (more outer, older) frame.  */
-extern struct frame_info *get_prev_frame (struct frame_info *);
-extern struct frame_info *get_next_frame (struct frame_info *);
+extern frame_info_ptr get_prev_frame (frame_info_ptr );
+extern frame_info_ptr get_next_frame (frame_info_ptr );
 
 /* Like get_next_frame(), but allows return of the sentinel frame.  NULL
    is never returned.  */
-extern struct frame_info *get_next_frame_sentinel_okay (struct frame_info *);
+extern frame_info_ptr get_next_frame_sentinel_okay (frame_info_ptr );
 
 /* Return a "struct frame_info" corresponding to the frame that called
    THIS_FRAME.  Returns NULL if there is no such frame.
 
    Unlike get_prev_frame, this function always tries to unwind the
    frame.  */
-extern struct frame_info *get_prev_frame_always (struct frame_info *);
+extern frame_info_ptr get_prev_frame_always (frame_info_ptr );
 
 /* Given a frame's ID, relocate the frame.  Returns NULL if the frame
    is not found.  */
-extern struct frame_info *frame_find_by_id (struct frame_id id);
+extern frame_info_ptr frame_find_by_id (struct frame_id id);
 
 /* Base attributes of a frame: */
 
@@ -409,12 +409,12 @@ extern struct frame_info *frame_find_by_id (struct frame_id id);
    this frame.
 
    This replaced: frame->pc; */
-extern CORE_ADDR get_frame_pc (struct frame_info *);
+extern CORE_ADDR get_frame_pc (frame_info_ptr );
 
 /* Same as get_frame_pc, but return a boolean indication of whether
    the PC is actually available, instead of throwing an error.  */
 
-extern bool get_frame_pc_if_available (frame_info *frame, CORE_ADDR *pc);
+extern bool get_frame_pc_if_available (frame_info_ptr frame, CORE_ADDR *pc);
 
 /* An address (not necessarily aligned to an instruction boundary)
    that falls within THIS frame's code block.
@@ -429,32 +429,32 @@ extern bool get_frame_pc_if_available (frame_info *frame, CORE_ADDR *pc);
    function returns the frame's PC-1 which "should" be an address in
    the frame's block.  */
 
-extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame);
+extern CORE_ADDR get_frame_address_in_block (frame_info_ptr this_frame);
 
 /* Same as get_frame_address_in_block, but returns a boolean
    indication of whether the frame address is determinable (when the
    PC is unavailable, it will not be), instead of possibly throwing an
    error trying to read an unavailable PC.  */
 
-extern bool get_frame_address_in_block_if_available (frame_info *this_frame,
+extern bool get_frame_address_in_block_if_available (frame_info_ptr this_frame,
 						     CORE_ADDR *pc);
 
 /* The frame's inner-most bound.  AKA the stack-pointer.  Confusingly
    known as top-of-stack.  */
 
-extern CORE_ADDR get_frame_sp (struct frame_info *);
+extern CORE_ADDR get_frame_sp (frame_info_ptr );
 
 /* Following on from the `resume' address.  Return the entry point
    address of the function containing that resume address, or zero if
    that function isn't known.  */
-extern CORE_ADDR get_frame_func (struct frame_info *fi);
+extern CORE_ADDR get_frame_func (frame_info_ptr fi);
 
 /* Same as get_frame_func, but returns a boolean indication of whether
    the frame function is determinable (when the PC is unavailable, it
    will not be), instead of possibly throwing an error trying to read
    an unavailable PC.  */
 
-extern bool get_frame_func_if_available (frame_info *fi, CORE_ADDR *);
+extern bool get_frame_func_if_available (frame_info_ptr fi, CORE_ADDR *);
 
 /* Closely related to the resume address, various symbol table
    attributes that are determined by the PC.  Note that for a normal
@@ -474,12 +474,12 @@ extern bool get_frame_func_if_available (frame_info *fi, CORE_ADDR *);
    find_frame_symtab(), find_frame_function().  Each will need to be
    carefully considered to determine if the real intent was for it to
    apply to the PC or the adjusted PC.  */
-extern symtab_and_line find_frame_sal (frame_info *frame);
+extern symtab_and_line find_frame_sal (frame_info_ptr frame);
 
 /* Set the current source and line to the location given by frame
    FRAME, if possible.  */
 
-void set_current_sal_from_frame (struct frame_info *);
+void set_current_sal_from_frame (frame_info_ptr );
 
 /* Return the frame base (what ever that is) (DEPRECATED).
 
@@ -503,52 +503,52 @@ void set_current_sal_from_frame (struct frame_info *);
 
    This replaced: frame->frame; */
 
-extern CORE_ADDR get_frame_base (struct frame_info *);
+extern CORE_ADDR get_frame_base (frame_info_ptr );
 
 /* Return the per-frame unique identifer.  Can be used to relocate a
    frame after a frame cache flush (and other similar operations).  If
    FI is NULL, return the null_frame_id.  */
-extern struct frame_id get_frame_id (struct frame_info *fi);
-extern struct frame_id get_stack_frame_id (struct frame_info *fi);
-extern struct frame_id frame_unwind_caller_id (struct frame_info *next_frame);
+extern struct frame_id get_frame_id (frame_info_ptr fi);
+extern struct frame_id get_stack_frame_id (frame_info_ptr fi);
+extern struct frame_id frame_unwind_caller_id (frame_info_ptr next_frame);
 
 /* Assuming that a frame is `normal', return its base-address, or 0 if
    the information isn't available.  NOTE: This address is really only
    meaningful to the frame's high-level debug info.  */
-extern CORE_ADDR get_frame_base_address (struct frame_info *);
+extern CORE_ADDR get_frame_base_address (frame_info_ptr );
 
 /* Assuming that a frame is `normal', return the base-address of the
    local variables, or 0 if the information isn't available.  NOTE:
    This address is really only meaningful to the frame's high-level
    debug info.  Typically, the argument and locals share a single
    base-address.  */
-extern CORE_ADDR get_frame_locals_address (struct frame_info *);
+extern CORE_ADDR get_frame_locals_address (frame_info_ptr );
 
 /* Assuming that a frame is `normal', return the base-address of the
    parameter list, or 0 if that information isn't available.  NOTE:
    This address is really only meaningful to the frame's high-level
    debug info.  Typically, the argument and locals share a single
    base-address.  */
-extern CORE_ADDR get_frame_args_address (struct frame_info *);
+extern CORE_ADDR get_frame_args_address (frame_info_ptr );
 
 /* The frame's level: 0 for innermost, 1 for its caller, ...; or -1
    for an invalid frame).  */
-extern int frame_relative_level (struct frame_info *fi);
+extern int frame_relative_level (frame_info_ptr fi);
 
 /* Return the frame's type.  */
 
-extern enum frame_type get_frame_type (struct frame_info *);
+extern enum frame_type get_frame_type (frame_info_ptr );
 
 /* Return the frame's program space.  */
-extern struct program_space *get_frame_program_space (struct frame_info *);
+extern struct program_space *get_frame_program_space (frame_info_ptr );
 
 /* Unwind THIS frame's program space from the NEXT frame.  */
-extern struct program_space *frame_unwind_program_space (struct frame_info *);
+extern struct program_space *frame_unwind_program_space (frame_info_ptr );
 
 class address_space;
 
 /* Return the frame's address space.  */
-extern const address_space *get_frame_address_space (struct frame_info *);
+extern const address_space *get_frame_address_space (frame_info_ptr );
 
 /* For frames where we can not unwind further, describe why.  */
 
@@ -568,7 +568,7 @@ enum unwind_stop_reason
 
 /* Return the reason why we can't unwind past this frame.  */
 
-enum unwind_stop_reason get_frame_unwind_stop_reason (struct frame_info *);
+enum unwind_stop_reason get_frame_unwind_stop_reason (frame_info_ptr );
 
 /* Translate a reason code to an informative string.  This converts the
    generic stop reason codes into a generic string describing the code.
@@ -585,13 +585,13 @@ const char *unwind_stop_reason_to_string (enum unwind_stop_reason);
 
    Should only be called for frames that don't have a previous frame.  */
 
-const char *frame_stop_reason_string (struct frame_info *);
+const char *frame_stop_reason_string (frame_info_ptr );
 
 /* Unwind the stack frame so that the value of REGNUM, in the previous
    (up, older) frame is returned.  If VALUEP is NULL, don't
    fetch/compute the value.  Instead just return the location of the
    value.  */
-extern void frame_register_unwind (frame_info *frame, int regnum,
+extern void frame_register_unwind (frame_info_ptr frame, int regnum,
 				   int *optimizedp, int *unavailablep,
 				   enum lval_type *lvalp,
 				   CORE_ADDR *addrp, int *realnump,
@@ -603,23 +603,23 @@ extern void frame_register_unwind (frame_info *frame, int regnum,
    fetch fails.  The value methods never return NULL, but usually
    do return a lazy value.  */
 
-extern void frame_unwind_register (frame_info *next_frame,
+extern void frame_unwind_register (frame_info_ptr next_frame,
 				   int regnum, gdb_byte *buf);
-extern void get_frame_register (struct frame_info *frame,
+extern void get_frame_register (frame_info_ptr frame,
 				int regnum, gdb_byte *buf);
 
-struct value *frame_unwind_register_value (frame_info *next_frame,
+struct value *frame_unwind_register_value (frame_info_ptr next_frame,
 					   int regnum);
-struct value *get_frame_register_value (struct frame_info *frame,
+struct value *get_frame_register_value (frame_info_ptr frame,
 					int regnum);
 
-extern LONGEST frame_unwind_register_signed (frame_info *next_frame,
+extern LONGEST frame_unwind_register_signed (frame_info_ptr next_frame,
 					     int regnum);
-extern LONGEST get_frame_register_signed (struct frame_info *frame,
+extern LONGEST get_frame_register_signed (frame_info_ptr frame,
 					  int regnum);
-extern ULONGEST frame_unwind_register_unsigned (frame_info *frame,
+extern ULONGEST frame_unwind_register_unsigned (frame_info_ptr frame,
 						int regnum);
-extern ULONGEST get_frame_register_unsigned (struct frame_info *frame,
+extern ULONGEST get_frame_register_unsigned (frame_info_ptr frame,
 					     int regnum);
 
 /* Read a register from this, or unwind a register from the next
@@ -627,7 +627,7 @@ extern ULONGEST get_frame_register_unsigned (struct frame_info *frame,
    get_frame_register_value, that do not throw if the result is
    optimized out or unavailable.  */
 
-extern bool read_frame_register_unsigned (frame_info *frame,
+extern bool read_frame_register_unsigned (frame_info_ptr frame,
 					  int regnum, ULONGEST *val);
 
 /* Get the value of the register that belongs to this FRAME.  This
@@ -635,7 +635,7 @@ extern bool read_frame_register_unsigned (frame_info *frame,
    (get_next_frame (FRAME))''.  As per frame_register_unwind(), if
    VALUEP is NULL, the registers value is not fetched/computed.  */
 
-extern void frame_register (struct frame_info *frame, int regnum,
+extern void frame_register (frame_info_ptr frame, int regnum,
 			    int *optimizedp, int *unavailablep,
 			    enum lval_type *lvalp,
 			    CORE_ADDR *addrp, int *realnump,
@@ -644,21 +644,21 @@ extern void frame_register (struct frame_info *frame, int regnum,
 /* The reverse.  Store a register value relative to the specified
    frame.  Note: this call makes the frame's state undefined.  The
    register and frame caches must be flushed.  */
-extern void put_frame_register (struct frame_info *frame, int regnum,
+extern void put_frame_register (frame_info_ptr frame, int regnum,
 				const gdb_byte *buf);
 
 /* Read LEN bytes from one or multiple registers starting with REGNUM
    in frame FRAME, starting at OFFSET, into BUF.  If the register
    contents are optimized out or unavailable, set *OPTIMIZEDP,
    *UNAVAILABLEP accordingly.  */
-extern bool get_frame_register_bytes (frame_info *frame, int regnum,
+extern bool get_frame_register_bytes (frame_info_ptr frame, int regnum,
 				      CORE_ADDR offset,
 				      gdb::array_view<gdb_byte> buffer,
 				      int *optimizedp, int *unavailablep);
 
 /* Write bytes from BUFFER to one or multiple registers starting with REGNUM
    in frame FRAME, starting at OFFSET.  */
-extern void put_frame_register_bytes (struct frame_info *frame, int regnum,
+extern void put_frame_register_bytes (frame_info_ptr frame, int regnum,
 				      CORE_ADDR offset,
 				      gdb::array_view<const gdb_byte> buffer);
 
@@ -666,11 +666,11 @@ extern void put_frame_register_bytes (struct frame_info *frame, int regnum,
    calling frame.  For GDB, `pc' is the resume address and not a
    specific register.  */
 
-extern CORE_ADDR frame_unwind_caller_pc (struct frame_info *frame);
+extern CORE_ADDR frame_unwind_caller_pc (frame_info_ptr frame);
 
 /* Discard the specified frame.  Restoring the registers to the state
    of the caller.  */
-extern void frame_pop (struct frame_info *frame);
+extern void frame_pop (frame_info_ptr frame);
 
 /* Return memory from the specified frame.  A frame knows its thread /
    LWP and hence can find its way down to a target.  The assumption
@@ -685,26 +685,26 @@ extern void frame_pop (struct frame_info *frame);
    If architecture / memory changes are always separated by special
    adaptor frames this should be ok.  */
 
-extern void get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr,
+extern void get_frame_memory (frame_info_ptr this_frame, CORE_ADDR addr,
 			      gdb::array_view<gdb_byte> buffer);
-extern LONGEST get_frame_memory_signed (struct frame_info *this_frame,
+extern LONGEST get_frame_memory_signed (frame_info_ptr this_frame,
 					CORE_ADDR memaddr, int len);
-extern ULONGEST get_frame_memory_unsigned (struct frame_info *this_frame,
+extern ULONGEST get_frame_memory_unsigned (frame_info_ptr this_frame,
 					   CORE_ADDR memaddr, int len);
 
 /* Same as above, but return true zero when the entire memory read
    succeeds, false otherwise.  */
-extern bool safe_frame_unwind_memory (frame_info *this_frame, CORE_ADDR addr,
+extern bool safe_frame_unwind_memory (frame_info_ptr this_frame, CORE_ADDR addr,
 				      gdb::array_view<gdb_byte> buffer);
 
 /* Return this frame's architecture.  */
-extern struct gdbarch *get_frame_arch (struct frame_info *this_frame);
+extern struct gdbarch *get_frame_arch (frame_info_ptr this_frame);
 
 /* Return the previous frame's architecture.  */
-extern struct gdbarch *frame_unwind_arch (frame_info *next_frame);
+extern struct gdbarch *frame_unwind_arch (frame_info_ptr next_frame);
 
 /* Return the previous frame's architecture, skipping inline functions.  */
-extern struct gdbarch *frame_unwind_caller_arch (struct frame_info *frame);
+extern struct gdbarch *frame_unwind_caller_arch (frame_info_ptr frame);
 
 
 /* Values for the source flag to be used in print_frame_info ().
@@ -744,9 +744,9 @@ extern void *frame_obstack_zalloc (unsigned long size);
 class readonly_detached_regcache;
 /* Create a regcache, and copy the frame's registers into it.  */
 std::unique_ptr<readonly_detached_regcache> frame_save_as_regcache
-    (struct frame_info *this_frame);
+    (frame_info_ptr this_frame);
 
-extern const struct block *get_frame_block (struct frame_info *,
+extern const struct block *get_frame_block (frame_info_ptr ,
 					    CORE_ADDR *addr_in_block);
 
 /* Return the `struct block' that belongs to the selected thread's
@@ -777,32 +777,32 @@ extern const struct block *get_frame_block (struct frame_info *,
 
 extern const struct block *get_selected_block (CORE_ADDR *addr_in_block);
 
-extern struct symbol *get_frame_function (struct frame_info *);
+extern struct symbol *get_frame_function (frame_info_ptr );
 
 extern CORE_ADDR get_pc_function_start (CORE_ADDR);
 
-extern struct frame_info *find_relative_frame (struct frame_info *, int *);
+extern frame_info_ptr find_relative_frame (frame_info_ptr , int *);
 
 /* Wrapper over print_stack_frame modifying current_uiout with UIOUT for
    the function call.  */
 
 extern void print_stack_frame_to_uiout (struct ui_out *uiout,
-					struct frame_info *, int print_level,
+					frame_info_ptr , int print_level,
 					enum print_what print_what,
 					int set_current_sal);
 
-extern void print_stack_frame (struct frame_info *, int print_level,
+extern void print_stack_frame (frame_info_ptr , int print_level,
 			       enum print_what print_what,
 			       int set_current_sal);
 
 extern void print_frame_info (const frame_print_options &fp_opts,
-			      struct frame_info *, int print_level,
+			      frame_info_ptr , int print_level,
 			      enum print_what print_what, int args,
 			      int set_current_sal);
 
-extern struct frame_info *block_innermost_frame (const struct block *);
+extern frame_info_ptr block_innermost_frame (const struct block *);
 
-extern bool deprecated_frame_register_read (frame_info *frame, int regnum,
+extern bool deprecated_frame_register_read (frame_info_ptr frame, int regnum,
 					    gdb_byte *buf);
 
 /* From stack.c.  */
@@ -874,10 +874,10 @@ struct frame_arg
 };
 
 extern void read_frame_arg (const frame_print_options &fp_opts,
-			    symbol *sym, frame_info *frame,
+			    symbol *sym, frame_info_ptr frame,
 			    struct frame_arg *argp,
 			    struct frame_arg *entryargp);
-extern void read_frame_local (struct symbol *sym, struct frame_info *frame,
+extern void read_frame_local (struct symbol *sym, frame_info_ptr frame,
 			      struct frame_arg *argp);
 
 extern void info_args_command (const char *, int);
@@ -890,13 +890,13 @@ extern void return_command (const char *, int);
    If sniffing fails, the caller should be sure to call
    frame_cleanup_after_sniffer.  */
 
-extern void frame_prepare_for_sniffer (struct frame_info *frame,
+extern void frame_prepare_for_sniffer (frame_info_ptr frame,
 				       const struct frame_unwind *unwind);
 
 /* Clean up after a failed (wrong unwinder) attempt to unwind past
    FRAME.  */
 
-extern void frame_cleanup_after_sniffer (struct frame_info *frame);
+extern void frame_cleanup_after_sniffer (frame_info_ptr frame);
 
 /* Notes (cagney/2002-11-27, drow/2003-09-06):
 
@@ -928,31 +928,31 @@ extern void frame_cleanup_after_sniffer (struct frame_info *frame);
    This function calls get_selected_frame if the inferior should have a
    frame, or returns NULL otherwise.  */
 
-extern struct frame_info *deprecated_safe_get_selected_frame (void);
+extern frame_info_ptr deprecated_safe_get_selected_frame (void);
 
 /* Create a frame using the specified BASE and PC.  */
 
-extern struct frame_info *create_new_frame (CORE_ADDR base, CORE_ADDR pc);
+extern frame_info_ptr create_new_frame (CORE_ADDR base, CORE_ADDR pc);
 
 /* Return true if the frame unwinder for frame FI is UNWINDER; false
    otherwise.  */
 
-extern bool frame_unwinder_is (frame_info *fi, const frame_unwind *unwinder);
+extern bool frame_unwinder_is (frame_info_ptr fi, const frame_unwind *unwinder);
 
 /* Return the language of FRAME.  */
 
-extern enum language get_frame_language (struct frame_info *frame);
+extern enum language get_frame_language (frame_info_ptr frame);
 
 /* Return the first non-tailcall frame above FRAME or FRAME if it is not a
    tailcall frame.  Return NULL if FRAME is the start of a tailcall-only
    chain.  */
 
-extern struct frame_info *skip_tailcall_frames (struct frame_info *frame);
+extern frame_info_ptr skip_tailcall_frames (frame_info_ptr frame);
 
 /* Return the first frame above FRAME or FRAME of which the code is
    writable.  */
 
-extern struct frame_info *skip_unwritable_frames (struct frame_info *frame);
+extern frame_info_ptr skip_unwritable_frames (frame_info_ptr frame);
 
 /* Data for the "set backtrace" settings.  */
 
@@ -984,11 +984,11 @@ unsigned int get_frame_cache_generation ();
 
 /* Mark that the PC value is masked for the previous frame.  */
 
-extern void set_frame_previous_pc_masked (struct frame_info *frame);
+extern void set_frame_previous_pc_masked (frame_info_ptr frame);
 
 /* Get whether the PC value is masked for the given frame.  */
 
-extern bool get_frame_pc_masked (const struct frame_info *frame);
+extern bool get_frame_pc_masked (frame_info_ptr frame);
 
 
 #endif /* !defined (FRAME_H)  */
diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c
index b60af84e676..9a2593e10dc 100644
--- a/gdb/frv-linux-tdep.c
+++ b/gdb/frv-linux-tdep.c
@@ -168,7 +168,7 @@ frv_linux_pc_in_sigtramp (struct gdbarch *gdbarch, CORE_ADDR pc,
       } __attribute__((aligned(8)));  */
 
 static LONGEST
-frv_linux_sigcontext_reg_addr (struct frame_info *this_frame, int regno,
+frv_linux_sigcontext_reg_addr (frame_info_ptr this_frame, int regno,
 			       CORE_ADDR *sc_addr_cache_ptr)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -258,7 +258,7 @@ frv_linux_sigcontext_reg_addr (struct frame_info *this_frame, int regno,
 /* Signal trampolines.  */
 
 static struct trad_frame_cache *
-frv_linux_sigtramp_frame_cache (struct frame_info *this_frame,
+frv_linux_sigtramp_frame_cache (frame_info_ptr this_frame,
 				void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -297,7 +297,7 @@ frv_linux_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-frv_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
+frv_linux_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				  void **this_cache,
 				  struct frame_id *this_id)
 {
@@ -307,7 +307,7 @@ frv_linux_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-frv_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
+frv_linux_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
@@ -318,7 +318,7 @@ frv_linux_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				  struct frame_info *this_frame,
+				  frame_info_ptr this_frame,
 				  void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index 55a6cfd9618..d8b4ccfe243 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -510,7 +510,7 @@ is_argument_reg (int reg)
    prologue analysis.  */
 static CORE_ADDR
 frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
-		      struct frame_info *this_frame,
+		      frame_info_ptr this_frame,
 		      struct frv_unwind_cache *info)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -1084,7 +1084,7 @@ frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 
 static struct frv_unwind_cache *
-frv_frame_unwind_cache (struct frame_info *this_frame,
+frv_frame_unwind_cache (frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1369,7 +1369,7 @@ frv_return_value (struct gdbarch *gdbarch, struct value *function,
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-frv_frame_this_id (struct frame_info *this_frame,
+frv_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache, struct frame_id *this_id)
 {
   struct frv_unwind_cache *info
@@ -1399,7 +1399,7 @@ frv_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-frv_frame_prev_register (struct frame_info *this_frame,
+frv_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_prologue_cache, int regnum)
 {
   struct frv_unwind_cache *info
@@ -1418,7 +1418,7 @@ static const struct frame_unwind frv_frame_unwind = {
 };
 
 static CORE_ADDR
-frv_frame_base_address (struct frame_info *this_frame, void **this_cache)
+frv_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct frv_unwind_cache *info
     = frv_frame_unwind_cache (this_frame, this_cache);
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index 024ca47ce4d..d5b9379d77a 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -452,7 +452,7 @@ ft32_alloc_frame_cache (void)
 /* Populate a ft32_frame_cache object for this_frame.  */
 
 static struct ft32_frame_cache *
-ft32_frame_cache (struct frame_info *this_frame, void **this_cache)
+ft32_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct ft32_frame_cache *cache;
   CORE_ADDR current_pc;
@@ -492,7 +492,7 @@ ft32_frame_cache (struct frame_info *this_frame, void **this_cache)
    frame.  This will be used to create a new GDB frame struct.  */
 
 static void
-ft32_frame_this_id (struct frame_info *this_frame,
+ft32_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache, struct frame_id *this_id)
 {
   struct ft32_frame_cache *cache = ft32_frame_cache (this_frame,
@@ -508,7 +508,7 @@ ft32_frame_this_id (struct frame_info *this_frame,
 /* Get the value of register regnum in the previous stack frame.  */
 
 static struct value *
-ft32_frame_prev_register (struct frame_info *this_frame,
+ft32_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct ft32_frame_cache *cache = ft32_frame_cache (this_frame,
@@ -540,7 +540,7 @@ static const struct frame_unwind ft32_frame_unwind =
 /* Return the base address of this_frame.  */
 
 static CORE_ADDR
-ft32_frame_base_address (struct frame_info *this_frame, void **this_cache)
+ft32_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct ft32_frame_cache *cache = ft32_frame_cache (this_frame,
 						     this_cache);
diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c
index 77764944208..159603b8008 100644
--- a/gdb/guile/scm-frame.c
+++ b/gdb/guile/scm-frame.c
@@ -134,7 +134,7 @@ frscm_eq_frame_smob (const void *ap, const void *bp)
   const frame_smob *a = (const frame_smob *) ap;
   const frame_smob *b = (const frame_smob *) bp;
 
-  return (a->frame_id == b->frame_id
+  return (frame_id_eq (a->frame_id, b->frame_id)
 	  && a->inferior == b->inferior
 	  && a->inferior != NULL);
 }
diff --git a/gdb/i386-bsd-tdep.c b/gdb/i386-bsd-tdep.c
index dbbd3c786c3..dd91e302128 100644
--- a/gdb/i386-bsd-tdep.c
+++ b/gdb/i386-bsd-tdep.c
@@ -32,7 +32,7 @@
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-i386bsd_sigcontext_addr (struct frame_info *this_frame)
+i386bsd_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/i386-darwin-tdep.c b/gdb/i386-darwin-tdep.c
index 2a9198aceb3..615dbaedf52 100644
--- a/gdb/i386-darwin-tdep.c
+++ b/gdb/i386-darwin-tdep.c
@@ -66,7 +66,7 @@ const int i386_darwin_thread_state_num_regs =
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-i386_darwin_sigcontext_addr (struct frame_info *this_frame)
+i386_darwin_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -99,7 +99,7 @@ i386_darwin_sigcontext_addr (struct frame_info *this_frame)
 
 int
 darwin_dwarf_signal_frame_p (struct gdbarch *gdbarch,
-			     struct frame_info *this_frame)
+			     frame_info_ptr this_frame)
 {
   return i386_sigtramp_p (this_frame);
 }
diff --git a/gdb/i386-darwin-tdep.h b/gdb/i386-darwin-tdep.h
index 4c1660b9bc6..2628ef49bc4 100644
--- a/gdb/i386-darwin-tdep.h
+++ b/gdb/i386-darwin-tdep.h
@@ -27,6 +27,6 @@
 extern int i386_darwin_thread_state_reg_offset[];
 extern const int i386_darwin_thread_state_num_regs;
 
-int darwin_dwarf_signal_frame_p (struct gdbarch *, struct frame_info *);
+int darwin_dwarf_signal_frame_p (struct gdbarch *, frame_info_ptr );
 
 #endif /* I386_DARWIN_TDEP_H */
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index b7a524db68c..eef124fca0c 100644
--- a/gdb/i386-fbsd-tdep.c
+++ b/gdb/i386-fbsd-tdep.c
@@ -156,7 +156,7 @@ const struct regset i386_fbsd_segbases_regset =
 
 static void
 i386_fbsd_sigframe_init (const struct tramp_frame *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 struct trad_frame_cache *this_cache,
 			 CORE_ADDR func)
 {
diff --git a/gdb/i386-gnu-tdep.c b/gdb/i386-gnu-tdep.c
index 3d97fe36a85..1ce4a2137e9 100644
--- a/gdb/i386-gnu-tdep.c
+++ b/gdb/i386-gnu-tdep.c
@@ -56,7 +56,7 @@ static const gdb_byte gnu_sigtramp_code[] =
    start of the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-i386_gnu_sigtramp_start (struct frame_info *this_frame)
+i386_gnu_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[GNU_SIGTRAMP_LEN];
@@ -76,7 +76,7 @@ i386_gnu_sigtramp_start (struct frame_info *this_frame)
    routine.  */
 
 static int
-i386_gnu_sigtramp_p (struct frame_info *this_frame)
+i386_gnu_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -97,7 +97,7 @@ i386_gnu_sigtramp_p (struct frame_info *this_frame)
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-i386_gnu_sigcontext_addr (struct frame_info *this_frame)
+i386_gnu_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 6033104230f..5c2fed39868 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -122,7 +122,7 @@ static const gdb_byte linux_sigtramp_code[] =
    start of the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-i386_linux_sigtramp_start (struct frame_info *this_frame)
+i386_linux_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[LINUX_SIGTRAMP_LEN];
@@ -190,7 +190,7 @@ static const gdb_byte linux_rt_sigtramp_code[] =
    start of the routine.  Otherwise, return 0.  */
 
 static CORE_ADDR
-i386_linux_rt_sigtramp_start (struct frame_info *this_frame)
+i386_linux_rt_sigtramp_start (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   gdb_byte buf[LINUX_RT_SIGTRAMP_LEN];
@@ -227,7 +227,7 @@ i386_linux_rt_sigtramp_start (struct frame_info *this_frame)
    routine.  */
 
 static int
-i386_linux_sigtramp_p (struct frame_info *this_frame)
+i386_linux_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -252,7 +252,7 @@ i386_linux_sigtramp_p (struct frame_info *this_frame)
 
 static int
 i386_linux_dwarf_signal_frame_p (struct gdbarch *gdbarch,
-				 struct frame_info *this_frame)
+				 frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -275,7 +275,7 @@ i386_linux_dwarf_signal_frame_p (struct gdbarch *gdbarch,
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-i386_linux_sigcontext_addr (struct frame_info *this_frame)
+i386_linux_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/i386-netbsd-tdep.c b/gdb/i386-netbsd-tdep.c
index a9ebc3dd827..e0fc00e8b94 100644
--- a/gdb/i386-netbsd-tdep.c
+++ b/gdb/i386-netbsd-tdep.c
@@ -97,7 +97,7 @@ static int i386nbsd_mc_reg_offset[] =
 };
 
 static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
-					  struct frame_info *,
+					  frame_info_ptr ,
 					  struct trad_frame_cache *,
 					  CORE_ADDR);
 
@@ -329,7 +329,7 @@ static const struct tramp_frame i386nbsd_sigtramp_si4 =
 
 static void
 i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      struct trad_frame_cache *this_cache,
 			      CORE_ADDR func)
 {
diff --git a/gdb/i386-nto-tdep.c b/gdb/i386-nto-tdep.c
index 259867f262b..013e5a64e76 100644
--- a/gdb/i386-nto-tdep.c
+++ b/gdb/i386-nto-tdep.c
@@ -270,7 +270,7 @@ i386nto_regset_fill (const struct regcache *regcache, int regset, char *data)
    routine.  */
 
 static int
-i386nto_sigtramp_p (struct frame_info *this_frame)
+i386nto_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -283,7 +283,7 @@ i386nto_sigtramp_p (struct frame_info *this_frame)
    address of the associated sigcontext structure.  */
 
 static CORE_ADDR
-i386nto_sigcontext_addr (struct frame_info *this_frame)
+i386nto_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
diff --git a/gdb/i386-obsd-tdep.c b/gdb/i386-obsd-tdep.c
index 798094509c6..b1b0a83ed21 100644
--- a/gdb/i386-obsd-tdep.c
+++ b/gdb/i386-obsd-tdep.c
@@ -64,7 +64,7 @@ static const int i386obsd_sigreturn_offset[] = {
    routine.  */
 
 static int
-i386obsd_sigtramp_p (struct frame_info *this_frame)
+i386obsd_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
@@ -303,7 +303,7 @@ static int i386obsd_tf_reg_offset[] =
 };
 
 static struct trad_frame_cache *
-i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+i386obsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -350,7 +350,7 @@ i386obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-i386obsd_trapframe_this_id (struct frame_info *this_frame,
+i386obsd_trapframe_this_id (frame_info_ptr this_frame,
 			    void **this_cache, struct frame_id *this_id)
 {
   struct trad_frame_cache *cache =
@@ -360,7 +360,7 @@ i386obsd_trapframe_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-i386obsd_trapframe_prev_register (struct frame_info *this_frame,
+i386obsd_trapframe_prev_register (frame_info_ptr this_frame,
 				  void **this_cache, int regnum)
 {
   struct trad_frame_cache *cache =
@@ -371,7 +371,7 @@ i386obsd_trapframe_prev_register (struct frame_info *this_frame,
 
 static int
 i386obsd_trapframe_sniffer (const struct frame_unwind *self,
-			    struct frame_info *this_frame,
+			    frame_info_ptr this_frame,
 			    void **this_prologue_cache)
 {
   ULONGEST cs;
diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c
index 5ee108d3578..f9df0f3d500 100644
--- a/gdb/i386-sol2-tdep.c
+++ b/gdb/i386-sol2-tdep.c
@@ -50,7 +50,7 @@ static int i386_sol2_gregset_reg_offset[] =
    `mcontext_t' that contains the saved set of machine registers.  */
 
 static CORE_ADDR
-i386_sol2_mcontext_addr (struct frame_info *this_frame)
+i386_sol2_mcontext_addr (frame_info_ptr this_frame)
 {
   CORE_ADDR sp, ucontext_addr;
 
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index d8e910bb407..06bf88d8eda 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -1965,7 +1965,7 @@ i386_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* This function is 64-bit safe.  */
 
 static CORE_ADDR
-i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+i386_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   gdb_byte buf[8];
 
@@ -1977,7 +1977,7 @@ i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Normal frames.  */
 
 static void
-i386_frame_cache_1 (struct frame_info *this_frame,
+i386_frame_cache_1 (frame_info_ptr this_frame,
 		    struct i386_frame_cache *cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2078,7 +2078,7 @@ i386_frame_cache_1 (struct frame_info *this_frame,
 }
 
 static struct i386_frame_cache *
-i386_frame_cache (struct frame_info *this_frame, void **this_cache)
+i386_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct i386_frame_cache *cache;
 
@@ -2102,7 +2102,7 @@ i386_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-i386_frame_this_id (struct frame_info *this_frame, void **this_cache,
+i386_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
@@ -2121,7 +2121,7 @@ i386_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static enum unwind_stop_reason
-i386_frame_unwind_stop_reason (struct frame_info *this_frame,
+i386_frame_unwind_stop_reason (frame_info_ptr this_frame,
 			       void **this_cache)
 {
   struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
@@ -2137,7 +2137,7 @@ i386_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static struct value *
-i386_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+i386_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			  int regnum)
 {
   struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
@@ -2236,7 +2236,7 @@ i386_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 
 static int
 i386_epilogue_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   if (frame_relative_level (this_frame) == 0)
@@ -2247,7 +2247,7 @@ i386_epilogue_frame_sniffer (const struct frame_unwind *self,
 }
 
 static struct i386_frame_cache *
-i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+i386_epilogue_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct i386_frame_cache *cache;
   CORE_ADDR sp;
@@ -2282,7 +2282,7 @@ i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static enum unwind_stop_reason
-i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
+i386_epilogue_frame_unwind_stop_reason (frame_info_ptr this_frame,
 					void **this_cache)
 {
   struct i386_frame_cache *cache =
@@ -2295,7 +2295,7 @@ i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static void
-i386_epilogue_frame_this_id (struct frame_info *this_frame,
+i386_epilogue_frame_this_id (frame_info_ptr this_frame,
 			     void **this_cache,
 			     struct frame_id *this_id)
 {
@@ -2309,7 +2309,7 @@ i386_epilogue_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-i386_epilogue_frame_prev_register (struct frame_info *this_frame,
+i386_epilogue_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
@@ -2391,7 +2391,7 @@ i386_in_stack_tramp_p (CORE_ADDR pc)
 
 static int
 i386_stack_tramp_frame_sniffer (const struct frame_unwind *self,
-				struct frame_info *this_frame,
+				frame_info_ptr this_frame,
 				void **this_cache)
 {
   if (frame_relative_level (this_frame) == 0)
@@ -2431,7 +2431,7 @@ i386_gen_return_address (struct gdbarch *gdbarch,
 /* Signal trampolines.  */
 
 static struct i386_frame_cache *
-i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+i386_sigtramp_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
@@ -2480,7 +2480,7 @@ i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static enum unwind_stop_reason
-i386_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
+i386_sigtramp_frame_unwind_stop_reason (frame_info_ptr this_frame,
 					void **this_cache)
 {
   struct i386_frame_cache *cache =
@@ -2493,7 +2493,7 @@ i386_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
 }
 
 static void
-i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
+i386_sigtramp_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			     struct frame_id *this_id)
 {
   struct i386_frame_cache *cache =
@@ -2509,7 +2509,7 @@ i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-i386_sigtramp_frame_prev_register (struct frame_info *this_frame,
+i386_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   /* Make sure we've initialized the cache.  */
@@ -2520,7 +2520,7 @@ i386_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   gdbarch *arch = get_frame_arch (this_frame);
@@ -2562,7 +2562,7 @@ static const struct frame_unwind i386_sigtramp_frame_unwind =
 \f
 
 static CORE_ADDR
-i386_frame_base_address (struct frame_info *this_frame, void **this_cache)
+i386_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
 
@@ -2578,7 +2578,7 @@ static const struct frame_base i386_frame_base =
 };
 
 static struct frame_id
-i386_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+i386_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR fp;
 
@@ -2605,7 +2605,7 @@ i386_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
    success.  */
 
 static int
-i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+i386_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   gdb_byte buf[4];
   CORE_ADDR sp, jb_addr;
@@ -3827,7 +3827,7 @@ i386_convert_register_p (struct gdbarch *gdbarch,
    return its contents in TO.  */
 
 static int
-i386_register_to_value (struct frame_info *frame, int regnum,
+i386_register_to_value (frame_info_ptr frame, int regnum,
 			struct type *type, gdb_byte *to,
 			int *optimizedp, int *unavailablep)
 {
@@ -3867,7 +3867,7 @@ i386_register_to_value (struct frame_info *frame, int regnum,
    REGNUM in frame FRAME.  */
 
 static void
-i386_value_to_register (struct frame_info *frame, int regnum,
+i386_value_to_register (frame_info_ptr frame, int regnum,
 			struct type *type, const gdb_byte *from)
 {
   int len = TYPE_LENGTH (type);
@@ -4019,7 +4019,7 @@ i386_iterate_over_regset_sections (struct gdbarch *gdbarch,
 /* Stuff for WIN32 PE style DLL's but is pretty generic really.  */
 
 CORE_ADDR
-i386_pe_skip_trampoline_code (struct frame_info *frame,
+i386_pe_skip_trampoline_code (frame_info_ptr frame,
 			      CORE_ADDR pc, char *name)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -4050,7 +4050,7 @@ i386_pe_skip_trampoline_code (struct frame_info *frame,
    routine.  */
 
 int
-i386_sigtramp_p (struct frame_info *this_frame)
+i386_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -4086,7 +4086,7 @@ i386_print_insn (bfd_vma pc, struct disassemble_info *info)
    routine.  */
 
 static int
-i386_svr4_sigtramp_p (struct frame_info *this_frame)
+i386_svr4_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
@@ -4101,7 +4101,7 @@ i386_svr4_sigtramp_p (struct frame_info *this_frame)
    address of the associated sigcontext (ucontext) structure.  */
 
 static CORE_ADDR
-i386_svr4_sigcontext_addr (struct frame_info *this_frame)
+i386_svr4_sigcontext_addr (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -4657,7 +4657,7 @@ i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 /* Get the ARGIth function argument for the current function.  */
 
 static CORE_ADDR
-i386_fetch_pointer_argument (struct frame_info *frame, int argi, 
+i386_fetch_pointer_argument (frame_info_ptr frame, int argi, 
 			     struct type *type)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index cd77e0308e0..72e10457b2a 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -24,7 +24,7 @@
 #include "infrun.h"
 #include "expression.h"
 
-struct frame_info;
+class frame_info_ptr;
 struct gdbarch;
 struct reggroup;
 struct regset;
@@ -223,10 +223,10 @@ struct i386_gdbarch_tdep : gdbarch_tdep_base
   CORE_ADDR sigtramp_end = 0;
 
   /* Detect sigtramp.  */
-  int (*sigtramp_p) (struct frame_info *) = nullptr;
+  int (*sigtramp_p) (frame_info_ptr ) = nullptr;
 
   /* Get address of sigcontext for sigtramp.  */
-  CORE_ADDR (*sigcontext_addr) (struct frame_info *) = nullptr;
+  CORE_ADDR (*sigcontext_addr) (frame_info_ptr ) = nullptr;
 
   /* Offset of registers in `struct sigcontext'.  */
   int *sc_reg_offset = 0;
@@ -395,7 +395,7 @@ extern int i386_ax_pseudo_register_collect (struct gdbarch *gdbarch,
 #define I386_MAX_INSN_LEN (16)
 
 /* Functions exported from i386-tdep.c.  */
-extern CORE_ADDR i386_pe_skip_trampoline_code (struct frame_info *frame,
+extern CORE_ADDR i386_pe_skip_trampoline_code (frame_info_ptr frame,
 					       CORE_ADDR pc, char *name);
 extern CORE_ADDR i386_skip_main_prologue (struct gdbarch *gdbarch,
 					  CORE_ADDR pc);
@@ -414,7 +414,7 @@ extern CORE_ADDR i386_thiscall_push_dummy_call (struct gdbarch *gdbarch,
 						bool thiscall);
 
 /* Return whether the THIS_FRAME corresponds to a sigtramp routine.  */
-extern int i386_sigtramp_p (struct frame_info *this_frame);
+extern int i386_sigtramp_p (frame_info_ptr this_frame);
 
 /* Return non-zero if REGNUM is a member of the specified group.  */
 extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
diff --git a/gdb/i386-windows-tdep.c b/gdb/i386-windows-tdep.c
index 9eec6e28109..478e6ec6207 100644
--- a/gdb/i386-windows-tdep.c
+++ b/gdb/i386-windows-tdep.c
@@ -90,7 +90,7 @@ static int i386_windows_gregset_reg_offset[] =
 #define I386_WINDOWS_SIZEOF_GREGSET 716
 
 static CORE_ADDR
-i386_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
+i386_windows_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc)
 {
   return i386_pe_skip_trampoline_code (frame, pc, NULL);
 }
diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c
index 42ed4eebc2c..a3c642b2643 100644
--- a/gdb/i387-tdep.c
+++ b/gdb/i387-tdep.c
@@ -202,7 +202,7 @@ print_i387_control_word (int control_p,
 
 void
 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
-		       struct frame_info *frame, const char *args)
+		       frame_info_ptr frame, const char *args)
 {
   i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
   ULONGEST fctrl;
@@ -345,7 +345,7 @@ i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
    return its contents in TO.  */
 
 int
-i387_register_to_value (struct frame_info *frame, int regnum,
+i387_register_to_value (frame_info_ptr frame, int regnum,
 			struct type *type, gdb_byte *to,
 			int *optimizedp, int *unavailablep)
 {
@@ -380,7 +380,7 @@ i387_register_to_value (struct frame_info *frame, int regnum,
    REGNUM in frame FRAME.  */
 
 void
-i387_value_to_register (struct frame_info *frame, int regnum,
+i387_value_to_register (frame_info_ptr frame, int regnum,
 			struct type *type, const gdb_byte *from)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h
index 698ff2ee206..3b223067c5d 100644
--- a/gdb/i387-tdep.h
+++ b/gdb/i387-tdep.h
@@ -21,7 +21,7 @@
 #define I387_TDEP_H
 
 struct gdbarch;
-struct frame_info;
+class frame_info_ptr;
 struct regcache;
 struct type;
 struct ui_file;
@@ -88,7 +88,7 @@ struct ui_file;
 
 extern void i387_print_float_info (struct gdbarch *gdbarch,
 				   struct ui_file *file,
-				   struct frame_info *frame,
+				   frame_info_ptr frame,
 				   const char *args);
 
 /* Return nonzero if a value of type TYPE stored in register REGNUM
@@ -100,14 +100,14 @@ extern int i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
    return its contents in TO.  */
 
-extern int i387_register_to_value (struct frame_info *frame, int regnum,
+extern int i387_register_to_value (frame_info_ptr frame, int regnum,
 				   struct type *type, gdb_byte *to,
 				   int *optimizedp, int *unavailablep);
 
 /* Write the contents FROM of a value of type TYPE into register
    REGNUM in frame FRAME.  */
 
-extern void i387_value_to_register (struct frame_info *frame, int regnum,
+extern void i387_value_to_register (frame_info_ptr frame, int regnum,
 				    struct type *type, const gdb_byte *from);
 \f
 
diff --git a/gdb/ia64-libunwind-tdep.c b/gdb/ia64-libunwind-tdep.c
index 4c788f20956..6fc75629631 100644
--- a/gdb/ia64-libunwind-tdep.c
+++ b/gdb/ia64-libunwind-tdep.c
@@ -153,7 +153,7 @@ libunwind_frame_set_descr (struct gdbarch *gdbarch,
 }
 
 static struct libunwind_frame_cache *
-libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
+libunwind_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   unw_accessors_t *acc;
   unw_addr_space_t as;
@@ -228,7 +228,7 @@ libunwind_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 void
-libunwind_frame_dealloc_cache (struct frame_info *self, void *this_cache)
+libunwind_frame_dealloc_cache (frame_info_ptr self, void *this_cache)
 {
   struct libunwind_frame_cache *cache
     = (struct libunwind_frame_cache *) this_cache;
@@ -247,7 +247,7 @@ libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
    libunwind frame unwinding.  */
 int
 libunwind_frame_sniffer (const struct frame_unwind *self,
-			 struct frame_info *this_frame, void **this_cache)
+			 frame_info_ptr this_frame, void **this_cache)
 {
   unw_cursor_t cursor;
   unw_accessors_t *acc;
@@ -292,7 +292,7 @@ libunwind_frame_sniffer (const struct frame_unwind *self,
 }
 
 void
-libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
+libunwind_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			 struct frame_id *this_id)
 {
   struct libunwind_frame_cache *cache =
@@ -303,7 +303,7 @@ libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 struct value *
-libunwind_frame_prev_register (struct frame_info *this_frame,
+libunwind_frame_prev_register (frame_info_ptr this_frame,
 			       void **this_cache, int regnum)
 {
   struct libunwind_frame_cache *cache =
@@ -387,7 +387,7 @@ libunwind_search_unwind_table (void *as, long ip, void *di,
 /* Verify if we are in a sigtramp frame and we can use libunwind to unwind.  */
 int
 libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				  struct frame_info *this_frame,
+				  frame_info_ptr this_frame,
 				  void **this_cache)
 {
   unw_cursor_t cursor;
diff --git a/gdb/ia64-libunwind-tdep.h b/gdb/ia64-libunwind-tdep.h
index 56425d0d754..a4e20f6eb3d 100644
--- a/gdb/ia64-libunwind-tdep.h
+++ b/gdb/ia64-libunwind-tdep.h
@@ -22,7 +22,7 @@
 #ifndef IA64_LIBUNWIND_TDEP_H
 #define IA64_LIBUNWIND_TDEP_H 1
 
-struct frame_info;
+class frame_info_ptr;
 struct frame_id;
 struct regcache;
 struct gdbarch;
@@ -48,21 +48,21 @@ struct libunwind_descr
 };
 
 int libunwind_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_cache);
 			  
 int libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				      struct frame_info *this_frame,
+				      frame_info_ptr this_frame,
 				      void **this_cache);
 
 void libunwind_frame_set_descr (struct gdbarch *arch,
 				struct libunwind_descr *descr);
 
-void libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
+void libunwind_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			      struct frame_id *this_id);
-struct value *libunwind_frame_prev_register (struct frame_info *this_frame,
+struct value *libunwind_frame_prev_register (frame_info_ptr this_frame,
 					     void **this_cache, int regnum);
-void libunwind_frame_dealloc_cache (struct frame_info *self, void *cache);
+void libunwind_frame_dealloc_cache (frame_info_ptr self, void *cache);
 
 int libunwind_is_initialized (void);
 
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 1e24debf17f..c6595a3592c 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -1217,7 +1217,7 @@ ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
 }
 
 static int
-ia64_register_to_value (struct frame_info *frame, int regnum,
+ia64_register_to_value (frame_info_ptr frame, int regnum,
 			struct type *valtype, gdb_byte *out,
 			int *optimizedp, int *unavailablep)
 {
@@ -1238,7 +1238,7 @@ ia64_register_to_value (struct frame_info *frame, int regnum,
 }
 
 static void
-ia64_value_to_register (struct frame_info *frame, int regnum,
+ia64_value_to_register (frame_info_ptr frame, int regnum,
 			 struct type *valtype, const gdb_byte *in)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1358,7 +1358,7 @@ ia64_alloc_frame_cache (void)
 
 static CORE_ADDR
 examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
-		  struct frame_info *this_frame,
+		  frame_info_ptr this_frame,
 		  struct ia64_frame_cache *cache)
 {
   CORE_ADDR next_pc;
@@ -1839,7 +1839,7 @@ ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Normal frames.  */
 
 static struct ia64_frame_cache *
-ia64_frame_cache (struct frame_info *this_frame, void **this_cache)
+ia64_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -1884,7 +1884,7 @@ ia64_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-ia64_frame_this_id (struct frame_info *this_frame, void **this_cache,
+ia64_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1901,11 +1901,11 @@ ia64_frame_this_id (struct frame_info *this_frame, void **this_cache,
 		paddress (gdbarch, this_id->code_addr),
 		paddress (gdbarch, this_id->stack_addr),
 		paddress (gdbarch, cache->bsp),
-		host_address_to_string (this_frame));
+		host_address_to_string (this_frame.get ()));
 }
 
 static struct value *
-ia64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+ia64_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			  int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2173,7 +2173,7 @@ static const struct frame_unwind ia64_frame_unwind =
 /* Signal trampolines.  */
 
 static void
-ia64_sigtramp_frame_init_saved_regs (struct frame_info *this_frame,
+ia64_sigtramp_frame_init_saved_regs (frame_info_ptr this_frame,
 				     struct ia64_frame_cache *cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2227,7 +2227,7 @@ ia64_sigtramp_frame_init_saved_regs (struct frame_info *this_frame,
 }
 
 static struct ia64_frame_cache *
-ia64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+ia64_sigtramp_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -2258,7 +2258,7 @@ ia64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-ia64_sigtramp_frame_this_id (struct frame_info *this_frame,
+ia64_sigtramp_frame_this_id (frame_info_ptr this_frame,
 			     void **this_cache, struct frame_id *this_id)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2275,11 +2275,11 @@ ia64_sigtramp_frame_this_id (struct frame_info *this_frame,
 		paddress (gdbarch, this_id->code_addr),
 		paddress (gdbarch, this_id->stack_addr),
 		paddress (gdbarch, cache->bsp),
-		host_address_to_string (this_frame));
+		host_address_to_string (this_frame.get ()));
 }
 
 static struct value *
-ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ia64_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_cache, int regnum)
 {
   struct ia64_frame_cache *cache =
@@ -2332,7 +2332,7 @@ ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_cache)
 {
   gdbarch *arch = get_frame_arch (this_frame);
@@ -2362,7 +2362,7 @@ static const struct frame_unwind ia64_sigtramp_frame_unwind =
 \f
 
 static CORE_ADDR
-ia64_frame_base_address (struct frame_info *this_frame, void **this_cache)
+ia64_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
 
@@ -2483,7 +2483,7 @@ ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
   unw_word_t bsp, sof, cfm, psr, ip;
-  struct frame_info *this_frame = (struct frame_info *) arg;
+  struct frame_info *this_frame = (frame_info *) arg;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   ia64_gdbarch_tdep *tdep = gdbarch_tdep<ia64_gdbarch_tdep> (gdbarch);
   
@@ -2538,7 +2538,7 @@ ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
 		   unw_fpreg_t *val, int write, void *arg)
 {
   int regnum = ia64_uw2gdb_regnum (uw_regnum);
-  struct frame_info *this_frame = (struct frame_info *) arg;
+  frame_info_ptr this_frame = (frame_info_ptr ) arg;
   
   /* We never call any libunwind routines that need to write registers.  */
   gdb_assert (!write);
@@ -2891,7 +2891,7 @@ ia64_get_dyn_info_list (unw_addr_space_t as,
 /* Frame interface functions for libunwind.  */
 
 static void
-ia64_libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
+ia64_libunwind_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			      struct frame_id *this_id)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2925,7 +2925,7 @@ ia64_libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
+ia64_libunwind_frame_prev_register (frame_info_ptr this_frame,
 				    void **this_cache, int regnum)
 {
   int reg = regnum;
@@ -2998,7 +2998,7 @@ ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
 
 static int
 ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
-			      struct frame_info *this_frame,
+			      frame_info_ptr this_frame,
 			      void **this_cache)
 {
   if (libunwind_is_initialized ()
@@ -3021,7 +3021,7 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
 };
 
 static void
-ia64_libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
+ia64_libunwind_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				       void **this_cache,
 				       struct frame_id *this_id)
 {
@@ -3057,7 +3057,7 @@ ia64_libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *this_frame,
+ia64_libunwind_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					     void **this_cache, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -3084,7 +3084,7 @@ ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				       struct frame_info *this_frame,
+				       frame_info_ptr this_frame,
 				       void **this_cache)
 {
   if (libunwind_is_initialized ())
@@ -3864,7 +3864,7 @@ static const struct ia64_infcall_ops ia64_infcall_ops =
 };
 
 static struct frame_id
-ia64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+ia64_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[8];
@@ -3886,7 +3886,7 @@ ia64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 }
 
 static CORE_ADDR 
-ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+ia64_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[8];
@@ -3911,7 +3911,7 @@ ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
 /* The default "size_of_register_frame" gdbarch_tdep routine for ia64.  */
 
 static int
-ia64_size_of_register_frame (struct frame_info *this_frame, ULONGEST cfm)
+ia64_size_of_register_frame (frame_info_ptr this_frame, ULONGEST cfm)
 {
   return (cfm & 0x7f);
 }
diff --git a/gdb/ia64-tdep.h b/gdb/ia64-tdep.h
index f06974fd296..fed879a2907 100644
--- a/gdb/ia64-tdep.h
+++ b/gdb/ia64-tdep.h
@@ -201,7 +201,7 @@
 #define IA64_NAT32_REGNUM	(IA64_NAT0_REGNUM + 32)
 #define IA64_NAT127_REGNUM	(IA64_NAT0_REGNUM + 127)
 
-struct frame_info;
+class frame_info_ptr;
 struct regcache;
 
 /* A struction containing pointers to all the target-dependent operations
@@ -240,7 +240,7 @@ struct ia64_gdbarch_tdep : gdbarch_tdep_base
 
      Normally, the size of the register frame is always obtained by
      extracting the lowest 7 bits ("cfm & 0x7f").  */
-  int (*size_of_register_frame) (struct frame_info *this_frame, ULONGEST cfm)
+  int (*size_of_register_frame) (frame_info_ptr this_frame, ULONGEST cfm)
     = nullptr;
 
   /* Determine the function address FADDR belongs to a shared library.
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 2acceed4b07..197d649b7e0 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -673,7 +673,7 @@ run_inferior_call (std::unique_ptr<call_thread_fsm> sm,
 static CORE_ADDR
 reserve_stack_space (const type *values_type, CORE_ADDR &sp)
 {
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
   struct gdbarch *gdbarch = get_frame_arch (frame);
   CORE_ADDR addr = 0;
 
@@ -771,7 +771,7 @@ call_function_by_hand_dummy (struct value *function,
   CORE_ADDR real_pc;
   CORE_ADDR bp_addr;
   struct frame_id dummy_id;
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *gdbarch;
   ptid_t call_thread_ptid;
   struct gdb_exception e;
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 69a7896b560..d292a0e55bf 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -749,7 +749,7 @@ set_step_frame (thread_info *tp)
      inferior_ptid value.  */
   gdb_assert (inferior_ptid == tp->ptid);
 
-  frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
 
   symtab_and_line sal = find_frame_sal (frame);
   set_step_info (tp, frame, sal);
@@ -939,7 +939,7 @@ prepare_one_step (thread_info *tp, struct step_command_fsm *sm)
 
   if (sm->count > 0)
     {
-      struct frame_info *frame = get_current_frame ();
+      frame_info_ptr frame = get_current_frame ();
 
       set_step_frame (tp);
 
@@ -1320,7 +1320,7 @@ until_next_fsm::do_async_reply_reason ()
 static void
 until_next_command (int from_tty)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   CORE_ADDR pc;
   struct symbol *func;
   struct symtab_and_line sal;
@@ -1711,7 +1711,7 @@ finish_backward (struct finish_command_fsm *sm)
 
   if (sal.pc != pc)
     {
-      struct frame_info *frame = get_selected_frame (NULL);
+      frame_info_ptr frame = get_selected_frame (NULL);
       struct gdbarch *gdbarch = get_frame_arch (frame);
 
       /* Set a step-resume at the function's entry point.  Once that's
@@ -1737,7 +1737,7 @@ finish_backward (struct finish_command_fsm *sm)
    frame that called the function we're about to step out of.  */
 
 static void
-finish_forward (struct finish_command_fsm *sm, struct frame_info *frame)
+finish_forward (struct finish_command_fsm *sm, frame_info_ptr frame)
 {
   struct frame_id frame_id = get_frame_id (frame);
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -1764,10 +1764,10 @@ finish_forward (struct finish_command_fsm *sm, struct frame_info *frame)
 
 /* Skip frames for "finish".  */
 
-static struct frame_info *
-skip_finish_frames (struct frame_info *frame)
+static frame_info_ptr
+skip_finish_frames (frame_info_ptr frame)
 {
-  struct frame_info *start;
+  frame_info_ptr start;
 
   do
     {
@@ -1792,7 +1792,7 @@ skip_finish_frames (struct frame_info *frame)
 static void
 finish_command (const char *arg, int from_tty)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   int async_exec;
   struct finish_command_fsm *sm;
   struct thread_info *tp;
@@ -2193,7 +2193,7 @@ default_print_one_register_info (struct ui_file *file,
 void
 default_print_registers_info (struct gdbarch *gdbarch,
 			      struct ui_file *file,
-			      struct frame_info *frame,
+			      frame_info_ptr frame,
 			      int regnum, int print_all)
 {
   int i;
@@ -2237,7 +2237,7 @@ default_print_registers_info (struct gdbarch *gdbarch,
 void
 registers_info (const char *addr_exp, int fpregs)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *gdbarch;
 
   if (!target_has_registers ())
@@ -2354,7 +2354,7 @@ info_registers_command (const char *addr_exp, int from_tty)
 
 static void
 print_vector_info (struct ui_file *file,
-		   struct frame_info *frame, const char *args)
+		   frame_info_ptr frame, const char *args)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
@@ -2887,7 +2887,7 @@ interrupt_command (const char *args, int from_tty)
 
 void
 default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
-			  struct frame_info *frame, const char *args)
+			  frame_info_ptr frame, const char *args)
 {
   int regnum;
   int printed_something = 0;
@@ -2908,7 +2908,7 @@ default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
 static void
 info_float_command (const char *args, int from_tty)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   if (!target_has_registers ())
     error (_("The program has no registers now."));
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 017800165b4..4d6fdd89e34 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -25,7 +25,7 @@
 #include <list>
 
 struct target_waitstatus;
-struct frame_info;
+class frame_info_ptr;
 struct ui_file;
 struct type;
 struct gdbarch;
@@ -156,7 +156,7 @@ extern void reopen_exec_file (void);
 
 extern void default_print_registers_info (struct gdbarch *gdbarch,
 					  struct ui_file *file,
-					  struct frame_info *frame,
+					  frame_info_ptr frame,
 					  int regnum, int all);
 
 /* Default implementation of gdbarch_print_float_info.  Print
@@ -164,7 +164,7 @@ extern void default_print_registers_info (struct gdbarch *gdbarch,
 
 extern void default_print_float_info (struct gdbarch *gdbarch,
 				      struct ui_file *file,
-				      struct frame_info *frame,
+				      frame_info_ptr frame,
 				      const char *args);
 
 extern void child_terminal_info (struct target_ops *self, const char *, int);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index f846eb050a5..a21731481e1 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -84,9 +84,9 @@ static void follow_inferior_reset_breakpoints (void);
 
 static bool currently_stepping (struct thread_info *tp);
 
-static void insert_hp_step_resume_breakpoint_at_frame (struct frame_info *);
+static void insert_hp_step_resume_breakpoint_at_frame (frame_info_ptr );
 
-static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
+static void insert_step_resume_breakpoint_at_caller (frame_info_ptr );
 
 static void insert_longjmp_resume_breakpoint (struct gdbarch *, CORE_ADDR);
 
@@ -3475,7 +3475,7 @@ static void handle_step_into_function_backward (struct gdbarch *gdbarch,
 						struct execution_control_state *ecs);
 static void handle_signal_stop (struct execution_control_state *ecs);
 static void check_exception_resume (struct execution_control_state *,
-				    struct frame_info *);
+				    frame_info_ptr );
 
 static void end_stepping_range (struct execution_control_state *ecs);
 static void stop_waiting (struct execution_control_state *ecs);
@@ -4327,7 +4327,7 @@ fetch_inferior_event ()
 /* See infrun.h.  */
 
 void
-set_step_info (thread_info *tp, struct frame_info *frame,
+set_step_info (thread_info *tp, frame_info_ptr frame,
 	       struct symtab_and_line sal)
 {
   /* This can be removed once this function no longer implicitly relies on the
@@ -4559,7 +4559,7 @@ adjust_pc_after_break (struct thread_info *thread,
 }
 
 static bool
-stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
+stepped_in_from (frame_info_ptr frame, struct frame_id step_frame_id)
 {
   for (frame = get_prev_frame (frame);
        frame != NULL;
@@ -4584,7 +4584,7 @@ stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
 static bool
 inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
 {
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
 
   if (prev_frame)
     frame = get_prev_frame (frame);
@@ -6118,7 +6118,7 @@ finish_step_over (struct execution_control_state *ecs)
 static void
 handle_signal_stop (struct execution_control_state *ecs)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *gdbarch;
   int stopped_by_watchpoint;
   enum stop_kind stop_soon;
@@ -6629,7 +6629,7 @@ static void
 process_event_stop_test (struct execution_control_state *ecs)
 {
   struct symtab_and_line stop_pc_sal;
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *gdbarch;
   CORE_ADDR jmp_buf_pc;
   struct bpstat_what what;
@@ -6700,7 +6700,7 @@ process_event_stop_test (struct execution_control_state *ecs)
 
     case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
       {
-	struct frame_info *init_frame;
+	frame_info_ptr init_frame;
 
 	/* There are several cases to consider.
 
@@ -7675,7 +7675,7 @@ restart_after_all_stop_detach (process_stratum_target *proc_target)
 static bool
 keep_going_stepped_thread (struct thread_info *tp)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct execution_control_state ecss;
   struct execution_control_state *ecs = &ecss;
 
@@ -7932,7 +7932,7 @@ insert_step_resume_breakpoint_at_sal (struct gdbarch *gdbarch,
    RETURN_FRAME.pc.  */
 
 static void
-insert_hp_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
+insert_hp_step_resume_breakpoint_at_frame (frame_info_ptr return_frame)
 {
   gdb_assert (return_frame != NULL);
 
@@ -7963,7 +7963,7 @@ insert_hp_step_resume_breakpoint_at_frame (struct frame_info *return_frame)
    of frame_unwind_caller_id for an example).  */
 
 static void
-insert_step_resume_breakpoint_at_caller (struct frame_info *next_frame)
+insert_step_resume_breakpoint_at_caller (frame_info_ptr next_frame)
 {
   /* We shouldn't have gotten here if we don't know where the call site
      is.  */
@@ -8010,7 +8010,7 @@ insert_longjmp_resume_breakpoint (struct gdbarch *gdbarch, CORE_ADDR pc)
 static void
 insert_exception_resume_breakpoint (struct thread_info *tp,
 				    const struct block *b,
-				    struct frame_info *frame,
+				    frame_info_ptr frame,
 				    struct symbol *sym)
 {
   try
@@ -8054,7 +8054,7 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
 static void
 insert_exception_resume_from_probe (struct thread_info *tp,
 				    const struct bound_probe *probe,
-				    struct frame_info *frame)
+				    frame_info_ptr frame)
 {
   struct value *arg_value;
   CORE_ADDR handler;
@@ -8081,7 +8081,7 @@ insert_exception_resume_from_probe (struct thread_info *tp,
 
 static void
 check_exception_resume (struct execution_control_state *ecs,
-			struct frame_info *frame)
+			frame_info_ptr frame)
 {
   struct bound_probe probe;
   struct symbol *func;
@@ -8740,7 +8740,7 @@ normal_stop (void)
 	  /* Pop the empty frame that contains the stack dummy.  This
 	     also restores inferior state prior to the call (struct
 	     infcall_suspend_state).  */
-	  struct frame_info *frame = get_current_frame ();
+	  frame_info_ptr frame = get_current_frame ();
 
 	  gdb_assert (get_frame_type (frame) == DUMMY_FRAME);
 	  frame_pop (frame);
diff --git a/gdb/infrun.h b/gdb/infrun.h
index 0c7c55eabec..d1209a94a22 100644
--- a/gdb/infrun.h
+++ b/gdb/infrun.h
@@ -24,7 +24,7 @@
 #include "gdbsupport/intrusive_list.h"
 
 struct target_waitstatus;
-struct frame_info;
+class frame_info_ptr;
 struct address_space;
 struct return_value_info;
 struct process_stratum_target;
@@ -198,7 +198,7 @@ extern int stepping_past_nonsteppable_watchpoint (void);
 
 /* Record in TP the frame and location we're currently stepping through.  */
 extern void set_step_info (thread_info *tp,
-			   struct frame_info *frame,
+			   frame_info_ptr frame,
 			   struct symtab_and_line sal);
 
 /* Several print_*_reason helper functions to print why the inferior
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
index 5cb6776aaff..5f4ab66609a 100644
--- a/gdb/inline-frame.c
+++ b/gdb/inline-frame.c
@@ -150,7 +150,7 @@ clear_inline_frame_state (thread_info *thread)
 }
 
 static void
-inline_frame_this_id (struct frame_info *this_frame,
+inline_frame_this_id (frame_info_ptr this_frame,
 		      void **this_cache,
 		      struct frame_id *this_id)
 {
@@ -163,7 +163,7 @@ inline_frame_this_id (struct frame_info *this_frame,
      function, there must be previous frames, so this is safe - as
      long as we're careful not to create any cycles.  See related
      comments in get_prev_frame_always_1.  */
-  frame_info *prev_frame = get_prev_frame_always (this_frame);
+  frame_info_ptr prev_frame = get_prev_frame_always (this_frame);
   if (prev_frame == nullptr)
     error (_("failed to find previous frame when computing inline frame id"));
   *this_id = get_frame_id (prev_frame);
@@ -186,7 +186,7 @@ inline_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-inline_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+inline_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			    int regnum)
 {
   /* Use get_frame_register_value instead of
@@ -208,13 +208,13 @@ inline_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 
 static int
 inline_frame_sniffer (const struct frame_unwind *self,
-		      struct frame_info *this_frame,
+		      frame_info_ptr this_frame,
 		      void **this_cache)
 {
   CORE_ADDR this_pc;
   const struct block *frame_block, *cur_block;
   int depth;
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
   struct inline_state *state = find_inline_frame_state (inferior_thread ());
 
   this_pc = get_frame_address_in_block (this_frame);
@@ -441,9 +441,9 @@ inline_skipped_symbol (thread_info *thread)
    skip_inline_frames).  */
 
 int
-frame_inlined_callees (struct frame_info *this_frame)
+frame_inlined_callees (frame_info_ptr this_frame)
 {
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
   int inline_count = 0;
 
   /* First count how many inlined functions at this PC have frames
diff --git a/gdb/inline-frame.h b/gdb/inline-frame.h
index d4822d49dbd..211a9eca956 100644
--- a/gdb/inline-frame.h
+++ b/gdb/inline-frame.h
@@ -20,7 +20,7 @@
 #if !defined (INLINE_FRAME_H)
 #define INLINE_FRAME_H 1
 
-struct frame_info;
+class frame_info_ptr;
 struct frame_unwind;
 struct bpstat;
 struct process_stratum_target;
@@ -68,6 +68,6 @@ struct symbol *inline_skipped_symbol (thread_info *thread);
    the callees may not have associated frames (see
    skip_inline_frames).  */
 
-int frame_inlined_callees (struct frame_info *this_frame);
+int frame_inlined_callees (frame_info_ptr this_frame);
 
 #endif /* !defined (INLINE_FRAME_H) */
diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c
index 42fcc46ac85..241aa2155c0 100644
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -199,7 +199,7 @@ static CORE_ADDR
 iq2000_scan_prologue (struct gdbarch *gdbarch,
 		      CORE_ADDR scan_start,
 		      CORE_ADDR scan_end,
-		      struct frame_info *fi,
+		      frame_info_ptr fi,
 		      struct iq2000_frame_cache *cache)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
@@ -359,7 +359,7 @@ iq2000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 }
 
 static struct iq2000_frame_cache *
-iq2000_frame_cache (struct frame_info *this_frame, void **this_cache)
+iq2000_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct iq2000_frame_cache *cache;
@@ -392,7 +392,7 @@ iq2000_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static struct value *
-iq2000_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+iq2000_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			    int regnum)
 {
   struct iq2000_frame_cache *cache = iq2000_frame_cache (this_frame,
@@ -412,7 +412,7 @@ iq2000_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 }
 
 static void
-iq2000_frame_this_id (struct frame_info *this_frame, void **this_cache,
+iq2000_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		      struct frame_id *this_id)
 {
   struct iq2000_frame_cache *cache = iq2000_frame_cache (this_frame,
@@ -436,7 +436,7 @@ static const struct frame_unwind iq2000_frame_unwind = {
 };
 
 static CORE_ADDR
-iq2000_frame_base_address (struct frame_info *this_frame, void **this_cache)
+iq2000_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct iq2000_frame_cache *cache = iq2000_frame_cache (this_frame,
 							 this_cache);
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index 40c1345404d..f23559f886c 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -44,7 +44,7 @@ enum what_to_list { locals, arguments, all };
 static void list_args_or_locals (const frame_print_options &fp_opts,
 				 enum what_to_list what,
 				 enum print_values values,
-				 struct frame_info *fi,
+				 frame_info_ptr fi,
 				 int skip_unavailable);
 
 /* True if we want to allow Python-based frame filters.  */
@@ -61,7 +61,7 @@ mi_cmd_enable_frame_filters (const char *command, char **argv, int argc)
 /* Like apply_ext_lang_frame_filter, but take a print_values */
 
 static enum ext_lang_bt_status
-mi_apply_ext_lang_frame_filter (struct frame_info *frame,
+mi_apply_ext_lang_frame_filter (frame_info_ptr frame,
 				frame_filter_flags flags,
 				enum print_values print_values,
 				struct ui_out *out,
@@ -87,7 +87,7 @@ mi_cmd_stack_list_frames (const char *command, char **argv, int argc)
   int frame_low;
   int frame_high;
   int i;
-  struct frame_info *fi;
+  frame_info_ptr fi;
   enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
   int raw_arg = 0;
   int oind = 0;
@@ -189,7 +189,7 @@ mi_cmd_stack_info_depth (const char *command, char **argv, int argc)
 {
   int frame_high;
   int i;
-  struct frame_info *fi;
+  frame_info_ptr fi;
 
   if (argc > 1)
     error (_("-stack-info-depth: Usage: [MAX_DEPTH]"));
@@ -216,7 +216,7 @@ mi_cmd_stack_info_depth (const char *command, char **argv, int argc)
 void
 mi_cmd_stack_list_locals (const char *command, char **argv, int argc)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   int raw_arg = 0;
   enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
   enum print_values print_value;
@@ -295,7 +295,7 @@ mi_cmd_stack_list_args (const char *command, char **argv, int argc)
   int frame_low;
   int frame_high;
   int i;
-  struct frame_info *fi;
+  frame_info_ptr fi;
   enum print_values print_values;
   struct ui_out *uiout = current_uiout;
   int raw_arg = 0;
@@ -408,7 +408,7 @@ mi_cmd_stack_list_args (const char *command, char **argv, int argc)
 void
 mi_cmd_stack_list_variables (const char *command, char **argv, int argc)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   int raw_arg = 0;
   enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
   enum print_values print_value;
@@ -566,7 +566,7 @@ list_arg_or_local (const struct frame_arg *arg, enum what_to_list what,
 static void
 list_args_or_locals (const frame_print_options &fp_opts,
 		     enum what_to_list what, enum print_values values,
-		     struct frame_info *fi, int skip_unavailable)
+		     frame_info_ptr fi, int skip_unavailable)
 {
   const struct block *block;
   struct symbol *sym;
@@ -692,7 +692,7 @@ list_args_or_locals (const frame_print_options &fp_opts,
    manual, this feature is supported here purely for backward
    compatibility.  */
 
-static struct frame_info *
+static frame_info_ptr
 parse_frame_specification (const char *frame_exp)
 {
   gdb_assert (frame_exp != NULL);
@@ -706,7 +706,7 @@ parse_frame_specification (const char *frame_exp)
   struct value *arg = parse_and_eval (frame_exp);
 
   /* Assume ARG is an integer, and try using that to select a frame.  */
-  struct frame_info *fid;
+  frame_info_ptr fid;
   int level = value_as_long (arg);
 
   fid = find_relative_frame (get_current_frame (), &level);
@@ -731,7 +731,7 @@ parse_frame_specification (const char *frame_exp)
     {
       if (id == get_frame_id (fid))
 	{
-	  struct frame_info *prev_frame;
+	  frame_info_ptr prev_frame;
 
 	  while (1)
 	    {
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index ee2e9acf634..5f3b707bb9b 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -95,7 +95,7 @@ static void mi_execute_async_cli_command (const char *cli_command,
 					  char **argv, int argc);
 static bool register_changed_p (int regnum, readonly_detached_regcache *,
 			       readonly_detached_regcache *);
-static void output_register (struct frame_info *, int regnum, int format,
+static void output_register (frame_info_ptr , int regnum, int format,
 			     int skip_unavailable);
 
 /* Controls whether the frontend wants MI in async mode.  */
@@ -1008,7 +1008,7 @@ void
 mi_cmd_data_list_register_values (const char *command, char **argv, int argc)
 {
   struct ui_out *uiout = current_uiout;
-  struct frame_info *frame;
+  frame_info_ptr frame;
   struct gdbarch *gdbarch;
   int regnum, numregs, format;
   int i;
@@ -1095,7 +1095,7 @@ mi_cmd_data_list_register_values (const char *command, char **argv, int argc)
    unavailable.  */
 
 static void
-output_register (struct frame_info *frame, int regnum, int format,
+output_register (frame_info_ptr frame, int regnum, int format,
 		 int skip_unavailable)
 {
   struct ui_out *uiout = current_uiout;
@@ -2083,7 +2083,7 @@ mi_cmd_execute (struct mi_parse *parse)
   gdb::optional<scoped_restore_selected_frame> frame_saver;
   if (parse->frame != -1)
     {
-      struct frame_info *fid;
+      frame_info_ptr fid;
       int frame = parse->frame;
 
       fid = find_relative_frame (get_current_frame (), &frame);
@@ -2618,7 +2618,7 @@ mi_cmd_trace_frame_collected (const char *command, char **argv, int argc)
      the trace frame info, but instead consult the register cache for
      register availability.  */
   {
-    struct frame_info *frame;
+    frame_info_ptr frame;
     struct gdbarch *gdbarch;
     int regnum;
     int numregs;
diff --git a/gdb/python/py-event.h b/gdb/python/py-event.h
index 220af1f7b12..1aa888f081a 100644
--- a/gdb/python/py-event.h
+++ b/gdb/python/py-event.h
@@ -55,7 +55,7 @@ enum inferior_call_kind
 
 extern int emit_inferior_call_event (inferior_call_kind kind,
 				     ptid_t thread, CORE_ADDR addr);
-extern int emit_register_changed_event (struct frame_info *frame,
+extern int emit_register_changed_event (frame_info_ptr frame,
 					int regnum);
 extern int emit_memory_changed_event (CORE_ADDR addr, ssize_t len);
 extern int evpy_emit_event (PyObject *event,
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c
index 2d476114b35..5d9b14b19c3 100644
--- a/gdb/python/py-finishbreakpoint.c
+++ b/gdb/python/py-finishbreakpoint.c
@@ -164,8 +164,8 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
       (struct finish_breakpoint_object *) self;
   PyObject *frame_obj = NULL;
   int thread;
-  struct frame_info *frame = NULL; /* init for gcc -Wall */
-  struct frame_info *prev_frame = NULL;
+  frame_info_ptr frame = NULL; /* init for gcc -Wall */
+  frame_info_ptr prev_frame = NULL;
   struct frame_id frame_id;
   PyObject *internal = NULL;
   int internal_bp = 0;
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 9b3a0ac142b..85256a8807d 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -57,11 +57,11 @@ struct frame_object {
    object.  If the frame doesn't exist anymore (the frame id doesn't
    correspond to any frame in the inferior), returns NULL.  */
 
-struct frame_info *
+frame_info_ptr
 frame_object_to_frame_info (PyObject *obj)
 {
   frame_object *frame_obj = (frame_object *) obj;
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   frame = frame_find_by_id (frame_obj->frame_id);
   if (frame == NULL)
@@ -90,7 +90,7 @@ frapy_str (PyObject *self)
 static PyObject *
 frapy_is_valid (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
 
   try
     {
@@ -113,7 +113,7 @@ frapy_is_valid (PyObject *self, PyObject *args)
 static PyObject *
 frapy_name (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   gdb::unique_xmalloc_ptr<char> name;
   enum language lang;
   PyObject *result;
@@ -149,7 +149,7 @@ frapy_name (PyObject *self, PyObject *args)
 static PyObject *
 frapy_type (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning.  */
 
   try
@@ -172,7 +172,7 @@ frapy_type (PyObject *self, PyObject *args)
 static PyObject *
 frapy_arch (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame = NULL;    /* Initialize to appease gcc warning.  */
+  frame_info_ptr frame = NULL;    /* Initialize to appease gcc warning.  */
   frame_object *obj = (frame_object *) self;
 
   try
@@ -193,7 +193,7 @@ frapy_arch (PyObject *self, PyObject *args)
 static PyObject *
 frapy_unwind_stop_reason (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame = NULL;    /* Initialize to appease gcc warning.  */
+  frame_info_ptr frame = NULL;    /* Initialize to appease gcc warning.  */
   enum unwind_stop_reason stop_reason;
 
   try
@@ -217,7 +217,7 @@ static PyObject *
 frapy_pc (PyObject *self, PyObject *args)
 {
   CORE_ADDR pc = 0;	      /* Initialize to appease gcc warning.  */
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   try
     {
@@ -246,7 +246,7 @@ frapy_read_register (PyObject *self, PyObject *args)
     return NULL;
   try
     {
-      struct frame_info *frame;
+      frame_info_ptr frame;
       int regnum;
 
       FRAPY_REQUIRE_VALID (self, frame);
@@ -278,7 +278,7 @@ frapy_read_register (PyObject *self, PyObject *args)
 static PyObject *
 frapy_block (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   const struct block *block = NULL, *fn_block;
 
   try
@@ -320,7 +320,7 @@ static PyObject *
 frapy_function (PyObject *self, PyObject *args)
 {
   struct symbol *sym = NULL;
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   try
     {
@@ -346,7 +346,7 @@ frapy_function (PyObject *self, PyObject *args)
    Sets a Python exception and returns NULL on error.  */
 
 PyObject *
-frame_info_to_frame_object (struct frame_info *frame)
+frame_info_to_frame_object (frame_info_ptr frame)
 {
   gdbpy_ref<frame_object> frame_obj (PyObject_New (frame_object,
 						   &frame_object_type));
@@ -389,7 +389,7 @@ frame_info_to_frame_object (struct frame_info *frame)
 static PyObject *
 frapy_older (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame, *prev = NULL;
+  frame_info_ptr frame, prev = NULL;
   PyObject *prev_obj = NULL;   /* Initialize to appease gcc warning.  */
 
   try
@@ -421,7 +421,7 @@ frapy_older (PyObject *self, PyObject *args)
 static PyObject *
 frapy_newer (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame, *next = NULL;
+  frame_info_ptr frame, next = NULL;
   PyObject *next_obj = NULL;   /* Initialize to appease gcc warning.  */
 
   try
@@ -452,7 +452,7 @@ frapy_newer (PyObject *self, PyObject *args)
 static PyObject *
 frapy_find_sal (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   PyObject *sal_obj = NULL;   /* Initialize to appease gcc warning.  */
 
   try
@@ -480,7 +480,7 @@ frapy_find_sal (PyObject *self, PyObject *args)
 static PyObject *
 frapy_read_var (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   PyObject *sym_obj, *block_obj = NULL;
   struct symbol *var = NULL;	/* gcc-4.3.2 false warning.  */
   const struct block *block = NULL;
@@ -561,7 +561,7 @@ frapy_read_var (PyObject *self, PyObject *args)
 static PyObject *
 frapy_select (PyObject *self, PyObject *args)
 {
-  struct frame_info *fi;
+  frame_info_ptr fi;
 
   try
     {
@@ -582,7 +582,7 @@ frapy_select (PyObject *self, PyObject *args)
 static PyObject *
 frapy_level (PyObject *self, PyObject *args)
 {
-  struct frame_info *fi;
+  frame_info_ptr fi;
 
   try
     {
@@ -605,7 +605,7 @@ frapy_language (PyObject *self, PyObject *args)
 {
   try
     {
-      struct frame_info *fi;
+      frame_info_ptr fi;
       FRAPY_REQUIRE_VALID (self, fi);
 
       enum language lang = get_frame_language (fi);
@@ -627,7 +627,7 @@ frapy_language (PyObject *self, PyObject *args)
 PyObject *
 gdbpy_newest_frame (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
 
   try
     {
@@ -647,7 +647,7 @@ gdbpy_newest_frame (PyObject *self, PyObject *args)
 PyObject *
 gdbpy_selected_frame (PyObject *self, PyObject *args)
 {
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
 
   try
     {
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 366f3745b9d..0d7dc48c5a0 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -419,7 +419,7 @@ enumerate_args (PyObject *iter,
 		struct ui_out *out,
 		enum ext_lang_frame_args args_type,
 		int print_args_field,
-		struct frame_info *frame)
+		frame_info_ptr frame)
 {
   struct value_print_options opts;
 
@@ -550,7 +550,7 @@ enumerate_locals (PyObject *iter,
 		  int indent,
 		  enum ext_lang_frame_args args_type,
 		  int print_args_field,
-		  struct frame_info *frame)
+		  frame_info_ptr frame)
 {
   struct value_print_options opts;
 
@@ -638,7 +638,7 @@ static enum ext_lang_bt_status
 py_mi_print_variables (PyObject *filter, struct ui_out *out,
 		       struct value_print_options *opts,
 		       enum ext_lang_frame_args args_type,
-		       struct frame_info *frame)
+		       frame_info_ptr frame)
 {
   gdbpy_ref<> args_iter (get_py_iter_from_func (filter, "frame_args"));
   if (args_iter == NULL)
@@ -672,7 +672,7 @@ py_print_locals (PyObject *filter,
 		 struct ui_out *out,
 		 enum ext_lang_frame_args args_type,
 		 int indent,
-		 struct frame_info *frame)
+		 frame_info_ptr frame)
 {
   gdbpy_ref<> locals_iter (get_py_iter_from_func (filter, "frame_locals"));
   if (locals_iter == NULL)
@@ -697,7 +697,7 @@ static enum ext_lang_bt_status
 py_print_args (PyObject *filter,
 	       struct ui_out *out,
 	       enum ext_lang_frame_args args_type,
-	       struct frame_info *frame)
+	       frame_info_ptr frame)
 {
   gdbpy_ref<> args_iter (get_py_iter_from_func (filter, "frame_args"));
   if (args_iter == NULL)
@@ -754,7 +754,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
   int has_addr = 0;
   CORE_ADDR address = 0;
   struct gdbarch *gdbarch = NULL;
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
   struct value_print_options opts;
 
   int print_level, print_frame_info, print_args, print_locals;
@@ -862,8 +862,8 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
       struct frame_info **slot;
       int level;
 
-      slot = (struct frame_info **) htab_find_slot (levels_printed,
-						    frame, INSERT);
+      slot = (frame_info **) htab_find_slot (levels_printed,
+						   frame.get(), INSERT);
 
       level = frame_relative_level (frame);
 
@@ -875,7 +875,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
 	out->field_skip ("level");
       else
 	{
-	  *slot = frame;
+	  *slot = frame.get ();
 	  annotate_frame_begin (print_level ? level : 0,
 				gdbarch, address);
 	  out->text ("#");
@@ -1078,7 +1078,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
    frame FRAME.  */
 
 static PyObject *
-bootstrap_python_frame_filters (struct frame_info *frame,
+bootstrap_python_frame_filters (frame_info_ptr frame,
 				int frame_low, int frame_high)
 {
   gdbpy_ref<> frame_obj (frame_info_to_frame_object (frame));
@@ -1133,7 +1133,7 @@ bootstrap_python_frame_filters (struct frame_info *frame,
 
 enum ext_lang_bt_status
 gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
-			  struct frame_info *frame, frame_filter_flags flags,
+			  frame_info_ptr frame, frame_filter_flags flags,
 			  enum ext_lang_frame_args args_type,
 			  struct ui_out *out, int frame_low, int frame_high)
 {
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 6ea384e26a0..f188f376c58 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -174,7 +174,7 @@ python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len,
    command). */
 
 static void
-python_on_register_change (struct frame_info *frame, int regnum)
+python_on_register_change (frame_info_ptr frame, int regnum)
 {
   gdbpy_enter enter_py (target_gdbarch ());
 
diff --git a/gdb/python/py-infevents.c b/gdb/python/py-infevents.c
index 0a0ca998134..9920bed98c5 100644
--- a/gdb/python/py-infevents.c
+++ b/gdb/python/py-infevents.c
@@ -62,7 +62,7 @@ create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid,
    register number. */
 
 static gdbpy_ref<>
-create_register_changed_event_object (struct frame_info *frame, 
+create_register_changed_event_object (frame_info_ptr frame, 
 				      int regnum)
 {
   gdbpy_ref<> event = create_event_object (&register_changed_event_object_type);
@@ -151,7 +151,7 @@ emit_memory_changed_event (CORE_ADDR addr, ssize_t len)
    will create a new Python register changed event object. */
 
 int
-emit_register_changed_event (struct frame_info* frame, int regnum)
+emit_register_changed_event (frame_info_ptr frame, int regnum)
 {
   if (evregpy_no_listeners_p (gdb_py_events.register_changed))
     return 0;
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index e5fe5cf8c92..93c86964f3e 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -265,7 +265,7 @@ static PyObject *
 sympy_value (PyObject *self, PyObject *args)
 {
   struct symbol *symbol = NULL;
-  struct frame_info *frame_info = NULL;
+  frame_info_ptr frame_info = NULL;
   PyObject *frame_obj = NULL;
   struct value *value = NULL;
 
@@ -401,7 +401,7 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
     block = block_object_to_block (block_obj);
   else
     {
-      struct frame_info *selected_frame;
+      frame_info_ptr selected_frame;
 
       try
 	{
@@ -511,7 +511,7 @@ gdbpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw)
   const struct block *block = NULL;
   try
     {
-      struct frame_info *selected_frame
+      frame_info_ptr selected_frame
 	= get_selected_frame (_("No frame selected."));
       block = get_frame_block (selected_frame, NULL);
     }
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index fb9466102c4..fa8f128a32e 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -57,7 +57,7 @@ struct pending_frame_object
   PyObject_HEAD
 
   /* Frame we are unwinding.  */
-  struct frame_info *frame_info;
+  frame_info_ptr frame_info;
 
   /* Its architecture, passed by the sniffer caller.  */
   struct gdbarch *gdbarch;
@@ -342,7 +342,7 @@ unwind_infopy_dealloc (PyObject *self)
 static PyObject *
 pending_framepy_str (PyObject *self)
 {
-  struct frame_info *frame = ((pending_frame_object *) self)->frame_info;
+  frame_info_ptr frame = ((pending_frame_object *) self)->frame_info;
   const char *sp_str = NULL;
   const char *pc_str = NULL;
 
@@ -481,7 +481,7 @@ pending_framepy_level (PyObject *self, PyObject *args)
 /* frame_unwind.this_id method.  */
 
 static void
-pyuw_this_id (struct frame_info *this_frame, void **cache_ptr,
+pyuw_this_id (frame_info_ptr this_frame, void **cache_ptr,
 	      struct frame_id *this_id)
 {
   *this_id = ((cached_frame_info *) *cache_ptr)->frame_id;
@@ -491,7 +491,7 @@ pyuw_this_id (struct frame_info *this_frame, void **cache_ptr,
 /* frame_unwind.prev_register.  */
 
 static struct value *
-pyuw_prev_register (struct frame_info *this_frame, void **cache_ptr,
+pyuw_prev_register (frame_info_ptr this_frame, void **cache_ptr,
 		    int regnum)
 {
   PYUW_SCOPED_DEBUG_ENTER_EXIT;
@@ -514,7 +514,7 @@ pyuw_prev_register (struct frame_info *this_frame, void **cache_ptr,
 /* Frame sniffer dispatch.  */
 
 static int
-pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
+pyuw_sniffer (const struct frame_unwind *self, frame_info_ptr this_frame,
 	      void **cache_ptr)
 {
   PYUW_SCOPED_DEBUG_ENTER_EXIT;
@@ -641,7 +641,7 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
 /* Frame cache release shim.  */
 
 static void
-pyuw_dealloc_cache (struct frame_info *this_frame, void *cache)
+pyuw_dealloc_cache (frame_info *this_frame, void *cache)
 {
   PYUW_SCOPED_DEBUG_ENTER_EXIT;
   cached_frame_info *cached_frame = (cached_frame_info *) cache;
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 800b03a105c..df6eeb5dfe7 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -366,7 +366,7 @@ extern enum ext_lang_rc gdbpy_apply_val_pretty_printer
    const struct language_defn *language);
 extern enum ext_lang_bt_status gdbpy_apply_frame_filter
   (const struct extension_language_defn *,
-   struct frame_info *frame, frame_filter_flags flags,
+   frame_info_ptr frame, frame_filter_flags flags,
    enum ext_lang_frame_args args_type,
    struct ui_out *out, int frame_low, int frame_high);
 extern void gdbpy_preserve_values (const struct extension_language_defn *,
@@ -427,7 +427,7 @@ PyObject *block_to_block_object (const struct block *block,
 PyObject *value_to_value_object (struct value *v);
 PyObject *value_to_value_object_no_release (struct value *v);
 PyObject *type_to_type_object (struct type *);
-PyObject *frame_info_to_frame_object (struct frame_info *frame);
+PyObject *frame_info_to_frame_object (frame_info_ptr frame);
 PyObject *symtab_to_linetable_object (PyObject *symtab);
 gdbpy_ref<> pspace_to_pspace_object (struct program_space *);
 PyObject *pspy_get_printers (PyObject *, void *);
@@ -467,7 +467,7 @@ struct value *convert_value_from_python (PyObject *obj);
 struct type *type_object_to_type (PyObject *obj);
 struct symtab *symtab_object_to_symtab (PyObject *obj);
 struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
-struct frame_info *frame_object_to_frame_info (PyObject *frame_obj);
+frame_info_ptr frame_object_to_frame_info (PyObject *frame_obj);
 struct gdbarch *arch_object_to_gdbarch (PyObject *obj);
 
 /* Convert Python object OBJ to a program_space pointer.  OBJ must be a
diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c
index 5e49c615f1b..f6eda88da6a 100644
--- a/gdb/s12z-tdep.c
+++ b/gdb/s12z-tdep.c
@@ -241,7 +241,7 @@ push_pull_get_stack_adjustment (int n_operands,
 /* Initialize a prologue cache.  */
 
 static struct trad_frame_cache *
-s12z_frame_cache (struct frame_info *this_frame, void **prologue_cache)
+s12z_frame_cache (frame_info_ptr this_frame, void **prologue_cache)
 {
   struct trad_frame_cache *info;
 
@@ -420,7 +420,7 @@ s12z_frame_cache (struct frame_info *this_frame, void **prologue_cache)
 
 /* Implement the this_id function for the stub unwinder.  */
 static void
-s12z_frame_this_id (struct frame_info *this_frame,
+s12z_frame_this_id (frame_info_ptr this_frame,
 		    void **prologue_cache, struct frame_id *this_id)
 {
   struct trad_frame_cache *info = s12z_frame_cache (this_frame,
@@ -432,7 +432,7 @@ s12z_frame_this_id (struct frame_info *this_frame,
 
 /* Implement the prev_register function for the stub unwinder.  */
 static struct value *
-s12z_frame_prev_register (struct frame_info *this_frame,
+s12z_frame_prev_register (frame_info_ptr this_frame,
 			  void **prologue_cache, int regnum)
 {
   struct trad_frame_cache *info = s12z_frame_cache (this_frame,
@@ -491,7 +491,7 @@ static const char ccw_bits[] =
 static void
 s12z_print_ccw_info (struct gdbarch *gdbarch,
 		     struct ui_file *file,
-		     struct frame_info *frame,
+		     frame_info_ptr frame,
 		     int reg)
 {
   struct value *v = value_of_register (reg, frame);
@@ -524,7 +524,7 @@ s12z_print_ccw_info (struct gdbarch *gdbarch,
 static void
 s12z_print_registers_info (struct gdbarch *gdbarch,
 			    struct ui_file *file,
-			    struct frame_info *frame,
+			    frame_info_ptr frame,
 			    int regnum, int print_all)
 {
   const int numregs = (gdbarch_num_regs (gdbarch)
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 05bf03973fc..1ead5403ff1 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -386,7 +386,7 @@ struct s390_sigtramp_unwind_cache {
    s390_sigtramp_frame_unwind.  */
 
 static struct s390_sigtramp_unwind_cache *
-s390_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
+s390_sigtramp_frame_unwind_cache (frame_info_ptr this_frame,
 				  void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -496,7 +496,7 @@ s390_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
 /* Implement this_id frame_unwind method for s390_sigtramp_frame_unwind.  */
 
 static void
-s390_sigtramp_frame_this_id (struct frame_info *this_frame,
+s390_sigtramp_frame_this_id (frame_info_ptr this_frame,
 			     void **this_prologue_cache,
 			     struct frame_id *this_id)
 {
@@ -508,7 +508,7 @@ s390_sigtramp_frame_this_id (struct frame_info *this_frame,
 /* Implement prev_register frame_unwind method for sigtramp frames.  */
 
 static struct value *
-s390_sigtramp_frame_prev_register (struct frame_info *this_frame,
+s390_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 				   void **this_prologue_cache, int regnum)
 {
   struct s390_sigtramp_unwind_cache *info
@@ -520,7 +520,7 @@ s390_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 s390_sigtramp_frame_sniffer (const struct frame_unwind *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     void **this_prologue_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 2aeb3a14637..37c5df21c6d 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -1982,7 +1982,7 @@ s390_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
    breakpoint.  */
 
 static struct frame_id
-s390_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+s390_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   int word_size = gdbarch_ptr_bit (gdbarch) / 8;
   CORE_ADDR sp = get_frame_register_unsigned (this_frame, S390_SP_REGNUM);
@@ -2166,7 +2166,7 @@ s390_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Implement unwind_pc gdbarch method.  */
 
 static CORE_ADDR
-s390_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+s390_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   s390_gdbarch_tdep *tdep = gdbarch_tdep<s390_gdbarch_tdep> (gdbarch);
   ULONGEST pc;
@@ -2177,7 +2177,7 @@ s390_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Implement unwind_sp gdbarch method.  */
 
 static CORE_ADDR
-s390_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+s390_unwind_sp (struct gdbarch *gdbarch, frame_info_ptr next_frame)
 {
   ULONGEST sp;
   sp = frame_unwind_register_unsigned (next_frame, S390_SP_REGNUM);
@@ -2187,7 +2187,7 @@ s390_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 /* Helper routine to unwind pseudo registers.  */
 
 static struct value *
-s390_unwind_pseudo_register (struct frame_info *this_frame, int regnum)
+s390_unwind_pseudo_register (frame_info_ptr this_frame, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   s390_gdbarch_tdep *tdep = gdbarch_tdep<s390_gdbarch_tdep> (gdbarch);
@@ -2258,7 +2258,7 @@ s390_adjust_frame_regnum (struct gdbarch *gdbarch, int num, int eh_frame_p)
    s390_dwarf2_frame_init_reg.  */
 
 static struct value *
-s390_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache,
+s390_dwarf2_prev_register (frame_info_ptr this_frame, void **this_cache,
 			   int regnum)
 {
   return s390_unwind_pseudo_register (this_frame, regnum);
@@ -2269,7 +2269,7 @@ s390_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache,
 static void
 s390_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			    struct dwarf2_frame_state_reg *reg,
-			    struct frame_info *this_frame)
+			    frame_info_ptr this_frame)
 {
   /* The condition code (and thus PSW mask) is call-clobbered.  */
   if (regnum == S390_PSWM_REGNUM)
@@ -2303,7 +2303,7 @@ s390_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
    register translation.  */
 
 struct value *
-s390_trad_frame_prev_register (struct frame_info *this_frame,
+s390_trad_frame_prev_register (frame_info_ptr this_frame,
 			       trad_frame_saved_reg saved_regs[],
 			       int regnum)
 {
@@ -2328,7 +2328,7 @@ struct s390_unwind_cache {
    prologue analysis.  Helper for s390_frame_unwind_cache.  */
 
 static int
-s390_prologue_frame_unwind_cache (struct frame_info *this_frame,
+s390_prologue_frame_unwind_cache (frame_info_ptr this_frame,
 				  struct s390_unwind_cache *info)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2344,7 +2344,7 @@ s390_prologue_frame_unwind_cache (struct frame_info *this_frame,
   CORE_ADDR prev_sp;
   int frame_pointer;
   int size;
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
 
   /* Try to find the function start address.  If we can't find it, we don't
      bother searching for it -- with modern compilers this would be mostly
@@ -2515,7 +2515,7 @@ s390_prologue_frame_unwind_cache (struct frame_info *this_frame,
    back chain unwinding.  Helper for s390_frame_unwind_cache.  */
 
 static void
-s390_backchain_frame_unwind_cache (struct frame_info *this_frame,
+s390_backchain_frame_unwind_cache (frame_info_ptr this_frame,
 				   struct s390_unwind_cache *info)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2572,7 +2572,7 @@ s390_backchain_frame_unwind_cache (struct frame_info *this_frame,
    s390_frame_unwind and s390_frame_base.  */
 
 static struct s390_unwind_cache *
-s390_frame_unwind_cache (struct frame_info *this_frame,
+s390_frame_unwind_cache (frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   struct s390_unwind_cache *info;
@@ -2606,7 +2606,7 @@ s390_frame_unwind_cache (struct frame_info *this_frame,
 /* Implement this_id frame_unwind method for s390_frame_unwind.  */
 
 static void
-s390_frame_this_id (struct frame_info *this_frame,
+s390_frame_this_id (frame_info_ptr this_frame,
 		    void **this_prologue_cache,
 		    struct frame_id *this_id)
 {
@@ -2626,7 +2626,7 @@ s390_frame_this_id (struct frame_info *this_frame,
 /* Implement prev_register frame_unwind method for s390_frame_unwind.  */
 
 static struct value *
-s390_frame_prev_register (struct frame_info *this_frame,
+s390_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_prologue_cache, int regnum)
 {
   struct s390_unwind_cache *info
@@ -2661,7 +2661,7 @@ struct s390_stub_unwind_cache
    s390_stub_frame_unwind.  */
 
 static struct s390_stub_unwind_cache *
-s390_stub_frame_unwind_cache (struct frame_info *this_frame,
+s390_stub_frame_unwind_cache (frame_info_ptr this_frame,
 			      void **this_prologue_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -2689,7 +2689,7 @@ s390_stub_frame_unwind_cache (struct frame_info *this_frame,
 /* Implement this_id frame_unwind method for s390_stub_frame_unwind.  */
 
 static void
-s390_stub_frame_this_id (struct frame_info *this_frame,
+s390_stub_frame_this_id (frame_info_ptr this_frame,
 			 void **this_prologue_cache,
 			 struct frame_id *this_id)
 {
@@ -2701,7 +2701,7 @@ s390_stub_frame_this_id (struct frame_info *this_frame,
 /* Implement prev_register frame_unwind method for s390_stub_frame_unwind.  */
 
 static struct value *
-s390_stub_frame_prev_register (struct frame_info *this_frame,
+s390_stub_frame_prev_register (frame_info_ptr this_frame,
 			       void **this_prologue_cache, int regnum)
 {
   struct s390_stub_unwind_cache *info
@@ -2713,7 +2713,7 @@ s390_stub_frame_prev_register (struct frame_info *this_frame,
 
 static int
 s390_stub_frame_sniffer (const struct frame_unwind *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 void **this_prologue_cache)
 {
   CORE_ADDR addr_in_block;
@@ -2744,7 +2744,7 @@ static const struct frame_unwind s390_stub_frame_unwind = {
 /* Frame base handling.  */
 
 static CORE_ADDR
-s390_frame_base_address (struct frame_info *this_frame, void **this_cache)
+s390_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct s390_unwind_cache *info
     = s390_frame_unwind_cache (this_frame, this_cache);
@@ -2752,7 +2752,7 @@ s390_frame_base_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static CORE_ADDR
-s390_local_base_address (struct frame_info *this_frame, void **this_cache)
+s390_local_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct s390_unwind_cache *info
     = s390_frame_unwind_cache (this_frame, this_cache);
diff --git a/gdb/s390-tdep.h b/gdb/s390-tdep.h
index f51423cb018..a7b16c2066e 100644
--- a/gdb/s390-tdep.h
+++ b/gdb/s390-tdep.h
@@ -314,7 +314,7 @@ enum
 /* Frame unwinding.  */
 
 extern struct value *s390_trad_frame_prev_register
-    (struct frame_info *this_frame, struct trad_frame_saved_reg saved_regs[],
+    (frame_info_ptr this_frame, struct trad_frame_saved_reg saved_regs[],
      int regnum);
 
 extern struct target_desc *tdesc_s390_linux32;
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 2e02ad3ca56..a948ddd10b0 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -42,7 +42,7 @@ sentinel_frame_cache (struct regcache *regcache)
 /* Here the register value is taken direct from the register cache.  */
 
 static struct value *
-sentinel_frame_prev_register (struct frame_info *this_frame,
+sentinel_frame_prev_register (frame_info_ptr this_frame,
 			      void **this_prologue_cache,
 			      int regnum)
 {
@@ -57,7 +57,7 @@ sentinel_frame_prev_register (struct frame_info *this_frame,
 }
 
 static void
-sentinel_frame_this_id (struct frame_info *this_frame,
+sentinel_frame_this_id (frame_info_ptr this_frame,
 			void **this_prologue_cache,
 			struct frame_id *this_id)
 {
@@ -68,7 +68,7 @@ sentinel_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct gdbarch *
-sentinel_frame_prev_arch (struct frame_info *this_frame,
+sentinel_frame_prev_arch (frame_info_ptr this_frame,
 			  void **this_prologue_cache)
 {
   struct frame_unwind_cache *cache
diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
index f146f023add..9802fd44a20 100644
--- a/gdb/sh-linux-tdep.c
+++ b/gdb/sh-linux-tdep.c
@@ -77,7 +77,7 @@ static const struct sh_corefile_regmap fpregs_table[] =
 /* SH signal handler frame support.  */
 
 static void
-sh_linux_sigtramp_cache (struct frame_info *this_frame,
+sh_linux_sigtramp_cache (frame_info_ptr this_frame,
 			 struct trad_frame_cache *this_cache,
 			 CORE_ADDR func, int regs_offset)
 {
@@ -114,7 +114,7 @@ sh_linux_sigtramp_cache (struct frame_info *this_frame,
 
 static void
 sh_linux_sigreturn_init (const struct tramp_frame *self,
-			 struct frame_info *this_frame,
+			 frame_info_ptr this_frame,
 			 struct trad_frame_cache *this_cache,
 			 CORE_ADDR func)
 {
@@ -125,7 +125,7 @@ sh_linux_sigreturn_init (const struct tramp_frame *self,
 
 static void
 sh_linux_rt_sigreturn_init (const struct tramp_frame *self,
-			    struct frame_info *this_frame,
+			    frame_info_ptr this_frame,
 			    struct trad_frame_cache *this_cache,
 			    CORE_ADDR func)
 {
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 062df860c81..493ffe89375 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1793,7 +1793,7 @@ sh_sh2a_register_sim_regno (struct gdbarch *gdbarch, int nr)
 static void
 sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			  struct dwarf2_frame_state_reg *reg,
-			  struct frame_info *this_frame)
+			  frame_info_ptr this_frame)
 {
   /* Mark the PC as the destination for the return address.  */
   if (regnum == gdbarch_pc_regnum (gdbarch))
@@ -1863,7 +1863,7 @@ sh_alloc_frame_cache (void)
 }
 
 static struct sh_frame_cache *
-sh_frame_cache (struct frame_info *this_frame, void **this_cache)
+sh_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct sh_frame_cache *cache;
@@ -1930,7 +1930,7 @@ sh_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static struct value *
-sh_frame_prev_register (struct frame_info *this_frame,
+sh_frame_prev_register (frame_info_ptr this_frame,
 			void **this_cache, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1955,7 +1955,7 @@ sh_frame_prev_register (struct frame_info *this_frame,
 }
 
 static void
-sh_frame_this_id (struct frame_info *this_frame, void **this_cache,
+sh_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		  struct frame_id *this_id)
 {
   struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
@@ -1978,7 +1978,7 @@ static const struct frame_unwind sh_frame_unwind = {
 };
 
 static CORE_ADDR
-sh_frame_base_address (struct frame_info *this_frame, void **this_cache)
+sh_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache);
 
@@ -1993,7 +1993,7 @@ static const struct frame_base sh_frame_base = {
 };
 
 static struct sh_frame_cache *
-sh_make_stub_cache (struct frame_info *this_frame)
+sh_make_stub_cache (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct sh_frame_cache *cache;
@@ -2007,7 +2007,7 @@ sh_make_stub_cache (struct frame_info *this_frame)
 }
 
 static void
-sh_stub_this_id (struct frame_info *this_frame, void **this_cache,
+sh_stub_this_id (frame_info_ptr this_frame, void **this_cache,
 		 struct frame_id *this_id)
 {
   struct sh_frame_cache *cache;
@@ -2021,7 +2021,7 @@ sh_stub_this_id (struct frame_info *this_frame, void **this_cache,
 
 static int
 sh_stub_unwind_sniffer (const struct frame_unwind *self,
-			struct frame_info *this_frame,
+			frame_info_ptr this_frame,
 			void **this_prologue_cache)
 {
   CORE_ADDR addr_in_block;
diff --git a/gdb/skip.c b/gdb/skip.c
index 3a3734a296d..c040f87c928 100644
--- a/gdb/skip.c
+++ b/gdb/skip.c
@@ -204,7 +204,7 @@ skip_function_command (const char *arg, int from_tty)
   /* Default to the current function if no argument is given.  */
   if (arg == NULL)
     {
-      frame_info *fi = get_selected_frame (_("No default function now."));
+      frame_info_ptr fi = get_selected_frame (_("No default function now."));
       struct symbol *sym = get_frame_function (fi);
       const char *name = NULL;
 
diff --git a/gdb/sol2-tdep.c b/gdb/sol2-tdep.c
index a7bf8836269..2cc2407656d 100644
--- a/gdb/sol2-tdep.c
+++ b/gdb/sol2-tdep.c
@@ -52,7 +52,7 @@ sol2_pc_in_sigtramp (CORE_ADDR pc, const char *name)
 /* Return whether THIS_FRAME corresponds to a Solaris sigtramp routine.  */
 
 int
-sol2_sigtramp_p (struct frame_info *this_frame)
+sol2_sigtramp_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
   const char *name;
diff --git a/gdb/sol2-tdep.h b/gdb/sol2-tdep.h
index 14ee5e64c69..cd3bdc1f343 100644
--- a/gdb/sol2-tdep.h
+++ b/gdb/sol2-tdep.h
@@ -22,7 +22,7 @@
 
 struct gdbarch;
 
-int sol2_sigtramp_p (struct frame_info *this_frame);
+int sol2_sigtramp_p (frame_info_ptr this_frame);
 
 void sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 95a1e1eb722..a4873c5dc69 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1645,7 +1645,7 @@ solib_event_probe_action (struct probe_and_action *pa)
 {
   enum probe_action action;
   unsigned probe_argc = 0;
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
 
   action = pa->action;
   if (action == DO_NOTHING || action == PROBES_INTERFACE_FAILED)
@@ -1780,7 +1780,7 @@ svr4_handle_solib_event (void)
   enum probe_action action;
   struct value *val = NULL;
   CORE_ADDR pc, debug_base, lm = 0;
-  struct frame_info *frame = get_current_frame ();
+  frame_info_ptr frame = get_current_frame ();
 
   /* Do nothing if not using the probes interface.  */
   if (info->probes_table == NULL)
diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c
index 66481ea7b8a..cd8c35ed5da 100644
--- a/gdb/sparc-linux-tdep.c
+++ b/gdb/sparc-linux-tdep.c
@@ -42,7 +42,7 @@
 /* Signal trampoline support.  */
 
 static void sparc32_linux_sigframe_init (const struct tramp_frame *self,
-					 struct frame_info *this_frame,
+					 frame_info_ptr this_frame,
 					 struct trad_frame_cache *this_cache,
 					 CORE_ADDR func);
 
@@ -117,7 +117,7 @@ enum
 
 static void
 sparc32_linux_sigframe_init (const struct tramp_frame *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
@@ -159,7 +159,7 @@ sparc32_linux_sigframe_init (const struct tramp_frame *self,
    address.  */
 
 static CORE_ADDR
-sparc32_linux_step_trap (struct frame_info *frame, unsigned long insn)
+sparc32_linux_step_trap (frame_info_ptr frame, unsigned long insn)
 {
   if (insn == 0x91d02010)
     {
diff --git a/gdb/sparc-netbsd-tdep.c b/gdb/sparc-netbsd-tdep.c
index 57c178511fa..479ec13aeda 100644
--- a/gdb/sparc-netbsd-tdep.c
+++ b/gdb/sparc-netbsd-tdep.c
@@ -95,7 +95,7 @@ sparc32nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
 }
 
 trad_frame_saved_reg *
-sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
+sparc32nbsd_sigcontext_saved_regs (frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   trad_frame_saved_reg *saved_regs;
@@ -180,7 +180,7 @@ sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
 }
 
 static struct sparc_frame_cache *
-sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
+sparc32nbsd_sigcontext_frame_cache (frame_info_ptr this_frame,
 				    void **this_cache)
 {
   struct sparc_frame_cache *cache;
@@ -211,7 +211,7 @@ sparc32nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
+sparc32nbsd_sigcontext_frame_this_id (frame_info_ptr this_frame,
 				      void **this_cache,
 				      struct frame_id *this_id)
 {
@@ -222,7 +222,7 @@ sparc32nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
+sparc32nbsd_sigcontext_frame_prev_register (frame_info_ptr this_frame,
 					    void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
@@ -233,7 +233,7 @@ sparc32nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
-				      struct frame_info *this_frame,
+				      frame_info_ptr this_frame,
 				      void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -264,7 +264,7 @@ static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
    address.  */
 
 CORE_ADDR
-sparcnbsd_step_trap (struct frame_info *frame, unsigned long insn)
+sparcnbsd_step_trap (frame_info_ptr frame, unsigned long insn)
 {
   if ((X_I (insn) == 0 && X_RS1 (insn) == 0 && X_RS2 (insn) == 0)
       || (X_I (insn) == 1 && X_RS1 (insn) == 0 && (insn & 0x7f) == 0))
diff --git a/gdb/sparc-obsd-tdep.c b/gdb/sparc-obsd-tdep.c
index e4253c11aff..57457dfa115 100644
--- a/gdb/sparc-obsd-tdep.c
+++ b/gdb/sparc-obsd-tdep.c
@@ -68,7 +68,7 @@ sparc32obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
 }
 
 static struct sparc_frame_cache *
-sparc32obsd_sigtramp_frame_cache (struct frame_info *this_frame,
+sparc32obsd_sigtramp_frame_cache (frame_info_ptr this_frame,
 				  void **this_cache)
 {
   struct sparc_frame_cache *cache;
@@ -100,7 +100,7 @@ sparc32obsd_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-sparc32obsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+sparc32obsd_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				    void **this_cache,
 				    struct frame_id *this_id)
 {
@@ -111,7 +111,7 @@ sparc32obsd_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc32obsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+sparc32obsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					  void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
@@ -122,7 +122,7 @@ sparc32obsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				    struct frame_info *this_frame,
+				    frame_info_ptr this_frame,
 				    void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c
index a92e95ce71b..8b862c4dea4 100644
--- a/gdb/sparc-sol2-tdep.c
+++ b/gdb/sparc-sol2-tdep.c
@@ -100,7 +100,7 @@ static const struct regset sparc32_sol2_fpregset =
 \f
 
 static struct sparc_frame_cache *
-sparc32_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
+sparc32_sol2_sigtramp_frame_cache (frame_info_ptr this_frame,
 				   void **this_cache)
 {
   struct sparc_frame_cache *cache;
@@ -151,7 +151,7 @@ sparc32_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-sparc32_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
+sparc32_sol2_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				     void **this_cache,
 				     struct frame_id *this_id)
 {
@@ -162,7 +162,7 @@ sparc32_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
+sparc32_sol2_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					   void **this_cache,
 					   int regnum)
 {
@@ -174,7 +174,7 @@ sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				     struct frame_info *this_frame,
+				     frame_info_ptr this_frame,
 				     void **this_cache)
 {
   return sol2_sigtramp_p (this_frame);
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 397f5489550..7bdeaf5f9e3 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1187,7 +1187,7 @@ sparc32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 /* Normal frames.  */
 
 struct sparc_frame_cache *
-sparc_frame_cache (struct frame_info *this_frame, void **this_cache)
+sparc_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache;
 
@@ -1244,7 +1244,7 @@ sparc32_struct_return_from_sym (struct symbol *sym)
 }
 
 struct sparc_frame_cache *
-sparc32_frame_cache (struct frame_info *this_frame, void **this_cache)
+sparc32_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache;
   struct symbol *sym;
@@ -1280,7 +1280,7 @@ sparc32_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-sparc32_frame_this_id (struct frame_info *this_frame, void **this_cache,
+sparc32_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		       struct frame_id *this_id)
 {
   struct sparc_frame_cache *cache =
@@ -1294,7 +1294,7 @@ sparc32_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-sparc32_frame_prev_register (struct frame_info *this_frame,
+sparc32_frame_prev_register (frame_info_ptr this_frame,
 			     void **this_cache, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1364,7 +1364,7 @@ static const struct frame_unwind sparc32_frame_unwind =
 \f
 
 static CORE_ADDR
-sparc32_frame_base_address (struct frame_info *this_frame, void **this_cache)
+sparc32_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache =
     sparc32_frame_cache (this_frame, this_cache);
@@ -1381,7 +1381,7 @@ static const struct frame_base sparc32_frame_base =
 };
 
 static struct frame_id
-sparc_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+sparc_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR sp;
 
@@ -1550,7 +1550,7 @@ sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
 }
 
 static int
-sparc32_dwarf2_struct_return_p (struct frame_info *this_frame)
+sparc32_dwarf2_struct_return_p (frame_info_ptr this_frame)
 {
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
   struct symbol *sym = find_pc_function (pc);
@@ -1563,7 +1563,7 @@ sparc32_dwarf2_struct_return_p (struct frame_info *this_frame)
 static void
 sparc32_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			       struct dwarf2_frame_state_reg *reg,
-			       struct frame_info *this_frame)
+			       frame_info_ptr this_frame)
 {
   int off;
 
@@ -1676,7 +1676,7 @@ sparc_analyze_control_transfer (struct regcache *regcache,
     }
   else if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3a)
     {
-      struct frame_info *frame = get_current_frame ();
+      frame_info_ptr frame = get_current_frame ();
 
       /* Trap instruction (TRAP).  */
       gdbarch *arch = regcache->arch ();
@@ -1722,7 +1722,7 @@ sparc_analyze_control_transfer (struct regcache *regcache,
 }
 
 static CORE_ADDR
-sparc_step_trap (struct frame_info *frame, unsigned long insn)
+sparc_step_trap (frame_info_ptr frame, unsigned long insn)
 {
   return 0;
 }
diff --git a/gdb/sparc-tdep.h b/gdb/sparc-tdep.h
index f2070f10e12..ffdf0a46e17 100644
--- a/gdb/sparc-tdep.h
+++ b/gdb/sparc-tdep.h
@@ -28,7 +28,7 @@
   "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
   "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7"
 
-struct frame_info;
+class frame_info_ptr;
 struct gdbarch;
 struct regcache;
 struct regset;
@@ -85,7 +85,7 @@ struct sparc_gdbarch_tdep : gdbarch_tdep_base
   size_t plt_entry_size = 0;
 
   /* Alternative location for trap return.  Used for single-stepping.  */
-  CORE_ADDR (*step_trap) (struct frame_info *frame, unsigned long insn)
+  CORE_ADDR (*step_trap) (frame_info_ptr frame, unsigned long insn)
     = nullptr;
 
   /* ISA-specific data types.  */
@@ -207,10 +207,10 @@ extern CORE_ADDR sparc_analyze_prologue (struct gdbarch *gdbarch,
 					 struct sparc_frame_cache *cache);
 
 extern struct sparc_frame_cache *
-  sparc_frame_cache (struct frame_info *this_frame, void **this_cache);
+  sparc_frame_cache (frame_info_ptr this_frame, void **this_cache);
 
 extern struct sparc_frame_cache *
-  sparc32_frame_cache (struct frame_info *this_frame, void **this_cache);
+  sparc32_frame_cache (frame_info_ptr this_frame, void **this_cache);
 
 extern int
   sparc_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc);
@@ -255,13 +255,13 @@ extern const struct sparc_gregmap sparc32nbsd_gregmap;
 
 /* Return the address of a system call's alternative return
    address.  */
-extern CORE_ADDR sparcnbsd_step_trap (struct frame_info *frame,
+extern CORE_ADDR sparcnbsd_step_trap (frame_info_ptr frame,
 				      unsigned long insn);
 
 extern void sparc32nbsd_init_abi (struct gdbarch_info info,
 				  struct gdbarch *gdbarch);
 
 extern struct trad_frame_saved_reg *
-  sparc32nbsd_sigcontext_saved_regs (struct frame_info *next_frame);
+  sparc32nbsd_sigcontext_saved_regs (frame_info_ptr next_frame);
 
 #endif /* sparc-tdep.h */
diff --git a/gdb/sparc64-fbsd-tdep.c b/gdb/sparc64-fbsd-tdep.c
index 76c682fd521..a13407a5e3b 100644
--- a/gdb/sparc64-fbsd-tdep.c
+++ b/gdb/sparc64-fbsd-tdep.c
@@ -89,7 +89,7 @@ sparc64fbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
 }
 
 static struct sparc_frame_cache *
-sparc64fbsd_sigtramp_frame_cache (struct frame_info *this_frame,
+sparc64fbsd_sigtramp_frame_cache (frame_info_ptr this_frame,
 				   void **this_cache)
 {
   struct sparc_frame_cache *cache;
@@ -162,7 +162,7 @@ sparc64fbsd_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-sparc64fbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
+sparc64fbsd_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				    void **this_cache,
 				    struct frame_id *this_id)
 {
@@ -173,7 +173,7 @@ sparc64fbsd_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
+sparc64fbsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					  void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
@@ -184,7 +184,7 @@ sparc64fbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				    struct frame_info *this_frame,
+				    frame_info_ptr this_frame,
 				    void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c
index f5940cfcdee..fc8bd065c4c 100644
--- a/gdb/sparc64-linux-tdep.c
+++ b/gdb/sparc64-linux-tdep.c
@@ -52,7 +52,7 @@
 /* Signal trampoline support.  */
 
 static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
-					 struct frame_info *this_frame,
+					 frame_info_ptr this_frame,
 					 struct trad_frame_cache *this_cache,
 					 CORE_ADDR func);
 
@@ -73,7 +73,7 @@ static const struct tramp_frame sparc64_linux_rt_sigframe =
 
 static void
 sparc64_linux_sigframe_init (const struct tramp_frame *self,
-			     struct frame_info *this_frame,
+			     frame_info_ptr this_frame,
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
@@ -176,7 +176,7 @@ sparc64_linux_report_signal_info (struct gdbarch *gdbarch, struct ui_out *uiout,
    address.  */
 
 static CORE_ADDR
-sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
+sparc64_linux_step_trap (frame_info_ptr frame, unsigned long insn)
 {
   /* __NR_rt_sigreturn is 101  */
   if ((insn == 0x91d0206d)
@@ -306,7 +306,7 @@ sparc64_linux_get_syscall_number (struct gdbarch *gdbarch,
 /* Implement the "get_longjmp_target" gdbarch method.  */
 
 static int
-sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+sparc64_linux_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   CORE_ADDR jb_addr;
diff --git a/gdb/sparc64-netbsd-tdep.c b/gdb/sparc64-netbsd-tdep.c
index db368118f23..fb15877ccf5 100644
--- a/gdb/sparc64-netbsd-tdep.c
+++ b/gdb/sparc64-netbsd-tdep.c
@@ -86,7 +86,7 @@ sparc64nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
 
 trad_frame_saved_reg *
 sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
-				   struct frame_info *this_frame)
+				   frame_info_ptr this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   trad_frame_saved_reg *saved_regs;
@@ -149,7 +149,7 @@ sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
 }
 
 static struct sparc_frame_cache *
-sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
+sparc64nbsd_sigcontext_frame_cache (frame_info_ptr this_frame,
 				    void **this_cache)
 {
   struct sparc_frame_cache *cache;
@@ -185,7 +185,7 @@ sparc64nbsd_sigcontext_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
+sparc64nbsd_sigcontext_frame_this_id (frame_info_ptr this_frame,
 				      void **this_cache,
 				      struct frame_id *this_id)
 {
@@ -196,7 +196,7 @@ sparc64nbsd_sigcontext_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
+sparc64nbsd_sigcontext_frame_prev_register (frame_info_ptr this_frame,
 					    void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
@@ -207,7 +207,7 @@ sparc64nbsd_sigcontext_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				    struct frame_info *this_frame,
+				    frame_info_ptr this_frame,
 				    void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
diff --git a/gdb/sparc64-obsd-tdep.c b/gdb/sparc64-obsd-tdep.c
index d6470a51b65..1b887df89b2 100644
--- a/gdb/sparc64-obsd-tdep.c
+++ b/gdb/sparc64-obsd-tdep.c
@@ -150,7 +150,7 @@ sparc64obsd_pc_in_sigtramp (CORE_ADDR pc, const char *name)
 }
 
 static struct sparc_frame_cache *
-sparc64obsd_frame_cache (struct frame_info *this_frame, void **this_cache)
+sparc64obsd_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache;
   CORE_ADDR addr;
@@ -186,7 +186,7 @@ sparc64obsd_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-sparc64obsd_frame_this_id (struct frame_info *this_frame, void **this_cache,
+sparc64obsd_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 			   struct frame_id *this_id)
 {
   struct sparc_frame_cache *cache =
@@ -196,7 +196,7 @@ sparc64obsd_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-sparc64obsd_frame_prev_register (struct frame_info *this_frame,
+sparc64obsd_frame_prev_register (frame_info_ptr this_frame,
 				 void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
@@ -207,7 +207,7 @@ sparc64obsd_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc64obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				    struct frame_info *this_frame,
+				    frame_info_ptr this_frame,
 				    void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
@@ -234,7 +234,7 @@ static const struct frame_unwind sparc64obsd_frame_unwind =
 /* Kernel debugging support.  */
 
 static struct sparc_frame_cache *
-sparc64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
+sparc64obsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache;
   CORE_ADDR sp, trapframe_addr;
@@ -263,7 +263,7 @@ sparc64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-sparc64obsd_trapframe_this_id (struct frame_info *this_frame,
+sparc64obsd_trapframe_this_id (frame_info_ptr this_frame,
 			       void **this_cache, struct frame_id *this_id)
 {
   struct sparc_frame_cache *cache =
@@ -273,7 +273,7 @@ sparc64obsd_trapframe_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc64obsd_trapframe_prev_register (struct frame_info *this_frame,
+sparc64obsd_trapframe_prev_register (frame_info_ptr this_frame,
 				     void **this_cache, int regnum)
 {
   struct sparc_frame_cache *cache =
@@ -284,7 +284,7 @@ sparc64obsd_trapframe_prev_register (struct frame_info *this_frame,
 
 static int
 sparc64obsd_trapframe_sniffer (const struct frame_unwind *self,
-			       struct frame_info *this_frame,
+			       frame_info_ptr this_frame,
 			       void **this_cache)
 {
   CORE_ADDR pc;
diff --git a/gdb/sparc64-sol2-tdep.c b/gdb/sparc64-sol2-tdep.c
index e656c359efa..3d52d8caa35 100644
--- a/gdb/sparc64-sol2-tdep.c
+++ b/gdb/sparc64-sol2-tdep.c
@@ -99,7 +99,7 @@ static const struct regset sparc64_sol2_fpregset =
 \f
 
 static struct sparc_frame_cache *
-sparc64_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
+sparc64_sol2_sigtramp_frame_cache (frame_info_ptr this_frame,
 				   void **this_cache)
 {
   struct sparc_frame_cache *cache;
@@ -154,7 +154,7 @@ sparc64_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
 }
 
 static void
-sparc64_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
+sparc64_sol2_sigtramp_frame_this_id (frame_info_ptr this_frame,
 				     void **this_cache,
 				     struct frame_id *this_id)
 {
@@ -165,7 +165,7 @@ sparc64_sol2_sigtramp_frame_this_id (struct frame_info *this_frame,
 }
 
 static struct value *
-sparc64_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
+sparc64_sol2_sigtramp_frame_prev_register (frame_info_ptr this_frame,
 					   void **this_cache,
 					   int regnum)
 {
@@ -177,7 +177,7 @@ sparc64_sol2_sigtramp_frame_prev_register (struct frame_info *this_frame,
 
 static int
 sparc64_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
-				     struct frame_info *this_frame,
+				     frame_info_ptr this_frame,
 				     void **this_cache)
 {
   return sol2_sigtramp_p (this_frame);
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 5ca5f2dca8c..8a801d351c6 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -1068,13 +1068,13 @@ sparc64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
 /* Normal frames.  */
 
 static struct sparc_frame_cache *
-sparc64_frame_cache (struct frame_info *this_frame, void **this_cache)
+sparc64_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   return sparc_frame_cache (this_frame, this_cache);
 }
 
 static void
-sparc64_frame_this_id (struct frame_info *this_frame, void **this_cache,
+sparc64_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		       struct frame_id *this_id)
 {
   struct sparc_frame_cache *cache =
@@ -1088,7 +1088,7 @@ sparc64_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-sparc64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+sparc64_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
 			     int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
@@ -1152,7 +1152,7 @@ static const struct frame_unwind sparc64_frame_unwind =
 \f
 
 static CORE_ADDR
-sparc64_frame_base_address (struct frame_info *this_frame, void **this_cache)
+sparc64_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct sparc_frame_cache *cache =
     sparc64_frame_cache (this_frame, this_cache);
@@ -1771,7 +1771,7 @@ sparc64_return_value (struct gdbarch *gdbarch, struct value *function,
 static void
 sparc64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 			       struct dwarf2_frame_state_reg *reg,
-			       struct frame_info *this_frame)
+			       frame_info_ptr this_frame)
 {
   switch (regnum)
     {
diff --git a/gdb/sparc64-tdep.h b/gdb/sparc64-tdep.h
index 4e5e8f5c0f3..3fcfc394edc 100644
--- a/gdb/sparc64-tdep.h
+++ b/gdb/sparc64-tdep.h
@@ -20,7 +20,7 @@
 #ifndef SPARC64_TDEP_H
 #define SPARC64_TDEP_H 1
 
-struct frame_info;
+class frame_info_ptr;
 struct gdbarch;
 struct regcache;
 struct sparc_gregmap;
@@ -131,7 +131,7 @@ extern const struct sparc_gregmap sparc64nbsd_gregmap;
 
 extern struct trad_frame_saved_reg *
   sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
-				     struct frame_info *next_frame);
+				     frame_info_ptr next_frame);
 
 extern const struct sparc_fpregmap sparc64_bsd_fpregmap;
 
diff --git a/gdb/stack.c b/gdb/stack.c
index 6e0f58565fe..8a8936535f8 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -215,18 +215,18 @@ static const gdb::option::option_def backtrace_command_option_defs[] = {
 
 /* Prototypes for local functions.  */
 
-static void print_frame_local_vars (struct frame_info *frame,
+static void print_frame_local_vars (frame_info_ptr frame,
 				    bool quiet,
 				    const char *regexp, const char *t_regexp,
 				    int num_tabs, struct ui_file *stream);
 
 static void print_frame (const frame_print_options &opts,
-			 frame_info *frame, int print_level,
+			 frame_info_ptr frame, int print_level,
 			 enum print_what print_what,  int print_args,
 			 struct symtab_and_line sal);
 
-static struct frame_info *find_frame_for_function (const char *);
-static struct frame_info *find_frame_for_address (CORE_ADDR);
+static frame_info_ptr find_frame_for_function (const char *);
+static frame_info_ptr find_frame_for_address (CORE_ADDR);
 
 /* Zero means do things normally; we are interacting directly with the
    user.  One means print the full filename and linenumber when a
@@ -314,7 +314,7 @@ static last_displayed_symtab_info_type last_displayed_symtab_info;
 /* See stack.h.  */
 
 bool
-frame_show_address (struct frame_info *frame,
+frame_show_address (frame_info_ptr frame,
 		    struct symtab_and_line sal)
 {
   /* If there is a line number, but no PC, then there is no location
@@ -337,7 +337,7 @@ frame_show_address (struct frame_info *frame,
 /* See frame.h.  */
 
 void
-print_stack_frame_to_uiout (struct ui_out *uiout, struct frame_info *frame,
+print_stack_frame_to_uiout (struct ui_out *uiout, frame_info_ptr frame,
 			    int print_level, enum print_what print_what,
 			    int set_current_sal)
 {
@@ -353,7 +353,7 @@ print_stack_frame_to_uiout (struct ui_out *uiout, struct frame_info *frame,
    source line, the actual PC is printed at the beginning.  */
 
 void
-print_stack_frame (struct frame_info *frame, int print_level,
+print_stack_frame (frame_info_ptr frame, int print_level,
 		   enum print_what print_what,
 		   int set_current_sal)
 {
@@ -381,7 +381,7 @@ print_stack_frame (struct frame_info *frame, int print_level,
    argument (not just the first nameless argument).  */
 
 static void
-print_frame_nameless_args (struct frame_info *frame, long start, int num,
+print_frame_nameless_args (frame_info_ptr frame, long start, int num,
 			   int first, struct ui_file *stream)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -503,7 +503,7 @@ print_frame_arg (const frame_print_options &fp_opts,
    exception.  */
 
 void
-read_frame_local (struct symbol *sym, struct frame_info *frame,
+read_frame_local (struct symbol *sym, frame_info_ptr frame,
 		  struct frame_arg *argp)
 {
   argp->sym = sym;
@@ -525,7 +525,7 @@ read_frame_local (struct symbol *sym, struct frame_info *frame,
 
 void
 read_frame_arg (const frame_print_options &fp_opts,
-		symbol *sym, frame_info *frame,
+		symbol *sym, frame_info_ptr frame,
 		struct frame_arg *argp, struct frame_arg *entryargp)
 {
   struct value *val = NULL, *entryval = NULL;
@@ -722,7 +722,7 @@ read_frame_arg (const frame_print_options &fp_opts,
 
 static void
 print_frame_args (const frame_print_options &fp_opts,
-		  struct symbol *func, struct frame_info *frame,
+		  struct symbol *func, frame_info_ptr frame,
 		  int num, struct ui_file *stream)
 {
   struct ui_out *uiout = current_uiout;
@@ -929,7 +929,7 @@ print_frame_args (const frame_print_options &fp_opts,
    line is in the center of the next 'list'.  */
 
 void
-set_current_sal_from_frame (struct frame_info *frame)
+set_current_sal_from_frame (frame_info_ptr frame)
 {
   symtab_and_line sal = find_frame_sal (frame);
   if (sal.symtab != NULL)
@@ -996,7 +996,7 @@ print_frame_info_to_print_what (const char *print_frame_info)
 /* Print the PC from FRAME, plus any flags, to UIOUT.  */
 
 static void
-print_pc (struct ui_out *uiout, struct gdbarch *gdbarch, frame_info *frame,
+print_pc (struct ui_out *uiout, struct gdbarch *gdbarch, frame_info_ptr frame,
 	  CORE_ADDR pc)
 {
   uiout->field_core_addr ("addr", gdbarch, pc);
@@ -1031,7 +1031,7 @@ get_user_print_what_frame_info (gdb::optional<enum print_what> *what)
 
 void
 print_frame_info (const frame_print_options &fp_opts,
-		  frame_info *frame, int print_level,
+		  frame_info_ptr frame, int print_level,
 		  enum print_what print_what, int print_args,
 		  int set_current_sal)
 {
@@ -1265,7 +1265,7 @@ get_last_displayed_sal ()
    corresponding to FRAME.  */
 
 gdb::unique_xmalloc_ptr<char>
-find_frame_funname (struct frame_info *frame, enum language *funlang,
+find_frame_funname (frame_info_ptr frame, enum language *funlang,
 		    struct symbol **funcp)
 {
   struct symbol *func;
@@ -1319,7 +1319,7 @@ find_frame_funname (struct frame_info *frame, enum language *funlang,
 
 static void
 print_frame (const frame_print_options &fp_opts,
-	     frame_info *frame, int print_level,
+	     frame_info_ptr frame, int print_level,
 	     enum print_what print_what, int print_args,
 	     struct symtab_and_line sal)
 {
@@ -1474,11 +1474,11 @@ frame_selection_by_function_completer (struct cmd_list_element *ignore,
    level 1') then SELECTED_FRAME_P will be false.  */
 
 static void
-info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
+info_frame_command_core (frame_info_ptr fi, bool selected_frame_p)
 {
   struct symbol *func;
   struct symtab *s;
-  struct frame_info *calling_frame_info;
+  frame_info_ptr calling_frame_info;
   int numregs;
   const char *funname = 0;
   enum language funlang = language_unknown;
@@ -1780,10 +1780,10 @@ info_frame_command_core (struct frame_info *fi, bool selected_frame_p)
 
 /* Return the innermost frame at level LEVEL.  */
 
-static struct frame_info *
+static frame_info_ptr
 leading_innermost_frame (int level)
 {
-  struct frame_info *leading;
+  frame_info_ptr leading;
 
   leading = get_current_frame ();
 
@@ -1801,11 +1801,11 @@ leading_innermost_frame (int level)
 
 /* Return the starting frame needed to handle COUNT outermost frames.  */
 
-static struct frame_info *
+static frame_info_ptr
 trailing_outermost_frame (int count)
 {
-  struct frame_info *current;
-  struct frame_info *trailing;
+  frame_info_ptr current;
+  frame_info_ptr trailing;
 
   trailing = get_current_frame ();
 
@@ -1834,9 +1834,9 @@ trailing_outermost_frame (int count)
    SELECT_FRAME.  */
 
 static void
-select_frame_command_core (struct frame_info *fi, bool ignored)
+select_frame_command_core (frame_info_ptr fi, bool ignored)
 {
-  frame_info *prev_frame = get_selected_frame ();
+  frame_info_ptr prev_frame = get_selected_frame ();
   select_frame (fi);
   if (get_selected_frame () != prev_frame)
     gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
@@ -1847,9 +1847,9 @@ select_frame_command_core (struct frame_info *fi, bool ignored)
    reprint the current frame summary).   */
 
 static void
-frame_command_core (struct frame_info *fi, bool ignored)
+frame_command_core (frame_info_ptr fi, bool ignored)
 {
-  frame_info *prev_frame = get_selected_frame ();
+  frame_info_ptr prev_frame = get_selected_frame ();
   select_frame (fi);
   if (get_selected_frame () != prev_frame)
     gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
@@ -1871,7 +1871,7 @@ frame_command_core (struct frame_info *fi, bool ignored)
    'frame' will all cause SELECTED_FRAME_P to be true.  In all other cases
    SELECTED_FRAME_P is false.  */
 
-template <void (*FPTR) (struct frame_info *fi, bool selected_frame_p)>
+template <void (*FPTR) (frame_info_ptr fi, bool selected_frame_p)>
 class frame_command_helper
 {
 public:
@@ -1882,7 +1882,7 @@ class frame_command_helper
   level (const char *arg, int from_tty)
   {
     int level = value_as_long (parse_and_eval (arg));
-    struct frame_info *fid
+    frame_info_ptr fid
       = find_relative_frame (get_current_frame (), &level);
     if (level != 0)
       error (_("No frame at level %s."), arg);
@@ -1897,7 +1897,7 @@ class frame_command_helper
   address (const char *arg, int from_tty)
   {
     CORE_ADDR addr = value_as_address (parse_and_eval (arg));
-    struct frame_info *fid = find_frame_for_address (addr);
+    frame_info_ptr fid = find_frame_for_address (addr);
     if (fid == NULL)
       error (_("No frame at address %s."), arg);
     FPTR (fid, false);
@@ -1910,7 +1910,7 @@ class frame_command_helper
   static void
   view (const char *args, int from_tty)
   {
-    struct frame_info *fid;
+    frame_info_ptr fid;
 
     if (args == NULL)
       error (_("Missing address argument to view a frame"));
@@ -1942,7 +1942,7 @@ class frame_command_helper
   {
     if (arg == NULL)
       error (_("Missing function name argument"));
-    struct frame_info *fid = find_frame_for_function (arg);
+    frame_info_ptr fid = find_frame_for_function (arg);
     if (fid == NULL)
       error (_("No frame for function \"%s\"."), arg);
     FPTR (fid, false);
@@ -1981,7 +1981,7 @@ backtrace_command_1 (const frame_print_options &fp_opts,
 		     const char *count_exp, int from_tty)
 
 {
-  struct frame_info *fi;
+  frame_info_ptr fi;
   int count;
   int py_start = 0, py_end = 0;
   enum ext_lang_bt_status result = EXT_LANG_BT_ERROR;
@@ -2043,7 +2043,7 @@ backtrace_command_1 (const frame_print_options &fp_opts,
      "-no-filters" has been specified from the command.  */
   if (bt_opts.no_filters || result == EXT_LANG_BT_NO_FILTERS)
     {
-      struct frame_info *trailing;
+      frame_info_ptr trailing;
 
       /* The following code must do two things.  First, it must set the
 	 variable TRAILING to the frame from which we should start
@@ -2301,7 +2301,7 @@ void
 print_variable_and_value_data::operator() (const char *print_name,
 					   struct symbol *sym)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   if (preg.has_value ()
       && preg->exec (sym->natural_name (), 0, NULL, 0) != 0)
@@ -2355,7 +2355,7 @@ prepare_reg (const char *regexp, gdb::optional<compiled_regex> *reg)
    This function will invalidate FRAME.  */
 
 static void
-print_frame_local_vars (struct frame_info *frame,
+print_frame_local_vars (frame_info_ptr frame,
 			bool quiet,
 			const char *regexp, const char *t_regexp,
 			int num_tabs, struct ui_file *stream)
@@ -2521,7 +2521,7 @@ iterate_over_block_arg_vars (const struct block *b,
    This function will invalidate FRAME.  */
 
 static void
-print_frame_arg_vars (struct frame_info *frame,
+print_frame_arg_vars (frame_info_ptr frame,
 		      bool quiet,
 		      const char *regexp, const char *t_regexp,
 		      struct ui_file *stream)
@@ -2613,14 +2613,14 @@ get_selected_block (CORE_ADDR *addr_in_block)
    but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates
    how much farther the original request asked to go.  */
 
-struct frame_info *
-find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
+frame_info_ptr
+find_relative_frame (frame_info_ptr frame, int *level_offset_ptr)
 {
   /* Going up is simple: just call get_prev_frame enough times or
      until the initial frame is reached.  */
   while (*level_offset_ptr > 0)
     {
-      struct frame_info *prev = get_prev_frame (frame);
+      frame_info_ptr prev = get_prev_frame (frame);
 
       if (!prev)
 	break;
@@ -2631,7 +2631,7 @@ find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
   /* Going down is just as simple.  */
   while (*level_offset_ptr < 0)
     {
-      struct frame_info *next = get_next_frame (frame);
+      frame_info_ptr next = get_next_frame (frame);
 
       if (!next)
 	break;
@@ -2648,7 +2648,7 @@ find_relative_frame (struct frame_info *frame, int *level_offset_ptr)
 static void
 up_silently_base (const char *count_exp)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   int count = 1;
 
   if (count_exp)
@@ -2679,7 +2679,7 @@ up_command (const char *count_exp, int from_tty)
 static void
 down_silently_base (const char *count_exp)
 {
-  struct frame_info *frame;
+  frame_info_ptr frame;
   int count = -1;
 
   if (count_exp)
@@ -2717,7 +2717,7 @@ return_command (const char *retval_exp, int from_tty)
 {
   /* Initialize it just to avoid a GCC false warning.  */
   enum return_value_convention rv_conv = RETURN_VALUE_STRUCT_CONVENTION;
-  struct frame_info *thisframe;
+  frame_info_ptr thisframe;
   struct gdbarch *gdbarch;
   struct symbol *thisfun;
   struct value *return_value = NULL;
@@ -2854,7 +2854,7 @@ return_command (const char *retval_exp, int from_tty)
 /* Find the most inner frame in the current stack for a function called
    FUNCTION_NAME.  If no matching frame is found return NULL.  */
 
-static struct frame_info *
+static frame_info_ptr
 find_frame_for_function (const char *function_name)
 {
   /* Used to hold the lower and upper addresses for each of the
@@ -2863,7 +2863,7 @@ find_frame_for_function (const char *function_name)
   {
     CORE_ADDR low, high;
   };
-  struct frame_info *frame;
+  frame_info_ptr frame;
   bool found = false;
   int level = 1;
 
@@ -2966,7 +2966,7 @@ make_frame_apply_options_def_group (qcs_flags *flags,
 static void
 frame_apply_command_count (const char *which_command,
 			   const char *cmd, int from_tty,
-			   struct frame_info *trailing, int count)
+			   frame_info_ptr trailing, int count)
 {
   qcs_flags flags;
   set_backtrace_options set_bt_opts = user_set_backtrace_options;
@@ -2991,7 +2991,7 @@ frame_apply_command_count (const char *which_command,
   scoped_restore restore_set_backtrace_options
     = make_scoped_restore (&user_set_backtrace_options, set_bt_opts);
 
-  for (frame_info *fi = trailing; fi && count--; fi = get_prev_frame (fi))
+  for (frame_info_ptr fi = trailing; fi && count--; fi = get_prev_frame (fi))
     {
       QUIT;
 
@@ -3198,7 +3198,7 @@ static void
 frame_apply_command (const char* cmd, int from_tty)
 {
   int count;
-  struct frame_info *trailing;
+  frame_info_ptr trailing;
 
   if (!target_has_stack ())
     error (_("No stack."));
@@ -3236,11 +3236,11 @@ faas_command (const char *cmd, int from_tty)
 /* Find inner-mode frame with frame address ADDRESS.  Return NULL if no
    matching frame can be found.  */
 
-static struct frame_info *
+static frame_info_ptr
 find_frame_for_address (CORE_ADDR address)
 {
   struct frame_id id;
-  struct frame_info *fid;
+  frame_info_ptr fid;
 
   id = frame_id_build_wild (address);
 
@@ -3254,7 +3254,7 @@ find_frame_for_address (CORE_ADDR address)
     {
       if (id == get_frame_id (fid))
 	{
-	  struct frame_info *prev_frame;
+	  frame_info_ptr prev_frame;
 
 	  while (1)
 	    {
diff --git a/gdb/stack.h b/gdb/stack.h
index f78aedf1c85..97ee60a9be4 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -20,7 +20,7 @@
 #ifndef STACK_H
 #define STACK_H
 
-gdb::unique_xmalloc_ptr<char> find_frame_funname (struct frame_info *frame,
+gdb::unique_xmalloc_ptr<char> find_frame_funname (frame_info_ptr frame,
 						  enum language *funlang,
 						  struct symbol **funcp);
 
@@ -43,7 +43,7 @@ void get_user_print_what_frame_info (gdb::optional<enum print_what> *what);
 /* Return true if we should display the address in addition to the location,
    because we are in the middle of a statement.  */
 
-bool frame_show_address (struct frame_info *frame, struct symtab_and_line sal);
+bool frame_show_address (frame_info_ptr frame, struct symtab_and_line sal);
 
 /* Forget the last sal we displayed.  */
 
diff --git a/gdb/stap-probe.c b/gdb/stap-probe.c
index 2b3eb37b39a..9d6d129069f 100644
--- a/gdb/stap-probe.c
+++ b/gdb/stap-probe.c
@@ -151,7 +151,7 @@ class stap_probe : public probe
 
   /* See probe.h.  */
   struct value *evaluate_argument (unsigned n,
-				   struct frame_info *frame) override;
+				   frame_info_ptr frame) override;
 
   /* See probe.h.  */
   void compile_to_ax (struct agent_expr *aexpr,
@@ -1441,7 +1441,7 @@ stap_probe::can_evaluate_arguments () const
    corresponding to it.  Assertion is thrown if N does not exist.  */
 
 struct value *
-stap_probe::evaluate_argument (unsigned n, struct frame_info *frame)
+stap_probe::evaluate_argument (unsigned n, frame_info_ptr frame)
 {
   struct stap_probe_arg *arg;
   struct gdbarch *gdbarch = get_frame_arch (frame);
diff --git a/gdb/std-regs.c b/gdb/std-regs.c
index d71e2ad998e..5b880a49b16 100644
--- a/gdb/std-regs.c
+++ b/gdb/std-regs.c
@@ -27,7 +27,7 @@
 #include "gdbarch.h"
 
 static struct value *
-value_of_builtin_frame_fp_reg (struct frame_info *frame, const void *baton)
+value_of_builtin_frame_fp_reg (frame_info_ptr frame, const void *baton)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
@@ -53,7 +53,7 @@ value_of_builtin_frame_fp_reg (struct frame_info *frame, const void *baton)
 }
 
 static struct value *
-value_of_builtin_frame_pc_reg (struct frame_info *frame, const void *baton)
+value_of_builtin_frame_pc_reg (frame_info_ptr frame, const void *baton)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
@@ -72,7 +72,7 @@ value_of_builtin_frame_pc_reg (struct frame_info *frame, const void *baton)
 }
 
 static struct value *
-value_of_builtin_frame_sp_reg (struct frame_info *frame, const void *baton)
+value_of_builtin_frame_sp_reg (frame_info_ptr frame, const void *baton)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
@@ -82,7 +82,7 @@ value_of_builtin_frame_sp_reg (struct frame_info *frame, const void *baton)
 }
 
 static struct value *
-value_of_builtin_frame_ps_reg (struct frame_info *frame, const void *baton)
+value_of_builtin_frame_ps_reg (frame_info_ptr frame, const void *baton)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 1d13e82502b..ffd1acddfdb 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -37,7 +37,7 @@ struct obj_section;
 struct obstack;
 struct block;
 struct value;
-struct frame_info;
+class frame_info_ptr;
 struct agent_expr;
 struct axs_value;
 class probe;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 89d7a183ff3..90f5b45738b 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -40,7 +40,7 @@
 
 /* Opaque declarations.  */
 struct ui_file;
-struct frame_info;
+class frame_info_ptr;
 struct symbol;
 struct obstack;
 struct objfile;
@@ -1069,13 +1069,13 @@ struct symbol_computed_ops
      FRAME may be zero.  */
 
   struct value *(*read_variable) (struct symbol * symbol,
-				  struct frame_info * frame);
+				  frame_info_ptr  frame);
 
   /* Read variable SYMBOL like read_variable at (callee) FRAME's function
      entry.  SYMBOL should be a function parameter, otherwise
      NO_ENTRY_VALUE_ERROR will be thrown.  */
   struct value *(*read_variable_at_entry) (struct symbol *symbol,
-					   struct frame_info *frame);
+					   frame_info_ptr frame);
 
   /* Find the "symbol_needs_kind" value for the given symbol.  This
      value determines whether reading the symbol needs memory (e.g., a
@@ -1147,7 +1147,7 @@ struct symbol_block_ops
      computed with DW_AT_static_link and this method must be used to compute
      the corresponding DW_AT_frame_base attribute.  */
   CORE_ADDR (*get_frame_base) (struct symbol *framefunc,
-			       struct frame_info *frame);
+			       frame_info_ptr frame);
 };
 
 /* Functions used with LOC_REGISTER and LOC_REGPARM_ADDR.  */
@@ -2254,7 +2254,7 @@ struct gnu_ifunc_fns
 
 extern const struct gnu_ifunc_fns *gnu_ifunc_fns_p;
 
-extern CORE_ADDR find_solib_trampoline_target (struct frame_info *, CORE_ADDR);
+extern CORE_ADDR find_solib_trampoline_target (frame_info_ptr , CORE_ADDR);
 
 struct symtab_and_line
 {
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index 2cb9c75ca8d..e4bbc47daa9 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -484,7 +484,7 @@ tui_disasm_window::addr_is_displayed (CORE_ADDR addr) const
 }
 
 void
-tui_disasm_window::maybe_update (struct frame_info *fi, symtab_and_line sal)
+tui_disasm_window::maybe_update (frame_info_ptr fi, symtab_and_line sal)
 {
   CORE_ADDR low;
 
diff --git a/gdb/tui/tui-disasm.h b/gdb/tui/tui-disasm.h
index e33c6411cc5..d9d9794998b 100644
--- a/gdb/tui/tui-disasm.h
+++ b/gdb/tui/tui-disasm.h
@@ -41,7 +41,7 @@ struct tui_disasm_window : public tui_source_window_base
 
   bool location_matches_p (struct bp_location *loc, int line_no) override;
 
-  void maybe_update (struct frame_info *fi, symtab_and_line sal) override;
+  void maybe_update (frame_info_ptr fi, symtab_and_line sal) override;
 
   void erase_source_content () override
   {
diff --git a/gdb/tui/tui-hooks.c b/gdb/tui/tui-hooks.c
index 83172789227..967ac30e6bb 100644
--- a/gdb/tui/tui-hooks.c
+++ b/gdb/tui/tui-hooks.c
@@ -62,9 +62,9 @@ static bool tui_refreshing_registers = false;
 /* Observer for the register_changed notification.  */
 
 static void
-tui_register_changed (struct frame_info *frame, int regno)
+tui_register_changed (frame_info_ptr frame, int regno)
 {
-  struct frame_info *fi;
+  frame_info_ptr fi;
 
   if (!tui_is_window_visible (DATA_WIN))
     return;
@@ -129,7 +129,7 @@ tui_refresh_frame_and_register_information ()
 
   if (from_stack && has_stack_frames ())
     {
-      struct frame_info *fi = get_selected_frame (NULL);
+      frame_info_ptr fi = get_selected_frame (NULL);
 
       /* Display the frame position (even if there is no symbols or
 	 the PC is not known).  */
diff --git a/gdb/tui/tui-regs.c b/gdb/tui/tui-regs.c
index 5106a3b9670..b94acfde8a3 100644
--- a/gdb/tui/tui-regs.c
+++ b/gdb/tui/tui-regs.c
@@ -85,7 +85,7 @@ tab_expansion_file::write (const char *buf, long length_buf)
    representation of it.  */
 
 static std::string
-tui_register_format (struct frame_info *frame, int regnum)
+tui_register_format (frame_info_ptr frame, int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
 
@@ -111,7 +111,7 @@ tui_register_format (struct frame_info *frame, int regnum)
    display.  When changep is set, check if the new register value has
    changed with respect to the previous call.  */
 static void
-tui_get_register (struct frame_info *frame,
+tui_get_register (frame_info_ptr frame,
 		  struct tui_data_item_window *data, 
 		  int regnum, bool *changedp)
 {
@@ -208,7 +208,7 @@ tui_data_window::show_registers (const reggroup *group)
 
 void
 tui_data_window::show_register_group (const reggroup *group,
-				      struct frame_info *frame, 
+				      frame_info_ptr frame, 
 				      bool refresh_values_only)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -462,7 +462,7 @@ tui_data_window::do_scroll_vertical (int num_to_scroll)
    given a particular frame.  If the values have changed, they are
    updated with the new value and highlighted.  */
 void
-tui_data_window::check_register_values (struct frame_info *frame)
+tui_data_window::check_register_values (frame_info_ptr frame)
 {
   if (m_regs_content.empty ())
     show_registers (m_current_group);
diff --git a/gdb/tui/tui-regs.h b/gdb/tui/tui-regs.h
index 5289d3a892d..fc838d3dffd 100644
--- a/gdb/tui/tui-regs.h
+++ b/gdb/tui/tui-regs.h
@@ -59,7 +59,7 @@ struct tui_data_window : public tui_win_info
     return DATA_NAME;
   }
 
-  void check_register_values (struct frame_info *frame);
+  void check_register_values (frame_info_ptr frame);
 
   void show_registers (const reggroup *group);
 
@@ -101,7 +101,7 @@ struct tui_data_window : public tui_win_info
   void display_reg_element_at_line (int start_element_no, int start_line_no);
 
   void show_register_group (const reggroup *group,
-			    struct frame_info *frame,
+			    frame_info_ptr frame,
 			    bool refresh_values_only);
 
   /* Answer the number of the last line in the regs display.  If there
diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c
index 208889d0bf7..c45463ec765 100644
--- a/gdb/tui/tui-source.c
+++ b/gdb/tui/tui-source.c
@@ -140,7 +140,7 @@ tui_source_window::do_scroll_vertical (int num_to_scroll)
 
       if (cursal.symtab == NULL)
 	{
-	  struct frame_info *fi = get_selected_frame (NULL);
+	  frame_info_ptr fi = get_selected_frame (NULL);
 	  s = find_pc_line_symtab (get_frame_pc (fi));
 	  arch = get_frame_arch (fi);
 	}
@@ -191,7 +191,7 @@ tui_source_window::line_is_displayed (int line) const
 }
 
 void
-tui_source_window::maybe_update (struct frame_info *fi, symtab_and_line sal)
+tui_source_window::maybe_update (frame_info_ptr fi, symtab_and_line sal)
 {
   int start_line = (sal.line - ((height - 2) / 2)) + 1;
   if (start_line <= 0)
diff --git a/gdb/tui/tui-source.h b/gdb/tui/tui-source.h
index d2c6338acc3..7187debbd34 100644
--- a/gdb/tui/tui-source.h
+++ b/gdb/tui/tui-source.h
@@ -46,7 +46,7 @@ struct tui_source_window : public tui_source_window_base
 
   bool showing_source_p (const char *filename) const;
 
-  void maybe_update (struct frame_info *fi, symtab_and_line sal) override;
+  void maybe_update (frame_info_ptr fi, symtab_and_line sal) override;
 
   void erase_source_content () override
   {
diff --git a/gdb/tui/tui-stack.c b/gdb/tui/tui-stack.c
index be8ffbd0c12..85e71c0bc25 100644
--- a/gdb/tui/tui-stack.c
+++ b/gdb/tui/tui-stack.c
@@ -195,7 +195,7 @@ tui_locator_window::make_status_line () const
    name is demangled if demangling is turned on.  Returns a pointer to
    a static area holding the result.  */
 static char*
-tui_get_function_from_frame (struct frame_info *fi)
+tui_get_function_from_frame (frame_info_ptr fi)
 {
   static char name[256];
   string_file stream;
@@ -251,7 +251,7 @@ tui_locator_window::rerender ()
    subsequently refreshed), false otherwise.  */
 
 bool
-tui_show_frame_info (struct frame_info *fi)
+tui_show_frame_info (frame_info_ptr fi)
 {
   bool locator_changed_p;
 
diff --git a/gdb/tui/tui-stack.h b/gdb/tui/tui-stack.h
index 971ff1dd413..5cb570f779e 100644
--- a/gdb/tui/tui-stack.h
+++ b/gdb/tui/tui-stack.h
@@ -24,7 +24,7 @@
 
 #include "tui/tui-data.h"
 
-struct frame_info;
+class frame_info_ptr;
 
 /* Locator window class.  */
 
@@ -79,6 +79,6 @@ struct tui_locator_window : public tui_win_info
 };
 
 extern void tui_show_locator_content (void);
-extern bool tui_show_frame_info (struct frame_info *);
+extern bool tui_show_frame_info (frame_info_ptr );
 
 #endif /* TUI_TUI_STACK_H */
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index 87b8dcff154..27ac446f4d2 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -329,7 +329,7 @@ tui_source_window_base::rerender ()
     {
       struct symtab_and_line cursal
 	= get_current_source_symtab_and_line ();
-      struct frame_info *frame = deprecated_safe_get_selected_frame ();
+      frame_info_ptr frame = deprecated_safe_get_selected_frame ();
       struct gdbarch *gdbarch = get_frame_arch (frame);
 
       struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
@@ -353,7 +353,7 @@ tui_source_window_base::refill ()
       sal = get_current_source_symtab_and_line ();
       if (sal.symtab == NULL)
 	{
-	  struct frame_info *fi = deprecated_safe_get_selected_frame ();
+	  frame_info_ptr fi = deprecated_safe_get_selected_frame ();
 	  if (fi != nullptr)
 	    sal = find_pc_line (get_frame_pc (fi), 0);
 	}
diff --git a/gdb/tui/tui-winsource.h b/gdb/tui/tui-winsource.h
index 1e4dc12044a..f7301aacd26 100644
--- a/gdb/tui/tui-winsource.h
+++ b/gdb/tui/tui-winsource.h
@@ -153,7 +153,7 @@ struct tui_source_window_base : public tui_win_info
 
   /* Update the window to display the given location.  Does nothing if
      the location is already displayed.  */
-  virtual void maybe_update (struct frame_info *fi, symtab_and_line sal) = 0;
+  virtual void maybe_update (frame_info_ptr fi, symtab_and_line sal) = 0;
 
   void update_source_window_as_is  (struct gdbarch *gdbarch,
 				    const struct symtab_and_line &sal);
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
index f7094e37a92..3caa209a273 100644
--- a/gdb/v850-tdep.c
+++ b/gdb/v850-tdep.c
@@ -1214,7 +1214,7 @@ v850_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
 }
 
 static struct v850_frame_cache *
-v850_alloc_frame_cache (struct frame_info *this_frame)
+v850_alloc_frame_cache (frame_info_ptr this_frame)
 {
   struct v850_frame_cache *cache;
 
@@ -1233,7 +1233,7 @@ v850_alloc_frame_cache (struct frame_info *this_frame)
 }
 
 static struct v850_frame_cache *
-v850_frame_cache (struct frame_info *this_frame, void **this_cache)
+v850_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct v850_frame_cache *cache;
@@ -1299,7 +1299,7 @@ v850_frame_cache (struct frame_info *this_frame, void **this_cache)
 
 
 static struct value *
-v850_frame_prev_register (struct frame_info *this_frame,
+v850_frame_prev_register (frame_info_ptr this_frame,
 			  void **this_cache, int regnum)
 {
   struct v850_frame_cache *cache = v850_frame_cache (this_frame, this_cache);
@@ -1310,7 +1310,7 @@ v850_frame_prev_register (struct frame_info *this_frame,
 }
 
 static void
-v850_frame_this_id (struct frame_info *this_frame, void **this_cache,
+v850_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		    struct frame_id *this_id)
 {
   struct v850_frame_cache *cache = v850_frame_cache (this_frame, this_cache);
@@ -1333,7 +1333,7 @@ static const struct frame_unwind v850_frame_unwind = {
 };
 
 static CORE_ADDR
-v850_frame_base_address (struct frame_info *this_frame, void **this_cache)
+v850_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct v850_frame_cache *cache = v850_frame_cache (this_frame, this_cache);
 
diff --git a/gdb/valops.c b/gdb/valops.c
index 27e84d9f6b3..87724cb72e8 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1182,7 +1182,7 @@ value_assign (struct value *toval, struct value *fromval)
 
     case lval_register:
       {
-	struct frame_info *frame;
+	frame_info_ptr frame;
 	struct gdbarch *gdbarch;
 	int value_reg;
 
@@ -1301,7 +1301,7 @@ value_assign (struct value *toval, struct value *fromval)
 	 re-find the previously selected frame automatically.  */
 
       {
-	struct frame_info *fi = frame_find_by_id (old_frame);
+	frame_info_ptr fi = frame_find_by_id (old_frame);
 
 	if (fi != NULL)
 	  select_frame (fi);
@@ -1376,7 +1376,7 @@ value_repeat (struct value *arg1, int count)
 struct value *
 value_of_variable (struct symbol *var, const struct block *b)
 {
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
 
   if (symbol_read_needs_frame (var))
     frame = get_selected_frame (_("No frame selected."));
@@ -1409,7 +1409,7 @@ address_of_variable (struct symbol *var, const struct block *b)
     {
     case lval_register:
       {
-	struct frame_info *frame;
+	frame_info_ptr frame;
 	const char *regname;
 
 	frame = frame_find_by_id (VALUE_NEXT_FRAME_ID (val));
@@ -3945,7 +3945,7 @@ value_of_this (const struct language_defn *lang)
 {
   struct block_symbol sym;
   const struct block *b;
-  struct frame_info *frame;
+  frame_info_ptr frame;
 
   if (lang->name_of_this () == NULL)
     error (_("no `this' in current language"));
diff --git a/gdb/value.c b/gdb/value.c
index 3a0cac741e4..c5106e3484f 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3958,7 +3958,7 @@ value_fetch_lazy_memory (struct value *val)
 static void
 value_fetch_lazy_register (struct value *val)
 {
-  struct frame_info *next_frame;
+  frame_info_ptr next_frame;
   int regnum;
   struct type *type = check_typedef (value_type (val));
   struct value *new_val = val, *mark = value_mark ();
@@ -4024,7 +4024,7 @@ value_fetch_lazy_register (struct value *val)
   if (frame_debug)
     {
       struct gdbarch *gdbarch;
-      struct frame_info *frame;
+      frame_info_ptr frame;
       frame = frame_find_by_id (VALUE_NEXT_FRAME_ID (val));
       frame = get_prev_frame_always (frame);
       regnum = VALUE_REGNUM (val);
diff --git a/gdb/value.h b/gdb/value.h
index 7e1eec22413..086175e80f1 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -621,7 +621,7 @@ struct value *value_vector_widen (struct value *scalar_value,
 #include "gdbtypes.h"
 #include "expression.h"
 
-struct frame_info;
+class frame_info_ptr;
 struct fn_field;
 
 extern int print_address_demangle (const struct value_print_options *,
@@ -703,13 +703,13 @@ extern struct value *default_value_from_register (struct gdbarch *gdbarch,
 						  struct frame_id frame_id);
 
 extern void read_frame_register_value (struct value *value,
-				       struct frame_info *frame);
+				       frame_info_ptr frame);
 
 extern struct value *value_from_register (struct type *type, int regnum,
-					  struct frame_info *frame);
+					  frame_info_ptr frame);
 
 extern CORE_ADDR address_from_register (int regnum,
-					struct frame_info *frame);
+					frame_info_ptr frame);
 
 extern struct value *value_of_variable (struct symbol *var,
 					const struct block *b);
@@ -717,9 +717,9 @@ extern struct value *value_of_variable (struct symbol *var,
 extern struct value *address_of_variable (struct symbol *var,
 					  const struct block *b);
 
-extern struct value *value_of_register (int regnum, struct frame_info *frame);
+extern struct value *value_of_register (int regnum, frame_info_ptr frame);
 
-struct value *value_of_register_lazy (struct frame_info *frame, int regnum);
+struct value *value_of_register_lazy (frame_info_ptr frame, int regnum);
 
 /* Return the symbol's reading requirement.  */
 
@@ -732,7 +732,7 @@ extern int symbol_read_needs_frame (struct symbol *);
 
 extern struct value *read_var_value (struct symbol *var,
 				     const struct block *var_block,
-				     struct frame_info *frame);
+				     frame_info_ptr frame);
 
 extern struct value *allocate_value (struct type *type);
 extern struct value *allocate_value_lazy (struct type *type);
@@ -1110,7 +1110,7 @@ extern int val_print_string (struct type *elttype, const char *encoding,
 
 extern void print_variable_and_value (const char *name,
 				      struct symbol *var,
-				      struct frame_info *frame,
+				      frame_info_ptr frame,
 				      struct ui_file *stream,
 				      int indent);
 
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 0683af1991e..6a0c9c99616 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -225,10 +225,10 @@ gdbpy_enter_varobj::gdbpy_enter_varobj (const struct varobj *var)
 /* Return the full FRAME which corresponds to the given CORE_ADDR
    or NULL if no FRAME on the chain corresponds to CORE_ADDR.  */
 
-static struct frame_info *
+static frame_info_ptr
 find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
 {
-  struct frame_info *frame = NULL;
+  frame_info_ptr frame = NULL;
 
   if (frame_addr == (CORE_ADDR) 0)
     return NULL;
@@ -265,7 +265,7 @@ varobj_create (const char *objname,
 
   if (expression != NULL)
     {
-      struct frame_info *fi;
+      frame_info_ptr fi;
       struct frame_id old_id = null_frame_id;
       const struct block *block;
       const char *p;
@@ -1947,7 +1947,7 @@ name_of_child (struct varobj *var, int index)
 static bool
 check_scope (const struct varobj *var)
 {
-  struct frame_info *fi;
+  frame_info_ptr fi;
   bool scope;
 
   fi = frame_find_by_id (var->root->frame);
diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c
index 6ad0dda021e..0fe57f92a80 100644
--- a/gdb/vax-tdep.c
+++ b/gdb/vax-tdep.c
@@ -189,7 +189,7 @@ vax_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 }
 
 static struct frame_id
-vax_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+vax_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame)
 {
   CORE_ADDR fp;
 
@@ -305,7 +305,7 @@ struct vax_frame_cache
 };
 
 static struct vax_frame_cache *
-vax_frame_cache (struct frame_info *this_frame, void **this_cache)
+vax_frame_cache (frame_info_ptr this_frame, void **this_cache)
 {
   struct vax_frame_cache *cache;
   CORE_ADDR addr;
@@ -367,7 +367,7 @@ vax_frame_cache (struct frame_info *this_frame, void **this_cache)
 }
 
 static void
-vax_frame_this_id (struct frame_info *this_frame, void **this_cache,
+vax_frame_this_id (frame_info_ptr this_frame, void **this_cache,
 		   struct frame_id *this_id)
 {
   struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache);
@@ -380,7 +380,7 @@ vax_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static struct value *
-vax_frame_prev_register (struct frame_info *this_frame,
+vax_frame_prev_register (frame_info_ptr this_frame,
 			 void **this_cache, int regnum)
 {
   struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache);
@@ -401,7 +401,7 @@ static const struct frame_unwind vax_frame_unwind =
 \f
 
 static CORE_ADDR
-vax_frame_base_address (struct frame_info *this_frame, void **this_cache)
+vax_frame_base_address (frame_info_ptr this_frame, void **this_cache)
 {
   struct vax_frame_cache *cache = vax_frame_cache (this_frame, this_cache);
 
@@ -409,7 +409,7 @@ vax_frame_base_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static CORE_ADDR
-vax_frame_args_address (struct frame_info *this_frame, void **this_cache)
+vax_frame_args_address (frame_info_ptr this_frame, void **this_cache)
 {
   return get_frame_register_unsigned (this_frame, VAX_AP_REGNUM);
 }
@@ -425,7 +425,7 @@ static const struct frame_base vax_frame_base =
 /* Return number of arguments for FRAME.  */
 
 static int
-vax_frame_num_args (struct frame_info *frame)
+vax_frame_num_args (frame_info_ptr frame)
 {
   CORE_ADDR args;
 
-- 
2.37.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr
  2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
                   ` (3 preceding siblings ...)
  2022-08-30 10:08 ` [PATCH v4 4/5] Continue making GDB " Bruno Larsen
@ 2022-08-30 10:08 ` Bruno Larsen
  2022-10-07 19:34   ` Tom Tromey
  2022-10-11  7:58   ` Tom de Vries
  2022-09-13  8:06 ` [Ping][PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
  5 siblings, 2 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-08-30 10:08 UTC (permalink / raw)
  To: gdb-patches

Currently, despite having a smart pointer for frame_infos, GDB may
attempt to use an invalidated frame_info_ptr, which would cause internal
errors to happen.  One such example has been documented as PR
python/28856, that happened when printing frame arguments calls an
inferior function.

To avoid failures, the smart wrapper was changed to also cache the frame
id, so the pointer can be reinflated later.  For this to work, the
frame-id stuff had to be moved to their own .h file, which is included
by frame-info.h.

Frame_id caching is done explicitly using the prepare_reinflate method.
Caching is done manually so that only the pointers that need to be saved
will be, and reinflating has to be done manually using the reinflate
method because the get method and the -> operator must not change
the internals of the class.  Finally, attempting to reinflate when the
pointer is being invalidated causes the following assertion errors:

check_ptrace_stopped_lwp_gone: assertion `lp->stopped` failed.
get_frame_pc: Assertion `frame->next != NULL` failed.

As for performance concerns, my personal testing with `time make
chec-perf GDB_PERFTEST_MODE=run` showed an actual reduction of around
10% of time running.

This commit also adds a testcase that exercises the python/28856 bug with
7 different triggers, run, continue, step, backtrace, finish, up and down.
Some of them can seem to be testing the same thing twice, but since this
test relies on stale pointers, there is always a chance that GDB got lucky
when testing, so better to test extra.

Regression tested on x86_64, using both gcc and clang.
---
 gdb/frame-id.h                                | 135 +++++++++++++++++
 gdb/frame-info.h                              |  31 +++-
 gdb/frame.h                                   | 116 ---------------
 gdb/infcmd.c                                  |   2 +
 gdb/mi/mi-cmd-stack.c                         |   3 +
 gdb/stack.c                                   |  11 ++
 .../gdb.python/pretty-print-call-by-hand.c    |  53 +++++++
 .../gdb.python/pretty-print-call-by-hand.exp  | 136 ++++++++++++++++++
 .../gdb.python/pretty-print-call-by-hand.py   |  41 ++++++
 9 files changed, 410 insertions(+), 118 deletions(-)
 create mode 100644 gdb/frame-id.h
 create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
 create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
 create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.py

diff --git a/gdb/frame-id.h b/gdb/frame-id.h
new file mode 100644
index 00000000000..142488f7319
--- /dev/null
+++ b/gdb/frame-id.h
@@ -0,0 +1,135 @@
+/* Definitions for dealing with stack frames, for GDB, the GNU debugger.
+
+   Copyright (C) 1986-2022 Free Software Foundation, 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/>.  */
+
+#ifndef GDB_FRAME_ID_H
+#define GDB_FRAME_ID_H 1
+
+/* Status of a given frame's stack.  */
+
+enum frame_id_stack_status
+{
+  /* Stack address is invalid.  */
+  FID_STACK_INVALID = 0,
+
+  /* Stack address is valid, and is found in the stack_addr field.  */
+  FID_STACK_VALID = 1,
+
+  /* Sentinel frame.  */
+  FID_STACK_SENTINEL = 2,
+
+  /* Outer frame.  Since a frame's stack address is typically defined as the
+     value the stack pointer had prior to the activation of the frame, an outer
+     frame doesn't have a stack address.  The frame ids of frames inlined in the
+     outer frame are also of this type.  */
+  FID_STACK_OUTER = 3,
+
+  /* Stack address is unavailable.  I.e., there's a valid stack, but
+     we don't know where it is (because memory or registers we'd
+     compute it from were not collected).  */
+  FID_STACK_UNAVAILABLE = -1
+};
+
+/* The frame object's ID.  This provides a per-frame unique identifier
+   that can be used to relocate a `struct frame_info' after a target
+   resume or a frame cache destruct.  It of course assumes that the
+   inferior hasn't unwound the stack past that frame.  */
+
+struct frame_id
+{
+  /* The frame's stack address.  This shall be constant through out
+     the lifetime of a frame.  Note that this requirement applies to
+     not just the function body, but also the prologue and (in theory
+     at least) the epilogue.  Since that value needs to fall either on
+     the boundary, or within the frame's address range, the frame's
+     outer-most address (the inner-most address of the previous frame)
+     is used.  Watch out for all the legacy targets that still use the
+     function pointer register or stack pointer register.  They are
+     wrong.
+
+     This field is valid only if frame_id.stack_status is
+     FID_STACK_VALID.  It will be 0 for other
+     FID_STACK_... statuses.  */
+  CORE_ADDR stack_addr;
+
+  /* The frame's code address.  This shall be constant through out the
+     lifetime of the frame.  While the PC (a.k.a. resume address)
+     changes as the function is executed, this code address cannot.
+     Typically, it is set to the address of the entry point of the
+     frame's function (as returned by get_frame_func).
+
+     For inlined functions (INLINE_DEPTH != 0), this is the address of
+     the first executed instruction in the block corresponding to the
+     inlined function.
+
+     This field is valid only if code_addr_p is true.  Otherwise, this
+     frame is considered to have a wildcard code address, i.e. one that
+     matches every address value in frame comparisons.  */
+  CORE_ADDR code_addr;
+
+  /* The frame's special address.  This shall be constant through out the
+     lifetime of the frame.  This is used for architectures that may have
+     frames that do not change the stack but are still distinct and have
+     some form of distinct identifier (e.g. the ia64 which uses a 2nd
+     stack for registers).  This field is treated as unordered - i.e. will
+     not be used in frame ordering comparisons.
+
+     This field is valid only if special_addr_p is true.  Otherwise, this
+     frame is considered to have a wildcard special address, i.e. one that
+     matches every address value in frame comparisons.  */
+  CORE_ADDR special_addr;
+
+  /* Flags to indicate the above fields have valid contents.  */
+  ENUM_BITFIELD(frame_id_stack_status) stack_status : 3;
+  unsigned int code_addr_p : 1;
+  unsigned int special_addr_p : 1;
+
+  /* It is non-zero for a frame made up by GDB without stack data
+     representation in inferior, such as INLINE_FRAME or TAILCALL_FRAME.
+     Caller of inlined function will have it zero, each more inner called frame
+     will have it increasingly one, two etc.  Similarly for TAILCALL_FRAME.  */
+  int artificial_depth;
+
+  /* Return a string representation of this frame id.  */
+  std::string to_string () const;
+
+  /* Returns true when this frame_id and R identify the same
+     frame.  */
+  bool operator== (const frame_id &r) const;
+
+  /* Inverse of ==.  */
+  bool operator!= (const frame_id &r) const
+  {
+    return !(*this == r);
+  }
+};
+
+/* Methods for constructing and comparing Frame IDs.  */
+
+/* For convenience.  All fields are zero.  This means "there is no frame".  */
+extern const struct frame_id null_frame_id;
+
+/* Sentinel frame.  */
+extern const struct frame_id sentinel_frame_id;
+
+/* This means "there is no frame ID, but there is a frame".  It should be
+   replaced by best-effort frame IDs for the outermost frame, somehow.
+   The implementation is only special_addr_p set.  */
+extern const struct frame_id outer_frame_id;
+
+#endif /* ifdef GDB_FRAME_ID_H  */
diff --git a/gdb/frame-info.h b/gdb/frame-info.h
index 195aa5ccf03..00b2a15ba47 100644
--- a/gdb/frame-info.h
+++ b/gdb/frame-info.h
@@ -21,10 +21,15 @@
 #define GDB_FRAME_INFO_H
 
 #include "gdbsupport/intrusive_list.h"
+#include "frame-id.h"
 
 struct frame_info;
 
+/* Forward declarations of functions, needed for the frame_info_ptr
+   to work correctly.  */
 extern void reinit_frame_cache ();
+extern struct frame_id get_frame_id (frame_info_ptr);
+extern frame_info_ptr frame_find_by_id (struct frame_id id);
 
 /* A wrapper for "frame_info *".  frame_info objects are invalidated
    whenever reinit_frame_cache is called.  This class arranges to
@@ -57,13 +62,13 @@ class frame_info_ptr : public intrusive_list_node<frame_info_ptr>
   }
 
   frame_info_ptr (const frame_info_ptr &other)
-    : m_ptr (other.m_ptr)
+    : m_ptr (other.m_ptr), m_cached_id (other.m_cached_id)
   {
     frame_list.push_back (*this);
   }
 
   frame_info_ptr (frame_info_ptr &&other)
-    : m_ptr (other.m_ptr)
+    : m_ptr (other.m_ptr), m_cached_id (other.m_cached_id)
   {
     other.m_ptr = nullptr;
     frame_list.push_back (*this);
@@ -77,19 +82,23 @@ class frame_info_ptr : public intrusive_list_node<frame_info_ptr>
   frame_info_ptr &operator= (const frame_info_ptr &other)
   {
     m_ptr = other.m_ptr;
+    m_cached_id = other.m_cached_id;
     return *this;
   }
 
   frame_info_ptr &operator= (std::nullptr_t)
   {
     m_ptr = nullptr;
+    m_cached_id = null_frame_id;
     return *this;
   }
 
   frame_info_ptr &operator= (frame_info_ptr &&other)
   {
     m_ptr = other.m_ptr;
+    m_cached_id = other.m_cached_id;
     other.m_ptr = nullptr;
+    other.m_cached_id = null_frame_id;
     return *this;
   }
 
@@ -125,11 +134,29 @@ class frame_info_ptr : public intrusive_list_node<frame_info_ptr>
     m_ptr = nullptr;
   }
 
+  /* Cache the frame_id that the pointer will use to reinflate.  */
+  void prepare_reinflate ()
+  {
+    m_cached_id = get_frame_id(*this);
+  }
+
+  /* Use the cached frame_id to reinflate the pointer.  */
+  void reinflate ()
+  {
+    gdb_assert (m_cached_id != null_frame_id);
+
+    if(m_ptr == nullptr)
+      m_ptr = frame_find_by_id (m_cached_id).get ();
+    gdb_assert (m_ptr != nullptr);
+  }
+
 private:
 
   /* The underlying pointer.  */
   frame_info *m_ptr = nullptr;
 
+  /* The frame_id of the underlying pointer.  */
+  frame_id m_cached_id = null_frame_id;
 
   /* All frame_info_ptr objects are kept on an intrusive list.
      This keeps their construction and destruction costs
diff --git a/gdb/frame.h b/gdb/frame.h
index 759cd32c5e3..5ee96cee46c 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -84,109 +84,10 @@ struct ui_file;
 struct ui_out;
 struct frame_print_options;
 
-/* Status of a given frame's stack.  */
-
-enum frame_id_stack_status
-{
-  /* Stack address is invalid.  */
-  FID_STACK_INVALID = 0,
-
-  /* Stack address is valid, and is found in the stack_addr field.  */
-  FID_STACK_VALID = 1,
-
-  /* Sentinel frame.  */
-  FID_STACK_SENTINEL = 2,
-
-  /* Outer frame.  Since a frame's stack address is typically defined as the
-     value the stack pointer had prior to the activation of the frame, an outer
-     frame doesn't have a stack address.  The frame ids of frames inlined in the
-     outer frame are also of this type.  */
-  FID_STACK_OUTER = 3,
-
-  /* Stack address is unavailable.  I.e., there's a valid stack, but
-     we don't know where it is (because memory or registers we'd
-     compute it from were not collected).  */
-  FID_STACK_UNAVAILABLE = -1
-};
-
 /* The frame object.  */
 
 class frame_info_ptr;
 
-/* The frame object's ID.  This provides a per-frame unique identifier
-   that can be used to relocate a `struct frame_info' after a target
-   resume or a frame cache destruct.  It of course assumes that the
-   inferior hasn't unwound the stack past that frame.  */
-
-struct frame_id
-{
-  /* The frame's stack address.  This shall be constant through out
-     the lifetime of a frame.  Note that this requirement applies to
-     not just the function body, but also the prologue and (in theory
-     at least) the epilogue.  Since that value needs to fall either on
-     the boundary, or within the frame's address range, the frame's
-     outer-most address (the inner-most address of the previous frame)
-     is used.  Watch out for all the legacy targets that still use the
-     function pointer register or stack pointer register.  They are
-     wrong.
-
-     This field is valid only if frame_id.stack_status is
-     FID_STACK_VALID.  It will be 0 for other
-     FID_STACK_... statuses.  */
-  CORE_ADDR stack_addr;
-
-  /* The frame's code address.  This shall be constant through out the
-     lifetime of the frame.  While the PC (a.k.a. resume address)
-     changes as the function is executed, this code address cannot.
-     Typically, it is set to the address of the entry point of the
-     frame's function (as returned by get_frame_func).
-
-     For inlined functions (INLINE_DEPTH != 0), this is the address of
-     the first executed instruction in the block corresponding to the
-     inlined function.
-
-     This field is valid only if code_addr_p is true.  Otherwise, this
-     frame is considered to have a wildcard code address, i.e. one that
-     matches every address value in frame comparisons.  */
-  CORE_ADDR code_addr;
-
-  /* The frame's special address.  This shall be constant through out the
-     lifetime of the frame.  This is used for architectures that may have
-     frames that do not change the stack but are still distinct and have
-     some form of distinct identifier (e.g. the ia64 which uses a 2nd
-     stack for registers).  This field is treated as unordered - i.e. will
-     not be used in frame ordering comparisons.
-
-     This field is valid only if special_addr_p is true.  Otherwise, this
-     frame is considered to have a wildcard special address, i.e. one that
-     matches every address value in frame comparisons.  */
-  CORE_ADDR special_addr;
-
-  /* Flags to indicate the above fields have valid contents.  */
-  ENUM_BITFIELD(frame_id_stack_status) stack_status : 3;
-  unsigned int code_addr_p : 1;
-  unsigned int special_addr_p : 1;
-
-  /* It is non-zero for a frame made up by GDB without stack data
-     representation in inferior, such as INLINE_FRAME or TAILCALL_FRAME.
-     Caller of inlined function will have it zero, each more inner called frame
-     will have it increasingly one, two etc.  Similarly for TAILCALL_FRAME.  */
-  int artificial_depth;
-
-  /* Return a string representation of this frame id.  */
-  std::string to_string () const;
-
-  /* Returns true when this frame_id and R identify the same
-     frame.  */
-  bool operator== (const frame_id &r) const;
-
-  /* Inverse of ==.  */
-  bool operator!= (const frame_id &r) const
-  {
-    return !(*this == r);
-  }
-};
-
 /* Save and restore the currently selected frame.  */
 
 class scoped_restore_selected_frame
@@ -212,19 +113,6 @@ class scoped_restore_selected_frame
   enum language m_lang;
 };
 
-/* Methods for constructing and comparing Frame IDs.  */
-
-/* For convenience.  All fields are zero.  This means "there is no frame".  */
-extern const struct frame_id null_frame_id;
-
-/* Sentinel frame.  */
-extern const struct frame_id sentinel_frame_id;
-
-/* This means "there is no frame ID, but there is a frame".  It should be
-   replaced by best-effort frame IDs for the outermost frame, somehow.
-   The implementation is only special_addr_p set.  */
-extern const struct frame_id outer_frame_id;
-
 /* Flag to control debugging.  */
 
 extern bool frame_debug;
@@ -399,10 +287,6 @@ extern frame_info_ptr get_next_frame_sentinel_okay (frame_info_ptr );
    frame.  */
 extern frame_info_ptr get_prev_frame_always (frame_info_ptr );
 
-/* Given a frame's ID, relocate the frame.  Returns NULL if the frame
-   is not found.  */
-extern frame_info_ptr frame_find_by_id (struct frame_id id);
-
 /* Base attributes of a frame: */
 
 /* The frame's `resume' address.  Where the program will resume in
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index d292a0e55bf..bc171d8818a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1814,6 +1814,7 @@ finish_command (const char *arg, int from_tty)
   frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
   if (frame == 0)
     error (_("\"finish\" not meaningful in the outermost frame."));
+  frame.prepare_reinflate ();
 
   clear_proceed_status (0);
 
@@ -1872,6 +1873,7 @@ finish_command (const char *arg, int from_tty)
 
       print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
     }
+  frame.reinflate ();
 
   if (execution_direction == EXEC_REVERSE)
     finish_backward (sm);
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index f23559f886c..2c5bd2db96d 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -39,6 +39,7 @@
 #include "inferior.h"
 #include "observable.h"
 
+
 enum what_to_list { locals, arguments, all };
 
 static void list_args_or_locals (const frame_print_options &fp_opts,
@@ -176,10 +177,12 @@ mi_cmd_stack_list_frames (const char *command, char **argv, int argc)
 	   i++, fi = get_prev_frame (fi))
 	{
 	  QUIT;
+	  fi.prepare_reinflate ();
 	  /* Print the location and the address always, even for level 0.
 	     If args is 0, don't print the arguments.  */
 	  print_frame_info (user_frame_print_options,
 			    fi, 1, LOC_AND_ADDRESS, 0 /* args */, 0);
+	  fi.reinflate ();
 	}
     }
 }
diff --git a/gdb/stack.c b/gdb/stack.c
index 8a8936535f8..8c54e822d1f 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -362,11 +362,13 @@ print_stack_frame (frame_info_ptr frame, int print_level,
   if (current_uiout->is_mi_like_p ())
     print_what = LOC_AND_ADDRESS;
 
+  frame.prepare_reinflate ();
   try
     {
       print_frame_info (user_frame_print_options,
 			frame, print_level, print_what, 1 /* print_args */,
 			set_current_sal);
+      frame.reinflate ();
       if (set_current_sal)
 	set_current_sal_from_frame (frame);
     }
@@ -742,6 +744,11 @@ print_frame_args (const frame_print_options &fp_opts,
     = (print_names
        && fp_opts.print_frame_arguments != print_frame_arguments_none);
 
+  /* If one of the arguments has a pretty printer that calls a
+     function of the inferior to print it, the pointer must be
+     reinflatable.  */
+  frame.prepare_reinflate ();
+
   /* Temporarily change the selected frame to the given FRAME.
      This allows routines that rely on the selected frame instead
      of being given a frame as parameter to use the correct frame.  */
@@ -902,6 +909,7 @@ print_frame_args (const frame_print_options &fp_opts,
 	    }
 
 	  first = 0;
+	  frame.reinflate ();
 	}
     }
 
@@ -1172,6 +1180,7 @@ print_frame_info (const frame_print_options &fp_opts,
 
 	  print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
 	}
+      frame.reinflate ();
 
       /* If disassemble-next-line is set to on and there is line debug
 	 messages, output assembly codes for next line.  */
@@ -2061,6 +2070,7 @@ backtrace_command_1 (const frame_print_options &fp_opts,
       for (fi = trailing; fi && count--; fi = get_prev_frame (fi))
 	{
 	  QUIT;
+	  fi.prepare_reinflate ();
 
 	  /* Don't use print_stack_frame; if an error() occurs it probably
 	     means further attempts to backtrace would fail (on the other
@@ -2085,6 +2095,7 @@ backtrace_command_1 (const frame_print_options &fp_opts,
 	    }
 
 	  /* Save the last frame to check for error conditions.  */
+	  fi.reinflate ();
 	  trailing = fi;
 	}
 
diff --git a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.c b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
new file mode 100644
index 00000000000..3be5675b096
--- /dev/null
+++ b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
@@ -0,0 +1,53 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2022 Free Software Foundation, Inc.
+
+   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/>.  */
+
+struct mytype
+{
+  char *x;
+};
+
+void
+rec (int i)
+{
+  if (i <= 0)
+    return;
+  rec (i-1);
+}
+
+int
+f ()
+{
+  rec (100);
+  return 2;
+}
+
+void
+g (struct mytype mt, int depth)
+{
+  if (depth <= 0)
+    return; /* TAG: final frame */
+  g (mt, depth - 1); /* TAG: first frame */
+}
+
+int
+main ()
+{
+  struct mytype mt;
+  mt.x = "hello world";
+  g (mt, 10); /* TAG: outside the frame */
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
new file mode 100644
index 00000000000..0aeb2218f91
--- /dev/null
+++ b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
@@ -0,0 +1,136 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# 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/>.
+
+# This file is part of the GDB testsuite.  It tests a pretty printer that
+# calls an inferior function by hand, triggering a Use-after-Free bug
+# (PR gdb/28856).
+
+load_lib gdb-python.exp
+
+standard_testfile
+
+# gdb needs to be started here for skip_python_tests to work.
+# prepare_for_testing could be used instead, but it could compile the program
+# unnecessarily, so starting GDB like this is preferable.
+gdb_start
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
+    untested "failed to compile"
+    return -1
+}
+
+# This proc restarts GDB, makes the inferior reach the desired spot - marked
+# by a comment in the .c file - and turns on the pretty printer for testing.
+# Starting with a new GDB is important because the test may crash GDB.  The
+# return values are here to avoid us trying to test the pretty printer if
+# there was a problem getting to main.
+proc start_test { breakpoint_comment } {
+    global srcdir subdir testfile binfile
+
+    # Start with a fresh gdb.
+    # This is important because the test can crash GDB.
+
+    clean_restart ${binfile}
+
+    if { ![runto_main] } then {
+	untested "couldn't run to breakpoint"
+	return -1
+    }
+
+    # Let GDB get to the return line.
+    gdb_breakpoint [gdb_get_line_number ${breakpoint_comment} ${testfile}.c ]
+    gdb_continue_to_breakpoint ${breakpoint_comment} ".*"
+
+    gdb_test_no_output "set print pretty on" "starting to pretty print"
+
+    set remote_python_file [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
+    gdb_test_no_output "source ${remote_python_file}" "load python file"
+
+    return 0
+}
+
+# Start by testing the "run" command, it can't leverage start_test
+with_test_prefix "run to frame" {
+    if { ![runto_main] } then {
+	untested "couldn't run to main"
+    }
+
+    gdb_test_no_output "set print pretty on" "starting to pretty print"
+
+    set remote_python_file [gdb_remote_download host ${srcdir}/${subdir}/${testfile}.py]
+    gdb_test_no_output "source ${remote_python_file}" "load python file"
+
+    gdb_breakpoint [gdb_get_line_number "TAG: final frame" ${testfile}.c]
+    gdb_continue_to_breakpoint "TAG: final frame" ".*"
+}
+
+# Testing the backtrace command.
+with_test_prefix "frame print" {
+    if { [start_test "TAG: final frame"] == 0 } {
+	gdb_test "backtrace -frame-arguments all" [multi_line \
+	"#0 .*g \\(mt=mytype is .*\\, depth=0\\).*"\
+	"#1 .*g \\(mt=mytype is .*\\, depth=1\\).*"\
+	"#2 .*g \\(mt=mytype is .*\\, depth=2\\).*"\
+	"#3 .*g \\(mt=mytype is .*\\, depth=3\\).*"\
+	"#4 .*g \\(mt=mytype is .*\\, depth=4\\).*"\
+	"#5 .*g \\(mt=mytype is .*\\, depth=5\\).*"\
+	"#6 .*g \\(mt=mytype is .*\\, depth=6\\).*"\
+	"#7 .*g \\(mt=mytype is .*\\, depth=7\\).*"\
+	"#8 .*g \\(mt=mytype is .*\\, depth=8\\).*"\
+	"#9 .*g \\(mt=mytype is .*\\, depth=9\\).*"\
+	"#10 .*g \\(mt=mytype is .*\\, depth=10\\).*"\
+	"#11 .*main \\(\\).*"] \
+	"backtrace test"
+    }
+}
+# Testing the down command.
+with_test_prefix "frame movement down" {
+    if { [start_test "TAG: first frame"] == 0 } {
+	gdb_test "up" [multi_line "#1 .*in main \\(\\) at .*" ".*outside the frame.*"]
+	gdb_test "down" [multi_line "#0\\s+g \\(mt=mytype is .*\\, depth=10\\).*" ".*first frame.*"]
+    }
+}
+
+# Testing the up command.
+with_test_prefix "frame movement up" {
+    if { [start_test "TAG: final frame"] == 0 } {
+	gdb_test "up" [multi_line "#1 .*in g \\(mt=mytype is .*\\, depth=1\\).*" ".*first frame.*"]
+    }
+}
+
+# Testing the finish command.
+with_test_prefix "frame exit through finish" {
+    if { [start_test "TAG: final frame"] == 0 } {
+	gdb_test "finish" [multi_line ".*.*g \\(mt=mytype is .*\\, depth=0\\).*" ".*g \\(mt=mytype is .*\\, depth=1\\).*" ".*"]
+    }
+}
+
+# Testing the step command.
+with_test_prefix "frame enter through step" {
+    if { [start_test "TAG: outside the frame"] == 0 } {
+	gdb_test "step" [multi_line "g \\(mt=mytype is .*\\, depth=10\\).*" "41.*if \\(depth \\<= 0\\)"]
+    }
+}
+
+# Testing the continue command.
+with_test_prefix "frame enter through continue" {
+    if { [start_test "TAG: outside the frame"] == 0 } {
+	gdb_breakpoint [gdb_get_line_number "TAG: first frame" ${testfile}.c ]
+	gdb_continue_to_breakpoint "TAG: first frame" ".*TAG: first frame.*"
+    }
+}
diff --git a/gdb/testsuite/gdb.python/pretty-print-call-by-hand.py b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.py
new file mode 100644
index 00000000000..f8f5df678f8
--- /dev/null
+++ b/gdb/testsuite/gdb.python/pretty-print-call-by-hand.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# 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/>.
+
+
+class MytypePrinter:
+    """pretty print my type"""
+
+    def __init__(self, val):
+        self.val = val
+
+    def to_string(self):
+        calls = gdb.parse_and_eval('f()')
+        return "mytype is %s" % self.val['x']
+
+def ec_lookup_function(val):
+    typ = val.type
+    if typ.code == gdb.TYPE_CODE_REF:
+        typ = typ.target()
+    if str(typ) == 'struct mytype':
+        return MytypePrinter(val)
+    return None
+
+def disable_lookup_function():
+    ec_lookup_function.enabled = False
+
+def enable_lookup_function():
+    ec_lookup_function.enabled = True
+
+gdb.pretty_printers.append(ec_lookup_function)
-- 
2.37.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Ping][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
                   ` (4 preceding siblings ...)
  2022-08-30 10:08 ` [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr Bruno Larsen
@ 2022-09-13  8:06 ` Bruno Larsen
  2022-09-21 15:39   ` [PINGv2][PATCH " Bruno Larsen
  5 siblings, 1 reply; 18+ messages in thread
From: Bruno Larsen @ 2022-09-13  8:06 UTC (permalink / raw)
  To: Bruno Larsen, gdb-patches

ping

Cheers,
Bruno

On 30/08/2022 12:08, Bruno Larsen wrote:
> GDB occasionally gets bugs where a frame_info is kept alive across a
> call to reinit_frame_cache.  This causes a use-after-free and, if
> you're lucky, a crash.
>
> This series aims to make this setup more "reliable", in the sense that
> you'll always get a crash if you break the rules.  This is done by
> wrapping frame_info in a smart pointer class, and having
> reinit_frame_cache invalidate all the pointers.
>
> Tromey's original plan was that these pointers could be automatically
> reinflated after being invalidated, but most uses of the class would not
> need to be reinflated, and setting everything up to be reinflatable
> would be quite expensive, as calculating a frame_id requires some
> unwinding.
>
> I added a prepare_reinflate method, which stashes the relevant frame_id
> and allows the pointer to be reinflated. However, reinflation is done
> manually for now because doing it when reinit_frame_cache was creating
> weird problems.
>
> Changelog:
> v3:
>      Reverted instrusive list changes
>      Guile doesn't get fancy pointers because of exceptions through longjumps.
>
> v2:
>      Fix commit squashing and email threading
> Version 2 had some problematic squashing of commits, and I tried to add
> some unit tests, but those didn't work out, so I eventually dropped
> that.
>
> Bruno Larsen (2):
>    Continue making GDB use frame_info_ptr
>    gdb/frame: Add reinflation method for frame_info_ptr
>
> Tom Tromey (3):
>    Remove frame_id_eq
>    Introduce frame_info_ptr smart pointer class
>    Change GDB to use frame_info_ptr
>
>   gdb/aarch64-fbsd-tdep.c                       |   2 +-
>   gdb/aarch64-linux-tdep.c                      |   2 +-
>   gdb/aarch64-tdep.c                            |  34 +-
>   gdb/ada-lang.c                                |  10 +-
>   gdb/ada-lang.h                                |   4 +-
>   gdb/alpha-linux-tdep.c                        |   2 +-
>   gdb/alpha-mdebug-tdep.c                       |  16 +-
>   gdb/alpha-netbsd-tdep.c                       |   2 +-
>   gdb/alpha-obsd-tdep.c                         |   2 +-
>   gdb/alpha-tdep.c                              |  22 +-
>   gdb/alpha-tdep.h                              |   2 +-
>   gdb/amd64-darwin-tdep.c                       |   2 +-
>   gdb/amd64-fbsd-tdep.c                         |   2 +-
>   gdb/amd64-linux-tdep.c                        |   6 +-
>   gdb/amd64-netbsd-tdep.c                       |   4 +-
>   gdb/amd64-obsd-tdep.c                         |  12 +-
>   gdb/amd64-sol2-tdep.c                         |   2 +-
>   gdb/amd64-tdep.c                              |  34 +-
>   gdb/amd64-tdep.h                              |   2 +-
>   gdb/amd64-windows-tdep.c                      |  12 +-
>   gdb/arc-linux-tdep.c                          |   4 +-
>   gdb/arc-tdep.c                                |  20 +-
>   gdb/arc-tdep.h                                |   4 +-
>   gdb/arch-utils.c                              |   6 +-
>   gdb/arch-utils.h                              |   8 +-
>   gdb/arm-fbsd-tdep.c                           |   2 +-
>   gdb/arm-linux-tdep.c                          |  14 +-
>   gdb/arm-obsd-tdep.c                           |   2 +-
>   gdb/arm-tdep.c                                |  64 ++--
>   gdb/arm-tdep.h                                |   4 +-
>   gdb/arm-wince-tdep.c                          |   2 +-
>   gdb/avr-tdep.c                                |  14 +-
>   gdb/ax-gdb.c                                  |   2 +-
>   gdb/bfin-linux-tdep.c                         |   2 +-
>   gdb/bfin-tdep.c                               |  12 +-
>   gdb/blockframe.c                              |   8 +-
>   gdb/bpf-tdep.c                                |   8 +-
>   gdb/break-catch-throw.c                       |   2 +-
>   gdb/breakpoint.c                              |  20 +-
>   gdb/c-lang.c                                  |   2 +-
>   gdb/cli/cli-cmds.c                            |   2 +-
>   gdb/compile/compile-c-symbols.c               |   2 +-
>   gdb/compile/compile-cplus-symbols.c           |   2 +-
>   gdb/compile/compile-loc2c.c                   |   2 +-
>   gdb/cp-abi.c                                  |   2 +-
>   gdb/cp-abi.h                                  |   6 +-
>   gdb/cris-tdep.c                               |  36 +-
>   gdb/csky-linux-tdep.c                         |   2 +-
>   gdb/csky-tdep.c                               |  22 +-
>   gdb/defs.h                                    |   2 +-
>   gdb/dtrace-probe.c                            |   4 +-
>   gdb/dummy-frame.c                             |  12 +-
>   gdb/dummy-frame.h                             |   2 +-
>   gdb/dwarf2/expr.c                             |  20 +-
>   gdb/dwarf2/expr.h                             |   6 +-
>   gdb/dwarf2/frame-tailcall.c                   |  41 +--
>   gdb/dwarf2/frame-tailcall.h                   |   6 +-
>   gdb/dwarf2/frame.c                            |  39 +--
>   gdb/dwarf2/frame.h                            |  12 +-
>   gdb/dwarf2/loc.c                              |  38 +--
>   gdb/dwarf2/loc.h                              |   8 +-
>   gdb/elfread.c                                 |   4 +-
>   gdb/eval.c                                    |   2 +-
>   gdb/extension-priv.h                          |   2 +-
>   gdb/extension.c                               |   2 +-
>   gdb/extension.h                               |   4 +-
>   gdb/f-valprint.c                              |   2 +-
>   gdb/findvar.c                                 |  26 +-
>   gdb/frame-base.c                              |   8 +-
>   gdb/frame-base.h                              |  12 +-
>   gdb/frame-id.h                                | 135 ++++++++
>   gdb/frame-info.h                              | 206 +++++++++++
>   gdb/frame-unwind.c                            |  26 +-
>   gdb/frame-unwind.h                            |  36 +-
>   gdb/frame.c                                   | 323 +++++++++---------
>   gdb/frame.h                                   | 278 +++++----------
>   gdb/frv-linux-tdep.c                          |  10 +-
>   gdb/frv-tdep.c                                |  10 +-
>   gdb/ft32-tdep.c                               |   8 +-
>   gdb/gcore.c                                   |   2 +-
>   gdb/gdbarch-components.py                     |  30 +-
>   gdb/gdbarch-gen.h                             |  60 ++--
>   gdb/gdbarch-selftests.c                       |   2 +-
>   gdb/gdbarch.c                                 |  30 +-
>   gdb/gdbtypes.h                                |   5 +-
>   gdb/gnu-v3-abi.c                              |   2 +-
>   gdb/h8300-tdep.c                              |  12 +-
>   gdb/hppa-bsd-tdep.c                           |   2 +-
>   gdb/hppa-linux-tdep.c                         |   8 +-
>   gdb/hppa-netbsd-tdep.c                        |   4 +-
>   gdb/hppa-tdep.c                               |  32 +-
>   gdb/hppa-tdep.h                               |   8 +-
>   gdb/i386-bsd-tdep.c                           |   2 +-
>   gdb/i386-darwin-tdep.c                        |   4 +-
>   gdb/i386-darwin-tdep.h                        |   2 +-
>   gdb/i386-fbsd-tdep.c                          |   2 +-
>   gdb/i386-gnu-tdep.c                           |   6 +-
>   gdb/i386-linux-tdep.c                         |  10 +-
>   gdb/i386-netbsd-tdep.c                        |   4 +-
>   gdb/i386-nto-tdep.c                           |   4 +-
>   gdb/i386-obsd-tdep.c                          |  10 +-
>   gdb/i386-sol2-tdep.c                          |   2 +-
>   gdb/i386-tdep.c                               |  54 +--
>   gdb/i386-tdep.h                               |  10 +-
>   gdb/i386-windows-tdep.c                       |   2 +-
>   gdb/i387-tdep.c                               |   6 +-
>   gdb/i387-tdep.h                               |   8 +-
>   gdb/ia64-libunwind-tdep.c                     |  12 +-
>   gdb/ia64-libunwind-tdep.h                     |  12 +-
>   gdb/ia64-tdep.c                               |  54 +--
>   gdb/ia64-tdep.h                               |   4 +-
>   gdb/infcall.c                                 |   4 +-
>   gdb/infcmd.c                                  |  30 +-
>   gdb/inferior.h                                |   6 +-
>   gdb/infrun.c                                  |  78 +++--
>   gdb/infrun.h                                  |   4 +-
>   gdb/inline-frame.c                            |  14 +-
>   gdb/inline-frame.h                            |   4 +-
>   gdb/iq2000-tdep.c                             |  10 +-
>   gdb/jit.c                                     |  12 +-
>   gdb/language.c                                |   6 +-
>   gdb/language.h                                |   8 +-
>   gdb/lm32-tdep.c                               |   8 +-
>   gdb/loongarch-linux-tdep.c                    |   4 +-
>   gdb/loongarch-tdep.c                          |   8 +-
>   gdb/loongarch-tdep.h                          |   2 +-
>   gdb/m32c-tdep.c                               |  10 +-
>   gdb/m32r-linux-tdep.c                         |  14 +-
>   gdb/m32r-tdep.c                               |   8 +-
>   gdb/m68hc11-tdep.c                            |  16 +-
>   gdb/m68k-linux-tdep.c                         |  12 +-
>   gdb/m68k-tdep.c                               |  18 +-
>   gdb/m68k-tdep.h                               |   2 +-
>   gdb/macroscope.c                              |   2 +-
>   gdb/mep-tdep.c                                |   8 +-
>   gdb/mi/mi-cmd-stack.c                         |  29 +-
>   gdb/mi/mi-main.c                              |  12 +-
>   gdb/microblaze-linux-tdep.c                   |   4 +-
>   gdb/microblaze-tdep.c                         |  10 +-
>   gdb/minsyms.c                                 |   2 +-
>   gdb/mips-fbsd-tdep.c                          |   4 +-
>   gdb/mips-linux-tdep.c                         |  22 +-
>   gdb/mips-netbsd-tdep.c                        |   2 +-
>   gdb/mips-sde-tdep.c                           |  12 +-
>   gdb/mips-tdep.c                               |  96 +++---
>   gdb/mips-tdep.h                               |   2 +-
>   gdb/mips64-obsd-tdep.c                        |   2 +-
>   gdb/mn10300-linux-tdep.c                      |   4 +-
>   gdb/mn10300-tdep.c                            |   8 +-
>   gdb/moxie-tdep.c                              |   8 +-
>   gdb/msp430-tdep.c                             |  10 +-
>   gdb/nds32-tdep.c                              |  20 +-
>   gdb/nios2-linux-tdep.c                        |   4 +-
>   gdb/nios2-tdep.c                              |  22 +-
>   gdb/nios2-tdep.h                              |   2 +-
>   gdb/objc-lang.c                               |  10 +-
>   gdb/observable.h                              |   2 +-
>   gdb/or1k-linux-tdep.c                         |   4 +-
>   gdb/or1k-tdep.c                               |  12 +-
>   gdb/ppc-fbsd-tdep.c                           |   8 +-
>   gdb/ppc-linux-tdep.c                          |  12 +-
>   gdb/ppc-netbsd-tdep.c                         |   2 +-
>   gdb/ppc-obsd-tdep.c                           |   8 +-
>   gdb/ppc-tdep.h                                |   4 +-
>   gdb/ppc64-tdep.c                              |  20 +-
>   gdb/ppc64-tdep.h                              |   4 +-
>   gdb/printcmd.c                                |   4 +-
>   gdb/probe.c                                   |   4 +-
>   gdb/probe.h                                   |   4 +-
>   gdb/python/py-event.h                         |   2 +-
>   gdb/python/py-finishbreakpoint.c              |   6 +-
>   gdb/python/py-frame.c                         |  44 +--
>   gdb/python/py-framefilter.c                   |  22 +-
>   gdb/python/py-inferior.c                      |   2 +-
>   gdb/python/py-infevents.c                     |   4 +-
>   gdb/python/py-symbol.c                        |   6 +-
>   gdb/python/py-unwind.c                        |  12 +-
>   gdb/python/python-internal.h                  |   6 +-
>   gdb/record-btrace.c                           |  32 +-
>   gdb/riscv-fbsd-tdep.c                         |   2 +-
>   gdb/riscv-linux-tdep.c                        |   6 +-
>   gdb/riscv-tdep.c                              |  12 +-
>   gdb/riscv-tdep.h                              |   2 +-
>   gdb/rl78-tdep.c                               |  12 +-
>   gdb/rs6000-aix-tdep.c                         |  10 +-
>   gdb/rs6000-tdep.c                             |  34 +-
>   gdb/rx-tdep.c                                 |  16 +-
>   gdb/s12z-tdep.c                               |  10 +-
>   gdb/s390-linux-tdep.c                         |   8 +-
>   gdb/s390-tdep.c                               |  38 +--
>   gdb/s390-tdep.h                               |   2 +-
>   gdb/sentinel-frame.c                          |   6 +-
>   gdb/sh-linux-tdep.c                           |   6 +-
>   gdb/sh-tdep.c                                 |  16 +-
>   gdb/skip.c                                    |   2 +-
>   gdb/sol2-tdep.c                               |   2 +-
>   gdb/sol2-tdep.h                               |   2 +-
>   gdb/solib-svr4.c                              |   4 +-
>   gdb/sparc-linux-tdep.c                        |   6 +-
>   gdb/sparc-netbsd-tdep.c                       |  12 +-
>   gdb/sparc-obsd-tdep.c                         |   8 +-
>   gdb/sparc-sol2-tdep.c                         |   8 +-
>   gdb/sparc-tdep.c                              |  20 +-
>   gdb/sparc-tdep.h                              |  12 +-
>   gdb/sparc64-fbsd-tdep.c                       |   8 +-
>   gdb/sparc64-linux-tdep.c                      |   8 +-
>   gdb/sparc64-netbsd-tdep.c                     |  10 +-
>   gdb/sparc64-obsd-tdep.c                       |  16 +-
>   gdb/sparc64-sol2-tdep.c                       |   8 +-
>   gdb/sparc64-tdep.c                            |  10 +-
>   gdb/sparc64-tdep.h                            |   4 +-
>   gdb/stack.c                                   | 119 ++++---
>   gdb/stack.h                                   |   4 +-
>   gdb/stap-probe.c                              |   4 +-
>   gdb/std-regs.c                                |   8 +-
>   gdb/symfile.h                                 |   2 +-
>   gdb/symtab.h                                  |  10 +-
>   .../gdb.python/pretty-print-call-by-hand.c    |  53 +++
>   .../gdb.python/pretty-print-call-by-hand.exp  | 136 ++++++++
>   .../gdb.python/pretty-print-call-by-hand.py   |  41 +++
>   gdb/tic6x-linux-tdep.c                        |   4 +-
>   gdb/tic6x-tdep.c                              |  22 +-
>   gdb/tic6x-tdep.h                              |   2 +-
>   gdb/tilegx-linux-tdep.c                       |   2 +-
>   gdb/tilegx-tdep.c                             |  12 +-
>   gdb/top.c                                     |   2 +-
>   gdb/tracepoint.c                              |   5 +-
>   gdb/trad-frame.c                              |  10 +-
>   gdb/trad-frame.h                              |  10 +-
>   gdb/tramp-frame.c                             |  10 +-
>   gdb/tramp-frame.h                             |   6 +-
>   gdb/tui/tui-disasm.c                          |   2 +-
>   gdb/tui/tui-disasm.h                          |   2 +-
>   gdb/tui/tui-hooks.c                           |   6 +-
>   gdb/tui/tui-regs.c                            |   8 +-
>   gdb/tui/tui-regs.h                            |   4 +-
>   gdb/tui/tui-source.c                          |   4 +-
>   gdb/tui/tui-source.h                          |   2 +-
>   gdb/tui/tui-stack.c                           |   4 +-
>   gdb/tui/tui-stack.h                           |   4 +-
>   gdb/tui/tui-winsource.c                       |   4 +-
>   gdb/tui/tui-winsource.h                       |   2 +-
>   gdb/user-regs.c                               |   4 +-
>   gdb/user-regs.h                               |   6 +-
>   gdb/v850-tdep.c                               |  10 +-
>   gdb/valops.c                                  |  10 +-
>   gdb/value.c                                   |   6 +-
>   gdb/value.h                                   |  16 +-
>   gdb/varobj.c                                  |   8 +-
>   gdb/vax-tdep.c                                |  14 +-
>   gdb/xstormy16-tdep.c                          |  12 +-
>   gdb/xtensa-tdep.c                             |  22 +-
>   gdb/z80-tdep.c                                |   6 +-
>   253 files changed, 2172 insertions(+), 1702 deletions(-)
>   create mode 100644 gdb/frame-id.h
>   create mode 100644 gdb/frame-info.h
>   create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
>   create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
>   create mode 100644 gdb/testsuite/gdb.python/pretty-print-call-by-hand.py
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PINGv2][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-09-13  8:06 ` [Ping][PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
@ 2022-09-21 15:39   ` Bruno Larsen
  2022-09-29  7:01     ` [PINGv3][PATCH " Bruno Larsen
  0 siblings, 1 reply; 18+ messages in thread
From: Bruno Larsen @ 2022-09-21 15:39 UTC (permalink / raw)
  To: Bruno Larsen, gdb-patches

Ping!

Cheers,
Bruno

On 13/09/2022 10:06, Bruno Larsen wrote:
> ping
>
> Cheers,
> Bruno
>
> On 30/08/2022 12:08, Bruno Larsen wrote:
>> GDB occasionally gets bugs where a frame_info is kept alive across a
>> call to reinit_frame_cache.  This causes a use-after-free and, if
>> you're lucky, a crash.
>>
>> This series aims to make this setup more "reliable", in the sense that
>> you'll always get a crash if you break the rules.  This is done by
>> wrapping frame_info in a smart pointer class, and having
>> reinit_frame_cache invalidate all the pointers.
>>
>> Tromey's original plan was that these pointers could be automatically
>> reinflated after being invalidated, but most uses of the class would not
>> need to be reinflated, and setting everything up to be reinflatable
>> would be quite expensive, as calculating a frame_id requires some
>> unwinding.
>>
>> I added a prepare_reinflate method, which stashes the relevant frame_id
>> and allows the pointer to be reinflated. However, reinflation is done
>> manually for now because doing it when reinit_frame_cache was creating
>> weird problems.
>>
>> Changelog:
>> v3:
>>      Reverted instrusive list changes
>>      Guile doesn't get fancy pointers because of exceptions through 
>> longjumps.
>>
>> v2:
>>      Fix commit squashing and email threading
>> Version 2 had some problematic squashing of commits, and I tried to add
>> some unit tests, but those didn't work out, so I eventually dropped
>> that.
>>
>> Bruno Larsen (2):
>>    Continue making GDB use frame_info_ptr
>>    gdb/frame: Add reinflation method for frame_info_ptr
>>
>> Tom Tromey (3):
>>    Remove frame_id_eq
>>    Introduce frame_info_ptr smart pointer class
>>    Change GDB to use frame_info_ptr
>>
>>   gdb/aarch64-fbsd-tdep.c                       |   2 +-
>>   gdb/aarch64-linux-tdep.c                      |   2 +-
>>   gdb/aarch64-tdep.c                            |  34 +-
>>   gdb/ada-lang.c                                |  10 +-
>>   gdb/ada-lang.h                                |   4 +-
>>   gdb/alpha-linux-tdep.c                        |   2 +-
>>   gdb/alpha-mdebug-tdep.c                       |  16 +-
>>   gdb/alpha-netbsd-tdep.c                       |   2 +-
>>   gdb/alpha-obsd-tdep.c                         |   2 +-
>>   gdb/alpha-tdep.c                              |  22 +-
>>   gdb/alpha-tdep.h                              |   2 +-
>>   gdb/amd64-darwin-tdep.c                       |   2 +-
>>   gdb/amd64-fbsd-tdep.c                         |   2 +-
>>   gdb/amd64-linux-tdep.c                        |   6 +-
>>   gdb/amd64-netbsd-tdep.c                       |   4 +-
>>   gdb/amd64-obsd-tdep.c                         |  12 +-
>>   gdb/amd64-sol2-tdep.c                         |   2 +-
>>   gdb/amd64-tdep.c                              |  34 +-
>>   gdb/amd64-tdep.h                              |   2 +-
>>   gdb/amd64-windows-tdep.c                      |  12 +-
>>   gdb/arc-linux-tdep.c                          |   4 +-
>>   gdb/arc-tdep.c                                |  20 +-
>>   gdb/arc-tdep.h                                |   4 +-
>>   gdb/arch-utils.c                              |   6 +-
>>   gdb/arch-utils.h                              |   8 +-
>>   gdb/arm-fbsd-tdep.c                           |   2 +-
>>   gdb/arm-linux-tdep.c                          |  14 +-
>>   gdb/arm-obsd-tdep.c                           |   2 +-
>>   gdb/arm-tdep.c                                |  64 ++--
>>   gdb/arm-tdep.h                                |   4 +-
>>   gdb/arm-wince-tdep.c                          |   2 +-
>>   gdb/avr-tdep.c                                |  14 +-
>>   gdb/ax-gdb.c                                  |   2 +-
>>   gdb/bfin-linux-tdep.c                         |   2 +-
>>   gdb/bfin-tdep.c                               |  12 +-
>>   gdb/blockframe.c                              |   8 +-
>>   gdb/bpf-tdep.c                                |   8 +-
>>   gdb/break-catch-throw.c                       |   2 +-
>>   gdb/breakpoint.c                              |  20 +-
>>   gdb/c-lang.c                                  |   2 +-
>>   gdb/cli/cli-cmds.c                            |   2 +-
>>   gdb/compile/compile-c-symbols.c               |   2 +-
>>   gdb/compile/compile-cplus-symbols.c           |   2 +-
>>   gdb/compile/compile-loc2c.c                   |   2 +-
>>   gdb/cp-abi.c                                  |   2 +-
>>   gdb/cp-abi.h                                  |   6 +-
>>   gdb/cris-tdep.c                               |  36 +-
>>   gdb/csky-linux-tdep.c                         |   2 +-
>>   gdb/csky-tdep.c                               |  22 +-
>>   gdb/defs.h                                    |   2 +-
>>   gdb/dtrace-probe.c                            |   4 +-
>>   gdb/dummy-frame.c                             |  12 +-
>>   gdb/dummy-frame.h                             |   2 +-
>>   gdb/dwarf2/expr.c                             |  20 +-
>>   gdb/dwarf2/expr.h                             |   6 +-
>>   gdb/dwarf2/frame-tailcall.c                   |  41 +--
>>   gdb/dwarf2/frame-tailcall.h                   |   6 +-
>>   gdb/dwarf2/frame.c                            |  39 +--
>>   gdb/dwarf2/frame.h                            |  12 +-
>>   gdb/dwarf2/loc.c                              |  38 +--
>>   gdb/dwarf2/loc.h                              |   8 +-
>>   gdb/elfread.c                                 |   4 +-
>>   gdb/eval.c                                    |   2 +-
>>   gdb/extension-priv.h                          |   2 +-
>>   gdb/extension.c                               |   2 +-
>>   gdb/extension.h                               |   4 +-
>>   gdb/f-valprint.c                              |   2 +-
>>   gdb/findvar.c                                 |  26 +-
>>   gdb/frame-base.c                              |   8 +-
>>   gdb/frame-base.h                              |  12 +-
>>   gdb/frame-id.h                                | 135 ++++++++
>>   gdb/frame-info.h                              | 206 +++++++++++
>>   gdb/frame-unwind.c                            |  26 +-
>>   gdb/frame-unwind.h                            |  36 +-
>>   gdb/frame.c                                   | 323 +++++++++---------
>>   gdb/frame.h                                   | 278 +++++----------
>>   gdb/frv-linux-tdep.c                          |  10 +-
>>   gdb/frv-tdep.c                                |  10 +-
>>   gdb/ft32-tdep.c                               |   8 +-
>>   gdb/gcore.c                                   |   2 +-
>>   gdb/gdbarch-components.py                     |  30 +-
>>   gdb/gdbarch-gen.h                             |  60 ++--
>>   gdb/gdbarch-selftests.c                       |   2 +-
>>   gdb/gdbarch.c                                 |  30 +-
>>   gdb/gdbtypes.h                                |   5 +-
>>   gdb/gnu-v3-abi.c                              |   2 +-
>>   gdb/h8300-tdep.c                              |  12 +-
>>   gdb/hppa-bsd-tdep.c                           |   2 +-
>>   gdb/hppa-linux-tdep.c                         |   8 +-
>>   gdb/hppa-netbsd-tdep.c                        |   4 +-
>>   gdb/hppa-tdep.c                               |  32 +-
>>   gdb/hppa-tdep.h                               |   8 +-
>>   gdb/i386-bsd-tdep.c                           |   2 +-
>>   gdb/i386-darwin-tdep.c                        |   4 +-
>>   gdb/i386-darwin-tdep.h                        |   2 +-
>>   gdb/i386-fbsd-tdep.c                          |   2 +-
>>   gdb/i386-gnu-tdep.c                           |   6 +-
>>   gdb/i386-linux-tdep.c                         |  10 +-
>>   gdb/i386-netbsd-tdep.c                        |   4 +-
>>   gdb/i386-nto-tdep.c                           |   4 +-
>>   gdb/i386-obsd-tdep.c                          |  10 +-
>>   gdb/i386-sol2-tdep.c                          |   2 +-
>>   gdb/i386-tdep.c                               |  54 +--
>>   gdb/i386-tdep.h                               |  10 +-
>>   gdb/i386-windows-tdep.c                       |   2 +-
>>   gdb/i387-tdep.c                               |   6 +-
>>   gdb/i387-tdep.h                               |   8 +-
>>   gdb/ia64-libunwind-tdep.c                     |  12 +-
>>   gdb/ia64-libunwind-tdep.h                     |  12 +-
>>   gdb/ia64-tdep.c                               |  54 +--
>>   gdb/ia64-tdep.h                               |   4 +-
>>   gdb/infcall.c                                 |   4 +-
>>   gdb/infcmd.c                                  |  30 +-
>>   gdb/inferior.h                                |   6 +-
>>   gdb/infrun.c                                  |  78 +++--
>>   gdb/infrun.h                                  |   4 +-
>>   gdb/inline-frame.c                            |  14 +-
>>   gdb/inline-frame.h                            |   4 +-
>>   gdb/iq2000-tdep.c                             |  10 +-
>>   gdb/jit.c                                     |  12 +-
>>   gdb/language.c                                |   6 +-
>>   gdb/language.h                                |   8 +-
>>   gdb/lm32-tdep.c                               |   8 +-
>>   gdb/loongarch-linux-tdep.c                    |   4 +-
>>   gdb/loongarch-tdep.c                          |   8 +-
>>   gdb/loongarch-tdep.h                          |   2 +-
>>   gdb/m32c-tdep.c                               |  10 +-
>>   gdb/m32r-linux-tdep.c                         |  14 +-
>>   gdb/m32r-tdep.c                               |   8 +-
>>   gdb/m68hc11-tdep.c                            |  16 +-
>>   gdb/m68k-linux-tdep.c                         |  12 +-
>>   gdb/m68k-tdep.c                               |  18 +-
>>   gdb/m68k-tdep.h                               |   2 +-
>>   gdb/macroscope.c                              |   2 +-
>>   gdb/mep-tdep.c                                |   8 +-
>>   gdb/mi/mi-cmd-stack.c                         |  29 +-
>>   gdb/mi/mi-main.c                              |  12 +-
>>   gdb/microblaze-linux-tdep.c                   |   4 +-
>>   gdb/microblaze-tdep.c                         |  10 +-
>>   gdb/minsyms.c                                 |   2 +-
>>   gdb/mips-fbsd-tdep.c                          |   4 +-
>>   gdb/mips-linux-tdep.c                         |  22 +-
>>   gdb/mips-netbsd-tdep.c                        |   2 +-
>>   gdb/mips-sde-tdep.c                           |  12 +-
>>   gdb/mips-tdep.c                               |  96 +++---
>>   gdb/mips-tdep.h                               |   2 +-
>>   gdb/mips64-obsd-tdep.c                        |   2 +-
>>   gdb/mn10300-linux-tdep.c                      |   4 +-
>>   gdb/mn10300-tdep.c                            |   8 +-
>>   gdb/moxie-tdep.c                              |   8 +-
>>   gdb/msp430-tdep.c                             |  10 +-
>>   gdb/nds32-tdep.c                              |  20 +-
>>   gdb/nios2-linux-tdep.c                        |   4 +-
>>   gdb/nios2-tdep.c                              |  22 +-
>>   gdb/nios2-tdep.h                              |   2 +-
>>   gdb/objc-lang.c                               |  10 +-
>>   gdb/observable.h                              |   2 +-
>>   gdb/or1k-linux-tdep.c                         |   4 +-
>>   gdb/or1k-tdep.c                               |  12 +-
>>   gdb/ppc-fbsd-tdep.c                           |   8 +-
>>   gdb/ppc-linux-tdep.c                          |  12 +-
>>   gdb/ppc-netbsd-tdep.c                         |   2 +-
>>   gdb/ppc-obsd-tdep.c                           |   8 +-
>>   gdb/ppc-tdep.h                                |   4 +-
>>   gdb/ppc64-tdep.c                              |  20 +-
>>   gdb/ppc64-tdep.h                              |   4 +-
>>   gdb/printcmd.c                                |   4 +-
>>   gdb/probe.c                                   |   4 +-
>>   gdb/probe.h                                   |   4 +-
>>   gdb/python/py-event.h                         |   2 +-
>>   gdb/python/py-finishbreakpoint.c              |   6 +-
>>   gdb/python/py-frame.c                         |  44 +--
>>   gdb/python/py-framefilter.c                   |  22 +-
>>   gdb/python/py-inferior.c                      |   2 +-
>>   gdb/python/py-infevents.c                     |   4 +-
>>   gdb/python/py-symbol.c                        |   6 +-
>>   gdb/python/py-unwind.c                        |  12 +-
>>   gdb/python/python-internal.h                  |   6 +-
>>   gdb/record-btrace.c                           |  32 +-
>>   gdb/riscv-fbsd-tdep.c                         |   2 +-
>>   gdb/riscv-linux-tdep.c                        |   6 +-
>>   gdb/riscv-tdep.c                              |  12 +-
>>   gdb/riscv-tdep.h                              |   2 +-
>>   gdb/rl78-tdep.c                               |  12 +-
>>   gdb/rs6000-aix-tdep.c                         |  10 +-
>>   gdb/rs6000-tdep.c                             |  34 +-
>>   gdb/rx-tdep.c                                 |  16 +-
>>   gdb/s12z-tdep.c                               |  10 +-
>>   gdb/s390-linux-tdep.c                         |   8 +-
>>   gdb/s390-tdep.c                               |  38 +--
>>   gdb/s390-tdep.h                               |   2 +-
>>   gdb/sentinel-frame.c                          |   6 +-
>>   gdb/sh-linux-tdep.c                           |   6 +-
>>   gdb/sh-tdep.c                                 |  16 +-
>>   gdb/skip.c                                    |   2 +-
>>   gdb/sol2-tdep.c                               |   2 +-
>>   gdb/sol2-tdep.h                               |   2 +-
>>   gdb/solib-svr4.c                              |   4 +-
>>   gdb/sparc-linux-tdep.c                        |   6 +-
>>   gdb/sparc-netbsd-tdep.c                       |  12 +-
>>   gdb/sparc-obsd-tdep.c                         |   8 +-
>>   gdb/sparc-sol2-tdep.c                         |   8 +-
>>   gdb/sparc-tdep.c                              |  20 +-
>>   gdb/sparc-tdep.h                              |  12 +-
>>   gdb/sparc64-fbsd-tdep.c                       |   8 +-
>>   gdb/sparc64-linux-tdep.c                      |   8 +-
>>   gdb/sparc64-netbsd-tdep.c                     |  10 +-
>>   gdb/sparc64-obsd-tdep.c                       |  16 +-
>>   gdb/sparc64-sol2-tdep.c                       |   8 +-
>>   gdb/sparc64-tdep.c                            |  10 +-
>>   gdb/sparc64-tdep.h                            |   4 +-
>>   gdb/stack.c                                   | 119 ++++---
>>   gdb/stack.h                                   |   4 +-
>>   gdb/stap-probe.c                              |   4 +-
>>   gdb/std-regs.c                                |   8 +-
>>   gdb/symfile.h                                 |   2 +-
>>   gdb/symtab.h                                  |  10 +-
>>   .../gdb.python/pretty-print-call-by-hand.c    |  53 +++
>>   .../gdb.python/pretty-print-call-by-hand.exp  | 136 ++++++++
>>   .../gdb.python/pretty-print-call-by-hand.py   |  41 +++
>>   gdb/tic6x-linux-tdep.c                        |   4 +-
>>   gdb/tic6x-tdep.c                              |  22 +-
>>   gdb/tic6x-tdep.h                              |   2 +-
>>   gdb/tilegx-linux-tdep.c                       |   2 +-
>>   gdb/tilegx-tdep.c                             |  12 +-
>>   gdb/top.c                                     |   2 +-
>>   gdb/tracepoint.c                              |   5 +-
>>   gdb/trad-frame.c                              |  10 +-
>>   gdb/trad-frame.h                              |  10 +-
>>   gdb/tramp-frame.c                             |  10 +-
>>   gdb/tramp-frame.h                             |   6 +-
>>   gdb/tui/tui-disasm.c                          |   2 +-
>>   gdb/tui/tui-disasm.h                          |   2 +-
>>   gdb/tui/tui-hooks.c                           |   6 +-
>>   gdb/tui/tui-regs.c                            |   8 +-
>>   gdb/tui/tui-regs.h                            |   4 +-
>>   gdb/tui/tui-source.c                          |   4 +-
>>   gdb/tui/tui-source.h                          |   2 +-
>>   gdb/tui/tui-stack.c                           |   4 +-
>>   gdb/tui/tui-stack.h                           |   4 +-
>>   gdb/tui/tui-winsource.c                       |   4 +-
>>   gdb/tui/tui-winsource.h                       |   2 +-
>>   gdb/user-regs.c                               |   4 +-
>>   gdb/user-regs.h                               |   6 +-
>>   gdb/v850-tdep.c                               |  10 +-
>>   gdb/valops.c                                  |  10 +-
>>   gdb/value.c                                   |   6 +-
>>   gdb/value.h                                   |  16 +-
>>   gdb/varobj.c                                  |   8 +-
>>   gdb/vax-tdep.c                                |  14 +-
>>   gdb/xstormy16-tdep.c                          |  12 +-
>>   gdb/xtensa-tdep.c                             |  22 +-
>>   gdb/z80-tdep.c                                |   6 +-
>>   253 files changed, 2172 insertions(+), 1702 deletions(-)
>>   create mode 100644 gdb/frame-id.h
>>   create mode 100644 gdb/frame-info.h
>>   create mode 100644 
>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
>>   create mode 100644 
>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
>>   create mode 100644 
>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.py
>>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PINGv3][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-09-21 15:39   ` [PINGv2][PATCH " Bruno Larsen
@ 2022-09-29  7:01     ` Bruno Larsen
  2022-10-05  9:58       ` [PINGv4][PATCH " Bruno Larsen
  0 siblings, 1 reply; 18+ messages in thread
From: Bruno Larsen @ 2022-09-29  7:01 UTC (permalink / raw)
  To: Bruno Larsen, Bruno Larsen via Gdb-patches

Ping!

Cheers,
Bruno

On 21/09/2022 17:39, Bruno Larsen wrote:
> Ping!
>
> Cheers,
> Bruno
>
> On 13/09/2022 10:06, Bruno Larsen wrote:
>> ping
>>
>> Cheers,
>> Bruno
>>
>> On 30/08/2022 12:08, Bruno Larsen wrote:
>>> GDB occasionally gets bugs where a frame_info is kept alive across a
>>> call to reinit_frame_cache.  This causes a use-after-free and, if
>>> you're lucky, a crash.
>>>
>>> This series aims to make this setup more "reliable", in the sense that
>>> you'll always get a crash if you break the rules.  This is done by
>>> wrapping frame_info in a smart pointer class, and having
>>> reinit_frame_cache invalidate all the pointers.
>>>
>>> Tromey's original plan was that these pointers could be automatically
>>> reinflated after being invalidated, but most uses of the class would 
>>> not
>>> need to be reinflated, and setting everything up to be reinflatable
>>> would be quite expensive, as calculating a frame_id requires some
>>> unwinding.
>>>
>>> I added a prepare_reinflate method, which stashes the relevant frame_id
>>> and allows the pointer to be reinflated. However, reinflation is done
>>> manually for now because doing it when reinit_frame_cache was creating
>>> weird problems.
>>>
>>> Changelog:
>>> v3:
>>>      Reverted instrusive list changes
>>>      Guile doesn't get fancy pointers because of exceptions through 
>>> longjumps.
>>>
>>> v2:
>>>      Fix commit squashing and email threading
>>> Version 2 had some problematic squashing of commits, and I tried to add
>>> some unit tests, but those didn't work out, so I eventually dropped
>>> that.
>>>
>>> Bruno Larsen (2):
>>>    Continue making GDB use frame_info_ptr
>>>    gdb/frame: Add reinflation method for frame_info_ptr
>>>
>>> Tom Tromey (3):
>>>    Remove frame_id_eq
>>>    Introduce frame_info_ptr smart pointer class
>>>    Change GDB to use frame_info_ptr
>>>
>>>   gdb/aarch64-fbsd-tdep.c                       |   2 +-
>>>   gdb/aarch64-linux-tdep.c                      |   2 +-
>>>   gdb/aarch64-tdep.c                            |  34 +-
>>>   gdb/ada-lang.c                                |  10 +-
>>>   gdb/ada-lang.h                                |   4 +-
>>>   gdb/alpha-linux-tdep.c                        |   2 +-
>>>   gdb/alpha-mdebug-tdep.c                       |  16 +-
>>>   gdb/alpha-netbsd-tdep.c                       |   2 +-
>>>   gdb/alpha-obsd-tdep.c                         |   2 +-
>>>   gdb/alpha-tdep.c                              |  22 +-
>>>   gdb/alpha-tdep.h                              |   2 +-
>>>   gdb/amd64-darwin-tdep.c                       |   2 +-
>>>   gdb/amd64-fbsd-tdep.c                         |   2 +-
>>>   gdb/amd64-linux-tdep.c                        |   6 +-
>>>   gdb/amd64-netbsd-tdep.c                       |   4 +-
>>>   gdb/amd64-obsd-tdep.c                         |  12 +-
>>>   gdb/amd64-sol2-tdep.c                         |   2 +-
>>>   gdb/amd64-tdep.c                              |  34 +-
>>>   gdb/amd64-tdep.h                              |   2 +-
>>>   gdb/amd64-windows-tdep.c                      |  12 +-
>>>   gdb/arc-linux-tdep.c                          |   4 +-
>>>   gdb/arc-tdep.c                                |  20 +-
>>>   gdb/arc-tdep.h                                |   4 +-
>>>   gdb/arch-utils.c                              |   6 +-
>>>   gdb/arch-utils.h                              |   8 +-
>>>   gdb/arm-fbsd-tdep.c                           |   2 +-
>>>   gdb/arm-linux-tdep.c                          |  14 +-
>>>   gdb/arm-obsd-tdep.c                           |   2 +-
>>>   gdb/arm-tdep.c                                |  64 ++--
>>>   gdb/arm-tdep.h                                |   4 +-
>>>   gdb/arm-wince-tdep.c                          |   2 +-
>>>   gdb/avr-tdep.c                                |  14 +-
>>>   gdb/ax-gdb.c                                  |   2 +-
>>>   gdb/bfin-linux-tdep.c                         |   2 +-
>>>   gdb/bfin-tdep.c                               |  12 +-
>>>   gdb/blockframe.c                              |   8 +-
>>>   gdb/bpf-tdep.c                                |   8 +-
>>>   gdb/break-catch-throw.c                       |   2 +-
>>>   gdb/breakpoint.c                              |  20 +-
>>>   gdb/c-lang.c                                  |   2 +-
>>>   gdb/cli/cli-cmds.c                            |   2 +-
>>>   gdb/compile/compile-c-symbols.c               |   2 +-
>>>   gdb/compile/compile-cplus-symbols.c           |   2 +-
>>>   gdb/compile/compile-loc2c.c                   |   2 +-
>>>   gdb/cp-abi.c                                  |   2 +-
>>>   gdb/cp-abi.h                                  |   6 +-
>>>   gdb/cris-tdep.c                               |  36 +-
>>>   gdb/csky-linux-tdep.c                         |   2 +-
>>>   gdb/csky-tdep.c                               |  22 +-
>>>   gdb/defs.h                                    |   2 +-
>>>   gdb/dtrace-probe.c                            |   4 +-
>>>   gdb/dummy-frame.c                             |  12 +-
>>>   gdb/dummy-frame.h                             |   2 +-
>>>   gdb/dwarf2/expr.c                             |  20 +-
>>>   gdb/dwarf2/expr.h                             |   6 +-
>>>   gdb/dwarf2/frame-tailcall.c                   |  41 +--
>>>   gdb/dwarf2/frame-tailcall.h                   |   6 +-
>>>   gdb/dwarf2/frame.c                            |  39 +--
>>>   gdb/dwarf2/frame.h                            |  12 +-
>>>   gdb/dwarf2/loc.c                              |  38 +--
>>>   gdb/dwarf2/loc.h                              |   8 +-
>>>   gdb/elfread.c                                 |   4 +-
>>>   gdb/eval.c                                    |   2 +-
>>>   gdb/extension-priv.h                          |   2 +-
>>>   gdb/extension.c                               |   2 +-
>>>   gdb/extension.h                               |   4 +-
>>>   gdb/f-valprint.c                              |   2 +-
>>>   gdb/findvar.c                                 |  26 +-
>>>   gdb/frame-base.c                              |   8 +-
>>>   gdb/frame-base.h                              |  12 +-
>>>   gdb/frame-id.h                                | 135 ++++++++
>>>   gdb/frame-info.h                              | 206 +++++++++++
>>>   gdb/frame-unwind.c                            |  26 +-
>>>   gdb/frame-unwind.h                            |  36 +-
>>>   gdb/frame.c                                   | 323 
>>> +++++++++---------
>>>   gdb/frame.h                                   | 278 +++++----------
>>>   gdb/frv-linux-tdep.c                          |  10 +-
>>>   gdb/frv-tdep.c                                |  10 +-
>>>   gdb/ft32-tdep.c                               |   8 +-
>>>   gdb/gcore.c                                   |   2 +-
>>>   gdb/gdbarch-components.py                     |  30 +-
>>>   gdb/gdbarch-gen.h                             |  60 ++--
>>>   gdb/gdbarch-selftests.c                       |   2 +-
>>>   gdb/gdbarch.c                                 |  30 +-
>>>   gdb/gdbtypes.h                                |   5 +-
>>>   gdb/gnu-v3-abi.c                              |   2 +-
>>>   gdb/h8300-tdep.c                              |  12 +-
>>>   gdb/hppa-bsd-tdep.c                           |   2 +-
>>>   gdb/hppa-linux-tdep.c                         |   8 +-
>>>   gdb/hppa-netbsd-tdep.c                        |   4 +-
>>>   gdb/hppa-tdep.c                               |  32 +-
>>>   gdb/hppa-tdep.h                               |   8 +-
>>>   gdb/i386-bsd-tdep.c                           |   2 +-
>>>   gdb/i386-darwin-tdep.c                        |   4 +-
>>>   gdb/i386-darwin-tdep.h                        |   2 +-
>>>   gdb/i386-fbsd-tdep.c                          |   2 +-
>>>   gdb/i386-gnu-tdep.c                           |   6 +-
>>>   gdb/i386-linux-tdep.c                         |  10 +-
>>>   gdb/i386-netbsd-tdep.c                        |   4 +-
>>>   gdb/i386-nto-tdep.c                           |   4 +-
>>>   gdb/i386-obsd-tdep.c                          |  10 +-
>>>   gdb/i386-sol2-tdep.c                          |   2 +-
>>>   gdb/i386-tdep.c                               |  54 +--
>>>   gdb/i386-tdep.h                               |  10 +-
>>>   gdb/i386-windows-tdep.c                       |   2 +-
>>>   gdb/i387-tdep.c                               |   6 +-
>>>   gdb/i387-tdep.h                               |   8 +-
>>>   gdb/ia64-libunwind-tdep.c                     |  12 +-
>>>   gdb/ia64-libunwind-tdep.h                     |  12 +-
>>>   gdb/ia64-tdep.c                               |  54 +--
>>>   gdb/ia64-tdep.h                               |   4 +-
>>>   gdb/infcall.c                                 |   4 +-
>>>   gdb/infcmd.c                                  |  30 +-
>>>   gdb/inferior.h                                |   6 +-
>>>   gdb/infrun.c                                  |  78 +++--
>>>   gdb/infrun.h                                  |   4 +-
>>>   gdb/inline-frame.c                            |  14 +-
>>>   gdb/inline-frame.h                            |   4 +-
>>>   gdb/iq2000-tdep.c                             |  10 +-
>>>   gdb/jit.c                                     |  12 +-
>>>   gdb/language.c                                |   6 +-
>>>   gdb/language.h                                |   8 +-
>>>   gdb/lm32-tdep.c                               |   8 +-
>>>   gdb/loongarch-linux-tdep.c                    |   4 +-
>>>   gdb/loongarch-tdep.c                          |   8 +-
>>>   gdb/loongarch-tdep.h                          |   2 +-
>>>   gdb/m32c-tdep.c                               |  10 +-
>>>   gdb/m32r-linux-tdep.c                         |  14 +-
>>>   gdb/m32r-tdep.c                               |   8 +-
>>>   gdb/m68hc11-tdep.c                            |  16 +-
>>>   gdb/m68k-linux-tdep.c                         |  12 +-
>>>   gdb/m68k-tdep.c                               |  18 +-
>>>   gdb/m68k-tdep.h                               |   2 +-
>>>   gdb/macroscope.c                              |   2 +-
>>>   gdb/mep-tdep.c                                |   8 +-
>>>   gdb/mi/mi-cmd-stack.c                         |  29 +-
>>>   gdb/mi/mi-main.c                              |  12 +-
>>>   gdb/microblaze-linux-tdep.c                   |   4 +-
>>>   gdb/microblaze-tdep.c                         |  10 +-
>>>   gdb/minsyms.c                                 |   2 +-
>>>   gdb/mips-fbsd-tdep.c                          |   4 +-
>>>   gdb/mips-linux-tdep.c                         |  22 +-
>>>   gdb/mips-netbsd-tdep.c                        |   2 +-
>>>   gdb/mips-sde-tdep.c                           |  12 +-
>>>   gdb/mips-tdep.c                               |  96 +++---
>>>   gdb/mips-tdep.h                               |   2 +-
>>>   gdb/mips64-obsd-tdep.c                        |   2 +-
>>>   gdb/mn10300-linux-tdep.c                      |   4 +-
>>>   gdb/mn10300-tdep.c                            |   8 +-
>>>   gdb/moxie-tdep.c                              |   8 +-
>>>   gdb/msp430-tdep.c                             |  10 +-
>>>   gdb/nds32-tdep.c                              |  20 +-
>>>   gdb/nios2-linux-tdep.c                        |   4 +-
>>>   gdb/nios2-tdep.c                              |  22 +-
>>>   gdb/nios2-tdep.h                              |   2 +-
>>>   gdb/objc-lang.c                               |  10 +-
>>>   gdb/observable.h                              |   2 +-
>>>   gdb/or1k-linux-tdep.c                         |   4 +-
>>>   gdb/or1k-tdep.c                               |  12 +-
>>>   gdb/ppc-fbsd-tdep.c                           |   8 +-
>>>   gdb/ppc-linux-tdep.c                          |  12 +-
>>>   gdb/ppc-netbsd-tdep.c                         |   2 +-
>>>   gdb/ppc-obsd-tdep.c                           |   8 +-
>>>   gdb/ppc-tdep.h                                |   4 +-
>>>   gdb/ppc64-tdep.c                              |  20 +-
>>>   gdb/ppc64-tdep.h                              |   4 +-
>>>   gdb/printcmd.c                                |   4 +-
>>>   gdb/probe.c                                   |   4 +-
>>>   gdb/probe.h                                   |   4 +-
>>>   gdb/python/py-event.h                         |   2 +-
>>>   gdb/python/py-finishbreakpoint.c              |   6 +-
>>>   gdb/python/py-frame.c                         |  44 +--
>>>   gdb/python/py-framefilter.c                   |  22 +-
>>>   gdb/python/py-inferior.c                      |   2 +-
>>>   gdb/python/py-infevents.c                     |   4 +-
>>>   gdb/python/py-symbol.c                        |   6 +-
>>>   gdb/python/py-unwind.c                        |  12 +-
>>>   gdb/python/python-internal.h                  |   6 +-
>>>   gdb/record-btrace.c                           |  32 +-
>>>   gdb/riscv-fbsd-tdep.c                         |   2 +-
>>>   gdb/riscv-linux-tdep.c                        |   6 +-
>>>   gdb/riscv-tdep.c                              |  12 +-
>>>   gdb/riscv-tdep.h                              |   2 +-
>>>   gdb/rl78-tdep.c                               |  12 +-
>>>   gdb/rs6000-aix-tdep.c                         |  10 +-
>>>   gdb/rs6000-tdep.c                             |  34 +-
>>>   gdb/rx-tdep.c                                 |  16 +-
>>>   gdb/s12z-tdep.c                               |  10 +-
>>>   gdb/s390-linux-tdep.c                         |   8 +-
>>>   gdb/s390-tdep.c                               |  38 +--
>>>   gdb/s390-tdep.h                               |   2 +-
>>>   gdb/sentinel-frame.c                          |   6 +-
>>>   gdb/sh-linux-tdep.c                           |   6 +-
>>>   gdb/sh-tdep.c                                 |  16 +-
>>>   gdb/skip.c                                    |   2 +-
>>>   gdb/sol2-tdep.c                               |   2 +-
>>>   gdb/sol2-tdep.h                               |   2 +-
>>>   gdb/solib-svr4.c                              |   4 +-
>>>   gdb/sparc-linux-tdep.c                        |   6 +-
>>>   gdb/sparc-netbsd-tdep.c                       |  12 +-
>>>   gdb/sparc-obsd-tdep.c                         |   8 +-
>>>   gdb/sparc-sol2-tdep.c                         |   8 +-
>>>   gdb/sparc-tdep.c                              |  20 +-
>>>   gdb/sparc-tdep.h                              |  12 +-
>>>   gdb/sparc64-fbsd-tdep.c                       |   8 +-
>>>   gdb/sparc64-linux-tdep.c                      |   8 +-
>>>   gdb/sparc64-netbsd-tdep.c                     |  10 +-
>>>   gdb/sparc64-obsd-tdep.c                       |  16 +-
>>>   gdb/sparc64-sol2-tdep.c                       |   8 +-
>>>   gdb/sparc64-tdep.c                            |  10 +-
>>>   gdb/sparc64-tdep.h                            |   4 +-
>>>   gdb/stack.c                                   | 119 ++++---
>>>   gdb/stack.h                                   |   4 +-
>>>   gdb/stap-probe.c                              |   4 +-
>>>   gdb/std-regs.c                                |   8 +-
>>>   gdb/symfile.h                                 |   2 +-
>>>   gdb/symtab.h                                  |  10 +-
>>>   .../gdb.python/pretty-print-call-by-hand.c    |  53 +++
>>>   .../gdb.python/pretty-print-call-by-hand.exp  | 136 ++++++++
>>>   .../gdb.python/pretty-print-call-by-hand.py   |  41 +++
>>>   gdb/tic6x-linux-tdep.c                        |   4 +-
>>>   gdb/tic6x-tdep.c                              |  22 +-
>>>   gdb/tic6x-tdep.h                              |   2 +-
>>>   gdb/tilegx-linux-tdep.c                       |   2 +-
>>>   gdb/tilegx-tdep.c                             |  12 +-
>>>   gdb/top.c                                     |   2 +-
>>>   gdb/tracepoint.c                              |   5 +-
>>>   gdb/trad-frame.c                              |  10 +-
>>>   gdb/trad-frame.h                              |  10 +-
>>>   gdb/tramp-frame.c                             |  10 +-
>>>   gdb/tramp-frame.h                             |   6 +-
>>>   gdb/tui/tui-disasm.c                          |   2 +-
>>>   gdb/tui/tui-disasm.h                          |   2 +-
>>>   gdb/tui/tui-hooks.c                           |   6 +-
>>>   gdb/tui/tui-regs.c                            |   8 +-
>>>   gdb/tui/tui-regs.h                            |   4 +-
>>>   gdb/tui/tui-source.c                          |   4 +-
>>>   gdb/tui/tui-source.h                          |   2 +-
>>>   gdb/tui/tui-stack.c                           |   4 +-
>>>   gdb/tui/tui-stack.h                           |   4 +-
>>>   gdb/tui/tui-winsource.c                       |   4 +-
>>>   gdb/tui/tui-winsource.h                       |   2 +-
>>>   gdb/user-regs.c                               |   4 +-
>>>   gdb/user-regs.h                               |   6 +-
>>>   gdb/v850-tdep.c                               |  10 +-
>>>   gdb/valops.c                                  |  10 +-
>>>   gdb/value.c                                   |   6 +-
>>>   gdb/value.h                                   |  16 +-
>>>   gdb/varobj.c                                  |   8 +-
>>>   gdb/vax-tdep.c                                |  14 +-
>>>   gdb/xstormy16-tdep.c                          |  12 +-
>>>   gdb/xtensa-tdep.c                             |  22 +-
>>>   gdb/z80-tdep.c                                |   6 +-
>>>   253 files changed, 2172 insertions(+), 1702 deletions(-)
>>>   create mode 100644 gdb/frame-id.h
>>>   create mode 100644 gdb/frame-info.h
>>>   create mode 100644 
>>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
>>>   create mode 100644 
>>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
>>>   create mode 100644 
>>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.py
>>>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PINGv4][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-09-29  7:01     ` [PINGv3][PATCH " Bruno Larsen
@ 2022-10-05  9:58       ` Bruno Larsen
  2022-10-07 19:35         ` Tom Tromey
  0 siblings, 1 reply; 18+ messages in thread
From: Bruno Larsen @ 2022-10-05  9:58 UTC (permalink / raw)
  To: Bruno Larsen, Bruno Larsen via Gdb-patches

ping!

Cheers,
Bruno

On 29/09/2022 09:01, Bruno Larsen wrote:
> Ping!
>
> Cheers,
> Bruno
>
> On 21/09/2022 17:39, Bruno Larsen wrote:
>> Ping!
>>
>> Cheers,
>> Bruno
>>
>> On 13/09/2022 10:06, Bruno Larsen wrote:
>>> ping
>>>
>>> Cheers,
>>> Bruno
>>>
>>> On 30/08/2022 12:08, Bruno Larsen wrote:
>>>> GDB occasionally gets bugs where a frame_info is kept alive across a
>>>> call to reinit_frame_cache.  This causes a use-after-free and, if
>>>> you're lucky, a crash.
>>>>
>>>> This series aims to make this setup more "reliable", in the sense that
>>>> you'll always get a crash if you break the rules.  This is done by
>>>> wrapping frame_info in a smart pointer class, and having
>>>> reinit_frame_cache invalidate all the pointers.
>>>>
>>>> Tromey's original plan was that these pointers could be automatically
>>>> reinflated after being invalidated, but most uses of the class 
>>>> would not
>>>> need to be reinflated, and setting everything up to be reinflatable
>>>> would be quite expensive, as calculating a frame_id requires some
>>>> unwinding.
>>>>
>>>> I added a prepare_reinflate method, which stashes the relevant 
>>>> frame_id
>>>> and allows the pointer to be reinflated. However, reinflation is done
>>>> manually for now because doing it when reinit_frame_cache was creating
>>>> weird problems.
>>>>
>>>> Changelog:
>>>> v3:
>>>>      Reverted instrusive list changes
>>>>      Guile doesn't get fancy pointers because of exceptions through 
>>>> longjumps.
>>>>
>>>> v2:
>>>>      Fix commit squashing and email threading
>>>> Version 2 had some problematic squashing of commits, and I tried to 
>>>> add
>>>> some unit tests, but those didn't work out, so I eventually dropped
>>>> that.
>>>>
>>>> Bruno Larsen (2):
>>>>    Continue making GDB use frame_info_ptr
>>>>    gdb/frame: Add reinflation method for frame_info_ptr
>>>>
>>>> Tom Tromey (3):
>>>>    Remove frame_id_eq
>>>>    Introduce frame_info_ptr smart pointer class
>>>>    Change GDB to use frame_info_ptr
>>>>
>>>>   gdb/aarch64-fbsd-tdep.c                       |   2 +-
>>>>   gdb/aarch64-linux-tdep.c                      |   2 +-
>>>>   gdb/aarch64-tdep.c                            |  34 +-
>>>>   gdb/ada-lang.c                                |  10 +-
>>>>   gdb/ada-lang.h                                |   4 +-
>>>>   gdb/alpha-linux-tdep.c                        |   2 +-
>>>>   gdb/alpha-mdebug-tdep.c                       |  16 +-
>>>>   gdb/alpha-netbsd-tdep.c                       |   2 +-
>>>>   gdb/alpha-obsd-tdep.c                         |   2 +-
>>>>   gdb/alpha-tdep.c                              |  22 +-
>>>>   gdb/alpha-tdep.h                              |   2 +-
>>>>   gdb/amd64-darwin-tdep.c                       |   2 +-
>>>>   gdb/amd64-fbsd-tdep.c                         |   2 +-
>>>>   gdb/amd64-linux-tdep.c                        |   6 +-
>>>>   gdb/amd64-netbsd-tdep.c                       |   4 +-
>>>>   gdb/amd64-obsd-tdep.c                         |  12 +-
>>>>   gdb/amd64-sol2-tdep.c                         |   2 +-
>>>>   gdb/amd64-tdep.c                              |  34 +-
>>>>   gdb/amd64-tdep.h                              |   2 +-
>>>>   gdb/amd64-windows-tdep.c                      |  12 +-
>>>>   gdb/arc-linux-tdep.c                          |   4 +-
>>>>   gdb/arc-tdep.c                                |  20 +-
>>>>   gdb/arc-tdep.h                                |   4 +-
>>>>   gdb/arch-utils.c                              |   6 +-
>>>>   gdb/arch-utils.h                              |   8 +-
>>>>   gdb/arm-fbsd-tdep.c                           |   2 +-
>>>>   gdb/arm-linux-tdep.c                          |  14 +-
>>>>   gdb/arm-obsd-tdep.c                           |   2 +-
>>>>   gdb/arm-tdep.c                                |  64 ++--
>>>>   gdb/arm-tdep.h                                |   4 +-
>>>>   gdb/arm-wince-tdep.c                          |   2 +-
>>>>   gdb/avr-tdep.c                                |  14 +-
>>>>   gdb/ax-gdb.c                                  |   2 +-
>>>>   gdb/bfin-linux-tdep.c                         |   2 +-
>>>>   gdb/bfin-tdep.c                               |  12 +-
>>>>   gdb/blockframe.c                              |   8 +-
>>>>   gdb/bpf-tdep.c                                |   8 +-
>>>>   gdb/break-catch-throw.c                       |   2 +-
>>>>   gdb/breakpoint.c                              |  20 +-
>>>>   gdb/c-lang.c                                  |   2 +-
>>>>   gdb/cli/cli-cmds.c                            |   2 +-
>>>>   gdb/compile/compile-c-symbols.c               |   2 +-
>>>>   gdb/compile/compile-cplus-symbols.c           |   2 +-
>>>>   gdb/compile/compile-loc2c.c                   |   2 +-
>>>>   gdb/cp-abi.c                                  |   2 +-
>>>>   gdb/cp-abi.h                                  |   6 +-
>>>>   gdb/cris-tdep.c                               |  36 +-
>>>>   gdb/csky-linux-tdep.c                         |   2 +-
>>>>   gdb/csky-tdep.c                               |  22 +-
>>>>   gdb/defs.h                                    |   2 +-
>>>>   gdb/dtrace-probe.c                            |   4 +-
>>>>   gdb/dummy-frame.c                             |  12 +-
>>>>   gdb/dummy-frame.h                             |   2 +-
>>>>   gdb/dwarf2/expr.c                             |  20 +-
>>>>   gdb/dwarf2/expr.h                             |   6 +-
>>>>   gdb/dwarf2/frame-tailcall.c                   |  41 +--
>>>>   gdb/dwarf2/frame-tailcall.h                   |   6 +-
>>>>   gdb/dwarf2/frame.c                            |  39 +--
>>>>   gdb/dwarf2/frame.h                            |  12 +-
>>>>   gdb/dwarf2/loc.c                              |  38 +--
>>>>   gdb/dwarf2/loc.h                              |   8 +-
>>>>   gdb/elfread.c                                 |   4 +-
>>>>   gdb/eval.c                                    |   2 +-
>>>>   gdb/extension-priv.h                          |   2 +-
>>>>   gdb/extension.c                               |   2 +-
>>>>   gdb/extension.h                               |   4 +-
>>>>   gdb/f-valprint.c                              |   2 +-
>>>>   gdb/findvar.c                                 |  26 +-
>>>>   gdb/frame-base.c                              |   8 +-
>>>>   gdb/frame-base.h                              |  12 +-
>>>>   gdb/frame-id.h                                | 135 ++++++++
>>>>   gdb/frame-info.h                              | 206 +++++++++++
>>>>   gdb/frame-unwind.c                            |  26 +-
>>>>   gdb/frame-unwind.h                            |  36 +-
>>>>   gdb/frame.c                                   | 323 
>>>> +++++++++---------
>>>>   gdb/frame.h                                   | 278 +++++----------
>>>>   gdb/frv-linux-tdep.c                          |  10 +-
>>>>   gdb/frv-tdep.c                                |  10 +-
>>>>   gdb/ft32-tdep.c                               |   8 +-
>>>>   gdb/gcore.c                                   |   2 +-
>>>>   gdb/gdbarch-components.py                     |  30 +-
>>>>   gdb/gdbarch-gen.h                             |  60 ++--
>>>>   gdb/gdbarch-selftests.c                       |   2 +-
>>>>   gdb/gdbarch.c                                 |  30 +-
>>>>   gdb/gdbtypes.h                                |   5 +-
>>>>   gdb/gnu-v3-abi.c                              |   2 +-
>>>>   gdb/h8300-tdep.c                              |  12 +-
>>>>   gdb/hppa-bsd-tdep.c                           |   2 +-
>>>>   gdb/hppa-linux-tdep.c                         |   8 +-
>>>>   gdb/hppa-netbsd-tdep.c                        |   4 +-
>>>>   gdb/hppa-tdep.c                               |  32 +-
>>>>   gdb/hppa-tdep.h                               |   8 +-
>>>>   gdb/i386-bsd-tdep.c                           |   2 +-
>>>>   gdb/i386-darwin-tdep.c                        |   4 +-
>>>>   gdb/i386-darwin-tdep.h                        |   2 +-
>>>>   gdb/i386-fbsd-tdep.c                          |   2 +-
>>>>   gdb/i386-gnu-tdep.c                           |   6 +-
>>>>   gdb/i386-linux-tdep.c                         |  10 +-
>>>>   gdb/i386-netbsd-tdep.c                        |   4 +-
>>>>   gdb/i386-nto-tdep.c                           |   4 +-
>>>>   gdb/i386-obsd-tdep.c                          |  10 +-
>>>>   gdb/i386-sol2-tdep.c                          |   2 +-
>>>>   gdb/i386-tdep.c                               |  54 +--
>>>>   gdb/i386-tdep.h                               |  10 +-
>>>>   gdb/i386-windows-tdep.c                       |   2 +-
>>>>   gdb/i387-tdep.c                               |   6 +-
>>>>   gdb/i387-tdep.h                               |   8 +-
>>>>   gdb/ia64-libunwind-tdep.c                     |  12 +-
>>>>   gdb/ia64-libunwind-tdep.h                     |  12 +-
>>>>   gdb/ia64-tdep.c                               |  54 +--
>>>>   gdb/ia64-tdep.h                               |   4 +-
>>>>   gdb/infcall.c                                 |   4 +-
>>>>   gdb/infcmd.c                                  |  30 +-
>>>>   gdb/inferior.h                                |   6 +-
>>>>   gdb/infrun.c                                  |  78 +++--
>>>>   gdb/infrun.h                                  |   4 +-
>>>>   gdb/inline-frame.c                            |  14 +-
>>>>   gdb/inline-frame.h                            |   4 +-
>>>>   gdb/iq2000-tdep.c                             |  10 +-
>>>>   gdb/jit.c                                     |  12 +-
>>>>   gdb/language.c                                |   6 +-
>>>>   gdb/language.h                                |   8 +-
>>>>   gdb/lm32-tdep.c                               |   8 +-
>>>>   gdb/loongarch-linux-tdep.c                    |   4 +-
>>>>   gdb/loongarch-tdep.c                          |   8 +-
>>>>   gdb/loongarch-tdep.h                          |   2 +-
>>>>   gdb/m32c-tdep.c                               |  10 +-
>>>>   gdb/m32r-linux-tdep.c                         |  14 +-
>>>>   gdb/m32r-tdep.c                               |   8 +-
>>>>   gdb/m68hc11-tdep.c                            |  16 +-
>>>>   gdb/m68k-linux-tdep.c                         |  12 +-
>>>>   gdb/m68k-tdep.c                               |  18 +-
>>>>   gdb/m68k-tdep.h                               |   2 +-
>>>>   gdb/macroscope.c                              |   2 +-
>>>>   gdb/mep-tdep.c                                |   8 +-
>>>>   gdb/mi/mi-cmd-stack.c                         |  29 +-
>>>>   gdb/mi/mi-main.c                              |  12 +-
>>>>   gdb/microblaze-linux-tdep.c                   |   4 +-
>>>>   gdb/microblaze-tdep.c                         |  10 +-
>>>>   gdb/minsyms.c                                 |   2 +-
>>>>   gdb/mips-fbsd-tdep.c                          |   4 +-
>>>>   gdb/mips-linux-tdep.c                         |  22 +-
>>>>   gdb/mips-netbsd-tdep.c                        |   2 +-
>>>>   gdb/mips-sde-tdep.c                           |  12 +-
>>>>   gdb/mips-tdep.c                               |  96 +++---
>>>>   gdb/mips-tdep.h                               |   2 +-
>>>>   gdb/mips64-obsd-tdep.c                        |   2 +-
>>>>   gdb/mn10300-linux-tdep.c                      |   4 +-
>>>>   gdb/mn10300-tdep.c                            |   8 +-
>>>>   gdb/moxie-tdep.c                              |   8 +-
>>>>   gdb/msp430-tdep.c                             |  10 +-
>>>>   gdb/nds32-tdep.c                              |  20 +-
>>>>   gdb/nios2-linux-tdep.c                        |   4 +-
>>>>   gdb/nios2-tdep.c                              |  22 +-
>>>>   gdb/nios2-tdep.h                              |   2 +-
>>>>   gdb/objc-lang.c                               |  10 +-
>>>>   gdb/observable.h                              |   2 +-
>>>>   gdb/or1k-linux-tdep.c                         |   4 +-
>>>>   gdb/or1k-tdep.c                               |  12 +-
>>>>   gdb/ppc-fbsd-tdep.c                           |   8 +-
>>>>   gdb/ppc-linux-tdep.c                          |  12 +-
>>>>   gdb/ppc-netbsd-tdep.c                         |   2 +-
>>>>   gdb/ppc-obsd-tdep.c                           |   8 +-
>>>>   gdb/ppc-tdep.h                                |   4 +-
>>>>   gdb/ppc64-tdep.c                              |  20 +-
>>>>   gdb/ppc64-tdep.h                              |   4 +-
>>>>   gdb/printcmd.c                                |   4 +-
>>>>   gdb/probe.c                                   |   4 +-
>>>>   gdb/probe.h                                   |   4 +-
>>>>   gdb/python/py-event.h                         |   2 +-
>>>>   gdb/python/py-finishbreakpoint.c              |   6 +-
>>>>   gdb/python/py-frame.c                         |  44 +--
>>>>   gdb/python/py-framefilter.c                   |  22 +-
>>>>   gdb/python/py-inferior.c                      |   2 +-
>>>>   gdb/python/py-infevents.c                     |   4 +-
>>>>   gdb/python/py-symbol.c                        |   6 +-
>>>>   gdb/python/py-unwind.c                        |  12 +-
>>>>   gdb/python/python-internal.h                  |   6 +-
>>>>   gdb/record-btrace.c                           |  32 +-
>>>>   gdb/riscv-fbsd-tdep.c                         |   2 +-
>>>>   gdb/riscv-linux-tdep.c                        |   6 +-
>>>>   gdb/riscv-tdep.c                              |  12 +-
>>>>   gdb/riscv-tdep.h                              |   2 +-
>>>>   gdb/rl78-tdep.c                               |  12 +-
>>>>   gdb/rs6000-aix-tdep.c                         |  10 +-
>>>>   gdb/rs6000-tdep.c                             |  34 +-
>>>>   gdb/rx-tdep.c                                 |  16 +-
>>>>   gdb/s12z-tdep.c                               |  10 +-
>>>>   gdb/s390-linux-tdep.c                         |   8 +-
>>>>   gdb/s390-tdep.c                               |  38 +--
>>>>   gdb/s390-tdep.h                               |   2 +-
>>>>   gdb/sentinel-frame.c                          |   6 +-
>>>>   gdb/sh-linux-tdep.c                           |   6 +-
>>>>   gdb/sh-tdep.c                                 |  16 +-
>>>>   gdb/skip.c                                    |   2 +-
>>>>   gdb/sol2-tdep.c                               |   2 +-
>>>>   gdb/sol2-tdep.h                               |   2 +-
>>>>   gdb/solib-svr4.c                              |   4 +-
>>>>   gdb/sparc-linux-tdep.c                        |   6 +-
>>>>   gdb/sparc-netbsd-tdep.c                       |  12 +-
>>>>   gdb/sparc-obsd-tdep.c                         |   8 +-
>>>>   gdb/sparc-sol2-tdep.c                         |   8 +-
>>>>   gdb/sparc-tdep.c                              |  20 +-
>>>>   gdb/sparc-tdep.h                              |  12 +-
>>>>   gdb/sparc64-fbsd-tdep.c                       |   8 +-
>>>>   gdb/sparc64-linux-tdep.c                      |   8 +-
>>>>   gdb/sparc64-netbsd-tdep.c                     |  10 +-
>>>>   gdb/sparc64-obsd-tdep.c                       |  16 +-
>>>>   gdb/sparc64-sol2-tdep.c                       |   8 +-
>>>>   gdb/sparc64-tdep.c                            |  10 +-
>>>>   gdb/sparc64-tdep.h                            |   4 +-
>>>>   gdb/stack.c                                   | 119 ++++---
>>>>   gdb/stack.h                                   |   4 +-
>>>>   gdb/stap-probe.c                              |   4 +-
>>>>   gdb/std-regs.c                                |   8 +-
>>>>   gdb/symfile.h                                 |   2 +-
>>>>   gdb/symtab.h                                  |  10 +-
>>>>   .../gdb.python/pretty-print-call-by-hand.c    |  53 +++
>>>>   .../gdb.python/pretty-print-call-by-hand.exp  | 136 ++++++++
>>>>   .../gdb.python/pretty-print-call-by-hand.py   |  41 +++
>>>>   gdb/tic6x-linux-tdep.c                        |   4 +-
>>>>   gdb/tic6x-tdep.c                              |  22 +-
>>>>   gdb/tic6x-tdep.h                              |   2 +-
>>>>   gdb/tilegx-linux-tdep.c                       |   2 +-
>>>>   gdb/tilegx-tdep.c                             |  12 +-
>>>>   gdb/top.c                                     |   2 +-
>>>>   gdb/tracepoint.c                              |   5 +-
>>>>   gdb/trad-frame.c                              |  10 +-
>>>>   gdb/trad-frame.h                              |  10 +-
>>>>   gdb/tramp-frame.c                             |  10 +-
>>>>   gdb/tramp-frame.h                             |   6 +-
>>>>   gdb/tui/tui-disasm.c                          |   2 +-
>>>>   gdb/tui/tui-disasm.h                          |   2 +-
>>>>   gdb/tui/tui-hooks.c                           |   6 +-
>>>>   gdb/tui/tui-regs.c                            |   8 +-
>>>>   gdb/tui/tui-regs.h                            |   4 +-
>>>>   gdb/tui/tui-source.c                          |   4 +-
>>>>   gdb/tui/tui-source.h                          |   2 +-
>>>>   gdb/tui/tui-stack.c                           |   4 +-
>>>>   gdb/tui/tui-stack.h                           |   4 +-
>>>>   gdb/tui/tui-winsource.c                       |   4 +-
>>>>   gdb/tui/tui-winsource.h                       |   2 +-
>>>>   gdb/user-regs.c                               |   4 +-
>>>>   gdb/user-regs.h                               |   6 +-
>>>>   gdb/v850-tdep.c                               |  10 +-
>>>>   gdb/valops.c                                  |  10 +-
>>>>   gdb/value.c                                   |   6 +-
>>>>   gdb/value.h                                   |  16 +-
>>>>   gdb/varobj.c                                  |   8 +-
>>>>   gdb/vax-tdep.c                                |  14 +-
>>>>   gdb/xstormy16-tdep.c                          |  12 +-
>>>>   gdb/xtensa-tdep.c                             |  22 +-
>>>>   gdb/z80-tdep.c                                |   6 +-
>>>>   253 files changed, 2172 insertions(+), 1702 deletions(-)
>>>>   create mode 100644 gdb/frame-id.h
>>>>   create mode 100644 gdb/frame-info.h
>>>>   create mode 100644 
>>>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.c
>>>>   create mode 100644 
>>>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.exp
>>>>   create mode 100644 
>>>> gdb/testsuite/gdb.python/pretty-print-call-by-hand.py
>>>>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr
  2022-08-30 10:08 ` [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr Bruno Larsen
@ 2022-10-07 19:34   ` Tom Tromey
  2022-10-10  7:54     ` Bruno Larsen
  2022-10-11  7:58   ` Tom de Vries
  1 sibling, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2022-10-07 19:34 UTC (permalink / raw)
  To: Bruno Larsen via Gdb-patches

>>>>> "Bruno" == Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org> writes:

Bruno> +  /* Cache the frame_id that the pointer will use to reinflate.  */
Bruno> +  void prepare_reinflate ()
Bruno> +  {
Bruno> +    m_cached_id = get_frame_id(*this);

Missing space before the "(".

Bruno> +  /* Use the cached frame_id to reinflate the pointer.  */
Bruno> +  void reinflate ()
Bruno> +  {
Bruno> +    gdb_assert (m_cached_id != null_frame_id);
Bruno> +
Bruno> +    if(m_ptr == nullptr)

Here too.

Bruno> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
Bruno> index d292a0e55bf..bc171d8818a 100644
Bruno> --- a/gdb/infcmd.c
Bruno> +++ b/gdb/infcmd.c
Bruno> @@ -1814,6 +1814,7 @@ finish_command (const char *arg, int from_tty)
Bruno>    frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
Bruno>    if (frame == 0)
Bruno>      error (_("\"finish\" not meaningful in the outermost frame."));
Bruno> +  frame.prepare_reinflate ();
 
Bruno>    clear_proceed_status (0);
 
Bruno> @@ -1872,6 +1873,7 @@ finish_command (const char *arg, int from_tty)
 
Bruno>        print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
Bruno>      }
Bruno> +  frame.reinflate ();
 
I'm curious about this change.  Did you add this to avoid a crash?
I.e., it's a latent bug of some kind?

Bruno>    if (execution_direction == EXEC_REVERSE)
Bruno>      finish_backward (sm);
Bruno> diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
Bruno> index f23559f886c..2c5bd2db96d 100644
Bruno> --- a/gdb/mi/mi-cmd-stack.c
Bruno> +++ b/gdb/mi/mi-cmd-stack.c
Bruno> @@ -39,6 +39,7 @@
Bruno>  #include "inferior.h"
Bruno>  #include "observable.h"
 
Bruno> +
Bruno>  enum what_to_list { locals, arguments, all };

Spurious change.

Tom

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PINGv4][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-10-05  9:58       ` [PINGv4][PATCH " Bruno Larsen
@ 2022-10-07 19:35         ` Tom Tromey
  2022-10-10  7:55           ` Bruno Larsen
  0 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2022-10-07 19:35 UTC (permalink / raw)
  To: Bruno Larsen via Gdb-patches

>>>>> "Bruno" == Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org> writes:

Bruno> ping!

I had a couple minor nits on patch #5, but you can just fix those and
push it all without re-sending.  Thank you for doing this.

Tom

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr
  2022-10-07 19:34   ` Tom Tromey
@ 2022-10-10  7:54     ` Bruno Larsen
  0 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-10-10  7:54 UTC (permalink / raw)
  To: Tom Tromey, Bruno Larsen via Gdb-patches


On 07/10/2022 21:34, Tom Tromey wrote:
>>>>>> "Bruno" == Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org> writes:
> ...
>
> Bruno> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
> Bruno> index d292a0e55bf..bc171d8818a 100644
> Bruno> --- a/gdb/infcmd.c
> Bruno> +++ b/gdb/infcmd.c
> Bruno> @@ -1814,6 +1814,7 @@ finish_command (const char *arg, int from_tty)
> Bruno>    frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
> Bruno>    if (frame == 0)
> Bruno>      error (_("\"finish\" not meaningful in the outermost frame."));
> Bruno> +  frame.prepare_reinflate ();
>   
> Bruno>    clear_proceed_status (0);
>   
> Bruno> @@ -1872,6 +1873,7 @@ finish_command (const char *arg, int from_tty)
>   
> Bruno>        print_stack_frame (get_selected_frame (NULL), 1, LOCATION, 0);
> Bruno>      }
> Bruno> +  frame.reinflate ();
>   
> I'm curious about this change.  Did you add this to avoid a crash?
> I.e., it's a latent bug of some kind?

This is one of the triggers for bug python/28856 
(https://sourceware.org/bugzilla/show_bug.cgi?id=28856), but a quick 
recap: If one of the arguments of the function has a pretty printer that 
calls a function from the inferior, frame becomes stale and finish breaks.

That bug was the original reason I started this series, lol.

Cheers,
Bruno

>
> Bruno>    if (execution_direction == EXEC_REVERSE)
> Bruno>      finish_backward (sm);
> Bruno> diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
> Bruno> index f23559f886c..2c5bd2db96d 100644
> Bruno> --- a/gdb/mi/mi-cmd-stack.c
> Bruno> +++ b/gdb/mi/mi-cmd-stack.c
> Bruno> @@ -39,6 +39,7 @@
> Bruno>  #include "inferior.h"
> Bruno>  #include "observable.h"
>   
> Bruno> +
> Bruno>  enum what_to_list { locals, arguments, all };
>
> Spurious change.
>
> Tom
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PINGv4][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-10-07 19:35         ` Tom Tromey
@ 2022-10-10  7:55           ` Bruno Larsen
  2022-10-10 10:46             ` Tom de Vries
  0 siblings, 1 reply; 18+ messages in thread
From: Bruno Larsen @ 2022-10-10  7:55 UTC (permalink / raw)
  To: Tom Tromey, Bruno Larsen via Gdb-patches

On 07/10/2022 21:35, Tom Tromey wrote:
>>>>>> "Bruno" == Bruno Larsen via Gdb-patches <gdb-patches@sourceware.org> writes:
> Bruno> ping!
>
> I had a couple minor nits on patch #5, but you can just fix those and
> push it all without re-sending.  Thank you for doing this.
Thanks! I'll rebase it and push the series in a second

Cheers,
Bruno

> Tom
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PINGv4][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-10-10  7:55           ` Bruno Larsen
@ 2022-10-10 10:46             ` Tom de Vries
  2022-10-10 12:04               ` Bruno Larsen
  0 siblings, 1 reply; 18+ messages in thread
From: Tom de Vries @ 2022-10-10 10:46 UTC (permalink / raw)
  To: Bruno Larsen, Tom Tromey, Bruno Larsen via Gdb-patches

On 10/10/22 09:55, Bruno Larsen via Gdb-patches wrote:
> On 07/10/2022 21:35, Tom Tromey wrote:
>>>>>>> "Bruno" == Bruno Larsen via Gdb-patches 
>>>>>>> <gdb-patches@sourceware.org> writes:
>> Bruno> ping!
>>
>> I had a couple minor nits on patch #5, but you can just fix those and
>> push it all without re-sending.  Thank you for doing this.
> Thanks! I'll rebase it and push the series in a second
> 

I'm seeing a build breaker on x86_64-linux:
...
/home/vries/gdb_versions/devel/src/gdb/guile/scm-frame.c: In function 
‘int frscm_eq_frame_smob(const void*, const void*)’:
/home/vries/gdb_versions/devel/src/gdb/guile/scm-frame.c:137:11: error: 
‘frame_id_eq’ was not declared in this scope
    return (frame_id_eq (a->frame_id, b->frame_id)
            ^~~~~~~~~~~

...

Thanks,
- Tom

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PINGv4][PATCH v4 0/5] Smart pointer wrapper for frame_info
  2022-10-10 10:46             ` Tom de Vries
@ 2022-10-10 12:04               ` Bruno Larsen
  0 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-10-10 12:04 UTC (permalink / raw)
  To: Tom de Vries, Tom Tromey, Bruno Larsen via Gdb-patches


On 10/10/2022 12:46, Tom de Vries wrote:
> On 10/10/22 09:55, Bruno Larsen via Gdb-patches wrote:
>> On 07/10/2022 21:35, Tom Tromey wrote:
>>>>>>>> "Bruno" == Bruno Larsen via Gdb-patches 
>>>>>>>> <gdb-patches@sourceware.org> writes:
>>> Bruno> ping!
>>>
>>> I had a couple minor nits on patch #5, but you can just fix those and
>>> push it all without re-sending.  Thank you for doing this.
>> Thanks! I'll rebase it and push the series in a second
>>
>
> I'm seeing a build breaker on x86_64-linux:
> ...
> /home/vries/gdb_versions/devel/src/gdb/guile/scm-frame.c: In function 
> ‘int frscm_eq_frame_smob(const void*, const void*)’:
> /home/vries/gdb_versions/devel/src/gdb/guile/scm-frame.c:137:11: 
> error: ‘frame_id_eq’ was not declared in this scope
>    return (frame_id_eq (a->frame_id, b->frame_id)
>            ^~~~~~~~~~~
>
I'm looking into this. The problem is that guile uses longjumps for 
exceptions, so I tried to avoid frame_info_ptr at all in guile code, and 
this (and other issues) is what happened. The patch will not be trivial, 
unfortunately, but I'll get it on the mailing list as soon as I can.

Cheers,
Bruno

> ...
>
> Thanks,
> - Tom
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr
  2022-08-30 10:08 ` [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr Bruno Larsen
  2022-10-07 19:34   ` Tom Tromey
@ 2022-10-11  7:58   ` Tom de Vries
  2022-10-11  9:42     ` Bruno Larsen
  1 sibling, 1 reply; 18+ messages in thread
From: Tom de Vries @ 2022-10-11  7:58 UTC (permalink / raw)
  To: Bruno Larsen, gdb-patches

On 8/30/22 12:08, Bruno Larsen via Gdb-patches wrote:
>   .../gdb.python/pretty-print-call-by-hand.py   |  41 ++++++

I think it was already mentioned on  IRC, but in case you missed it, 
this caused the python black formatter to fail : 
https://builder.sourceware.org/buildbot/#/builders/74/builds/1337 .

Thanks,
- Tom

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr
  2022-10-11  7:58   ` Tom de Vries
@ 2022-10-11  9:42     ` Bruno Larsen
  0 siblings, 0 replies; 18+ messages in thread
From: Bruno Larsen @ 2022-10-11  9:42 UTC (permalink / raw)
  To: Tom de Vries, gdb-patches


On 11/10/2022 09:58, Tom de Vries wrote:
> On 8/30/22 12:08, Bruno Larsen via Gdb-patches wrote:
>> .../gdb.python/pretty-print-call-by-hand.py   |  41 ++++++
>
> I think it was already mentioned on  IRC, but in case you missed it, 
> this caused the python black formatter to fail : 
> https://builder.sourceware.org/buildbot/#/builders/74/builds/1337 .
Thanks for the heads up! I just pushed an obvious fix for this!

Cheers,
Bruno

>
> Thanks,
> - Tom
>


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2022-10-11  9:42 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-30 10:08 [PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
2022-08-30 10:08 ` [PATCH v4 1/5] Remove frame_id_eq Bruno Larsen
2022-08-30 10:08 ` [PATCH v4 2/5] Introduce frame_info_ptr smart pointer class Bruno Larsen
2022-08-30 10:08 ` [PATCH v4 3/5] Change GDB to use frame_info_ptr Bruno Larsen
2022-08-30 10:08 ` [PATCH v4 4/5] Continue making GDB " Bruno Larsen
2022-08-30 10:08 ` [PATCH v4 5/5] gdb/frame: Add reinflation method for frame_info_ptr Bruno Larsen
2022-10-07 19:34   ` Tom Tromey
2022-10-10  7:54     ` Bruno Larsen
2022-10-11  7:58   ` Tom de Vries
2022-10-11  9:42     ` Bruno Larsen
2022-09-13  8:06 ` [Ping][PATCH v4 0/5] Smart pointer wrapper for frame_info Bruno Larsen
2022-09-21 15:39   ` [PINGv2][PATCH " Bruno Larsen
2022-09-29  7:01     ` [PINGv3][PATCH " Bruno Larsen
2022-10-05  9:58       ` [PINGv4][PATCH " Bruno Larsen
2022-10-07 19:35         ` Tom Tromey
2022-10-10  7:55           ` Bruno Larsen
2022-10-10 10:46             ` Tom de Vries
2022-10-10 12:04               ` Bruno Larsen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).