Patchwork [PATCHv3,1/4] gdb: Add a default_unwind_pc method for gdbarch

login
register
mail settings
Submitter Andrew Burgess
Date June 5, 2018, 2:34 p.m.
Message ID <463a868d5e73934c24a0cf36e2f2e6363ea2679a.1528206468.git.andrew.burgess@embecosm.com>
Download mbox | patch
Permalink /patch/27628/
State New
Headers show

Comments

Andrew Burgess - June 5, 2018, 2:34 p.m.
Many architectures gdbarch unwind_pc method follow the same pattern.
Provide a default method and convert targets to use it where possible.

gdb/ChangeLog:

	* aarch64-tdep.c (aarch64_unwind_pc): Deleted.
	(aarch64_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* alpha-tdep.c (alpha_unwind_pc): Deleted.
	(alpha_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* bfin-tdep.c (bfin_unwind_pc): Deleted.
	(bfin_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* cris-tdep.c (cris_unwind_pc): Deleted.
	(cris_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* frame-unwind.c (default_unwind_pc): New function.
	* frame-unwind.h (default_unwind_pc): Declare new function.
	* frame.c: Remove use of gdbarch_unwind_pc_p and reindent.
	* frv-tdep.c (frv_unwind_pc): Deleted.
	(frv_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* ft32-tdep.c (ft32_unwind_pc): Deleted.
	(ft32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* gdbarch.c: Regenerate.
	* gdbarch.h: Regenerate.
	* gdbarch.sh: Update unwind_pc spec, and add new header file to be
	included.
	* h8300-tdep.c (h8300_unwind_pc): Deleted.
	(h8300_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* iq2000-tdep.c (iq2000_unwind_pc): Deleted.
	(iq2000_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* lm32-tdep.c (lm32_unwind_pc): Deleted.
	(lm32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* m32r-tdep.c (m32r_unwind_pc): Deleted.
	(m32r_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* m68hc11-tdep.c (m68hc11_unwind_pc): Deleted.
	(m68hc11_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* mep-tdep.c (mep_unwind_pc): Deleted.
	(mep_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* mn10300-tdep.c (mn10300_unwind_pc): Deleted.
	(mn10300_frame_unwind_init): Delete use of set_gdbarch_unwind_pc.
	* moxie-tdep.c (moxie_unwind_pc): Deleted.
	(moxie_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* msp430-tdep.c (msp430_unwind_pc): Deleted.
	(msp430_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* nds32-tdep.c (nds32_unwind_pc): Deleted.
	(nds32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* riscv-tdep.c (riscv_unwind_pc): Deleted.
	(riscv_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* rs6000-tdep.c (rs6000_unwind_pc): Deleted.
	(rs6000_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* rx-tdep.c (rx_unwind_pc): Deleted.
	(rx_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* score-tdep.c (score_unwind_pc): Deleted.
	(score_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* sh-tdep.c (sh_unwind_pc): Deleted.
	(sh_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* sparc-tdep.c (sparc_unwind_pc): Deleted.
	(sparc32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* tilegx-tdep.c (tilegx_unwind_pc): Deleted.
	(tilegx_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* v850-tdep.c (v850_unwind_pc): Deleted.
	(v850_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* vax-tdep.c (vax_unwind_pc): Deleted.
	(vax_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
	* xstormy16-tdep.c (xstormy16_unwind_pc): Deleted.
	(xstormy16_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
---
 gdb/ChangeLog        |  62 +++++++++++++++++++++++++++
 gdb/aarch64-tdep.c   |  12 ------
 gdb/alpha-tdep.c     |  11 -----
 gdb/bfin-tdep.c      |   7 ---
 gdb/cris-tdep.c      |  13 ------
 gdb/frame-unwind.c   |   9 ++++
 gdb/frame-unwind.h   |   6 +++
 gdb/frame.c          | 117 ++++++++++++++++++++++++---------------------------
 gdb/frv-tdep.c       |   7 ---
 gdb/ft32-tdep.c      |  10 -----
 gdb/gdbarch.c        |  14 ++----
 gdb/gdbarch.h        |   2 -
 gdb/gdbarch.sh       |   3 +-
 gdb/h8300-tdep.c     |   7 ---
 gdb/iq2000-tdep.c    |   7 ---
 gdb/lm32-tdep.c      |   7 ---
 gdb/m32r-tdep.c      |  11 -----
 gdb/m68hc11-tdep.c   |  14 ------
 gdb/mep-tdep.c       |   9 ----
 gdb/mn10300-tdep.c   |  10 -----
 gdb/moxie-tdep.c     |  10 -----
 gdb/msp430-tdep.c    |   9 ----
 gdb/nds32-tdep.c     |   9 ----
 gdb/riscv-tdep.c     |   9 ----
 gdb/rs6000-tdep.c    |   9 ----
 gdb/rx-tdep.c        |  11 -----
 gdb/score-tdep.c     |   7 ---
 gdb/sh-tdep.c        |   8 ----
 gdb/sparc-tdep.c     |   9 ----
 gdb/tilegx-tdep.c    |   7 ---
 gdb/v850-tdep.c      |   8 ----
 gdb/vax-tdep.c       |   8 ----
 gdb/xstormy16-tdep.c |   7 ---
 33 files changed, 138 insertions(+), 311 deletions(-)

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f77cb67271c..9d316fbce98 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,65 @@ 
+2018-06-05  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* aarch64-tdep.c (aarch64_unwind_pc): Deleted.
+	(aarch64_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* alpha-tdep.c (alpha_unwind_pc): Deleted.
+	(alpha_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* bfin-tdep.c (bfin_unwind_pc): Deleted.
+	(bfin_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* cris-tdep.c (cris_unwind_pc): Deleted.
+	(cris_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* frame-unwind.c (default_unwind_pc): New function.
+	* frame-unwind.h (default_unwind_pc): Declare new function.
+	* frame.c: Remove use of gdbarch_unwind_pc_p and reindent.
+	* frv-tdep.c (frv_unwind_pc): Deleted.
+	(frv_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* ft32-tdep.c (ft32_unwind_pc): Deleted.
+	(ft32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* gdbarch.c: Regenerate.
+	* gdbarch.h: Regenerate.
+	* gdbarch.sh: Update unwind_pc spec, and add new header file to be
+	included.
+	* h8300-tdep.c (h8300_unwind_pc): Deleted.
+	(h8300_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* iq2000-tdep.c (iq2000_unwind_pc): Deleted.
+	(iq2000_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* lm32-tdep.c (lm32_unwind_pc): Deleted.
+	(lm32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* m32r-tdep.c (m32r_unwind_pc): Deleted.
+	(m32r_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* m68hc11-tdep.c (m68hc11_unwind_pc): Deleted.
+	(m68hc11_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* mep-tdep.c (mep_unwind_pc): Deleted.
+	(mep_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* mn10300-tdep.c (mn10300_unwind_pc): Deleted.
+	(mn10300_frame_unwind_init): Delete use of set_gdbarch_unwind_pc.
+	* moxie-tdep.c (moxie_unwind_pc): Deleted.
+	(moxie_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* msp430-tdep.c (msp430_unwind_pc): Deleted.
+	(msp430_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* nds32-tdep.c (nds32_unwind_pc): Deleted.
+	(nds32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* riscv-tdep.c (riscv_unwind_pc): Deleted.
+	(riscv_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* rs6000-tdep.c (rs6000_unwind_pc): Deleted.
+	(rs6000_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* rx-tdep.c (rx_unwind_pc): Deleted.
+	(rx_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* score-tdep.c (score_unwind_pc): Deleted.
+	(score_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* sh-tdep.c (sh_unwind_pc): Deleted.
+	(sh_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* sparc-tdep.c (sparc_unwind_pc): Deleted.
+	(sparc32_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* tilegx-tdep.c (tilegx_unwind_pc): Deleted.
+	(tilegx_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* v850-tdep.c (v850_unwind_pc): Deleted.
+	(v850_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* vax-tdep.c (vax_unwind_pc): Deleted.
+	(vax_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+	* xstormy16-tdep.c (xstormy16_unwind_pc): Deleted.
+	(xstormy16_gdbarch_init): Delete use of set_gdbarch_unwind_pc.
+
 2018-06-04  Tom Tromey  <tom@tromey.com>
 
 	* ada-lang.h (ada_lookup_symbol_list): Update.
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index c6b1e2a9a3c..1d837ec4771 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1014,17 +1014,6 @@  aarch64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 			 get_frame_pc (this_frame));
 }
 
-/* Implement the "unwind_pc" gdbarch method.  */
-
-static CORE_ADDR
-aarch64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  CORE_ADDR pc
-    = frame_unwind_register_unsigned (this_frame, AARCH64_PC_REGNUM);
-
-  return pc;
-}
-
 /* Implement the "unwind_sp" gdbarch method.  */
 
 static CORE_ADDR
@@ -2952,7 +2941,6 @@  aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Frame handling.  */
   set_gdbarch_dummy_id (gdbarch, aarch64_dummy_id);
-  set_gdbarch_unwind_pc (gdbarch, aarch64_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, aarch64_unwind_sp);
 
   /* Advance PC across function entry code.  */
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 53943e1d77a..26b7e34ad23 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -1477,14 +1477,6 @@  alpha_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
   return frame_id_build (base, get_frame_pc (this_frame));
 }
 
-static CORE_ADDR
-alpha_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  ULONGEST pc;
-  pc = frame_unwind_register_unsigned (next_frame, ALPHA_PC_REGNUM);
-  return pc;
-}
-
 
 /* Helper routines for alpha*-nat.c files to move register sets to and
    from core files.  The UNIQUE pointer is allowed to be NULL, as most
@@ -1809,9 +1801,6 @@  alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Methods for saving / extracting a dummy frame's ID.  */
   set_gdbarch_dummy_id (gdbarch, alpha_dummy_id);
 
-  /* Return the unwound PC value.  */
-  set_gdbarch_unwind_pc (gdbarch, alpha_unwind_pc);
-
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index da62130231b..b60dd00dbb5 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -766,12 +766,6 @@  bfin_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
   return frame_id_build (sp, get_frame_pc (this_frame));
 }
 
-static CORE_ADDR
-bfin_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, BFIN_PC_REGNUM);
-}
-
 static CORE_ADDR
 bfin_frame_align (struct gdbarch *gdbarch, CORE_ADDR address)
 {
@@ -836,7 +830,6 @@  bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_sw_breakpoint_from_kind (gdbarch, bfin_sw_breakpoint_from_kind);
   set_gdbarch_decr_pc_after_break (gdbarch, 2);
   set_gdbarch_frame_args_skip (gdbarch, 8);
-  set_gdbarch_unwind_pc (gdbarch, bfin_unwind_pc);
   set_gdbarch_frame_align (gdbarch, bfin_frame_align);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index e0371a2a282..d86d9830b8d 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -651,9 +651,6 @@  static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc,
 					struct frame_info *this_frame,
 					struct cris_unwind_cache *info);
 
-static CORE_ADDR cris_unwind_pc (struct gdbarch *gdbarch, 
-				 struct frame_info *next_frame);
-
 static CORE_ADDR cris_unwind_sp (struct gdbarch *gdbarch, 
 				 struct frame_info *next_frame);
 
@@ -1373,15 +1370,6 @@  cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   return pc_after_prologue;
 }
 
-static CORE_ADDR
-cris_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  ULONGEST pc;
-  pc = frame_unwind_register_unsigned (next_frame,
-				       gdbarch_pc_regnum (gdbarch));
-  return pc;
-}
-
 static CORE_ADDR
 cris_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
@@ -4096,7 +4084,6 @@  cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_breakpoint_kind_from_pc (gdbarch, cris_breakpoint_kind_from_pc);
   set_gdbarch_sw_breakpoint_from_kind (gdbarch, cris_sw_breakpoint_from_kind);
   
-  set_gdbarch_unwind_pc (gdbarch, cris_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, cris_unwind_sp);
   set_gdbarch_dummy_id (gdbarch, cris_dummy_id);
 
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index e6e63539ad7..0eed572ebbb 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -193,6 +193,15 @@  default_frame_unwind_stop_reason (struct frame_info *this_frame,
     return UNWIND_NO_REASON;
 }
 
+/* Default unwind of the PC.  */
+
+CORE_ADDR
+default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  int pc_regnum = gdbarch_pc_regnum (gdbarch);
+  return frame_unwind_register_unsigned (next_frame, pc_regnum);
+}
+
 /* Helper functions for value-based register unwinding.  These return
    a (possibly lazy) value of the appropriate type.  */
 
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index af220f72a01..4dfc7bedcc6 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -70,6 +70,12 @@  enum unwind_stop_reason
   default_frame_unwind_stop_reason (struct frame_info *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);
+
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    use THIS frame, and through it the NEXT frame's register unwind
    method, to determine the frame ID of THIS frame.
diff --git a/gdb/frame.c b/gdb/frame.c
index 89f48aea696..7796cd265d3 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -872,76 +872,71 @@  frame_unwind_pc (struct frame_info *this_frame)
 {
   if (this_frame->prev_pc.status == CC_UNKNOWN)
     {
-      if (gdbarch_unwind_pc_p (frame_unwind_arch (this_frame)))
+      struct gdbarch *prev_gdbarch;
+      CORE_ADDR pc = 0;
+      int pc_p = 0;
+
+      /* The right way.  The `pure' way.  The one true way.  This
+	 method depends solely on the register-unwind code to
+	 determine the value of registers in THIS frame, and hence
+	 the value of this frame's PC (resume address).  A typical
+	 implementation is no more than:
+
+	 frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
+	 return extract_unsigned_integer (buf, size of ISA_PC_REGNUM);
+
+	 Note: this method is very heavily dependent on a correct
+	 register-unwind implementation, it pays to fix that
+	 method first; this method is frame type agnostic, since
+	 it only deals with register values, it works with any
+	 frame.  This is all in stark contrast to the old
+	 FRAME_SAVED_PC which would try to directly handle all the
+	 different ways that a PC could be unwound.  */
+      prev_gdbarch = frame_unwind_arch (this_frame);
+
+      TRY
 	{
-	  struct gdbarch *prev_gdbarch;
-	  CORE_ADDR pc = 0;
-	  int pc_p = 0;
-
-	  /* The right way.  The `pure' way.  The one true way.  This
-	     method depends solely on the register-unwind code to
-	     determine the value of registers in THIS frame, and hence
-	     the value of this frame's PC (resume address).  A typical
-	     implementation is no more than:
-	   
-	     frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
-	     return extract_unsigned_integer (buf, size of ISA_PC_REGNUM);
-
-	     Note: this method is very heavily dependent on a correct
-	     register-unwind implementation, it pays to fix that
-	     method first; this method is frame type agnostic, since
-	     it only deals with register values, it works with any
-	     frame.  This is all in stark contrast to the old
-	     FRAME_SAVED_PC which would try to directly handle all the
-	     different ways that a PC could be unwound.  */
-	  prev_gdbarch = frame_unwind_arch (this_frame);
-
-	  TRY
+	  pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
+	  pc_p = 1;
+	}
+      CATCH (ex, RETURN_MASK_ERROR)
+	{
+	  if (ex.error == NOT_AVAILABLE_ERROR)
 	    {
-	      pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
-	      pc_p = 1;
+	      this_frame->prev_pc.status = CC_UNAVAILABLE;
+
+	      if (frame_debug)
+		fprintf_unfiltered (gdb_stdlog,
+				    "{ frame_unwind_pc (this_frame=%d)"
+				    " -> <unavailable> }\n",
+				    this_frame->level);
 	    }
-	  CATCH (ex, RETURN_MASK_ERROR)
+	  else if (ex.error == OPTIMIZED_OUT_ERROR)
 	    {
-	      if (ex.error == NOT_AVAILABLE_ERROR)
-		{
-		  this_frame->prev_pc.status = CC_UNAVAILABLE;
-
-		  if (frame_debug)
-		    fprintf_unfiltered (gdb_stdlog,
-					"{ frame_unwind_pc (this_frame=%d)"
-					" -> <unavailable> }\n",
-					this_frame->level);
-		}
-	      else if (ex.error == OPTIMIZED_OUT_ERROR)
-		{
-		  this_frame->prev_pc.status = CC_NOT_SAVED;
-
-		  if (frame_debug)
-		    fprintf_unfiltered (gdb_stdlog,
-					"{ frame_unwind_pc (this_frame=%d)"
-					" -> <not saved> }\n",
-					this_frame->level);
-		}
-	      else
-		throw_exception (ex);
-	    }
-	  END_CATCH
+	      this_frame->prev_pc.status = CC_NOT_SAVED;
 
-	  if (pc_p)
-	    {
-	      this_frame->prev_pc.value = pc;
-	      this_frame->prev_pc.status = CC_VALUE;
 	      if (frame_debug)
 		fprintf_unfiltered (gdb_stdlog,
-				    "{ frame_unwind_pc (this_frame=%d) "
-				    "-> %s }\n",
-				    this_frame->level,
-				    hex_string (this_frame->prev_pc.value));
+				    "{ frame_unwind_pc (this_frame=%d)"
+				    " -> <not saved> }\n",
+				    this_frame->level);
 	    }
+	  else
+	    throw_exception (ex);
+	}
+      END_CATCH
+
+      if (pc_p)
+	{
+	  this_frame->prev_pc.value = pc;
+	  this_frame->prev_pc.status = CC_VALUE;
+	  if (frame_debug)
+	    fprintf_unfiltered (gdb_stdlog,
+				"{ frame_unwind_pc (this_frame=%d) "
+				"-> %s }\n",
+				this_frame->level,
+				hex_string (this_frame->prev_pc.value));
 	}
-      else
-	internal_error (__FILE__, __LINE__, _("No unwind_pc method"));
     }
 
   if (this_frame->prev_pc.status == CC_VALUE)
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index 1eed441f2b3..8170bf94fdb 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -1366,12 +1366,6 @@  frv_return_value (struct gdbarch *gdbarch, struct value *function,
     return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
-static CORE_ADDR
-frv_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, pc_regnum);
-}
-
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 
@@ -1539,7 +1533,6 @@  frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_return_value (gdbarch, frv_return_value);
 
   /* Frame stuff.  */
-  set_gdbarch_unwind_pc (gdbarch, frv_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, frv_unwind_sp);
   set_gdbarch_frame_align (gdbarch, frv_frame_align);
   frame_base_set_default (gdbarch, &frv_frame_base);
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index 7198b84aca0..5c0a3384dbd 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -492,14 +492,6 @@  ft32_frame_cache (struct frame_info *this_frame, void **this_cache)
   return cache;
 }
 
-/* Implement the "unwind_pc" gdbarch method.  */
-
-static CORE_ADDR
-ft32_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, FT32_PC_REGNUM);
-}
-
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 
@@ -627,8 +619,6 @@  ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
   set_gdbarch_dummy_id (gdbarch, ft32_dummy_id);
 
-  set_gdbarch_unwind_pc (gdbarch, ft32_unwind_pc);
-
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 558cc555b4b..dcd2d59f16c 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -48,6 +48,7 @@ 
 #include "regcache.h"
 #include "objfiles.h"
 #include "auxv.h"
+#include "frame-unwind.h"
 
 /* Static function declarations */
 
@@ -426,6 +427,7 @@  gdbarch_alloc (const struct gdbarch_info *info,
   gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
   gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
   gdbarch->remote_register_number = default_remote_register_number;
+  gdbarch->unwind_pc = default_unwind_pc;
   gdbarch->stabs_argument_has_addr = default_stabs_argument_has_addr;
   gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
   gdbarch->addr_bits_remove = core_addr_identity;
@@ -608,7 +610,7 @@  verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of remote_register_number, invalid_p == 0 */
   /* Skip verify of fetch_tls_load_module_address, has predicate.  */
   /* Skip verify of frame_args_skip, invalid_p == 0 */
-  /* Skip verify of unwind_pc, has predicate.  */
+  /* Skip verify of unwind_pc, invalid_p == 0 */
   /* Skip verify of unwind_sp, has predicate.  */
   /* Skip verify of frame_num_args, has predicate.  */
   /* Skip verify of frame_align, has predicate.  */
@@ -1435,9 +1437,6 @@  gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                       "gdbarch_dump: type_align = <%s>\n",
                       host_address_to_string (gdbarch->type_align));
-  fprintf_unfiltered (file,
-                      "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n",
-                      gdbarch_unwind_pc_p (gdbarch));
   fprintf_unfiltered (file,
                       "gdbarch_dump: unwind_pc = <%s>\n",
                       host_address_to_string (gdbarch->unwind_pc));
@@ -3041,13 +3040,6 @@  set_gdbarch_frame_args_skip (struct gdbarch *gdbarch,
   gdbarch->frame_args_skip = frame_args_skip;
 }
 
-int
-gdbarch_unwind_pc_p (struct gdbarch *gdbarch)
-{
-  gdb_assert (gdbarch != NULL);
-  return gdbarch->unwind_pc != NULL;
-}
-
 CORE_ADDR
 gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 09edcd5eb28..c71974f2b36 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -620,8 +620,6 @@  extern void set_gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch,
 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);
 
-extern int gdbarch_unwind_pc_p (struct gdbarch *gdbarch);
-
 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);
 extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 0a23b1ee0e7..19aaa4200d2 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -596,7 +596,7 @@  m;int;remote_register_number;int regno;regno;;default_remote_register_number;;0
 F;CORE_ADDR;fetch_tls_load_module_address;struct objfile *objfile;objfile
 #
 v;CORE_ADDR;frame_args_skip;;;0;;;0
-M;CORE_ADDR;unwind_pc;struct frame_info *next_frame;next_frame
+m;CORE_ADDR;unwind_pc;struct frame_info *next_frame;next_frame;;default_unwind_pc;;0
 M;CORE_ADDR;unwind_sp;struct frame_info *next_frame;next_frame
 # DEPRECATED_FRAME_LOCALS_ADDRESS as been replaced by the per-frame
 # frame-base.  Enable frame-base before frame-unwind.
@@ -1657,6 +1657,7 @@  cat <<EOF
 #include "regcache.h"
 #include "objfiles.h"
 #include "auxv.h"
+#include "frame-unwind.h"
 
 /* Static function declarations */
 
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index 65d33620c6a..48137ed02a0 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -92,12 +92,6 @@  static int is_h8300_normal_mode (struct gdbarch *gdbarch);
 		  && !is_h8300_normal_mode (gdbarch)) \
 		 ? h8300h_reg_size : h8300_reg_size)
 
-static CORE_ADDR
-h8300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
-}
-
 static CORE_ADDR
 h8300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
@@ -1353,7 +1347,6 @@  h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue);
 
   /* Frame unwinder.  */
-  set_gdbarch_unwind_pc (gdbarch, h8300_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, h8300_unwind_sp);
   set_gdbarch_dummy_id (gdbarch, h8300_dummy_id);
   frame_base_set_default (gdbarch, &h8300_frame_base);
diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c
index 9f7f35d287c..74fefdab374 100644
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -440,12 +440,6 @@  iq2000_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
 }   
 
-static CORE_ADDR
-iq2000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
-}
-
 static struct frame_id
 iq2000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
@@ -841,7 +835,6 @@  iq2000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_register_type (gdbarch, iq2000_register_type);
   set_gdbarch_frame_align (gdbarch, iq2000_frame_align);
   set_gdbarch_unwind_sp (gdbarch, iq2000_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, iq2000_unwind_pc);
   set_gdbarch_dummy_id (gdbarch, iq2000_dummy_id);
   frame_base_set_default (gdbarch, &iq2000_frame_base);
   set_gdbarch_push_dummy_call (gdbarch, iq2000_push_dummy_call);
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index 942852140d7..26f2faee365 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -382,12 +382,6 @@  lm32_return_value (struct gdbarch *gdbarch, struct value *function,
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
-static CORE_ADDR
-lm32_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, SIM_LM32_PC_REGNUM);
-}
-
 static CORE_ADDR
 lm32_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
@@ -551,7 +545,6 @@  lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Frame unwinding.  */
   set_gdbarch_frame_align (gdbarch, lm32_frame_align);
   frame_base_set_default (gdbarch, &lm32_frame_base);
-  set_gdbarch_unwind_pc (gdbarch, lm32_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, lm32_unwind_sp);
   set_gdbarch_dummy_id (gdbarch, lm32_dummy_id);
   frame_unwind_append_unwinder (gdbarch, &lm32_frame_unwind);
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index fd79f3f4cde..9bfff6b0675 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -798,14 +798,6 @@  m32r_return_value (struct gdbarch *gdbarch, struct value *function,
     }
 }
 
-
-
-static CORE_ADDR
-m32r_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, M32R_PC_REGNUM);
-}
-
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 
@@ -933,9 +925,6 @@  m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
   set_gdbarch_dummy_id (gdbarch, m32r_dummy_id);
 
-  /* Return the unwound PC value.  */
-  set_gdbarch_unwind_pc (gdbarch, m32r_unwind_pc);
-
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 1490ee28668..52dc118e622 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -757,16 +757,6 @@  m68hc11_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   return pc;
 }
 
-static CORE_ADDR
-m68hc11_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  ULONGEST pc;
-
-  pc = frame_unwind_register_unsigned (next_frame,
-				       gdbarch_pc_regnum (gdbarch));
-  return pc;
-}
-
 /* Put here the code to store, into fi->saved_regs, the addresses of
    the saved registers of frame described by FRAME_INFO.  This
    includes special registers such as pc and fp saved in special ways
@@ -1491,7 +1481,6 @@  m68hc11_gdbarch_init (struct gdbarch_info info,
   /* Characters are unsigned.  */
   set_gdbarch_char_signed (gdbarch, 0);
 
-  set_gdbarch_unwind_pc (gdbarch, m68hc11_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, m68hc11_unwind_sp);
 
   /* Set register info.  */
@@ -1528,9 +1517,6 @@  m68hc11_gdbarch_init (struct gdbarch_info info,
      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
   set_gdbarch_dummy_id (gdbarch, m68hc11_dummy_id);
 
-  /* Return the unwound PC value.  */
-  set_gdbarch_unwind_pc (gdbarch, m68hc11_unwind_pc);
-
   /* Minsymbol frobbing.  */
   set_gdbarch_elf_make_msymbol_special (gdbarch,
                                         m68hc11_elf_make_msymbol_special);
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index c8a5ecfbe07..0f205988680 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -2063,14 +2063,6 @@  static const struct frame_unwind mep_frame_unwind = {
 };
 
 
-/* Our general unwinding function can handle unwinding the PC.  */
-static CORE_ADDR
-mep_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, MEP_PC_REGNUM);
-}
-
-
 /* Our general unwinding function can handle unwinding the SP.  */
 static CORE_ADDR
 mep_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
@@ -2463,7 +2455,6 @@  mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Frames and frame unwinding.  */
   frame_unwind_append_unwinder (gdbarch, &mep_frame_unwind);
-  set_gdbarch_unwind_pc (gdbarch, mep_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, mep_unwind_sp);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_frame_args_skip (gdbarch, 0);
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index edc99a2faba..8b72c287ab4 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -1149,15 +1149,6 @@  static const struct frame_unwind mn10300_frame_unwind = {
   default_frame_sniffer
 };
 
-static CORE_ADDR
-mn10300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  ULONGEST pc;
-
-  pc = frame_unwind_register_unsigned (this_frame, E_PC_REGNUM);
-  return pc;
-}
-
 static CORE_ADDR
 mn10300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
@@ -1173,7 +1164,6 @@  mn10300_frame_unwind_init (struct gdbarch *gdbarch)
   dwarf2_append_unwinders (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &mn10300_frame_unwind);
   set_gdbarch_dummy_id (gdbarch, mn10300_dummy_id);
-  set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp);
 }
 
diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
index 078ff391e0b..515357c8ea3 100644
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -556,14 +556,6 @@  moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
   return cache;
 }
 
-/* Implement the "unwind_pc" gdbarch method.  */
-
-static CORE_ADDR
-moxie_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, MOXIE_PC_REGNUM);
-}
-
 /* Given a GDB frame, determine the address of the calling function's
    frame.  This will be used to create a new GDB frame struct.  */
 
@@ -1114,8 +1106,6 @@  moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
   set_gdbarch_dummy_id (gdbarch, moxie_dummy_id);
 
-  set_gdbarch_unwind_pc (gdbarch, moxie_unwind_pc);
-
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index b6e062a380f..2e30a648de2 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -447,14 +447,6 @@  msp430_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   return p.prologue_end;
 }
 
-/* Implement the "unwind_pc" gdbarch method.  */
-
-static CORE_ADDR
-msp430_unwind_pc (struct gdbarch *arch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, MSP430_PC_REGNUM);
-}
-
 /* Implement the "unwind_sp" gdbarch method.  */
 
 static CORE_ADDR
@@ -995,7 +987,6 @@  msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Frames, prologues, etc.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_skip_prologue (gdbarch, msp430_skip_prologue);
-  set_gdbarch_unwind_pc (gdbarch, msp430_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, msp430_unwind_sp);
   set_gdbarch_frame_align (gdbarch, msp430_frame_align);
   dwarf2_append_unwinders (gdbarch);
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index b616cc9b2ce..59cdacdad82 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -1398,14 +1398,6 @@  nds32_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
   return frame_id_build (sp, get_frame_pc (this_frame));
 }
 
-/* Implement the "unwind_pc" gdbarch method.  */
-
-static CORE_ADDR
-nds32_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, NDS32_PC_REGNUM);
-}
-
 /* Implement the "unwind_sp" gdbarch method.  */
 
 static CORE_ADDR
@@ -2139,7 +2131,6 @@  nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_sp_regnum (gdbarch, NDS32_SP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, NDS32_PC_REGNUM);
   set_gdbarch_unwind_sp (gdbarch, nds32_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, nds32_unwind_pc);
   set_gdbarch_stack_frame_destroyed_p (gdbarch, nds32_stack_frame_destroyed_p);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, nds32_dwarf2_reg_to_regnum);
 
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 154567136eb..c732f2cbe27 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -2322,14 +2322,6 @@  riscv_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
   return align_down (addr, 16);
 }
 
-/* Implement the unwind_pc gdbarch method.  */
-
-static CORE_ADDR
-riscv_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, RISCV_PC_REGNUM);
-}
-
 /* Implement the unwind_sp gdbarch method.  */
 
 static CORE_ADDR
@@ -2544,7 +2536,6 @@  riscv_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_frame_align (gdbarch, riscv_frame_align);
 
   /* Functions to access frame data.  */
-  set_gdbarch_unwind_pc (gdbarch, riscv_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, riscv_unwind_sp);
 
   /* Functions handling dummy frames.  */
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index a0f290f61b8..cf884b7f34f 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -3098,13 +3098,6 @@  find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
 }
 
 
-static CORE_ADDR
-rs6000_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame,
-					 gdbarch_pc_regnum (gdbarch));
-}
-
 static struct frame_id
 rs6000_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
@@ -6425,7 +6418,6 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     case GDB_OSABI_LINUX:
     case GDB_OSABI_NETBSD:
     case GDB_OSABI_UNKNOWN:
-      set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
       set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
@@ -6434,7 +6426,6 @@  rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     default:
       set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
-      set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
       frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind);
       frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind);
       set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id);
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index 94d57913a31..3d982795db4 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -751,16 +751,6 @@  static const struct frame_unwind rx_exception_unwind = {
   rx_exception_sniffer
 };
 
