svn commit: r315270 - in head/sys: arm/include dev/hwpmc

Fabien Thomas fabient at FreeBSD.org
Tue Mar 14 16:06:58 UTC 2017


Author: fabient
Date: Tue Mar 14 16:06:57 2017
New Revision: 315270
URL: https://svnweb.freebsd.org/changeset/base/315270

Log:
  Fix arm stack frame walking support:
  - Adjust stack offset for Clang
  - Correctly fill registers for fake stack frame (soft PMC)
  
  MFC after:	1 week
  Sponsored by:	Stormshield
  Differential Revision:	https://reviews.freebsd.org/D7396

Modified:
  head/sys/arm/include/pmc_mdep.h
  head/sys/dev/hwpmc/hwpmc_arm.c

Modified: head/sys/arm/include/pmc_mdep.h
==============================================================================
--- head/sys/arm/include/pmc_mdep.h	Tue Mar 14 16:01:36 2017	(r315269)
+++ head/sys/arm/include/pmc_mdep.h	Tue Mar 14 16:06:57 2017	(r315270)
@@ -70,7 +70,9 @@ union pmc_md_pmc {
 /* Build a fake kernel trapframe from current instruction pointer. */
 #define PMC_FAKE_TRAPFRAME(TF)						\
 	do {								\
+	(TF)->tf_spsr = PSR_SVC32_MODE;					\
 	__asm __volatile("mov %0, pc" : "=r" ((TF)->tf_pc));		\
+	__asm __volatile("mov %0, r11" : "=r" ((TF)->tf_r11));		\
 	} while (0)
 
 /*

Modified: head/sys/dev/hwpmc/hwpmc_arm.c
==============================================================================
--- head/sys/dev/hwpmc/hwpmc_arm.c	Tue Mar 14 16:01:36 2017	(r315269)
+++ head/sys/dev/hwpmc/hwpmc_arm.c	Tue Mar 14 16:06:57 2017	(r315270)
@@ -42,6 +42,17 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
 
+/* XXX: Userland code compiled with gcc will need an heuristic
+ * to be correctly detected. 
+ */
+#ifdef __clang__
+#define PC_OFF 1
+#define FP_OFF 0
+#else
+#define PC_OFF -1
+#define FP_OFF -3
+#endif
+
 struct pmc_mdep *
 pmc_md_initialize()
 {
@@ -100,7 +111,7 @@ pmc_save_kernel_callchain(uintptr_t *cc,
 
 	for (count = 1; count < maxsamples; count++) {
 		/* Use saved lr as pc. */
-		r = fp - sizeof(uintptr_t);
+		r = fp + PC_OFF * sizeof(uintptr_t);
 		if (!PMC_IN_KERNEL_STACK(r, stackstart, stackend))
 			break;
 		pc = *(uintptr_t *)r;
@@ -110,7 +121,7 @@ pmc_save_kernel_callchain(uintptr_t *cc,
 		*cc++ = pc;
 
 		/* Switch to next frame up */
-		r = fp - 3 * sizeof(uintptr_t);
+		r = fp + FP_OFF * sizeof(uintptr_t);
 		if (!PMC_IN_KERNEL_STACK(r, stackstart, stackend))
 			break;
 		fp = *(uintptr_t *)r;
@@ -147,7 +158,7 @@ pmc_save_user_callchain(uintptr_t *cc, i
 
 	for (count = 1; count < maxsamples; count++) {
 		/* Use saved lr as pc. */
-		r = fp - sizeof(uintptr_t);
+		r = fp + PC_OFF * sizeof(uintptr_t);
 		if (copyin((void *)r, &pc, sizeof(pc)) != 0)
 			break;
 		if (!PMC_IN_USERSPACE(pc))
@@ -157,7 +168,7 @@ pmc_save_user_callchain(uintptr_t *cc, i
 
 		/* Switch to next frame up */
 		oldfp = fp;
-		r = fp - 3 * sizeof(uintptr_t);
+		r = fp + FP_OFF * sizeof(uintptr_t);
 		if (copyin((void *)r, &fp, sizeof(fp)) != 0)
 			break;
 		if (fp < oldfp || !PMC_IN_USERSPACE(fp))


More information about the svn-src-head mailing list