NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-mips/59327: user stack pointer is not aligned properly



Here's a draft to add automatic tests on aarch64, amd64, alpha, and
mips, with WIP on hppa, for whether the stack is appropriately aligned
on various entry points to userland.  alpha and mips fail a lot of
these tests.  More work to be done, just sharing this now in case you
want to try it out.
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1745077373 0
#      Sat Apr 19 15:42:53 2025 +0000
# Branch trunk
# Node ID a15ce6172f14912aed11abf8edfd050b30aab9be
# Parent  b752b098d2ee168dcb79a215c54e8ec0ed634f09
# EXP-Topic riastradh-pr59327-stackalign
WIP: h_execregs: Properly request to statically link this.

Adding -static to LDFLAGS doesn't work because we end up passing
various other flags that cause it to come out as a dynamic executable
anyway, which would crash on SIGSEGV early at startup -- except that
the entry point exits before calling the normal start routine, so by
accident it works.

XXX cite the PR

diff -r b752b098d2ee -r a15ce6172f14 tests/kernel/Makefile
--- a/tests/kernel/Makefile	Fri Apr 18 02:16:16 2025 +0000
+++ b/tests/kernel/Makefile	Sat Apr 19 15:42:53 2025 +0000
@@ -142,7 +142,8 @@ CPPFLAGS.t_execregs.c+=	-I${.CURDIR}/../
 CPPFLAGS.t_execregs.c+=	-DHAVE_EXECREGS_TEST
 SRCS.t_execregs+=	t_execregs.c
 SRCS.t_execregs+=	execregs.c
-LDFLAGS.h_execregs+=	-static -Wl,-e,execregs_start
+LDSTATIC.h_execregs=	-static
+LDFLAGS.h_execregs+=	-Wl,-e,execregs_start
 .else
 SRCS.h_execregs=	h_execregs_unimpl.c
 .endif
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1745073355 0
#      Sat Apr 19 14:35:55 2025 +0000
# Branch trunk
# Node ID d7ffc903763d7fcf264ee539e89b315b081d289d
# Parent  a15ce6172f14912aed11abf8edfd050b30aab9be
# EXP-Topic riastradh-pr59327-stackalign
Test stack pointer alignment in various scenarios.

1. elf entry point
2. main function
3. signal handler

This extends the test that was previously written for:

PR kern/58149: aarch64: Cannot return from a signal handler if SP was
misaligned when the signal arrived

With any luck, this will help us to systematically eradicate misaligned
stack pointers as hypothesized in:

PR port-mips/59236: Multiple segfaults in erlite3 boot

diff -r a15ce6172f14 -r d7ffc903763d distrib/sets/lists/debug/mi
--- a/distrib/sets/lists/debug/mi	Sat Apr 19 15:42:53 2025 +0000
+++ b/distrib/sets/lists/debug/mi	Sat Apr 19 14:35:55 2025 +0000
@@ -1775,6 +1775,8 @@
 ./usr/libdata/debug/usr/tests/kernel/arch/i386/t_ptrace_waitpid.debug	tests-obsolete		obsolete,compattestfile
 ./usr/libdata/debug/usr/tests/kernel/h_cloexec.debug			tests-kernel-tests	debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/kernel/h_execregs.debug			tests-kernel-tests	debug,atf,compattestfile
+./usr/libdata/debug/usr/tests/kernel/h_execsp_dynamic.debug		tests-kernel-tests	debug,atf,compattestfile
+./usr/libdata/debug/usr/tests/kernel/h_execsp_static.debug		tests-kernel-tests	debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/kernel/h_fexecve.debug			tests-kernel-tests	debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/kernel/h_fpufork.debug			tests-kernel-tests	debug,atf,compattestfile
 ./usr/libdata/debug/usr/tests/kernel/h_getprocpath.debug		tests-kernel-tests	debug,atf,compattestfile
diff -r a15ce6172f14 -r d7ffc903763d distrib/sets/lists/tests/mi
--- a/distrib/sets/lists/tests/mi	Sat Apr 19 15:42:53 2025 +0000
+++ b/distrib/sets/lists/tests/mi	Sat Apr 19 14:35:55 2025 +0000
@@ -2271,6 +2271,8 @@
 ./usr/tests/kernel/arch/x86				tests-obsolete		obsolete
 ./usr/tests/kernel/h_cloexec				tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/h_execregs				tests-kernel-tests	compattestfile,atf
+./usr/tests/kernel/h_execsp_dynamic			tests-kernel-tests	compattestfile,atf
+./usr/tests/kernel/h_execsp_static			tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/h_fexecve				tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/h_fpufork				tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/h_getprocpath			tests-kernel-tests	compattestfile,atf
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/Makefile
--- a/tests/kernel/Makefile	Sat Apr 19 15:42:53 2025 +0000
+++ b/tests/kernel/Makefile	Sat Apr 19 14:35:55 2025 +0000
@@ -53,6 +53,8 @@ TESTS_SH+=	t_umount
 BINDIR=		${TESTSDIR}
 PROGS+=		h_cloexec
 PROGS+=		h_execregs
+PROGS+=		h_execsp_dynamic
+PROGS+=		h_execsp_static
 PROGS+=		h_fexecve
 PROGS+=		h_fpufork
 PROGS+=		h_getprocpath
@@ -93,11 +95,32 @@ LDADD.t_timeleft+=	-lpthread
 CPPFLAGS+=	-D_KERNTYPES
 CPPFLAGS.t_unmount.c+=	-D_KMEMUSER -D__EXPOSE_MOUNT
 
-ARCH_INCS_DIR:=	${.PARSEDIR}/arch/${MACHINE_ARCH}
-.if exists(${ARCH_INCS_DIR}/stack_pointer.h)
-CPPFLAGS+=	-I${ARCH_INCS_DIR} -DHAVE_STACK_POINTER_H
+ARCHDIR:=		${.PARSEDIR}/arch/${MACHINE_ARCH}
+.PATH:			${ARCHDIR}
+
+.if exists(${ARCHDIR}/stack_pointer.h)
+CPPFLAGS.t_signal_and_sp.c+=	-I${ARCHDIR} -DHAVE_STACK_POINTER_H
+.endif
+
+SRCS.t_signal_and_sp+=		t_signal_and_sp.c
+.if exists(${ARCHDIR}/signalsphandler.S)
+CPPFLAGS.t_signal_and_sp.c+=	-DHAVE_SIGNALSPHANDLER
+SRCS.t_signal_and_sp+=		signalsphandler.S
 .endif
 
+SRCS.h_execsp_dynamic+=		h_execsp.c
+SRCS.h_execsp_static+=		h_execsp.c
+.if exists(${ARCHDIR}/execsp.S)
+CPPFLAGS.t_signal_and_sp.c+=	-DHAVE_EXECSP
+SRCS.h_execsp_dynamic+=		execsp.S
+SRCS.h_execsp_static+=		execsp.S
+LDFLAGS.h_execsp_dynamic+=	-Wl,-e,execsp_start
+LDFLAGS.h_execsp_static+=	-Wl,-e,execsp_start
+.else
+CPPFLAGS.h_execsp.c+=		-Dexecsp_main=main
+.endif
+LDSTATIC.h_execsp_static=	-static
+
 .PATH:			${NETBSDSRCDIR}/sys/kern
 TESTS_C+=		t_extent
 SRCS.t_extent=		t_extent.c subr_extent.c
@@ -135,8 +158,6 @@ CLEANFILES+=	t_subr_prf.c
 LDADD.h_segv+=	-lm
 
 .if exists(arch/${MACHINE_ARCH}/execregs.h)