-/* Implement the "unwind_pc" gdbarch method.  */
-static CORE_ADDR
-rx_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  ULONGEST pc;
-
-  pc = frame_unwind_register_unsigned (this_frame, RX_PC_REGNUM);
-  return pc;
-}
-
 /* Implement the "unwind_sp" gdbarch method.  */
 static CORE_ADDR
 rx_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
@@ -1110,7 +1100,6 @@  rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_sw_breakpoint_from_kind (gdbarch, rx_breakpoint::bp_from_kind);
   set_gdbarch_skip_prologue (gdbarch, rx_skip_prologue);
 
-  set_gdbarch_unwind_pc (gdbarch, rx_unwind_pc);
   set_gdbarch_unwind_sp (gdbarch, rx_unwind_sp);
 
   /* Target builtin data types.  */
diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c
index 16bf00ea024..e47d7ce18fa 100644
--- a/gdb/score-tdep.c
+++ b/gdb/score-tdep.c
@@ -70,12 +70,6 @@  score_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return frame_unwind_register_unsigned (next_frame, SCORE_SP_REGNUM);
 }
 
-static CORE_ADDR
-score_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, SCORE_PC_REGNUM);
-}
-
 static const char *
 score7_register_name (struct gdbarch *gdbarch, int regnum)
 {
@@ -1480,7 +1474,6 @@  score_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_frame_align (gdbarch, score_frame_align);
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_unwind_sp (gdbarch, score_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, score_unwind_pc);
 
   switch (target_mach)
     {
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index d1a143414df..6dd7e575e64 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1982,13 +1982,6 @@  sh_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 					 gdbarch_sp_regnum (gdbarch));
 }
 
