Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Nov 2019 16:46:28 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354709 - in head/sys/arm: arm conf
Message-ID:  <201911141646.xAEGkSSw064195@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Thu Nov 14 16:46:27 2019
New Revision: 354709
URL: https://svnweb.freebsd.org/changeset/base/354709

Log:
  Rewrite arm/stack_machdep.c for EABI; add stack(9) support to arm kernels.
  
  The old stack_machdep.c code was written for the APCS ABI (aka "oldabi").
  When we switched to ARM EABI (back in freebsd 10) this file never got
  updated, and apparently nobody noticed that until now.
  
  The new implementation uses the same stack unwinder code used by the
  arm implemenation of the db_trace stuff.

Modified:
  head/sys/arm/arm/stack_machdep.c
  head/sys/arm/conf/std.armv6
  head/sys/arm/conf/std.armv7

Modified: head/sys/arm/arm/stack_machdep.c
==============================================================================
--- head/sys/arm/arm/stack_machdep.c	Thu Nov 14 16:28:02 2019	(r354708)
+++ head/sys/arm/arm/stack_machdep.c	Thu Nov 14 16:46:27 2019	(r354709)
@@ -1,8 +1,7 @@
 /*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2005 Antoine Brodin
- * All rights reserved.
+ * Copyright (c) 2019 Ian Lepore <ian@freebsd.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,63 +28,64 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
-#include <sys/param.h>
+#include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/stack.h>
-
-#include <machine/vmparam.h>
 #include <machine/pcb.h>
 #include <machine/stack.h>
 
-/*
- * This code makes assumptions about the stack layout. These are correct
- * when using APCS (the old ABI), but are no longer true with AAPCS and the
- * ARM EABI. There is also an issue with clang and llvm when building for
- * APCS where it lays out the stack incorrectly. Because of this we disable
- * this when building for ARM EABI or when building with clang.
- */
+static void
+stack_capture(struct stack *st, struct unwind_state *state)
+{
 
-extern vm_offset_t kernel_vm_end;
+	stack_zero(st);
+	while (unwind_stack_one(state, 1) == 0) {
+		if (stack_put(st, state->registers[PC]) == -1)
+			break;
+	}
+}
 
-static void
-stack_capture(struct stack *st, u_int32_t *frame)
+void
+stack_save(struct stack *st)
 {
+	struct unwind_state state;
+	uint32_t sp;
+
+	/* Read the stack pointer */
+	__asm __volatile("mov %0, sp" : "=&r" (sp));
+
+	state.registers[FP] = (uint32_t)__builtin_frame_address(0);
+	state.registers[SP] = sp;
+	state.registers[LR] = (uint32_t)__builtin_return_address(0);
+	state.registers[PC] = (uint32_t)stack_save;
+
+	stack_capture(st, &state);
 }
 
 void
 stack_save_td(struct stack *st, struct thread *td)
 {
-	u_int32_t *frame;
+	struct unwind_state state;
 
-	if (TD_IS_SWAPPED(td))
-		panic("stack_save_td: swapped");
-	if (TD_IS_RUNNING(td))
-		panic("stack_save_td: running");
+	KASSERT(!TD_IS_SWAPPED(td), ("stack_save_td: swapped"));
+	KASSERT(!TD_IS_RUNNING(td), ("stack_save_td: running"));
 
-	/*
-	 * This register, the frame pointer, is incorrect for the ARM EABI
-	 * as it doesn't have a frame pointer, however it's value is not used
-	 * when building for EABI.
-	 */
-	frame = (u_int32_t *)td->td_pcb->pcb_regs.sf_r11;
-	stack_zero(st);
-	stack_capture(st, frame);
+	state.registers[FP] = td->td_pcb->pcb_regs.sf_r11;
+	state.registers[SP] = td->td_pcb->pcb_regs.sf_sp;
+	state.registers[LR] = td->td_pcb->pcb_regs.sf_lr;
+	state.registers[PC] = td->td_pcb->pcb_regs.sf_pc;
+
+	stack_capture(st, &state);
 }
 
 int
 stack_save_td_running(struct stack *st, struct thread *td)
 {
 
+	if (td == curthread) {
+		stack_save(st);
+		return (0);
+	}
 	return (EOPNOTSUPP);
-}
-
-void
-stack_save(struct stack *st)
-{
-	u_int32_t *frame;
-
-	frame = (u_int32_t *)__builtin_frame_address(0);
-	stack_zero(st);
-	stack_capture(st, frame);
 }

Modified: head/sys/arm/conf/std.armv6
==============================================================================
--- head/sys/arm/conf/std.armv6	Thu Nov 14 16:28:02 2019	(r354708)
+++ head/sys/arm/conf/std.armv6	Thu Nov 14 16:46:27 2019	(r354709)
@@ -34,6 +34,7 @@ options 	GEOM_LABEL		# Provides labelization
 options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
 options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
 options 	KTRACE			# ktrace(1) support
+options 	STACK			# stack(9) support
 options 	SYSVSHM			# SYSV-style shared memory
 options 	SYSVMSG			# SYSV-style message queues
 options 	SYSVSEM			# SYSV-style semaphores

Modified: head/sys/arm/conf/std.armv7
==============================================================================
--- head/sys/arm/conf/std.armv7	Thu Nov 14 16:28:02 2019	(r354708)
+++ head/sys/arm/conf/std.armv7	Thu Nov 14 16:46:27 2019	(r354709)
@@ -34,6 +34,7 @@ options 	GEOM_LABEL		# Provides labelization
 options 	COMPAT_43		# Compatible with BSD 4.3 [KEEP THIS!]
 options 	SCSI_DELAY=5000		# Delay (in ms) before probing SCSI
 options 	KTRACE			# ktrace(1) support
+options 	STACK			# stack(9) support
 options 	SYSVSHM			# SYSV-style shared memory
 options 	SYSVMSG			# SYSV-style message queues
 options 	SYSVSEM			# SYSV-style semaphores



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