diff options
Diffstat (limited to 'kernel/arch/vax')
| -rw-r--r-- | kernel/arch/vax/execregs.c | 166 | ||||
| -rw-r--r-- | kernel/arch/vax/execregs.h | 77 | ||||
| -rw-r--r-- | kernel/arch/vax/h_execregs.S | 87 |
3 files changed, 330 insertions, 0 deletions
diff --git a/kernel/arch/vax/execregs.c b/kernel/arch/vax/execregs.c new file mode 100644 index 000000000000..414b810336d8 --- /dev/null +++ b/kernel/arch/vax/execregs.c @@ -0,0 +1,166 @@ +/* $NetBSD: execregs.c,v 1.1 2025/02/27 00:55:32 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. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: execregs.c,v 1.1 2025/02/27 00:55:32 riastradh Exp $"); + +#include "execregs.h" + +#include <errno.h> +#include <spawn.h> +#include <stddef.h> +#include <unistd.h> + +extern char **environ; + +static unsigned long +nonnull(unsigned long x) +{ + + x |= x << 8; + x |= x << 16; + return x; +} + +int +execregschild(char *path) +{ + /* fp: frame pointer, nonnull */ + /* ap: argument pointer, on user stack, nonnull */ + /* sp: stack pointer, nonnull */ + register long r0 __asm("r0") = nonnull(0x10); + register long r1 __asm("r1") = nonnull(1); + register long r2 __asm("r2") = nonnull(2); + register long r3 __asm("r3") = nonnull(3); + register long r4 __asm("r4") = nonnull(4); + register long r5 __asm("r5") = nonnull(5); + register long r6 __asm("r6") = nonnull(6); + register long r7 __asm("r7") = nonnull(7); + register long r8 __asm("r8") = nonnull(8); + register long r9 __asm("r9") = nonnull(9); + register long r10 __asm("r10") = nonnull(10); + register long r11 __asm("r11") = nonnull(11); + /* pc: user PC, will be nonnull */ + /* psl: processor status longword, will be nonnull */ + + char *argv[] = {path, NULL}; + char **envp = environ; + + /* + * Not perfect -- compiler might use some registers for + * stack/argument transfers, but all the arguments are nonnull + * so this is probably a good test anyway. + */ + __asm volatile("" : + "+r"(r0), + "+r"(r1), + "+r"(r2), + "+r"(r3), + "+r"(r4), + "+r"(r5), + "+r"(r6), + "+r"(r7), + "+r"(r8), + "+r"(r9), + "+r"(r10), + "+r"(r11) + :: "memory"); + + return execve(path, argv, envp); +} + +pid_t +spawnregschild(char *path, int fd) +{ + /* fp: frame pointer, nonnull */ + /* ap: argument pointer, on user stack, nonnull */ + /* sp: stack pointer, nonnull */ + register long r0 __asm("r0") = nonnull(0x10); + register long r1 __asm("r1") = nonnull(1); + register long r2 __asm("r2") = nonnull(2); + register long r3 __asm("r3") = nonnull(3); + register long r4 __asm("r4") = nonnull(4); + register long r5 __asm("r5") = nonnull(5); + register long r6 __asm("r6") = nonnull(6); + register long r7 __asm("r7") = nonnull(7); + register long r8 __asm("r8") = nonnull(8); + register long r9 __asm("r9") = nonnull(9); + register long r10 __asm("r10") = nonnull(10); + register long r11 __asm("r11") = nonnull(11); + /* pc: user PC, will be nonnull */ + /* psl: processor status longword, will be nonnull */ + + char *argv[] = {path, NULL}; + char **envp = environ; + posix_spawn_file_actions_t fileacts; + posix_spawnattr_t attr; + pid_t pid; + int error; + + error = posix_spawn_file_actions_init(&fileacts); + if (error) + goto out; + error = posix_spawn_file_actions_adddup2(&fileacts, fd, STDOUT_FILENO); + if (error) + goto out; + error = posix_spawnattr_init(&attr); + if (error) + goto out; + + /* + * Not perfect -- compiler might use some registers for + * stack/argument transfers, but all the arguments are nonnull + * so this is probably a good test anyway. + */ + __asm volatile("" : + "+r"(r0), + "+r"(r1), + "+r"(r2), + "+r"(r3), + "+r"(r4), + "+r"(r5), + "+r"(r6), + "+r"(r7), + "+r"(r8), + "+r"(r9), + "+r"(r10), + "+r"(r11) + :: "memory"); + + error = posix_spawn(&pid, path, &fileacts, &attr, argv, envp); + if (error) + goto out; + +out: posix_spawnattr_destroy(&attr); + posix_spawn_file_actions_destroy(&fileacts); + if (error) { + errno = error; + return -1; + } + return 0; +} diff --git a/kernel/arch/vax/execregs.h b/kernel/arch/vax/execregs.h new file mode 100644 index 000000000000..882bcd1b6702 --- /dev/null +++ b/kernel/arch/vax/execregs.h @@ -0,0 +1,77 @@ +/* $NetBSD: execregs.h,v 1.1 2025/02/27 00:55:32 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. + */ + +#ifndef TESTS_KERNEL_ARCH_VAX_EXECREGS_H +#define TESTS_KERNEL_ARCH_VAX_EXECREGS_H + +#include <sys/cdefs.h> + +#define NEXECREGS 12 + +#ifndef _LOCORE + +#include <unistd.h> + +/* + * The order matches that in struct trapframe in + * sys/arch/vax/include/trap.h + * + * Must match h_execregs.S. + * + * See also sys/arch/vax/vax/trap.c:setregs() + */ +static const char *const regname[] = { + "fp", /* Stack frame pointer */ + "ap", /* Argument pointer on user stack */ + /* sp: stack pointer */ + "r0", /* General registers saved upon trap/syscall */ + "r1", + "r2", + "r3", + "r4", + "r5", + /* r6: initial stack pointer */ + "r7", + "r8", + /* r9: ps_strings */ + "r10", + "r11", + /* trap: type of trap, not a register */ + /* code: trap specific code, not a register */ + /* pc: user PC */ + /* psl: processor status longword */ +}; + +__CTASSERT(NEXECREGS == __arraycount(regname)); + +int execregschild(char *); +pid_t spawnregschild(char *, int); + +#endif /* _LOCORE */ + +#endif /* TESTS_KERNEL_ARCH_VAX_EXECREGS_H */ diff --git a/kernel/arch/vax/h_execregs.S b/kernel/arch/vax/h_execregs.S new file mode 100644 index 000000000000..27c5c2052867 --- /dev/null +++ b/kernel/arch/vax/h_execregs.S @@ -0,0 +1,87 @@ +/* $NetBSD: h_execregs.S,v 1.1 2025/02/27 00:55:32 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 <sys/syscall.h> + +#include <machine/asm.h> + +#include "execregs.h" + +#define REGSIZE 4 +#define BUFSIZE (NEXECREGS * REGSIZE) +#define SLOT(n) (n)*REGSIZE(%sp) + +ENTRY(execregs_start, 0) + /* store registers to a buffer on stack */ + subl2 $BUFSIZE,%sp /* space for NEXECREGS registers */ + movl %fp,SLOT(0) /* order matches execregs.h */ + movl %ap,SLOT(1) + /* sp: stack pointer */ + movl %r0,SLOT(2) + movl %r1,SLOT(3) + movl %r2,SLOT(4) + movl %r3,SLOT(5) + movl %r4,SLOT(6) + movl %r5,SLOT(7) + /* r6: initial stack pointer */ + movl %r7,SLOT(8) + movl %r8,SLOT(9) + /* r9: ps_strings */ + movl %r10,SLOT(10) + movl %r11,SLOT(11) + + /* call write(STDOUT_FILENO, regs, sizeof(regs)) */ + pushl $BUFSIZE /* arg2 := sizeof(regs) */ + pushal 4(%sp) /* arg1 := regs */ + pushl $1 /* arg0 := STDOUT_FILENO */ + pushl $3 /* number of arguments */ + movl %sp,%ap /* argument pointer */ + chmk $SYS_write + + bcs 2f /* bail if write failed */ + cmpl $BUFSIZE,%r0 /* bail if wrote wrong # of bytes */ + bneq 2f + + /* call exit(0) */ + pushl $0 /* arg0 := 0 */ +1: pushl $1 /* number of arguments */ + movl %sp,%ap /* argument pointer */ + chmk $SYS_exit + .word 0xffff /* paranoia -- illegal opcode */ + +2: /* call exit(127) */ + pushl $127 /* arg0 := 127 */ + jmp 1b +END(execregs_start) + +/* main stub to simplify linking */ +ENTRY(main, 0) + .word 0xffff /* illegal opcode */ +END(main) |
