Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Feb 2010 07:34:38 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r204109 - head/sys/mips/mips
Message-ID:  <201002200734.o1K7Ycbs037179@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Sat Feb 20 07:34:37 2010
New Revision: 204109
URL: http://svn.freebsd.org/changeset/base/204109

Log:
  Fix DDB backtrace that includes a kernel exception frame.
  
  The backtrace code tries to look for an instruction of the form "sw ra, x(sp)"
  to figure out the program counter of the calling function. When we generate
  the kernel exception frame we store the 'ra' at the time of the exception
  using an instruction of the same form. The problem is that the 'ra' at the
  time of the exception is not the same as the 'program counter' at the time
  of the exception.
  
  The fix is to save the 'exception program counter' register by staging
  it through the 'ra' register.

Modified:
  head/sys/mips/mips/exception.S

Modified: head/sys/mips/mips/exception.S
==============================================================================
--- head/sys/mips/mips/exception.S	Sat Feb 20 06:39:14 2010	(r204108)
+++ head/sys/mips/mips/exception.S	Sat Feb 20 07:34:37 2010	(r204109)
@@ -275,6 +275,15 @@ SlowFault:
 	mtc0	a0, COP_0_STATUS_REG
 #endif
 	
+/*
+ * Save CPU and CP0 register state.
+ *
+ * This is straightforward except for saving the exception program
+ * counter. The ddb backtrace code looks for the first instruction
+ * matching the form "sw ra, (off)sp" to figure out the address of the
+ * calling function. So we must make sure that we save the exception
+ * PC by staging it through 'ra' as opposed to any other register.
+ */
 #define	SAVE_CPU \
 	SAVE_REG(AT, AST, sp)		;\
 	.set	at		        ; \
@@ -314,9 +323,12 @@ SlowFault:
 	SAVE_REG(v1, MULHI, sp)		;\
 	SAVE_REG(a0, SR, sp)		;\
 	SAVE_REG(a1, CAUSE, sp)		;\
-	SAVE_REG(ra, RA, sp)		;\
 	SAVE_REG(a2, BADVADDR, sp)	;\
-	SAVE_REG(a3, PC, sp)		;\
+	move	t0, ra			;\
+	move	ra, a3			;\
+	SAVE_REG(ra, PC, sp)		;\
+	move	ra, t0			;\
+	SAVE_REG(ra, RA, sp)		;\
 	PTR_ADDU v0, sp, KERN_EXC_FRAME_SIZE ;\
 	SAVE_REG(v0, SP, sp)		;\
 	CLEAR_STATUS			;\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002200734.o1K7Ycbs037179>