Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Jun 2019 16:56:56 +0000 (UTC)
From:      Olivier Houchard <cognet@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r349426 - head/sys/arm64/arm64
Message-ID:  <201906261656.x5QGuuwS061820@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: cognet
Date: Wed Jun 26 16:56:56 2019
New Revision: 349426
URL: https://svnweb.freebsd.org/changeset/base/349426

Log:
  Fix debugging of 32bits arm binaries on arm64.
  
  In set_regs32()/fill_regs32(), we have to get/set SP and LR from/to
  tf_x[13] and tf_x[14].
  set_regs() and fill_regs() may be called for a 32bits process, if the process
  is ptrace'd from a 64bits debugger. So, in set_regs() and fill_regs(), get
  or set PC and SPSR from where the debugger expects it, from tf_x[15] and
  tf_x[16].

Modified:
  head/sys/arm64/arm64/machdep.c

Modified: head/sys/arm64/arm64/machdep.c
==============================================================================
--- head/sys/arm64/arm64/machdep.c	Wed Jun 26 16:38:46 2019	(r349425)
+++ head/sys/arm64/arm64/machdep.c	Wed Jun 26 16:56:56 2019	(r349426)
@@ -194,6 +194,16 @@ fill_regs(struct thread *td, struct reg *regs)
 
 	memcpy(regs->x, frame->tf_x, sizeof(regs->x));
 
+#ifdef COMPAT_FREEBSD32
+	/*
+	 * We may be called here for a 32bits process, if we're using a
+	 * 64bits debugger. If so, put PC and SPSR where it expects it.
+	 */
+	if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+		regs->x[15] = frame->tf_elr;
+		regs->x[16] = frame->tf_spsr;
+	}
+#endif
 	return (0);
 }
 
@@ -211,6 +221,17 @@ set_regs(struct thread *td, struct reg *regs)
 
 	memcpy(frame->tf_x, regs->x, sizeof(frame->tf_x));
 
+#ifdef COMPAT_FREEBSD32
+	if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) {
+		/*
+		 * We may be called for a 32bits process if we're using
+		 * a 64bits debugger. If so, get PC and SPSR from where
+		 * it put it.
+		 */
+		frame->tf_elr = regs->x[15];
+		frame->tf_spsr = regs->x[16] & PSR_FLAGS;
+	}
+#endif
 	return (0);
 }
 
@@ -283,8 +304,9 @@ fill_regs32(struct thread *td, struct reg32 *regs)
 	tf = td->td_frame;
 	for (i = 0; i < 13; i++)
 		regs->r[i] = tf->tf_x[i];
-	regs->r_sp = tf->tf_sp;
-	regs->r_lr = tf->tf_lr;
+	/* For arm32, SP is r13 and LR is r14 */
+	regs->r_sp = tf->tf_x[13];
+	regs->r_lr = tf->tf_x[14];
 	regs->r_pc = tf->tf_elr;
 	regs->r_cpsr = tf->tf_spsr;
 
@@ -300,8 +322,9 @@ set_regs32(struct thread *td, struct reg32 *regs)
 	tf = td->td_frame;
 	for (i = 0; i < 13; i++)
 		tf->tf_x[i] = regs->r[i];
-	tf->tf_sp = regs->r_sp;
-	tf->tf_lr = regs->r_lr;
+	/* For arm 32, SP is r13 an LR is r14 */
+	tf->tf_x[13] = regs->r_sp;
+	tf->tf_x[14] = regs->r_lr;
 	tf->tf_elr = regs->r_pc;
 	tf->tf_spsr = regs->r_cpsr;
 



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