-static CORE_ADDR
-sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame,
-					 gdbarch_pc_regnum (gdbarch));
-}
-
 static struct frame_id
 sh_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
@@ -2306,7 +2299,6 @@  sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_frame_align (gdbarch, sh_frame_align);
   set_gdbarch_unwind_sp (gdbarch, sh_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, sh_unwind_pc);
   set_gdbarch_dummy_id (gdbarch, sh_dummy_id);
   frame_base_set_default (gdbarch, &sh_frame_base);
 
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 65c1f006204..985fe13a1b5 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1111,13 +1111,6 @@  sparc_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
   return pc;
 }
 
-static CORE_ADDR
-sparc_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  return frame_unwind_register_unsigned (this_frame, tdep->pc_regnum);
-}
-
 /* Return PC of first real instruction of the function starting at
    START_PC.  */
 
@@ -1877,8 +1870,6 @@  sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_dummy_id (gdbarch, sparc_dummy_id);
 
-  set_gdbarch_unwind_pc (gdbarch, sparc_unwind_pc);
-
   frame_base_set_default (gdbarch, &sparc32_frame_base);
 
   /* Hook in the DWARF CFI frame unwinder.  */
diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c
index 9ed696630eb..5885f60dbca 100644
--- a/gdb/tilegx-tdep.c
+++ b/gdb/tilegx-tdep.c
@@ -936,12 +936,6 @@  tilegx_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return frame_unwind_register_unsigned (next_frame, TILEGX_SP_REGNUM);
 }
 