-ARCHDIR:=		${.PARSEDIR}/arch/${MACHINE_ARCH}
-.PATH:			${ARCHDIR}
 CPPFLAGS.t_execregs.c+=	-I${ARCHDIR}
 CPPFLAGS.t_execregs.c+=	-I${.CURDIR}/../lib/libc/gen # isqemu.h
 CPPFLAGS.t_execregs.c+=	-DHAVE_EXECREGS_TEST
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/arch/aarch64/execsp.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/aarch64/execsp.S	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,60 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+/*
+ * void execsp_start(void (*cleanup@x0)(void), void *obj_main@x1,
+ *     struct ps_strings *ps_strings@x2)
+ *
+ *	ELF entry point.  Saves the stack pointer in startsp and defers
+ *	to the usual csu __start routine.
+ */
+ENTRY(execsp_start)
+	mov	x16, sp
+	adrp	x17, :pg_hi21:_C_LABEL(startsp)
+	str	x16, [x17, #:lo12:_C_LABEL(startsp)]
+	b	_C_LABEL(__start)
+END(execsp_start)
+
+/*
+ * int main(int argc@x0, char **argv@x1, ...)
+ *
+ *	Main function.  Saves the stack pointer in mainsp and defers to
+ *	the C execsp_main in h_execsp.c.
+ */
+ENTRY(main)
+	mov	x16, sp
+	adrp	x17, :pg_hi21:_C_LABEL(mainsp)
+	str	x16, [x17, #:lo12:_C_LABEL(mainsp)]
+	b	_C_LABEL(execsp_main)
+END(main)
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/arch/aarch64/signalsphandler.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/aarch64/signalsphandler.S	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,46 @@
+/*	$NetBSD: h_execregs.S,v 1.1 2025/02/27 00:55:31 riastradh Exp $	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+/*
+ * signalsphandler(signo@x0)
+ *
+ *	Signal handler.  Store the stack pointer on entry at the global
+ *	variable signalsp and return.
+ */
+ENTRY(signalsphandler)
+	mov	x0, sp
+	adrp	x1, :pg_hi21:_C_LABEL(signalsp)
+	str	x0, [x1, #:lo12:_C_LABEL(signalsp)]
+	ret
+END(signalsphandler)
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/arch/aarch64/stack_pointer.h
--- a/tests/kernel/arch/aarch64/stack_pointer.h	Sat Apr 19 15:42:53 2025 +0000
+++ b/tests/kernel/arch/aarch64/stack_pointer.h	Sat Apr 19 14:35:55 2025 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: stack_pointer.h,v 1.1 2024/04/22 07:24:22 pho Exp $ */
+/*	$NetBSD: stack_pointer.h,v 1.1 2024/04/22 07:24:22 pho Exp $	*/
 
 /*
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -26,18 +26,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/stdbool.h>
-#include <sys/stdint.h>
-
-#define LOAD_SP(var)					\
-	do {						\
-		register void* tmp __asm__("x0");	\
-		__asm__(				\
-			"mov %0, sp"			\
-			: "=r"(tmp)			\
-		);					\
-		(var) = tmp;				\
-	} while (0)
+#ifndef	TESTS_KERNEL_ARCH_AARCH64_STACK_POINTER_H
+#define	TESTS_KERNEL_ARCH_AARCH64_STACK_POINTER_H
 
 #define MISALIGN_SP				\
 	__asm__ volatile (			\
@@ -49,8 +39,4 @@
 		"add sp, sp, #8"		\
 	)
 
-static inline bool
-is_sp_aligned(uintptr_t sp)
-{
-	return sp % 16 == 0;
-}
+#endif	/* TESTS_KERNEL_ARCH_AARCH64_STACK_POINTER_H */
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/arch/x86_64/execsp.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/x86_64/execsp.S	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,74 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+/*
+ * void execsp_start(void (*cleanup@rbx)(void), void *obj_main@rcx,
+ *     struct ps_strings *ps_strings@rbx)
+ *
+ *	ELF entry point.  Saves the stack pointer in startsp and defers
+ *	to the usual csu __start routine.
+ */
+ENTRY(execsp_start)
+	movq	%rsp,_C_LABEL(startsp)(%rip)
+	/*
+	 * No adjustment like in main because entry point is special
+	 * and the amd64 csu __start routine takes care of it.
+	 *
+	 * XXX Why don't we just arrange to align it in the kernel
+	 * anyway?
+	 */
+	jmp	_C_LABEL(__start)
+END(execsp_start)
+
+/*
+ * int main(int argc@rdi, char **argv@rsi, ...)
+ *
+ *	Main function.  Saves the stack pointer in mainsp and defers to
+ *	the C execsp_main in h_execsp.c.
+ */
+ENTRY(main)
+	/*
+	 * `The end of the input argument area shall be aligned on a
+	 *  [16-byte] boundary.  In other words, the value of (%rsp + 8)
+	 *  is always a multiple of 16 when control is transferred to
+	 *  the function entry point.'
+	 *
+	 * To make it convenient for t_signal_and_sp.c, we subtract 8
+	 * from %rsp in order to get something congruent to zero modulo
+	 * the stack alignemnt.
+	 */
+	movq	%rsp,_C_LABEL(mainsp)(%rip)
+	addq	$-8,_C_LABEL(mainsp)(%rip)
+	jmp	_C_LABEL(execsp_main)
+END(main)
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/arch/x86_64/signalsphandler.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/x86_64/signalsphandler.S	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,55 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+/*
+ * signalsphandler(signo@rdi)
+ *
+ *	Signal handler.  Store the stack pointer on entry at the global
+ *	variable signalsp and return.
+ */
+ENTRY(signalsphandler)
+	/*
+	 * `The end of the input argument area shall be aligned on a
+	 *  [16-byte] boundary.  In other words, the value of (%rsp + 8)
+	 *  is always a multiple of 16 when control is transferred to
+	 *  the function entry point.'
+	 *
+	 * To make it convenient for t_signal_and_sp.c, we subtract 8
+	 * from %rsp in order to get something congruent to zero modulo
+	 * the stack alignemnt.
+	 */
+	movq	%rsp,_C_LABEL(signalsp)(%rip)
+	addq	$-8,_C_LABEL(signalsp)(%rip)
+	ret
+END(signalsphandler)
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/arch/x86_64/stack_pointer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/x86_64/stack_pointer.h	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,35 @@
+/*	$NetBSD$	*/
+
+/*
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	TESTS_KERNEL_ARCH_X86_64_STACK_POINTER_H
+#define	TESTS_KERNEL_ARCH_X86_64_STACK_POINTER_H
+
+#define MISALIGN_SP	__asm __volatile("addq $-1,%rsp")
+#define FIX_SP		__asm __volatile("addq $1,%rsp")
+
+#endif	/* TESTS_KERNEL_ARCH_X86_64_STACK_POINTER_H */
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/h_execsp.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/h_execsp.c	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,63 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+
+#include <err.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "h_execsp.h"
+
+/*
+ * The machine-dependent execsp.S assembly routines will initialize
+ * startsp and mainsp and then call execsp_main on program startup.
+ */
+void *startsp;
+void *mainsp;
+
+int execsp_main(void);
+int
+execsp_main(void)
+{
+	struct execsp execsp;
+	ssize_t nwrit;
+
+	memset(&execsp, 0, sizeof(execsp));
+	execsp.startsp = startsp;
+	execsp.mainsp = mainsp;
+
+	nwrit = write(STDOUT_FILENO, &execsp, sizeof(execsp));
+	if (nwrit == -1)
+		err(1, "write");
+	if ((size_t)nwrit != sizeof(execsp))
+		errx(1, "wrote %zu != %zu", (size_t)nwrit, sizeof(execsp));
+
+	return 0;
+}
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/h_execsp.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/h_execsp.h	Sat Apr 19 14:35:55 2025 +0000
@@ -0,0 +1,44 @@
+/*	$NetBSD: t_signal_and_sp.c,v 1.1 2024/04/22 07:24:22 pho Exp $	*/
+
+/*
+ * Copyright (c) 2024 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	TESTS_KERNEL_H_EXECSP_H
+#define	TESTS_KERNEL_H_EXECSP_H
+
+/*
+ * struct execsp
+ *
+ *	Structure passed from the h_execsp_* programs to the
+ *	t_signal_and_sp test, giving the stack pointer as it was at the
+ *	ELF entry point and the main function.
+ */
+struct execsp {
+	void	*startsp;
+	void	*mainsp;
+};
+
+#endif	/* TESTS_KERNEL_H_EXECSP_H */
diff -r a15ce6172f14 -r d7ffc903763d tests/kernel/t_signal_and_sp.c
--- a/tests/kernel/t_signal_and_sp.c	Sat Apr 19 15:42:53 2025 +0000
+++ b/tests/kernel/t_signal_and_sp.c	Sat Apr 19 14:35:55 2025 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_signal_and_sp.c,v 1.1 2024/04/22 07:24:22 pho Exp $ */
+/*	$NetBSD: t_signal_and_sp.c,v 1.1 2024/04/22 07:24:22 pho Exp $	*/
 
 /*
  * Copyright (c) 2024 The NetBSD Foundation, Inc.
@@ -26,32 +26,259 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+
+#include <sys/wait.h>
+
+#include <machine/param.h>
+
 #include <atf-c.h>
+#include <limits.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "h_execsp.h"
+#include "h_macros.h"
+
+#ifdef HAVE_STACK_POINTER_H
+#  include "stack_pointer.h"
+#endif
 
-#if defined(HAVE_STACK_POINTER_H)
-#  include <signal.h>
-#  include <string.h>
-#  include <sys/stdint.h>
-#  include <sys/time.h>
-#  include "stack_pointer.h"
+#ifdef HAVE_SIGNALSPHANDLER
+void signalsphandler(int);	/* signalsphandler.S assembly routine */
+#endif
+
+void *volatile signalsp;
+
+static void
+test_execsp(const struct atf_tc *tc, const char *prog)
+{
+#ifdef STACK_ALIGNBYTES
+	char h_execsp[PATH_MAX];
+	struct execsp execsp;
+	int fd[2];
+	pid_t pid;
+	struct pollfd pollfd;
+	int nfds;
+	ssize_t nread;
+	int status;
+
+	/*
+	 * Determine the full path to the helper program.
+	 */
+	RL(snprintf(h_execsp, sizeof(h_execsp), "%s/%s",
+		atf_tc_get_config_var(tc, "srcdir"), prog));
 
-static volatile void* stack_pointer = NULL;
-static void on_alarm(int sig __attribute__((__unused__)))
-{
+	/*
+	 * Create a pipe to read a bundle of stack pointer samples from
+	 * the child, and fork the child.
+	 */
+	RL(pipe(fd));
+	RL(pid = vfork());
+	if (pid == 0) {		/* child */
+		char *const argv[] = {h_execsp, NULL};
+
+		if (dup2(fd[1], STDOUT_FILENO) == -1)
+			_exit(1);
+		if (closefrom(STDERR_FILENO + 1) == -1)
+			_exit(2);
+		if (execve(argv[0], argv, NULL) == -1)
+			_exit(3);
+		_exit(4);
+	}
+
+	/*
+	 * Close the writing end so, if something goes wrong in the
+	 * child, we don't hang indefinitely waiting for output.
+	 */
+	RL(close(fd[1]));
+
 	/*
-	 * Store the stack pointer into a variable so that we can test if
-	 * it's aligned.
+	 * Wait up to 5sec for the child to return an answer.  Any more
+	 * than that, and we kill it.  The child is mostly hand-written
+	 * assembly routines where lots can go wrong, so don't bother
+	 * waiting if it gets stuck in a loop.
+	 */
+	pollfd.fd = fd[0];
+	pollfd.events = POLLIN;
+	RL(nfds = poll(&pollfd, 1, 5*1000/*ms*/));
+	if (nfds == 0) {
+		fprintf(stderr, "child hung, killing\n");
+		RL(kill(pid, SIGKILL));
+	}
+
+	/*
+	 * Read a bundle of stack pointer samples from the child.
 	 */
-	LOAD_SP(stack_pointer);
+	RL(nread = read(fd[0], &execsp, sizeof(execsp)));
+	ATF_CHECK_MSG((size_t)nread == sizeof(execsp),
+	    "nread=%zu sizeof(execsp)=%zu",
+	    (size_t)nread, sizeof(execsp));
+
+	/*
+	 * Wait for the child to terminate and report failure if it
+	 * didn't exit cleanly.
+	 */
+	RL(waitpid(pid, &status, 0));
+	if (WIFSIGNALED(status)) {
+		atf_tc_fail_nonfatal("child exited on signal %d (%s)",
+		    WTERMSIG(status), strsignal(WTERMSIG(status)));
+	} else if (!WIFEXITED(status)) {
+		atf_tc_fail_nonfatal("child exited status=0x%x", status);
+	} else {
+		ATF_CHECK_MSG(WEXITSTATUS(status) == 0,
+		    "child exited with code %d",
+		    WEXITSTATUS(status));
+	}
 
 	/*
-	 * Now we are going to return from a signal
-	 * handler. __sigtramp_siginfo_2 will call setcontext(2) with a
-	 * ucontext provided by the kernel. When that fails it will call
-	 * _Exit(2) with the errno, and the test will fail.
+	 * Now that we have reaped the child, stop here if the stack
+	 * pointer samples are bogus; otherwise verify they are all
+	 * aligned.
+	 */
+	if ((size_t)nread != sizeof(execsp))
+		return;		/* failed already */
+
+	printf("start sp @ %p\n", execsp.startsp);
+	printf("main sp @ %p\n", execsp.mainsp);
+
+	ATF_CHECK_MSG(((uintptr_t)execsp.startsp & STACK_ALIGNBYTES) == 0,
+	    "elf entry point was called with misaligned sp: %p",
+	    execsp.startsp);
+
+	ATF_CHECK_MSG(((uintptr_t)execsp.mainsp & STACK_ALIGNBYTES) == 0,
+	    "main function was called with misaligned sp: %p",
+	    execsp.mainsp);
+
+	/*
+	 * Leave a reminder on architectures for which we haven't
+	 * implemented execsp_start.S.
 	 */
+	if (execsp.startsp == NULL || execsp.mainsp == NULL)
+		atf_tc_skip("Not fully supported on this architecture");
+#else
+	atf_tc_skip("Unknown STACK_ALIGNBYTES on this architecture");
+#endif
 }
+
+ATF_TC(execsp_dynamic);
+ATF_TC_HEAD(execsp_dynamic, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify stack pointer is aligned on dynamic program start");
+}
+ATF_TC_BODY(execsp_dynamic, tc)
+{
+	test_execsp(tc, "h_execsp_dynamic");
+}
+
+ATF_TC(execsp_static);
+ATF_TC_HEAD(execsp_static, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify stack pointer is aligned on static program start");
+}
+ATF_TC_BODY(execsp_static, tc)
+{
+	test_execsp(tc, "h_execsp_static");
+}
+
+ATF_TC(signalsp);
+ATF_TC_HEAD(signalsp, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify stack pointer is aligned on entry to signal handler");
+}
+ATF_TC_BODY(signalsp, tc)
+{
+#if defined STACK_ALIGNBYTES && defined HAVE_SIGNALSPHANDLER
+	struct sigaction sa;
+
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = &signalsphandler;
+	RL(sigaction(SIGUSR1, &sa, NULL));
+	RL(raise(SIGUSR1));
+
+	ATF_CHECK_MSG(((uintptr_t)signalsp & STACK_ALIGNBYTES) == 0,
+	    "signal handler was called with a misaligned sp: %p",
+	    signalsp);
+#else
+	atf_tc_skip("Not implemented on this platform");
 #endif
+}
+
+ATF_TC(signalsp_sigaltstack);
+ATF_TC_HEAD(signalsp_sigaltstack, tc)
+{
+	atf_tc_set_md_var(tc, "descr",
+	    "Verify stack pointer is aligned on entry to signal handler"
+	    " with maximally misaligned sigaltstack");
+}
+ATF_TC_BODY(signalsp_sigaltstack, tc)
+{
+#if defined STACK_ALIGNBYTES && HAVE_SIGNALSPHANDLER
+	char *stack;
+	struct sigaction sa;
+	struct sigaltstack ss;
+	unsigned i;
+
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = &signalsphandler;
+	sa.sa_flags = SA_ONSTACK;
+	RL(sigaction(SIGUSR1, &sa, NULL));
+
+	/*
+	 * Allocate a signal stack with enough slop to try all possible
+	 * misalignments of the stack pointer.  Print it to stderr so
+	 * it always appears in atf output before shenanigans happen.
+	 */
+	REQUIRE_LIBC(stack = malloc(SIGSTKSZ + STACK_ALIGNBYTES), NULL);
+	fprintf(stderr, "stack @ [%p, %p)",
+	    stack, stack + SIGSTKSZ + STACK_ALIGNBYTES);
+
+	/*
+	 * Try with all alignments of high addresses.
+	 */
+	for (i = 0; i <= STACK_ALIGNBYTES; i++) {
+		ss.ss_sp = stack;
+		ss.ss_size = SIGSTKSZ + i;
+		ss.ss_flags = 0;
+		RL(sigaltstack(&ss, NULL));
+
+		signalsp = NULL;
+		RL(raise(SIGUSR1));
+		ATF_CHECK(signalsp != NULL);
+		ATF_CHECK_MSG(((uintptr_t)signalsp & STACK_ALIGNBYTES) == 0,
+		    "[%u] signal handler was called with a misaligned sp: %p",
+		    i, signalsp);
+	}
+
+	/*
+	 * Try with all alignments of low addresses.
+	 */
+	for (i = 0; i <= STACK_ALIGNBYTES; i++) {
+		ss.ss_sp = stack + i;
+		ss.ss_size = SIGSTKSZ;
+		ss.ss_flags = 0;
+		RL(sigaltstack(&ss, NULL));
+
+		signalsp = NULL;
+		RL(raise(SIGUSR1));
+		ATF_CHECK(signalsp != NULL);
+		ATF_CHECK_MSG(((uintptr_t)signalsp & STACK_ALIGNBYTES) == 0,
+		    "[%u] signal handler was called with a misaligned sp: %p",
+		    i, signalsp);
+	}
+#else
+	atf_tc_skip("Not implemented on this platform");
+#endif
+}
 
 ATF_TC(misaligned_sp_and_signal);
 ATF_TC_HEAD(misaligned_sp_and_signal, tc)
@@ -62,14 +289,14 @@ ATF_TC_HEAD(misaligned_sp_and_signal, tc
 }
 ATF_TC_BODY(misaligned_sp_and_signal, tc)
 {
-#if defined(HAVE_STACK_POINTER_H)
+#if defined STACK_ALIGNBYTES && defined HAVE_STACK_POINTER_H
 	/*
 	 * Set up a handler for SIGALRM.
 	 */
 	struct sigaction sa;
 	memset(&sa, 0, sizeof(sa));
-	sa.sa_handler = &on_alarm;
-	ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0);
+	sa.sa_handler = &signalsphandler;
+	RL(sigaction(SIGALRM, &sa, NULL));
 
 	/*
 	 * Set up an interval timer so that we receive SIGALRM after 50 ms.
@@ -77,7 +304,7 @@ ATF_TC_BODY(misaligned_sp_and_signal, tc
 	struct itimerval itv;
 	memset(&itv, 0, sizeof(itv));
 	itv.it_value.tv_usec = 1000 * 50;
-	ATF_REQUIRE(setitimer(ITIMER_MONOTONIC, &itv, NULL) == 0);
+	RL(setitimer(ITIMER_MONOTONIC, &itv, NULL));
 
 	/*
 	 * Now misalign the SP. Wait for the signal to arrive and see what
@@ -85,12 +312,12 @@ ATF_TC_BODY(misaligned_sp_and_signal, tc
 	 * access memory.
 	 */
 	MISALIGN_SP;
-	while (stack_pointer == NULL) {
+	while (signalsp == NULL) {
 		/*
 		 * Make sure the compiler does not optimize this busy loop
 		 * away.
 		 */
-		__asm__("" : : : "memory");
+		__asm__("" ::: "memory");
 	}
 	/*
 	 * We could successfully return from a signal handler. Now we
@@ -102,9 +329,9 @@ ATF_TC_BODY(misaligned_sp_and_signal, tc
 	 * But was the stack pointer aligned when we were on the signal
 	 * handler?
 	 */
-	ATF_CHECK_MSG(is_sp_aligned((uintptr_t)stack_pointer),
+	ATF_CHECK_MSG(((uintptr_t)signalsp & STACK_ALIGNBYTES) == 0,
 	    "signal handler was called with a misaligned sp: %p",
-	    stack_pointer);
+	    signalsp);
 #else
 	atf_tc_skip("Not implemented for this platform");
 #endif
@@ -112,6 +339,11 @@ ATF_TC_BODY(misaligned_sp_and_signal, tc
 
 ATF_TP_ADD_TCS(tp)
 {
+
+	ATF_TP_ADD_TC(tp, execsp_dynamic);
+	ATF_TP_ADD_TC(tp, execsp_static);
 	ATF_TP_ADD_TC(tp, misaligned_sp_and_signal);
+	ATF_TP_ADD_TC(tp, signalsp);
+	ATF_TP_ADD_TC(tp, signalsp_sigaltstack);
 	return atf_no_error();
 }
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1745075915 0
#      Sat Apr 19 15:18:35 2025 +0000
# Branch trunk
# Node ID efb233e8e830d26fe319b7761f800368fd82c74a
# Parent  d7ffc903763d7fcf264ee539e89b315b081d289d
# EXP-Topic riastradh-pr59327-stackalign
t_signal_and_sp: Check sp on elf constructor/destructor entry too.

XXX Should maybe test both .ctors/.dtors and .init/fini_array.

PR port-evbmips/59236: Multiple segfaults in erlite3 boot

diff -r d7ffc903763d -r efb233e8e830 tests/kernel/arch/aarch64/execsp.S
--- a/tests/kernel/arch/aarch64/execsp.S	Sat Apr 19 14:35:55 2025 +0000
+++ b/tests/kernel/arch/aarch64/execsp.S	Sat Apr 19 15:18:35 2025 +0000
@@ -47,14 +47,53 @@ ENTRY(execsp_start)
 END(execsp_start)
 
 /*
+ * void execsp_ctor(void)
+ *
+ *	ELF constructor.  Saves the stack pointer in ctorsp and
+ *	returns.
+ */
+ENTRY(execsp_ctor)
+	mov	x16, sp
+	adrp	x17, :pg_hi21:_C_LABEL(ctorsp)
+	str	x16, [x17, #:lo12:_C_LABEL(ctorsp)]
+	ret
+END(execsp_ctor)
+
+	/* Make execsp_ctor a constructor. */
+	.section .init_array,"aw",%init_array
+	.p2align 3
+	.xword	execsp_ctor
+
+/*
  * int main(int argc@x0, char **argv@x1, ...)
  *
- *	Main function.  Saves the stack pointer in mainsp and defers to
- *	the C execsp_main in h_execsp.c.
+ *	Main function.  Saves the stack pointer in mainsp and returns
+ *	zero.  We will call execsp_main in execsp_dtor once dtorsp has
+ *	been initialized.
  */
 ENTRY(main)
 	mov	x16, sp
 	adrp	x17, :pg_hi21:_C_LABEL(mainsp)
 	str	x16, [x17, #:lo12:_C_LABEL(mainsp)]
+	mov	x0, #0
+	ret
+END(main)
+
+/*
+ * void execsp_dtor(void)
+ *
+ *	ELF destructor.  Saves the stack pointer in dtorsp and defers
+ *	to the C execsp_main in h_execsp.c to report the stack pointers
+ *	back to the t_signal_and_sp parent.
+ */
+ENTRY(execsp_dtor)
+	mov	x16, sp
+	adrp	x17, :pg_hi21:_C_LABEL(dtorsp)
+	str	x16, [x17, #:lo12:_C_LABEL(dtorsp)]
 	b	_C_LABEL(execsp_main)
-END(main)
+END(execsp_dtor)
+
+	/* Make execsp_ctor a destructor. */
+	.section .fini_array,"aw",%fini_array
+	.p2align 3
+	.xword	execsp_dtor
diff -r d7ffc903763d -r efb233e8e830 tests/kernel/arch/x86_64/execsp.S
--- a/tests/kernel/arch/x86_64/execsp.S	Sat Apr 19 14:35:55 2025 +0000
+++ b/tests/kernel/arch/x86_64/execsp.S	Sat Apr 19 15:18:35 2025 +0000
@@ -52,12 +52,12 @@ ENTRY(execsp_start)
 END(execsp_start)
 
 /*
- * int main(int argc@rdi, char **argv@rsi, ...)
+ * void execsp_ctor(void)
  *
- *	Main function.  Saves the stack pointer in mainsp and defers to
- *	the C execsp_main in h_execsp.c.
+ *	ELF constructor.  Saves the stack pointer in ctorsp and
+ *	returns.
  */
-ENTRY(main)
+ENTRY(execsp_ctor)
 	/*
 	 * `The end of the input argument area shall be aligned on a
 	 *  [16-byte] boundary.  In other words, the value of (%rsp + 8)
@@ -68,7 +68,44 @@ ENTRY(main)
 	 * from %rsp in order to get something congruent to zero modulo
 	 * the stack alignemnt.
 	 */
+	movq	%rsp,_C_LABEL(ctorsp)(%rip)
+	addq	$-8,_C_LABEL(ctorsp)(%rip)
+	ret
+END(execsp_ctor)
+
+	/* Make execsp_ctor a constructor. */
+	.section .ctors,"aw",@progbits
+	.p2align 3
+	.quad	execsp_ctor
+
+/*
+ * int main(int argc@rdi, char **argv@rsi, ...)
+ *
+ *	Main function.  Saves the stack pointer in mainsp and returns
+ *	zero.  We will call execsp_main in execsp_dtor once dtorsp has
+ *	been initialized.
+ */
+ENTRY(main)
 	movq	%rsp,_C_LABEL(mainsp)(%rip)
 	addq	$-8,_C_LABEL(mainsp)(%rip)
+	xorl	%eax,%eax
+	ret
+END(main)
+
+/*
+ * void execsp_dtor(void)
+ *
+ *	ELF destructor.  Saves the stack pointer in dtorsp and defers
+ *	to the C execsp_main in h_execsp.c to report the stack pointers
+ *	back to the t_signal_and_sp parent.
+ */
+ENTRY(execsp_dtor)
+	movq	%rsp,_C_LABEL(dtorsp)(%rip)
+	addq	$-8,_C_LABEL(dtorsp)(%rip)
 	jmp	_C_LABEL(execsp_main)
-END(main)
+END(execsp_dtor)
+
+	/* Make execsp_ctor a destructor. */
+	.section .dtors,"aw",@progbits
+	.p2align 3
+	.quad	execsp_dtor
diff -r d7ffc903763d -r efb233e8e830 tests/kernel/h_execsp.c
--- a/tests/kernel/h_execsp.c	Sat Apr 19 14:35:55 2025 +0000
+++ b/tests/kernel/h_execsp.c	Sat Apr 19 15:18:35 2025 +0000
@@ -37,10 +37,13 @@
 
 /*
  * The machine-dependent execsp.S assembly routines will initialize
- * startsp and mainsp and then call execsp_main on program startup.
+ * startsp, ctorsp, mainsp, and dtorsp, and then call execsp_main on
+ * program startup.
  */
 void *startsp;
+void *ctorsp;
 void *mainsp;
+void *dtorsp;
 
 int execsp_main(void);
 int
@@ -51,7 +54,9 @@ execsp_main(void)
 
 	memset(&execsp, 0, sizeof(execsp));
 	execsp.startsp = startsp;
+	execsp.ctorsp = ctorsp;
 	execsp.mainsp = mainsp;
+	execsp.dtorsp = dtorsp;
 
 	nwrit = write(STDOUT_FILENO, &execsp, sizeof(execsp));
 	if (nwrit == -1)
diff -r d7ffc903763d -r efb233e8e830 tests/kernel/h_execsp.h
--- a/tests/kernel/h_execsp.h	Sat Apr 19 14:35:55 2025 +0000
+++ b/tests/kernel/h_execsp.h	Sat Apr 19 15:18:35 2025 +0000
@@ -34,11 +34,14 @@
  *
  *	Structure passed from the h_execsp_* programs to the
  *	t_signal_and_sp test, giving the stack pointer as it was at the
- *	ELF entry point and the main function.
+ *	ELF entry point, an ELF constructor, the main function, and an
+ *	ELF destructor.
  */
 struct execsp {
 	void	*startsp;
+	void	*ctorsp;
 	void	*mainsp;
+	void	*dtorsp;
 };
 
 #endif	/* TESTS_KERNEL_H_EXECSP_H */
diff -r d7ffc903763d -r efb233e8e830 tests/kernel/t_signal_and_sp.c
--- a/tests/kernel/t_signal_and_sp.c	Sat Apr 19 14:35:55 2025 +0000
+++ b/tests/kernel/t_signal_and_sp.c	Sat Apr 19 15:18:35 2025 +0000
@@ -146,21 +146,34 @@ test_execsp(const struct atf_tc *tc, con
 		return;		/* failed already */
 
 	printf("start sp @ %p\n", execsp.startsp);
+	printf("ctor sp @ %p\n", execsp.ctorsp);
 	printf("main sp @ %p\n", execsp.mainsp);
+	printf("dtor sp @ %p\n", execsp.dtorsp);
 
 	ATF_CHECK_MSG(((uintptr_t)execsp.startsp & STACK_ALIGNBYTES) == 0,
 	    "elf entry point was called with misaligned sp: %p",
 	    execsp.startsp);
 
+	ATF_CHECK_MSG(((uintptr_t)execsp.ctorsp & STACK_ALIGNBYTES) == 0,
+	    "elf constructor was called with misaligned sp: %p",
+	    execsp.ctorsp);
+
 	ATF_CHECK_MSG(((uintptr_t)execsp.mainsp & STACK_ALIGNBYTES) == 0,
 	    "main function was called with misaligned sp: %p",
 	    execsp.mainsp);
 
+	ATF_CHECK_MSG(((uintptr_t)execsp.dtorsp & STACK_ALIGNBYTES) == 0,
+	    "elf destructor was called with misaligned sp: %p",
+	    execsp.dtorsp);
+
 	/*
 	 * Leave a reminder on architectures for which we haven't
 	 * implemented execsp_start.S.
 	 */
-	if (execsp.startsp == NULL || execsp.mainsp == NULL)
+	if (execsp.startsp == NULL ||
+	    execsp.ctorsp == NULL ||
+	    execsp.mainsp == NULL ||
+	    execsp.dtorsp == NULL)
 		atf_tc_skip("Not fully supported on this architecture");
 #else
 	atf_tc_skip("Unknown STACK_ALIGNBYTES on this architecture");
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1745082299 0
#      Sat Apr 19 17:04:59 2025 +0000
# Branch trunk
# Node ID 85af35b9e0c55e3d2f0a06d5cb03569dbe9c02fe
# Parent  efb233e8e830d26fe319b7761f800368fd82c74a
# EXP-Topic riastradh-pr59327-stackalign
t_signal_and_sp: Add alpha support.

Turns out alpha gets confused by misaligned $sp when a signal is
delivered too.

PR kern/58149: Cannot return from a signal handler if SP was
misaligned when the signal arrived

diff -r efb233e8e830 -r 85af35b9e0c5 tests/kernel/arch/alpha/execsp.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/alpha/execsp.S	Sat Apr 19 17:04:59 2025 +0000
@@ -0,0 +1,105 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+	.set noat
+	.text
+
+/*
+ * void execsp_start(void *stackpointer@a0, void (*cleanup@a1)(void),
+ *     void *obj_main@a2, struct ps_strings *ps_strings@a3)
+ *
+ *	ELF entry point.  Saves the stack pointer in startsp and defers
+ *	to the usual csu __start routine.
+ */
+LEAF(execsp_start, 4)
+	LDGP(pv)
+	ldq	at_reg, startsp(gp)	!literal
+	stq	sp, 0(at_reg)
+	ldq	pv, __start(gp)		!literal
+	jmp	(pv), __start
+END(execsp_start)
+
+/*
+ * void execsp_ctor(void)
+ *
+ *	ELF constructor.  Saves the stack pointer in ctorsp and
+ *	returns.
+ */
+LEAF(execsp_ctor, 0)
+	LDGP(pv)
+	ldq	at_reg, ctorsp(gp)	!literal
+	stq	sp, 0(at_reg)
+	RET
+END(execsp_ctor)
+
+	/* Make execsp_ctor a constructor. */
+	.pushsection .ctors,"aw",@progbits
+	.p2align 3
+	.quad	execsp_ctor
+	.popsection
+
+/*
+ * int main(int argc@a0, char **argv@a1, ...)
+ *
+ *	Main function.  Saves the stack pointer in mainsp and returns
+ *	zero.  We will call execsp_main in execsp_dtor once dtorsp has
+ *	been initialized.
+ */
+LEAF(main, 2)
+	LDGP(pv)
+	ldq	at_reg, mainsp(gp)	!literal
+	stq	sp, 0(at_reg)
+	RET
+END(main)
+
+/*
+ * void execsp_dtor(void)
+ *
+ *	ELF destructor.  Saves the stack pointer in dtorsp and defers
+ *	to the C execsp_main in h_execsp.c to report the stack pointers
+ *	back to the t_signal_and_sp parent.
+ */
+LEAF(execsp_dtor, 0)
+	LDGP(pv)
+	ldq	at_reg, dtorsp(gp)	!literal
+	stq	sp, 0(at_reg)
+	ldq	pv, execsp_main(gp)	!literal
+	jmp	(pv), execsp_main
+END(execsp_dtor)
+
+	/* Make execsp_ctor a destructor. */
+	.pushsection .dtors,"aw",@progbits
+	.p2align 3
+	.quad	execsp_dtor
+	.popsection
diff -r efb233e8e830 -r 85af35b9e0c5 tests/kernel/arch/alpha/signalsphandler.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/alpha/signalsphandler.S	Sat Apr 19 17:04:59 2025 +0000
@@ -0,0 +1,49 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+	.set noat
+	.text
+
+/*
+ * signalsphandler(signo@a0)
+ *
+ *	Signal handler.  Store the stack pointer on entry at the global
+ *	variable signalsp and return.
+ */
+LEAF(signalsphandler, 1)
+	LDGP(pv)
+	ldq	at_reg, signalsp(gp)	!literal
+	stq	sp, 0(at_reg)
+	RET
+END(signalsphandler)
diff -r efb233e8e830 -r 85af35b9e0c5 tests/kernel/arch/alpha/stack_pointer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/alpha/stack_pointer.h	Sat Apr 19 17:04:59 2025 +0000
@@ -0,0 +1,35 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	TESTS_KERNEL_ARCH_ALPHA_STACK_POINTER_H
+#define	TESTS_KERNEL_ARCH_ALPHA_STACK_POINTER_H
+
+#define MISALIGN_SP	__asm __volatile("lda $sp,-1($sp)" ::: "memory")
+#define FIX_SP		__asm __volatile("lda $sp,1($sp)" ::: "memory")
+
+#endif	/* TESTS_KERNEL_ARCH_ALPHA_STACK_POINTER_H */
diff -r efb233e8e830 -r 85af35b9e0c5 tests/kernel/t_signal_and_sp.c
--- a/tests/kernel/t_signal_and_sp.c	Sat Apr 19 15:18:35 2025 +0000
+++ b/tests/kernel/t_signal_and_sp.c	Sat Apr 19 17:04:59 2025 +0000
@@ -255,6 +255,11 @@ ATF_TC_BODY(signalsp_sigaltstack, tc)
 	fprintf(stderr, "stack @ [%p, %p)",
 	    stack, stack + SIGSTKSZ + STACK_ALIGNBYTES);
 
+#ifdef __alpha__
+	atf_tc_expect_fail("PR port-evbmips/59236:"
+	    " Multiple segfaults in erlite3 boot");
+#endif
+
 	/*
 	 * Try with all alignments of high addresses.
 	 */
@@ -311,6 +316,12 @@ ATF_TC_BODY(misaligned_sp_and_signal, tc
 	sa.sa_handler = &signalsphandler;
 	RL(sigaction(SIGALRM, &sa, NULL));
 
+#ifdef __alpha__
+	atf_tc_expect_fail("PR kern/58149:"
+	    " Cannot return from a signal handler"
+	    " if SP was misaligned when the signal arrived");
+#endif
+
 	/*
 	 * Set up an interval timer so that we receive SIGALRM after 50 ms.
 	 */
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1745089078 0
#      Sat Apr 19 18:57:58 2025 +0000
# Branch trunk
# Node ID 4650ffe0718a4559d5b753b3b0c4925c58a5921e
# Parent  85af35b9e0c55e3d2f0a06d5cb03569dbe9c02fe
# EXP-Topic riastradh-pr59327-stackalign
t_signal_and_sp: Add mips support.

PR port-evbmips/59236: Multiple segfaults in erlite3 boot

PR kern/58149: Cannot return from a signal handler if SP was
misaligned when the signal arrived

diff -r 85af35b9e0c5 -r 4650ffe0718a sys/arch/mips/include/mips_param.h
--- a/sys/arch/mips/include/mips_param.h	Sat Apr 19 17:04:59 2025 +0000
+++ b/sys/arch/mips/include/mips_param.h	Sat Apr 19 18:57:58 2025 +0000
@@ -76,6 +76,12 @@
 #define	MACHINE "mips"
 #endif
 
+#if defined(__mips_n64) || defined(__mips_n32)
+#define	STACK_ALIGNBYTES	(16 - 1)
+#else
+#define	STACK_ALIGNBYTES	(8 - 1)
+#endif
+
 #define	ALIGNBYTES32		(sizeof(double) - 1)
 #define	ALIGN32(p)		(((uintptr_t)(p) + ALIGNBYTES32) &~ALIGNBYTES32)
 
diff -r 85af35b9e0c5 -r 4650ffe0718a tests/kernel/Makefile
--- a/tests/kernel/Makefile	Sat Apr 19 17:04:59 2025 +0000
+++ b/tests/kernel/Makefile	Sat Apr 19 18:57:58 2025 +0000
@@ -95,7 +95,11 @@ LDADD.t_timeleft+=	-lpthread
 CPPFLAGS+=	-D_KERNTYPES
 CPPFLAGS.t_unmount.c+=	-D_KMEMUSER -D__EXPOSE_MOUNT
 
+.if exists(${.PARSEDIR}/arch/${MACHINE_ARCH})
 ARCHDIR:=		${.PARSEDIR}/arch/${MACHINE_ARCH}
+.else
+ARCHDIR:=		${.PARSEDIR}/arch/${MACHINE_CPU}
+.endif
 .PATH:			${ARCHDIR}
 
 .if exists(${ARCHDIR}/stack_pointer.h)
@@ -121,6 +125,11 @@ CPPFLAGS.h_execsp.c+=		-Dexecsp_main=mai
 .endif
 LDSTATIC.h_execsp_static=	-static
 
+.if ${MACHINE_CPU} == "mips"
+CPPFLAGS.execsp.S+=		-I${NETBSDSRCDIR}/lib/libc/arch/mips
+CPPFLAGS.signalsphandler.S+=	-I${NETBSDSRCDIR}/lib/libc/arch/mips
+.endif
+
 .PATH:			${NETBSDSRCDIR}/sys/kern
 TESTS_C+=		t_extent
 SRCS.t_extent=		t_extent.c subr_extent.c
diff -r 85af35b9e0c5 -r 4650ffe0718a tests/kernel/arch/mips/execsp.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/mips/execsp.S	Sat Apr 19 18:57:58 2025 +0000
@@ -0,0 +1,126 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+#include "SYS.h"
+
+	.text
+
+/*
+ * void execsp_start(void *stackpointer@a0, void (*cleanup@a1)(void),
+ *     void *obj_main@a2, struct ps_strings *ps_strings@a3)
+ *
+ *	ELF entry point.  Saves the stack pointer in startsp and defers
+ *	to the usual csu __start routine.
+ */
+LEAF(execsp_start)
+	move	t0, sp			/* save stack pointer just in case */
+
+	PIC_PROLOGUE(execsp_start)	/* gp setup, sets t3 */
+
+	PTR_LA	t1, _C_LABEL(startsp)	/* load t1 := &startsp */
+	 NOP_L				/* load hazard */
+	PTR_S	t0, 0(t1)		/* store startsp := stack pointer */
+
+	PIC_TAILCALL(__start)		/* gp restore, uses t3 */
+END(execsp_start)
+
+/*
+ * void execsp_ctor(void)
+ *
+ *	ELF constructor.  Saves the stack pointer in ctorsp and
+ *	returns.
+ */
+LEAF(execsp_ctor)
+	move	t0, sp			/* save stack pointer just in case */
+
+	PIC_PROLOGUE(execsp_ctor)	/* gp setup, sets t3 */
+
+	PTR_LA	t1, _C_LABEL(ctorsp)	/* load t1 := &ctorsp */
+	 NOP_L				/* load hazard */
+	PTR_S	t0, 0(t1)		/* store ctorsp := stack pointer */
+
+	PIC_RETURN()			/* gp restore, uses t3 */
+END(execsp_ctor)
+
+	/* Make execsp_ctor a constructor. */
+	.pushsection .ctors,"aw",@progbits
+	.p2align PTR_SCALESHIFT
+	PTR_WORD	execsp_ctor
+	.popsection
+
+/*
+ * int main(int argc@a0, char **argv@a1, ...)
+ *
+ *	Main function.  Saves the stack pointer in mainsp and returns
+ *	zero.  We will call execsp_main in execsp_dtor once dtorsp has
+ *	been initialized.
+ */
+LEAF(main)
+	move	t0, sp			/* save stack pointer just in case */
+
+	PIC_PROLOGUE(main)		/* gp setup, sets t3 */
+
+	PTR_LA	t1, _C_LABEL(mainsp)	/* load t1 := &mainsp */
+	 NOP_L				/* load hazard */
+	PTR_S	t0, 0(t1)		/* store mainsp := stack pointer */
+
+	move	v0, zero		/* return 0 */
+
+	PIC_RETURN()			/* gp restore, uses t3 */
+END(main)
+
+/*
+ * void execsp_dtor(void)
+ *
+ *	ELF destructor.  Saves the stack pointer in dtorsp and defers
+ *	to the C execsp_main in h_execsp.c to report the stack pointers
+ *	back to the t_signal_and_sp parent.
+ */
+LEAF(execsp_dtor)
+	move	t0, sp			/* save stack pointer just in case */
+
+	PIC_PROLOGUE(execsp_dtor)	/* gp setup, sets t3 */
+
+	PTR_LA	t1, _C_LABEL(dtorsp)	/* load t1 := &dtorsp */
+	 NOP_L				/* load hazard */
+	PTR_S	t0, 0(t1)		/* store dtorsp := stack pointer */
+
+	PIC_TAILCALL(execsp_main)	/* gp restore, uses t3 */
+END(execsp_dtor)
+
+	/* Make execsp_ctor a destructor. */
+	.pushsection .dtors,"aw",@progbits
+	.p2align PTR_SCALESHIFT
+	PTR_WORD	execsp_dtor
+	.popsection
diff -r 85af35b9e0c5 -r 4650ffe0718a tests/kernel/arch/mips/signalsphandler.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/mips/signalsphandler.S	Sat Apr 19 18:57:58 2025 +0000
@@ -0,0 +1,55 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+#include "SYS.h"
+
+	.text
+
+/*
+ * signalsphandler(signo@a0)
+ *
+ *	Signal handler.  Store the stack pointer on entry at the global
+ *	variable signalsp and return.
+ */
+LEAF(signalsphandler)
+	move	t0, sp			/* save stack pointer just in case */
+
+	PIC_PROLOGUE(signalsphandler)	/* gp setup, sets t3 */
+
+	PTR_LA	t1, _C_LABEL(signalsp)	/* load t1 := &signalsp */
+	 NOP_L				/* load hazard */
+	PTR_S	t0, 0(t1)		/* store signalsp := stack pointer */
+
+	PIC_RETURN()
+END(signalsphandler)
diff -r 85af35b9e0c5 -r 4650ffe0718a tests/kernel/arch/mips/stack_pointer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/mips/stack_pointer.h	Sat Apr 19 18:57:58 2025 +0000
@@ -0,0 +1,35 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	TESTS_KERNEL_ARCH_MIPS_STACK_POINTER_H
+#define	TESTS_KERNEL_ARCH_MIPS_STACK_POINTER_H
+
+#define MISALIGN_SP	__asm __volatile("addiu $sp,$sp,-1" ::: "memory")
+#define FIX_SP		__asm __volatile("addiu $sp,$sp,1" ::: "memory")
+
+#endif	/* TESTS_KERNEL_ARCH_MIPS_STACK_POINTER_H */
diff -r 85af35b9e0c5 -r 4650ffe0718a tests/kernel/t_signal_and_sp.c
--- a/tests/kernel/t_signal_and_sp.c	Sat Apr 19 17:04:59 2025 +0000
+++ b/tests/kernel/t_signal_and_sp.c	Sat Apr 19 18:57:58 2025 +0000
@@ -255,7 +255,7 @@ ATF_TC_BODY(signalsp_sigaltstack, tc)
 	fprintf(stderr, "stack @ [%p, %p)",
 	    stack, stack + SIGSTKSZ + STACK_ALIGNBYTES);
 
-#ifdef __alpha__
+#if defined __alpha__ || defined __mips__
 	atf_tc_expect_fail("PR port-evbmips/59236:"
 	    " Multiple segfaults in erlite3 boot");
 #endif
@@ -316,7 +316,7 @@ ATF_TC_BODY(misaligned_sp_and_signal, tc
 	sa.sa_handler = &signalsphandler;
 	RL(sigaction(SIGALRM, &sa, NULL));
 
-#ifdef __alpha__
+#if defined __alpha__ || defined __mips__
 	atf_tc_expect_fail("PR kern/58149:"
 	    " Cannot return from a signal handler"
 	    " if SP was misaligned when the signal arrived");
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1745092499 0
#      Sat Apr 19 19:54:59 2025 +0000
# Branch trunk
# Node ID f4d9ab8a392c24b7af72b2f153a588c9ff6faf22
# Parent  4650ffe0718a4559d5b753b3b0c4925c58a5921e
# EXP-Topic riastradh-pr59327-stackalign
WIP: t_signal_and_sp: Add hppa support.

XXX Doesn't work yet -- h_execsp_static crashes with SIGSEGV.

diff -r 4650ffe0718a -r f4d9ab8a392c sys/arch/hppa/include/param.h
--- a/sys/arch/hppa/include/param.h	Sat Apr 19 18:57:58 2025 +0000
+++ b/sys/arch/hppa/include/param.h	Sat Apr 19 19:54:59 2025 +0000
@@ -79,6 +79,8 @@
 #define	MCLBYTES	(1 << MCLSHIFT)	/* large enough for ether MTU */
 #define	MCLOFSET	(MCLBYTES - 1)
 
+#define	STACK_ALIGNBYTES	(64 - 1)
+
 /*
  * Size of kernel malloc arena in logical pages
  */
diff -r 4650ffe0718a -r f4d9ab8a392c tests/kernel/arch/hppa/execsp.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/hppa/execsp.S	Sat Apr 19 19:54:59 2025 +0000
@@ -0,0 +1,109 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+/*
+ * void execsp_start(struct ps_strings *ps_strings@arg0,
+ *     void (*cleanup@arg1)(void), void *obj_main@arg2)
+ *
+ *	ELF entry point.  Saves the stack pointer in startsp and defers
+ *	to the usual csu __start routine.
+ */
+LEAF_ENTRY(execsp_start)
+	addil	LT%_C_LABEL(startsp), %r19	/* r20 := &startsp */
+	ldw	RT%_C_LABEL(startsp)(%r1), %r20
+
+	/* PIC_TAILCALL(__start), if we had it */
+	addil	LT%_C_LABEL(__start), %r19	/* r1 := __start */
+	ldw	RT%_C_LABEL(__start)(%r1), %r1
+	bv	%r0(%r1)			/* jump to __start */
+	 stw	%sp, 0(%r20)			/* startsp := sp */
+EXIT(execsp_start)
+
+/*
+ * void execsp_ctor(void)
+ *
+ *	ELF constructor.  Saves the stack pointer in ctorsp and
+ *	returns.
+ */
+LEAF_ENTRY(execsp_ctor)
+	addil	LT%_C_LABEL(ctorsp), %r19	/* r1 := &ctorsp */
+	ldw	RT%_C_LABEL(ctorsp)(%r1), %r1
+	bv	%r0(%rp)			/* return */
+	 stw	%sp, 0(%r1)			/* ctorsp := sp */
+EXIT(execsp_ctor)
+
+	/* Make execsp_ctor a constructor. */
+	.pushsection .ctors,"aw",@progbits
+	.p2align 2
+	.word	execsp_ctor
+	.popsection
+
+/*
+ * int main(int argc@arg0, char **argv@arg1, ...)
+ *
+ *	Main function.  Saves the stack pointer in mainsp and returns
+ *	zero.  We will call execsp_main in execsp_dtor once dtorsp has
+ *	been initialized.
+ */
+LEAF_ENTRY(main)
+	addil	LT%_C_LABEL(mainsp), %r19	/* r1 := &mainsp */
+	ldw	RT%_C_LABEL(mainsp)(%r1), %r1
+	stw	%sp, 0(%r1)			/* ctorsp := sp */
+	bv	%r0(%rp)			/* return... */
+	 copy	%r0, %ret0			/* ...zero */
+EXIT(main)
+
+/*
+ * void execsp_dtor(void)
+ *
+ *	ELF destructor.  Saves the stack pointer in dtorsp and defers
+ *	to the C execsp_main in h_execsp.c to report the stack pointers
+ *	back to the t_signal_and_sp parent.
+ */
+LEAF_ENTRY(execsp_dtor)
+	addil	LT%_C_LABEL(dtorsp), %r19	/* r20 := &dtorsp */
+	ldw	RT%_C_LABEL(dtorsp)(%r1), %r20
+
+	/* PIC_TAILCALL(__start), if we had it */
+	addil	LT%_C_LABEL(execsp_main), %r19	/* r1 := execsp_main */
+	ldw	RT%_C_LABEL(execsp_main)(%r1), %r1
+	bv	%r0(%r1)			/* jump to execsp_main */
+	 stw	%sp, 0(%r20)			/* startsp := sp */
+EXIT(execsp_dtor)
+
+	/* Make execsp_ctor a destructor. */
+	.pushsection .dtors,"aw",@progbits
+	.p2align 2
+	.word	execsp_dtor
+	.popsection
diff -r 4650ffe0718a -r f4d9ab8a392c tests/kernel/arch/hppa/signalsphandler.S
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/hppa/signalsphandler.S	Sat Apr 19 19:54:59 2025 +0000
@@ -0,0 +1,48 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define	_LOCORE
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD$")
+
+	.text
+
+/*
+ * signalsphandler(signo@arg0)
+ *
+ *	Signal handler.  Store the stack pointer on entry at the global
+ *	variable signalsp and return.
+ */
+LEAF_ENTRY(signalsphandler)
+	addil	LT%_C_LABEL(signalsp), %r19	/* r1 := &signalsp */
+	ldw	RT%_C_LABEL(signalsp)(%r1), %r1
+	bv	%r0(%rp)			/* return */
+	 stw	%sp, 0(%r1)			/* signalsp := sp */
+EXIT(signalsphandler)
diff -r 4650ffe0718a -r f4d9ab8a392c tests/kernel/arch/hppa/stack_pointer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/kernel/arch/hppa/stack_pointer.h	Sat Apr 19 19:54:59 2025 +0000
@@ -0,0 +1,35 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2025 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef	TESTS_KERNEL_ARCH_HPPA_STACK_POINTER_H
+#define	TESTS_KERNEL_ARCH_HPPA_STACK_POINTER_H
+
+#define MISALIGN_SP	__asm __volatile("ldo 1(%%sp),%%sp" ::: "memory")
+#define FIX_SP		__asm __volatile("ldo -1(%%sp),%%sp" ::: "memory")
+
+#endif	/* TESTS_KERNEL_ARCH_HPPA_STACK_POINTER_H */


Home | Main Index | Thread Index | Old Index