-static CORE_ADDR
-tilegx_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, TILEGX_PC_REGNUM);
-}
-
 static struct frame_id
 tilegx_unwind_dummy_id (struct gdbarch *gdbarch,
 			struct frame_info *this_frame)
@@ -1028,7 +1022,6 @@  tilegx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Frame Info.  */
   set_gdbarch_unwind_sp (gdbarch, tilegx_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, tilegx_unwind_pc);
   set_gdbarch_dummy_id (gdbarch, tilegx_unwind_dummy_id);
   set_gdbarch_frame_align (gdbarch, tilegx_frame_align);
   frame_base_set_default (gdbarch, &tilegx_frame_base);
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
index 2a3812d6c08..0f08c64f1d1 100644
--- a/gdb/v850-tdep.c
+++ b/gdb/v850-tdep.c
@@ -1333,13 +1333,6 @@  v850_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
 					 gdbarch_sp_regnum (gdbarch));
 } 
 
-static CORE_ADDR
-v850_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame,
-					 gdbarch_pc_regnum (gdbarch));
-}
-
 static struct frame_id
 v850_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
@@ -1465,7 +1458,6 @@  v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_frame_align (gdbarch, v850_frame_align);
   set_gdbarch_unwind_sp (gdbarch, v850_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, v850_unwind_pc);
   set_gdbarch_dummy_id (gdbarch, v850_dummy_id);
   frame_base_set_default (gdbarch, &v850_frame_base);
 
diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c
index d07a4779076..28c86db76cf 100644
--- a/gdb/vax-tdep.c
+++ b/gdb/vax-tdep.c
@@ -435,12 +435,6 @@  vax_frame_num_args (struct frame_info *frame)
   args = get_frame_register_unsigned (frame, VAX_AP_REGNUM);
   return get_frame_memory_unsigned (frame, args, 1);
 }
-
-static CORE_ADDR
-vax_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, VAX_PC_REGNUM);
-}
 
 
 /* Initialize the current architecture based on INFO.  If possible, re-use an
@@ -501,8 +495,6 @@  vax_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_deprecated_function_start_offset (gdbarch, 2);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
 
-  set_gdbarch_unwind_pc (gdbarch, vax_unwind_pc);
-
   frame_base_set_default (gdbarch, &vax_frame_base);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index b80d23e142d..45369cdf56a 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -757,12 +757,6 @@  xstormy16_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return frame_unwind_register_unsigned (next_frame, E_SP_REGNUM);
 }
 
-static CORE_ADDR
-xstormy16_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
-  return frame_unwind_register_unsigned (next_frame, E_PC_REGNUM);
-}
-
 static struct frame_id
 xstormy16_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 {
@@ -825,7 +819,6 @@  xstormy16_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
    * Frame Info
    */
   set_gdbarch_unwind_sp (gdbarch, xstormy16_unwind_sp);
-  set_gdbarch_unwind_pc (gdbarch, xstormy16_unwind_pc);
   set_gdbarch_dummy_id (gdbarch, xstormy16_dummy_id);
   set_gdbarch_frame_align (gdbarch, xstormy16_frame_align);
   frame_base_set_default (gdbarch, &xstormy16_frame_base);