2

pinning all system calls

 9 months ago
source link: https://marc.info/?l=openbsd-tech&m=170205367232026&w=2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

'pinning all system calls'

[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openbsd-tech
Subject:    pinning all system calls
From:       "Theo de Raadt" <deraadt () openbsd ! org>
Date:       2023-12-08 16:36:04
Message-ID: 26208.1702053364 () cvs ! openbsd ! org
[Download RAW message or body]

First, the backstory.

A few years ago I made changes so that system calls
could only be perform from 4 places in the address space:
  1) in the text of a static binary
  2) in the signal trampoline
  3) in ld.so text, and in that case the main program's text cannot do
     system calls
  4) in libc.so text, and ld.so tells the kernel where that is
The first 3 were cases were configured entirely by the kernel, the 4th case
used a new msyscall(2) system call to identify the correct libc.so region.

More recently, I made another change, so that the execve(2) system call could
only be called from a singular, precise point in a static binary or in libc.so.

These changes attempt to disrupt methodologies commonly used in attacks.  I
make no claim these changes stop all methods.  Combined with other behaviours
we have (like libc random relinking), they will require an attacker to use
other methods, which are hopefully more fragile.  Increasing the unknown and
requiring specific entry points increases the fragility and difficulty.
Another benefit is that it requires unique methodology for OpenBSD, which
requirements investment.

I have about 5 steps coming in the near future.  Here is one of those steps.

A few years ago immediately after msyscall(2), nayden@ asked me if it
was possible for the kernel to know validate the locations of system
call, and I proceeded to tell him a bunch of reasons this was
impossible, mostly relating to information not known, and cost
complexity.  But it hung around in my lower brain and I eventually had
to do it.

A system call stub generally looks something like this:

  xx:   b8 05 00 00 00          mov    $0x5,%eax
  xx:   0f 05                   syscall 

This means "perform operation #5, which is open(2)"

Inside the kernel, we know the system call # and the address of the syscall
instruction.

I add a non-LOAD ELF extension (program header and section header) called
"openbsd.syscalls".  This is found in ld.so(1) and the libc.so library
and in the system call stubs as .o files in libc.a for static binaries,
and also in static binaries that are linked against this new libc.a.

(There is no new risk from having this (unmapped non-LOAD) information
in the libc.so file, because an attacker with access to the file can
already use a debugger to find the specific offsets.  This format is
just easier for the kernel and ld.so to handle)

It is an array of { offset, system call # }.  For static binaries and ld.so(1),
the kernel parses this array and creates a new array attached to the process
which is indexed by the system call number, which has values: 0 (system call
not allowed), 1 (allowed, and we don't care about the address), or a specific
offset inside the ELF binary where the system call instruction is for that
specific system call number.

Like with msyscall(2) before, ld.so(1) does the same job of parsing the
"openbsd.syscalls" in libc.so, and uses a new pinsyscall(2) system call to
tell the kernel where the system calls are allowed to enter form.

Like msyscal(2) before, this results in 4 places that system calls can
come from:

  1) in the text of a static binary, because the kernel loaded a table for
     *ONLY* the system calls linked into the binary.  It's important to
     realize what this means, by example.  The ping(1) binary does not call
     execve(2) or fork(2).  So now you can't ever call fork() or execve()
     because there is no "syscall" instruction for those two system calls.
     It also cannot call accept(2).

  2) in the signal trampoline, we only accept sigreturn(2).  sigreturn(2)
     never occurs anwhere else.  This is a 2nd layer of SROP mitigation.

  3) The syscall instructions inside ld.so(1) text can only call the
     system calls it has stubs for, and each stub can only call the specific
     system call it is intended to call.

  4) in libc.so's table, all the system call stub "syscall instructions"
     are registered.    

There is an outstanding issue with syscall(2), which is SYS_syscall, or
syscall #0, the indirect system call.  That dangerous API is no longer
required and will be deleted soon.

A few pieces of this have been pre-commited to make development easier
(in particular, lld and ld.bfd support by kettenis@ so the toolchain
will propogate the ELF tables correctly, and a stub pinsyscall(2) system
call to avoid chicken-and-egg failures.)

5 architectures now work: amd64 i386 sparc64 powerpc64 mips64, some of
the .S files may still have subtle bugs for other architectures.


Index: sys/kern/exec_elf.c
===================================================================
RCS file: /cvs/src/sys/kern/exec_elf.c,v
diff -u -p -u -r1.183 exec_elf.c
--- sys/kern/exec_elf.c	12 Jul 2023 19:34:14 -0000	1.183
+++ sys/kern/exec_elf.c	6 Dec 2023 05:08:25 -0000
@@ -81,6 +81,7 @@
 #include <sys/ptrace.h>
 #include <sys/signalvar.h>
 #include <sys/pledge.h>
+#include <sys/syscall.h>
 
 #include <sys/mman.h>
 
@@ -97,6 +98,8 @@ void	elf_load_psection(struct exec_vmcmd
 	    Elf_Phdr *, Elf_Addr *, Elf_Addr *, int *, int);
 int	elf_os_pt_note_name(Elf_Note *);
 int	elf_os_pt_note(struct proc *, struct exec_package *, Elf_Ehdr *, int *);
+int	elf_read_pintable(struct proc *, Elf_Phdr *ph, struct vnode *, Elf_Ehdr *,
+	    uint **pinp);
 
 /* round up and down to page boundaries. */
 #define ELF_ROUND(a, b)		(((a) + (b) - 1) & ~((b) - 1))
@@ -265,6 +268,48 @@ elf_read_from(struct proc *p, struct vno
 	return (0);
 }
 
+int
+elf_read_pintable(struct proc *p, Elf_Phdr *pp, struct vnode *vp,
+    Elf_Ehdr *eh, uint **pinp)
+{
+	struct pinsyscalls {
+		u_int offset;
+		u_int sysno;
+	} *syscalls = NULL;
+	int i, npins = 0, nsyscalls;
+	uint *pins = NULL;
+
+	nsyscalls = pp->p_filesz / sizeof(*syscalls);
+	if (pp->p_filesz != nsyscalls * sizeof(*syscalls))
+		goto bad;
+	syscalls = malloc(pp->p_filesz, M_PINSYSCALL, M_WAITOK);
+	if (elf_read_from(p, vp, pp->p_offset, syscalls,
+	    pp->p_filesz) != 0) {
+		goto bad;
+	}
+
+	for (i = 0; i < nsyscalls; i++)
+		npins = MAX(npins, syscalls[i].sysno);
+	npins = MAX(npins, SYS_kbind);		/* XXX see ld.so/loader.c */
+	npins++;
+
+	pins = mallocarray(npins, sizeof(int), M_PINSYSCALL, M_WAITOK|M_ZERO);
+	for (i = 0; i < nsyscalls; i++) {
+		if (pins[syscalls[i].sysno])
+			pins[syscalls[i].sysno] = -1;	/* duplicated */
+		else
+			pins[syscalls[i].sysno] = syscalls[i].offset;
+	}
+	pins[SYS_kbind] = -1;			/* XXX see ld.so/loader.c */
+
+	*pinp = pins;
+	pins = NULL;
+bad:
+	free(syscalls, M_PINSYSCALL, nsyscalls * sizeof(*syscalls));
+	free(pins, M_PINSYSCALL, npins * sizeof(uint));
+	return npins;
+}
+
 /*
  * Load a file (interpreter/library) pointed to by path [stolen from
  * coff_load_shlib()]. Made slightly generic so it might be used externally.
@@ -276,7 +321,7 @@ elf_load_file(struct proc *p, char *path
 	int error, i;
 	struct nameidata nd;
 	Elf_Ehdr eh;
-	Elf_Phdr *ph = NULL;
+	Elf_Phdr *ph = NULL, *syscall_ph = NULL;
 	u_long phsize = 0;
 	Elf_Addr addr;
 	struct vnode *vp;
@@ -461,12 +506,29 @@ elf_load_file(struct proc *p, char *path
 			NEW_VMCMD(&epp->ep_vmcmds, vmcmd_mutable,
 			    ph[i].p_memsz, ph[i].p_vaddr + pos, NULLVP, 0, 0);
 			break;
-
+		case PT_OPENBSD_SYSCALLS:
+			syscall_ph = &ph[i];
+			break;
 		default:
 			break;
 		}
 	}
 
+	if (syscall_ph) {
+		struct process *pr = p->p_p;
+		uint *pins;
+		int npins;
+
+		npins = elf_read_pintable(p, syscall_ph, nd.ni_vp, &eh, &pins);
+		if (npins) {
+			pr->ps_pin.start = pos;
+			pr->ps_pin.end = pos + addr;
+			pr->ps_pin.p = pins;
+			pr->ps_pin.np = npins;
+			pr->ps_flags |= PS_PIN;
+		}
+	}
+
 	vn_marktext(nd.ni_vp);
 
 bad1:
@@ -491,8 +553,8 @@ int
 exec_elf_makecmds(struct proc *p, struct exec_package *epp)
 {
 	Elf_Ehdr *eh = epp->ep_hdr;
-	Elf_Phdr *ph, *pp, *base_ph = NULL;
-	Elf_Addr phdr = 0, exe_base = 0;
+	Elf_Phdr *ph, *pp, *base_ph = NULL, *syscall_ph = NULL;
+	Elf_Addr phdr = 0, exe_base = 0, exe_end = 0;
 	int error, i, has_phdr = 0, names = 0, textrel = 0;
 	char *interp = NULL;
 	u_long phsize;
@@ -696,6 +758,9 @@ exec_elf_makecmds(struct proc *p, struct
 						epp->ep_tsize = addr+size -
 						    epp->ep_taddr;
 				}
+				if (interp == NULL)
+					exe_end = epp->ep_taddr +
+					    epp->ep_tsize;	/* end of TEXT */
 			}
 			break;
 
@@ -735,13 +800,30 @@ exec_elf_makecmds(struct proc *p, struct
 			NEW_VMCMD(&epp->ep_vmcmds, vmcmd_mutable,
 			    ph[i].p_memsz, ph[i].p_vaddr + exe_base, NULLVP, 0, 0);
 			break;
-
+		case PT_OPENBSD_SYSCALLS:
+			if (interp == NULL)
+				syscall_ph = &ph[i];
+			break;
 		default:
 			/*
 			 * Not fatal, we don't need to understand everything
 			 * :-)
 			 */
 			break;
+		}
+	}
+
+	if (syscall_ph) {
+		uint *pins;
+		int npins;
+
+		npins = elf_read_pintable(p, syscall_ph, epp->ep_vp, eh, &pins);
+		if (npins) {
+			epp->ep_pinbase = exe_base;
+			epp->ep_pinend = exe_end;
+			epp->ep_pins = pins;
+			epp->ep_npins = npins;
+			p->p_p->ps_flags |= PS_PIN;
 		}
 	}
 
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exec.c,v
diff -u -p -u -r1.252 kern_exec.c
--- sys/kern/kern_exec.c	30 Oct 2023 07:13:10 -0000	1.252
+++ sys/kern/kern_exec.c	7 Dec 2023 14:38:58 -0000
@@ -314,6 +314,8 @@ sys_execve(struct proc *p, void *v, regi
 	VMCMDSET_INIT(&pack.ep_vmcmds);
 	pack.ep_vap = &attr;
 	pack.ep_flags = 0;
+	pack.ep_pins = NULL;
+	pack.ep_npins = 0;
 
 	/* see if we can run it. */
 	if ((error = check_exec(p, &pack)) != 0) {
@@ -514,6 +516,27 @@ sys_execve(struct proc *p, void *v, regi
 	if (copyout(&arginfo, (char *)pr->ps_strings, sizeof(arginfo)))
 		goto exec_abort;
 
+	free(pr->ps_pin.p, M_PINSYSCALL, pr->ps_pin.np * sizeof(uint));
+	if (pack.ep_npins) {
+		pr->ps_pin.start = pack.ep_pinbase;
+		pr->ps_pin.end = pack.ep_pinend;
+		pr->ps_pin.p = pack.ep_pins;
+		pack.ep_pins = NULL;
+		pr->ps_pin.np = pack.ep_npins;
+		pr->ps_flags |= PS_PIN;
+	} else {
+		pr->ps_pin.start = pr->ps_pin.end = pr->ps_pin.np = 0;
+		pr->ps_pin.p = NULL;
+		pr->ps_flags &= ~PS_PIN;
+	}
+	if (pr->ps_libcpin.p) {
+		free(pr->ps_libcpin.p, M_PINSYSCALL,
+		    pr->ps_libcpin.np * sizeof(uint));
+		pr->ps_libcpin.p = NULL;
+		pr->ps_libcpin.start = pr->ps_libcpin.end = 0;
+		pr->ps_flags &= ~PS_LIBCPIN;
+	}
+
 	stopprofclock(pr);	/* stop profiling */
 	fdcloseexec(p);		/* handle close on exec */
 	execsigs(p);		/* reset caught signals */
@@ -752,6 +775,7 @@ bad:
 	if (pack.ep_interp != NULL)
 		pool_put(&namei_pool, pack.ep_interp);
 	free(pack.ep_args, M_TEMP, sizeof *pack.ep_args);
+	free(pack.ep_pins, M_PINSYSCALL, pack.ep_npins * sizeof(uint));
 	/* close and put the exec'd file */
 	vn_close(pack.ep_vp, FREAD, cred, p);
 	pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
Index: sys/kern/kern_exit.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_exit.c,v
diff -u -p -u -r1.217 kern_exit.c
--- sys/kern/kern_exit.c	29 Sep 2023 12:47:34 -0000	1.217
+++ sys/kern/kern_exit.c	4 Dec 2023 13:55:33 -0000
@@ -215,6 +215,10 @@ exit1(struct proc *p, int xexit, int xsi
 
 		unveil_destroy(pr);
 
+		free(pr->ps_libcpin.p, M_PINSYSCALL,
+		    pr->ps_libcpin.np * sizeof(uint));
+		free(pr->ps_pin.p, M_PINSYSCALL, pr->ps_pin.np * sizeof(uint));
+
 		/*
 		 * If parent has the SAS_NOCLDWAIT flag set, we're not
 		 * going to become a zombie.
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_fork.c,v
diff -u -p -u -r1.253 kern_fork.c
--- sys/kern/kern_fork.c	24 Oct 2023 13:20:11 -0000	1.253
+++ sys/kern/kern_fork.c	6 Dec 2023 04:58:41 -0000
@@ -248,6 +248,21 @@ process_new(struct proc *p, struct proce
 	if (parent->ps_session->s_ttyvp != NULL)
 		pr->ps_flags |= parent->ps_flags & PS_CONTROLT;
 
+	if (parent->ps_libcpin.p) {
+		pr->ps_libcpin.p = malloc(parent->ps_libcpin.np * sizeof(uint),
+		    M_PINSYSCALL, M_WAITOK);
+		memcpy(pr->ps_libcpin.p, parent->ps_libcpin.p,
+		    parent->ps_libcpin.np * sizeof(uint));
+		pr->ps_flags |= PS_LIBCPIN;
+	}
+	if (parent->ps_pin.p) {
+		pr->ps_pin.p = malloc(parent->ps_pin.np * sizeof(uint),
+		    M_PINSYSCALL, M_WAITOK);
+		memcpy(pr->ps_pin.p, parent->ps_pin.p,
+		    parent->ps_pin.np * sizeof(uint));
+		pr->ps_flags |= PS_PIN;
+	}
+
 	/*
 	 * Duplicate sub-structures as needed.
 	 * Increase reference counts on shared objects.
Index: sys/kern/kern_ktrace.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_ktrace.c,v
diff -u -p -u -r1.112 kern_ktrace.c
--- sys/kern/kern_ktrace.c	11 May 2023 09:51:33 -0000	1.112
+++ sys/kern/kern_ktrace.c	7 Dec 2023 14:26:31 -0000
@@ -401,6 +401,24 @@ ktrpledge(struct proc *p, int error, uin
 	atomic_clearbits_int(&p->p_flag, P_INKTR);
 }
 
+void
+ktrpinsyscall(struct proc *p, int error, int syscall, vaddr_t addr)
+{
+	struct ktr_header kth;
+	struct ktr_pinsyscall kp;
+
+	atomic_setbits_int(&p->p_flag, P_INKTR);
+	ktrinitheader(&kth, p, KTR_PINSYSCALL);
+	kp.error = error;
+	kp.syscall = syscall;
+	kp.addr = addr;
+
+	KERNEL_LOCK();
+	ktrwrite(p, &kth, &kp, sizeof(kp));
+	KERNEL_UNLOCK();
+	atomic_clearbits_int(&p->p_flag, P_INKTR);
+}
+
 /* Interface and common routines */
 
 int
Index: sys/kern/kern_pledge.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_pledge.c,v
diff -u -p -u -r1.309 kern_pledge.c
--- sys/kern/kern_pledge.c	29 Sep 2023 12:47:34 -0000	1.309
+++ sys/kern/kern_pledge.c	19 Nov 2023 20:40:45 -0000
@@ -113,6 +113,7 @@ const uint64_t pledge_syscalls[SYS_MAXSY
 	[SYS_thrkill] = PLEDGE_ALWAYS,		/* raise, abort, stack pro */
 	[SYS_utrace] = PLEDGE_ALWAYS,		/* ltrace(1) from ld.so */
 	[SYS_pinsyscall] = PLEDGE_ALWAYS,
+	[SYS_pinsyscalls] = PLEDGE_ALWAYS,
 
 	/* "getting" information about self is considered safe */
 	[SYS_getuid] = PLEDGE_STDIO,
Index: sys/sys/acct.h
===================================================================
RCS file: /cvs/src/sys/sys/acct.h,v
diff -u -p -u -r1.13 acct.h
--- sys/sys/acct.h	21 Feb 2023 14:31:07 -0000	1.13
+++ sys/sys/acct.h	3 Dec 2023 19:31:15 -0000
@@ -67,6 +67,7 @@ struct acct {
 #define	ATRAP	0x00000040		/* memory access violation */
 #define	AUNVEIL	0x00000080		/* unveil access violation */
 #define	AEXECVE	0x00000100		/* execve from wrong libc stub */
+#define	APINSYS	0x00000200		/* syscall pin violation */
 	u_int32_t ac_flag;		/* accounting flags */
 };
 
Index: sys/sys/exec.h
===================================================================
RCS file: /cvs/src/sys/sys/exec.h,v
diff -u -p -u -r1.52 exec.h
--- sys/sys/exec.h	19 Apr 2023 15:37:36 -0000	1.52
+++ sys/sys/exec.h	26 Nov 2023 04:41:56 -0000
@@ -131,6 +131,9 @@ struct exec_package {
 	struct	elf_args *ep_args;	/* ELF info */
 	void	*ep_auxinfo;		/* userspace auxinfo address */
 	char	*ep_interp;		/* name of interpreter if any */
+	int	*ep_pins;
+	int	ep_npins;
+	u_long	ep_pinbase, ep_pinend;
 };
 #define	EXEC_INDIR	0x0001		/* script handling already done */
 #define	EXEC_HASFD	0x0002		/* holding a shell script */
Index: sys/sys/ktrace.h
===================================================================
RCS file: /cvs/src/sys/sys/ktrace.h,v
diff -u -p -u -r1.46 ktrace.h
--- sys/sys/ktrace.h	23 Feb 2023 01:33:20 -0000	1.46
+++ sys/sys/ktrace.h	7 Dec 2023 14:26:56 -0000
@@ -169,6 +169,16 @@ struct ktr_pledge {
 };
 
 /*
+ * KTR_PINSYSCALL - details of pinsyscall violation
+ */
+#define	KTR_PINSYSCALL	13
+struct ktr_pinsyscall {
+	int		error;
+	int		syscall;
+	vaddr_t		addr;
+};
+
+/*
  * kernel trace points (in ps_traceflag)
  */
 #define KTRFAC_MASK	0x00ffffff
@@ -182,6 +192,7 @@ struct ktr_pledge {
 #define KTRFAC_EXECARGS	(1<<KTR_EXECARGS)
 #define KTRFAC_EXECENV	(1<<KTR_EXECENV)
 #define	KTRFAC_PLEDGE	(1<<KTR_PLEDGE)
+#define	KTRFAC_PINSYSCALL	(1<<KTR_PINSYSCALL)
 
 /*
  * trace flags (also in ps_traceflag)
@@ -214,6 +225,7 @@ void ktrsysret(struct proc *, register_t
 int ktruser(struct proc *, const char *, const void *, size_t);
 void ktrexec(struct proc *, int, const char *, ssize_t);
 void ktrpledge(struct proc *, int, uint64_t, int);
+void ktrpinsyscall(struct proc *, int, int, vaddr_t);
 
 void ktrcleartrace(struct process *);
 void ktrsettrace(struct process *, int, struct vnode *, struct ucred *);
Index: sys/sys/malloc.h
===================================================================
RCS file: /cvs/src/sys/sys/malloc.h,v
diff -u -p -u -r1.125 malloc.h
--- sys/sys/malloc.h	3 Jul 2023 06:45:44 -0000	1.125
+++ sys/sys/malloc.h	4 Dec 2023 13:52:41 -0000
@@ -177,7 +177,9 @@
 
 #define	M_DRM		145	/* Direct Rendering Manager */
 
-#define	M_LAST		146	/* Must be last type + 1 */
+#define	M_PINSYSCALL	146	/* pinsyscall */
+
+#define	M_LAST		147	/* Must be last type + 1 */
 
 #define	INITKMEMNAMES { \
 	"free",		/* 0 M_FREE */ \
@@ -307,6 +309,7 @@
 	NULL,	/* 143 free */ \
 	"AGP Memory",	/* 144 M_AGP */ \
 	"DRM",	/* 145 M_DRM */ \
+	"pinsyscall",	/* 146 M_PINSYSCALL */ \
 }
 
 struct kmemstats {
Index: sys/sys/proc.h
===================================================================
RCS file: /cvs/src/sys/sys/proc.h,v
diff -u -p -u -r1.352 proc.h
--- sys/sys/proc.h	29 Sep 2023 12:47:34 -0000	1.352
+++ sys/sys/proc.h	6 Dec 2023 04:59:09 -0000
@@ -117,6 +117,13 @@ struct tslpentry;
 TAILQ_HEAD(tslpqueue, tslpentry);
 struct unveil;
 
+struct syscallpin {
+	vaddr_t		start;
+	vaddr_t		end;
+	uint		*p;	/* array of offsets, indexed by syscall# */
+	int		np;	/* number of entries in table */
+};
+
 /*
  * Locks used to protect struct members in this file:
  *	I	immutable after creation
@@ -240,6 +247,9 @@ struct process {
 /* an address that can't be in userspace or kernelspace */
 #define	BOGO_PC	(u_long)-1
 
+	struct syscallpin ps_pin;
+	struct syscallpin ps_libcpin;
+
 /* End area that is copied on creation. */
 #define ps_endcopy	ps_threadcnt
 	u_int	ps_threadcnt;		/* Number of threads. */
@@ -283,6 +293,8 @@ struct process {
 #define	PS_CHROOT	0x01000000	/* Process is chrooted */
 #define	PS_NOBTCFI	0x02000000	/* No Branch Target CFI */
 #define	PS_ITIMER	0x04000000	/* Virtual interval timers running */
+#define	PS_PIN		0x08000000	/* ld.so or static syscall pin */
+#define	PS_LIBCPIN	0x10000000	/* libc.so or static syscall pin */
 
 #define	PS_BITS \
     ("\20" "\01CONTROLT" "\02EXEC" "\03INEXEC" "\04EXITING" "\05SUGID" \
Index: sys/sys/syscall_mi.h
===================================================================
RCS file: /cvs/src/sys/sys/syscall_mi.h,v
diff -u -p -u -r1.28 syscall_mi.h
--- sys/sys/syscall_mi.h	11 Feb 2023 23:07:23 -0000	1.28
+++ sys/sys/syscall_mi.h	8 Dec 2023 14:34:46 -0000
@@ -33,8 +33,11 @@
 
 #include <sys/param.h>
 #include <sys/pledge.h>
+#include <sys/acct.h>
+#include <sys/syslog.h>
 #include <sys/tracepoint.h>
 #include <sys/syscall.h>
+#include <sys/signalvar.h>
 #include <uvm/uvm_extern.h>
 
 #ifdef KTRACE
@@ -46,6 +49,75 @@
 #include <dev/dt/dtvar.h>
 #endif
 
+/*
+ * Check if a system call is entered from precisely correct location
+ */
+static inline int
+pin_check(struct proc *p, register_t code)
+{
+	extern char sigcode[], sigcodecall[], sigcoderet[];
+	struct syscallpin *pin = NULL;
+	struct process *pr = p->p_p;
+	int error = 0;
+	vaddr_t addr;
+
+	/* point at start of syscall instruction */
+	addr = PROC_PC(p) - (long)(sigcoderet - sigcodecall);
+
+	/*
+	 * System calls come from 4 places:
+	 * 1) sigtramp, only sigreturn(2)
+	 * 2) dynamic binary, in libc.so (in the ps_libcpin region)
+	 * 3) ld.so (in the ps_pin region)
+	 * 4) static binary contains syscalls anywhere (in the ps_pin region)
+	 */
+	if (code == SYS_sigreturn) {
+		vaddr_t saddr = PROC_PC(p) - (long)(sigcoderet - sigcode);
+
+		if ((vaddr_t)pr->ps_sigcode == saddr)
+			return 0;
+		error = EPERM;
+	} else if (pr->ps_libcpin.start &&
+	    addr >= pr->ps_libcpin.start && addr < pr->ps_libcpin.end)
+		pin = &pr->ps_libcpin;
+	else if (pr->ps_pin.start &&
+	    addr >= pr->ps_pin.start && addr < pr->ps_pin.end)
+		pin = &pr->ps_pin;
+
+	if (pin) {
+		if (code > pin->np || pin->p[code] == 0)
+			error = ENOSYS;
+		else if (pin->p[code] + pin->start == addr)
+			; /* correct location */
+		else if (pin->p[code] == (uint)-1)
+			; /* multiple locations, hopefully a boring operation */
+		else
+			error = ENOSYS;
+	}
+	if (error == 0)
+		return 0;
+#ifdef KTRACE
+	if (KTRPOINT(p, KTR_PINSYSCALL))
+		ktrpinsyscall(p, error, code, addr);
+#endif
+	KERNEL_LOCK();
+	log(LOG_ERR,
+	    "%s[%d]: syscall %ld@%lx, off %d, pin (%lx-%lx) libcpin (%lx-%lx)\n",
+	    p->p_p->ps_comm, p->p_p->ps_pid, code, addr, pin->p[code],
+	    pr->ps_pin.start, pr->ps_pin.end,
+	    pr->ps_libcpin.start, pr->ps_libcpin.end);
+        p->p_p->ps_acflag |= APINSYS;
+
+	/* Try to stop threads immediately, because this process is suspect */
+	if (P_HASSIBLING(p))
+		single_thread_set(p, SINGLE_UNWIND | SINGLE_DEEP);
+
+	/* Send uncatchable SIGABRT for coredump */
+	sigabort(p);
+
+	KERNEL_UNLOCK();
+	return error;
+}
 
 /*
  * The MD setup for a system call has been done; here's the MI part.
@@ -97,6 +169,9 @@ mi_syscall(struct proc *p, register_t co
 	    "[%s]%d/%d pc=%lx inside %lx-%lx: bogus syscall\n",
 	    uvm_map_inentry_pc, p->p_vmspace->vm_map.wserial))
 		return (EPERM);
+
+	if ((error = pin_check(p, code)))
+		return (error);
 
 	pledged = (p->p_p->ps_flags & PS_PLEDGE);
 	if (pledged && (error = pledge_syscall(p, code, &tval))) {
Index: sys/uvm/uvm_mmap.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_mmap.c,v
diff -u -p -u -r1.183 uvm_mmap.c
--- sys/uvm/uvm_mmap.c	7 Dec 2023 13:59:05 -0000	1.183
+++ sys/uvm/uvm_mmap.c	8 Dec 2023 14:05:10 -0000
@@ -644,13 +644,59 @@ sys_pinsyscall(struct proc *p, void *v, 
 	return (0);
 }
 
- /*
+/*
  * sys_pinsyscalls
  */
 int
 sys_pinsyscalls(struct proc *p, void *v, register_t *retval)
 {
-	/* STUB until other parts are ready */
+	struct sys_pinsyscalls_args /* {
+		syscallarg(void *) base;
+		syscallarg(size_t) len;
+		syscallarg(void *) pins;
+		syscallarg(size_t) pinslen;
+	} */ *uap = v;
+	struct process *pr = p->p_p;
+	vaddr_t addr;
+	vsize_t size;
+	uint *pins;
+	size_t npins;
+	int error, i;
+
+	addr = (vaddr_t)SCARG(uap, base);
+	size = (vsize_t)SCARG(uap, len);
+	if (addr > SIZE_MAX - size)
+		return EINVAL;		/* disallow wrap-around. */
+
+	/* XXX MP unlock */
+
+	if (pr->ps_libcpin.start)
+		return (EINVAL);	/* Perhaps we should be more firm? */
+	
+	npins = SCARG(uap, pinslen) / sizeof(uint);
+	if (npins * sizeof(uint) != SCARG(uap, pinslen))
+		return (EINVAL);
+
+	pins = malloc(SCARG(uap, pinslen), M_PINSYSCALL, M_WAITOK|M_ZERO);
+	if (pins == NULL)
+		return (ENOMEM);
+	error = copyin(SCARG(uap, pins), pins, SCARG(uap, pinslen));
+	if (error)
+		goto err;
+	/* Range-check offsets */
+	for (i = 0; i < npins; i++)
+		if (pins[i] != (uint)-1 && pins[i] >= SCARG(uap, len))
+			error = ERANGE;
+	if (error) {
+err:
+		free(pins, M_PINSYSCALL, SCARG(uap, pinslen));
+		return (error);
+	}
+	pr->ps_libcpin.start = (vaddr_t)SCARG(uap, base);
+	pr->ps_libcpin.end = (vaddr_t)SCARG(uap, base) + SCARG(uap, len);
+	pr->ps_libcpin.p = pins;
+	pr->ps_libcpin.np = npins;
+	pr->ps_flags |= PS_LIBCPIN;
 	return (0);
 }
 
Index: sys/arch/alpha/alpha/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/locore.s,v
diff -u -p -u -r1.53 locore.s
--- sys/arch/alpha/alpha/locore.s	6 Dec 2023 06:15:33 -0000	1.53
+++ sys/arch/alpha/alpha/locore.s	6 Dec 2023 06:37:06 -0000
@@ -202,6 +202,8 @@ NESTED(sigcode,0,0,ra,0,0)
 	ldq	a0, 0(sp)		/* get the sigcontext pointer */
 	lda	sp, 16(sp)
 	ldiq	v0, SYS_sigreturn	/* and call sigreturn() with it. */
+	.globl	sigcodecall
+sigcodecall:
 	call_pal PAL_OSF1_callsys
 	.globl  sigcoderet
 sigcoderet:
Index: sys/arch/amd64/amd64/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/locore.S,v
diff -u -p -u -r1.141 locore.S
--- sys/arch/amd64/amd64/locore.S	24 Oct 2023 13:20:09 -0000	1.141
+++ sys/arch/amd64/amd64/locore.S	11 Nov 2023 16:59:04 -0000
@@ -176,6 +176,8 @@ sigcode:
 	movq	%rsp,%rdi
 	pushq	%rdi			/* fake return address */
 	movq	$SYS_sigreturn,%rax
+	.globl sigcodecall
+sigcodecall:
 	syscall
 	.globl	sigcoderet
 sigcoderet:
Index: sys/arch/arm/arm/sigcode.S
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/sigcode.S,v
diff -u -p -u -r1.12 sigcode.S
--- sys/arch/arm/arm/sigcode.S	8 Dec 2022 01:25:44 -0000	1.12
+++ sys/arch/arm/arm/sigcode.S	4 Dec 2023 15:11:38 -0000
@@ -56,6 +56,8 @@ sigcode:
 /*	mov	r0, sp */
 	add	r0, sp, #SIGF_SC
 	mov	r12, #SYS_sigreturn
+	.globl	sigcodecall
+sigcodecall:
 	swi	0
 	dsb	nsh
 	isb
Index: sys/arch/arm64/arm64/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/locore.S,v
diff -u -p -u -r1.43 locore.S
--- sys/arch/arm64/arm64/locore.S	26 Jan 2023 13:09:18 -0000	1.43
+++ sys/arch/arm64/arm64/locore.S	4 Dec 2023 15:12:01 -0000
@@ -365,6 +365,8 @@ sigcode:
 	add	x0, x0, #SF_SC
 
 	mov	x8, #SYS_sigreturn
+	.globl sigcodecall
+sigcodecall:
 	svc	0
 	dsb	nsh
 	isb
Index: sys/arch/hppa/hppa/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/locore.S,v
diff -u -p -u -r1.205 locore.S
--- sys/arch/hppa/hppa/locore.S	24 Oct 2023 13:20:10 -0000	1.205
+++ sys/arch/hppa/hppa/locore.S	3 Dec 2023 16:06:02 -0000
@@ -2866,8 +2866,10 @@ sigcode_call
 	ldil	L%SYSCALLGATE, r1
 	copy	r4, arg0
 	.call
+	.globl	sigcodecall
+sigcodecall:
 	ble	4(sr7, r1)
-	ldi	SYS_sigreturn, t1
+	 ldi	SYS_sigreturn, t1
 	.globl  sigcoderet
 sigcoderet:
 
Index: sys/arch/i386/i386/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/locore.s,v
diff -u -p -u -r1.202 locore.s
--- sys/arch/i386/i386/locore.s	24 Oct 2023 13:20:10 -0000	1.202
+++ sys/arch/i386/i386/locore.s	3 Dec 2023 16:05:48 -0000
@@ -341,6 +341,8 @@ sigcode:
 	pushl	%eax
 	pushl	%eax			# junk to fake return address
 	movl	$SYS_sigreturn,%eax
+	.globl	sigcodecall
+sigcodecall:
 	int	$0x80			# enter kernel with args on stack
 	.globl	sigcoderet
 sigcoderet:
Index: sys/arch/macppc/macppc/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/locore.S,v
diff -u -p -u -r1.62 locore.S
--- sys/arch/macppc/macppc/locore.S	24 Oct 2023 13:20:10 -0000	1.62
+++ sys/arch/macppc/macppc/locore.S	3 Dec 2023 16:05:46 -0000
@@ -1175,6 +1175,8 @@ sigcode:
 	lfd	%f13,104(%r6)
 	addi	%r3,%r1,((16+FPSIG_SIZEOF+15)&~0xf)+SF_SC	/* compute &sf_sc */
 	li	%r0,SYS_sigreturn
+	.globl	sigcodecall
+sigcodecall:
 	sc				/* sigreturn(scp) */
 	.globl	sigcoderet
 sigcoderet:
Index: sys/arch/mips64/mips64/lcore_access.S
===================================================================
RCS file: /cvs/src/sys/arch/mips64/mips64/lcore_access.S,v
diff -u -p -u -r1.34 lcore_access.S
--- sys/arch/mips64/mips64/lcore_access.S	31 Jan 2023 15:18:55 -0000	1.34
+++ sys/arch/mips64/mips64/lcore_access.S	3 Dec 2023 16:05:44 -0000
@@ -75,6 +75,8 @@ onfault_table:
 sigcode:
 	PTR_ADDU a0, sp, 4*REGSZ		# address of sigcontext
 	LI	v0, SYS_sigreturn	# sigreturn(scp)
+	.globl	sigcodecall
+sigcodecall:
 	syscall
 	.globl	sigcoderet
 sigcoderet:
Index: sys/arch/powerpc64/powerpc64/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/powerpc64/powerpc64/locore.S,v
diff -u -p -u -r1.46 locore.S
--- sys/arch/powerpc64/powerpc64/locore.S	24 Oct 2023 13:20:10 -0000	1.46
+++ sys/arch/powerpc64/powerpc64/locore.S	3 Dec 2023 16:05:42 -0000
@@ -31,14 +31,16 @@
 	.rodata
 
 	.globl sigcode
-	.globl sigcoderet
 sigcode:
 	addi	%r1, %r1, -32
 	mtctr	%r12
 	bctrl
 	addi	%r3, %r1, 32+SF_SC
 	li	%r0, SYS_sigreturn
+	.globl	sigcodecall
+sigcodecall:
 	sc
+	.globl sigcoderet
 sigcoderet:
 	li	%r0, SYS_exit
 	sc
Index: sys/arch/riscv64/riscv64/locore.S
===================================================================
RCS file: /cvs/src/sys/arch/riscv64/riscv64/locore.S,v
diff -u -p -u -r1.15 locore.S
--- sys/arch/riscv64/riscv64/locore.S	2 Dec 2022 12:27:08 -0000	1.15
+++ sys/arch/riscv64/riscv64/locore.S	3 Dec 2023 16:05:30 -0000
@@ -250,8 +250,9 @@ ENTRY(sigcode)
 	mv	a0, sp
 	addi	a0, a0, SF_SC
 	li	t0, SYS_sigreturn
+	.globl	sigcodecall
+sigcodecall:
 	ecall
-
 	.globl sigcoderet
 sigcoderet:
 	/* sigreturn failed, exit */
Index: sys/arch/sh/sh/locore_subr.S
===================================================================
RCS file: /cvs/src/sys/arch/sh/sh/locore_subr.S,v
diff -u -p -u -r1.17 locore_subr.S
--- sys/arch/sh/sh/locore_subr.S	24 Oct 2023 13:20:10 -0000	1.17
+++ sys/arch/sh/sh/locore_subr.S	3 Dec 2023 16:05:27 -0000
@@ -497,6 +497,8 @@ NENTRY(proc_trampoline)
 NENTRY(sigcode)
 	mov	r15, r4			/* get pointer to sigcontext */
 	mov.l	.L_SYS_sigreturn, r0
+	.globl	sigcodecall
+sigcodecall:
 	trapa	#0x80			/* and call sigreturn() */
 	.globl	sigcoderet
 sigcoderet:
Index: sys/arch/sparc64/sparc64/locore.s
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/locore.s,v
diff -u -p -u -r1.202 locore.s
--- sys/arch/sparc64/sparc64/locore.s	24 Oct 2023 13:20:11 -0000	1.202
+++ sys/arch/sparc64/sparc64/locore.s	3 Dec 2023 16:05:22 -0000
@@ -5399,6 +5399,8 @@ sigcode:
 !	andn	%o0, 0x0f, %o0
 	.globl	sigcoderet
 sigcoderet:
+	.globl	sigcodecall
+sigcodecall:
 	t	ST_SYSCALL		! sigreturn(scp)
 	! sigreturn does not return unless it fails
 	mov	SYS_exit, %g1		! exit(errno)
Index: lib/libc/arch/DEFS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/DEFS.h,v
diff -u -p -u -r1.1 DEFS.h
--- lib/libc/arch/DEFS.h	1 Jan 2022 23:47:14 -0000	1.1
+++ lib/libc/arch/DEFS.h	7 Dec 2023 19:26:47 -0000
@@ -67,3 +67,9 @@
 #endif
 
 #define _END(x)		.size x, . - x
+
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/aarch64/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/aarch64/SYS.h,v
diff -u -p -u -r1.6 SYS.h
--- lib/libc/arch/aarch64/SYS.h	8 Dec 2022 01:25:43 -0000	1.6
+++ lib/libc/arch/aarch64/SYS.h	4 Dec 2023 15:06:43 -0000
@@ -53,7 +53,8 @@
 
 #define SYSTRAP(x) \
 	ldr	x8, =SYS_ ## x;		\
-	svc	0;			\
+97:	svc	0;			\
+	PINSYSCALL(SYS_ ## x, 97b);	\
 	dsb	nsh;			\
 	isb
 
Index: lib/libc/arch/alpha/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/alpha/SYS.h,v
diff -u -p -u -r1.16 SYS.h
--- lib/libc/arch/alpha/SYS.h	6 Dec 2023 06:15:33 -0000	1.16
+++ lib/libc/arch/alpha/SYS.h	8 Dec 2023 13:45:46 -0000
@@ -56,6 +56,12 @@
  */
 #define _END(x)		.size x, . - x
 
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
+
 /*
  * For functions implemented in ASM that aren't syscalls.
  *   END_STRONG(x)	Like DEF_STRONG() in C; for standard/reserved C names
@@ -67,7 +73,8 @@
 
 #define	CALLSYS_NOERROR(name)					\
 	ldiq	v0, ___CONCAT(SYS_,name);			\
-	call_pal PAL_OSF1_callsys
+97:	call_pal PAL_OSF1_callsys;				\
+	PINSYSCALL(SYSCALLNUM(name), 97b)			\
 
 #define	CALLSYS_ERROR(name)					\
 	CALLSYS_NOERROR(name);					\
Index: lib/libc/arch/amd64/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/amd64/SYS.h,v
diff -u -p -u -r1.21 SYS.h
--- lib/libc/arch/amd64/SYS.h	11 Jan 2023 01:55:17 -0000	1.21
+++ lib/libc/arch/amd64/SYS.h	4 Dec 2023 15:06:20 -0000
@@ -41,7 +41,11 @@
 /* offsetof(struct tib, tib_errno) - offsetof(struct tib, __tib_tcb) */
 #define	TCB_OFFSET_ERRNO	32
 
-#define SYSTRAP(x)	movl $(SYS_ ## x),%eax; movq %rcx, %r10; syscall
+#define SYSTRAP(x)							\
+	movl $(SYS_ ## x),%eax;						\
+	movq %rcx, %r10;						\
+97:	syscall;							\
+	PINSYSCALL(SYS_ ## x, 97b)
 
 #define SYSENTRY(x)							\
 	SYSENTRY_HIDDEN(x);						\
Index: lib/libc/arch/amd64/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/amd64/gen/setjmp.S,v
diff -u -p -u -r1.9 setjmp.S
--- lib/libc/arch/amd64/gen/setjmp.S	21 Oct 2020 17:22:59 -0000	1.9
+++ lib/libc/arch/amd64/gen/setjmp.S	4 Dec 2023 14:58:32 -0000
@@ -64,7 +64,8 @@ ENTRY(setjmp)
 	movl	$1,%edi			/* how = SIG_BLOCK */
 	xorl	%esi,%esi		/* set = empty */
 	movl	$SYS_sigprocmask,%eax
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	movq	%r8,%rdi		/* restore jmpbuf addr */
 	movq	%rax,(_JB_SIGMASK * 8)(%rdi)
 
@@ -100,7 +101,8 @@ ENTRY(longjmp)
 	movq	(_JB_SIGMASK * 8)(%rdi),%rsi	/* get set from sc_mask */
 	movl	$3,%edi				/* how = SIG_SETMASK */
 	movl	$SYS_sigprocmask,%eax
-	syscall
+98:	syscall
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	movl	%r8d,%eax
 
 	leaq	 __jmpxor(%rip),%rcx
Index: lib/libc/arch/amd64/gen/sigsetjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/amd64/gen/sigsetjmp.S,v
diff -u -p -u -r1.9 sigsetjmp.S
--- lib/libc/arch/amd64/gen/sigsetjmp.S	21 Oct 2020 17:22:59 -0000	1.9
+++ lib/libc/arch/amd64/gen/sigsetjmp.S	4 Dec 2023 14:58:20 -0000
@@ -62,7 +62,8 @@ ENTRY(sigsetjmp)
 	movl	$1,%edi			/* how = SIG_BLOCK */
 	xorl	%esi,%esi		/* set = empty */
 	movl	$SYS_sigprocmask,%eax
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	movq	%r8,%rdi		/* restore jmpbuf addr */
 	movq	%rax,(_JB_SIGMASK * 8)(%rdi)
 
@@ -100,7 +101,8 @@ ENTRY(siglongjmp)
 	movq	(_JB_SIGMASK * 8)(%rdi),%rsi	/* get set from sc_mask */
 	movl	$3,%edi				/* how = SIG_SETMASK */
 	movl	$SYS_sigprocmask,%eax
-	syscall
+98:	syscall
+	PINSYSCALL(SYS_sigprocmask, 98b)
 2:	movl	%r8d,%eax
 
 	leaq	 __jmpxor(%rip),%rcx
Index: lib/libc/arch/amd64/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/amd64/sys/tfork_thread.S,v
diff -u -p -u -r1.11 tfork_thread.S
--- lib/libc/arch/amd64/sys/tfork_thread.S	11 Jan 2023 01:55:17 -0000	1.11
+++ lib/libc/arch/amd64/sys/tfork_thread.S	4 Dec 2023 14:58:09 -0000
@@ -56,7 +56,8 @@ ENTRY(__tfork_thread)
 	 */
 	movl	$SYS___tfork, %eax
 	.cfi_endproc
-	syscall
+99:	syscall
+	PINSYSCALL(SYS___tfork, 99b)
 	jb 	2f
 
 	/*
@@ -90,7 +91,8 @@ ENTRY(__tfork_thread)
 	 */
 	movl	$SYS___threxit, %eax
 	xorl	%edi, %edi
-	syscall
+98:	syscall
+	PINSYSCALL(SYS___threxit, 98b)
 	int3
 
 	/*
Index: lib/libc/arch/arm/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/arm/SYS.h,v
diff -u -p -u -r1.19 SYS.h
--- lib/libc/arch/arm/SYS.h	8 Dec 2022 01:25:43 -0000	1.19
+++ lib/libc/arch/arm/SYS.h	4 Dec 2023 15:06:14 -0000
@@ -54,7 +54,8 @@
 
 #define SYSTRAP(x) \
 	ldr	r12, =SYS_ ## x;			\
-	swi	0;					\
+97:	swi	0;					\
+	PINSYSCALL(SYS_ ## x, 97b);			\
 	dsb	nsh;					\
 	isb
 
Index: lib/libc/arch/hppa/DEFS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/hppa/DEFS.h,v
diff -u -p -u -r1.1 DEFS.h
--- lib/libc/arch/hppa/DEFS.h	28 Aug 1998 20:59:40 -0000	1.1
+++ lib/libc/arch/hppa/DEFS.h	7 Dec 2023 19:26:59 -0000
@@ -1,3 +1,9 @@
 /*	$OpenBSD: DEFS.h,v 1.1 1998/08/28 20:59:40 mickey Exp $	*/
 
 #include <machine/asm.h>
+
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/hppa/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/hppa/SYS.h,v
diff -u -p -u -r1.23 SYS.h
--- lib/libc/arch/hppa/SYS.h	11 Feb 2023 06:10:39 -0000	1.23
+++ lib/libc/arch/hppa/SYS.h	8 Dec 2023 13:46:17 -0000
@@ -84,8 +84,9 @@ LEAF_ENTRY(__CONCAT(_thread_sys_,x))
 #define	SYSCALL(x)				!\
 	stw	rp, HPPA_FRAME_ERP(sr0,sp)	!\
 	ldil	L%SYSCALLGATE, r1		!\
-	ble	4(sr7, r1)			!\
-	ldi	__CONCAT(SYS_,x), t1		!\
+97:	ble	4(sr7, r1)			!\
+	PINSYSCALL(__CONCAT(SYS_,x), 97b)	!\
+	 ldi	__CONCAT(SYS_,x), t1		!\
 	comb,=	0, t1, 1f			!\
 	ldw	HPPA_FRAME_ERP(sr0,sp), rp	!\
 	/* set errno */				\
@@ -113,8 +114,9 @@ SYSEXIT_HIDDEN(x)
 SYSENTRY(x)					!\
 	stw	rp, HPPA_FRAME_ERP(sr0,sp)	!\
 	ldil	L%SYSCALLGATE, r1		!\
-	ble	4(sr7, r1)			!\
-	ldi	__CONCAT(SYS_,y), t1		!\
+97:	ble	4(sr7, r1)			!\
+	PINSYSCALL(__CONCAT(SYS_,x), 97b)	!\
+	 ldi	__CONCAT(SYS_,y), t1		!\
 	ldw	HPPA_FRAME_ERP(sr0,sp), rp	!\
 	bv	r0(rp)				!\
 	nop					!\
@@ -122,4 +124,3 @@ SYSEXIT(x)
 
 #define	RSYSCALL(x)		PSEUDO(x,x)
 #define	RSYSCALL_HIDDEN(x)	PSEUDO_HIDDEN(x,x)
-
Index: lib/libc/arch/hppa/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/hppa/gen/setjmp.S,v
diff -u -p -u -r1.11 setjmp.S
--- lib/libc/arch/hppa/gen/setjmp.S	29 May 2016 07:59:36 -0000	1.11
+++ lib/libc/arch/hppa/gen/setjmp.S	4 Dec 2023 14:57:58 -0000
@@ -63,7 +63,8 @@ ALTENTRY(setjmp)
 	copy	%r0, %arg1		; set = empty
 	stw	%rp, HPPA_FRAME_ERP(%sr0,%sp)
 	ldil	L%SYSCALLGATE, %r1
-	ble	4(%sr7, %r1)
+99:	ble	4(%sr7, %r1)
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	 ldi	SYS_sigprocmask, %t1
 	ldw	HPPA_FRAME_ERP(%sr0,%sp), %rp
 
@@ -129,7 +130,8 @@ ALTENTRY(longjmp)
 	ldi	3, %arg0		; how = SIG_SETMASK
 	stw	%rp, HPPA_FRAME_ERP(%sr0,%sp)
 	ldil	L%SYSCALLGATE, %r1
-	ble	4(%sr7, %r1)
+98:	ble	4(%sr7, %r1)
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	 ldi	SYS_sigprocmask, %t1
 	ldw	HPPA_FRAME_ERP(%sr0,%sp), %rp
 
Index: lib/libc/arch/hppa/sys/Ovfork.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/hppa/sys/Ovfork.S,v
diff -u -p -u -r1.15 Ovfork.S
--- lib/libc/arch/hppa/sys/Ovfork.S	7 May 2016 19:05:21 -0000	1.15
+++ lib/libc/arch/hppa/sys/Ovfork.S	4 Dec 2023 14:57:44 -0000
@@ -32,8 +32,9 @@ SYSENTRY_HIDDEN(vfork)
 	.import errno, data
 	copy	rp, t4
 	ldil	L%SYSCALLGATE, r1
-	ble	4(sr7, r1)
-	ldi	__CONCAT(SYS_,vfork), t1
+99:	ble	4(sr7, r1)
+	PINSYSCALL(__CONCAT(SYS_,vfork), 99b)
+	 ldi	__CONCAT(SYS_,vfork), t1
 	comb,=	r0, t1, 1f
 	copy	t4, rp
 	/* set errno */
Index: lib/libc/arch/i386/DEFS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/DEFS.h,v
diff -u -p -u -r1.3 DEFS.h
--- lib/libc/arch/i386/DEFS.h	29 Nov 2017 05:13:57 -0000	1.3
+++ lib/libc/arch/i386/DEFS.h	7 Dec 2023 19:26:54 -0000
@@ -47,3 +47,9 @@
 #else
 #define	END_BUILTIN(x)	END_STRONG(x)
 #endif
+
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/i386/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/SYS.h,v
diff -u -p -u -r1.27 SYS.h
--- lib/libc/arch/i386/SYS.h	29 Nov 2017 05:13:57 -0000	1.27
+++ lib/libc/arch/i386/SYS.h	4 Dec 2023 15:05:56 -0000
@@ -59,7 +59,9 @@
 
 #define	__DO_SYSCALL(x)					\
 			movl $(SYS_ ## x),%eax;		\
-			int $0x80
+		97:	int $0x80;			\
+			PINSYSCALL(SYS_ ## x, 97b)
+
 
 #define SET_ERRNO()					\
 	movl	%eax,%gs:(TCB_OFFSET_ERRNO);		\
Index: lib/libc/arch/i386/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/gen/setjmp.S,v
diff -u -p -u -r1.14 setjmp.S
--- lib/libc/arch/i386/gen/setjmp.S	13 Dec 2020 21:21:32 -0000	1.14
+++ lib/libc/arch/i386/gen/setjmp.S	4 Dec 2023 14:57:33 -0000
@@ -59,7 +59,8 @@ ENTRY(setjmp)
 	pushl	$1			/* how = SIG_BLOCK */
 	call	1f
 1:	movl	$(SYS_sigprocmask),%eax
-	int	$0x80			/* leave oset in %eax */
+99:	int	$0x80			/* leave oset in %eax */
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	popl	%edx
 	addl	$8,%esp
 	addl	$__jmpxor-1b,%edx	# load cookie address
@@ -89,7 +90,8 @@ ENTRY(longjmp)
 	pushl	$3			/* how = SIG_SETMASK */
 	call	1f			/* get our eip */
 1:	movl	$(SYS_sigprocmask),%eax
-	int	$0x80
+98:	int	$0x80
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	popl	%ecx
 	addl	$8,%esp
 	addl	$__jmpxor-1b,%ecx	# load cookie address
Index: lib/libc/arch/i386/gen/sigsetjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/gen/sigsetjmp.S,v
diff -u -p -u -r1.13 sigsetjmp.S
--- lib/libc/arch/i386/gen/sigsetjmp.S	13 Dec 2020 21:21:32 -0000	1.13
+++ lib/libc/arch/i386/gen/sigsetjmp.S	4 Dec 2023 14:57:20 -0000
@@ -47,7 +47,8 @@ ENTRY(sigsetjmp)
 	pushl	$1			/* how = SIG_BLOCK */
 	subl	$4,%esp
 	movl	$(SYS_sigprocmask),%eax
-	int	$0x80			/* leave oset in %eax */
+99:	int	$0x80			/* leave oset in %eax */
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	addl	$12,%esp
 	movl	%eax,(_JB_SIGMASK * 4)(%ecx)
 
@@ -81,7 +82,8 @@ ENTRY(siglongjmp)
 	pushl	$3			/* how = SIG_SETMASK */
 	subl	$4,%esp
 	movl	$(SYS_sigprocmask),%eax
-	int	$0x80
+98:	int	$0x80
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	addl	$12,%esp
 
 1:	call	2f
Index: lib/libc/arch/i386/sys/Ovfork.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/sys/Ovfork.S,v
diff -u -p -u -r1.10 Ovfork.S
--- lib/libc/arch/i386/sys/Ovfork.S	7 May 2016 19:05:21 -0000	1.10
+++ lib/libc/arch/i386/sys/Ovfork.S	4 Dec 2023 14:57:07 -0000
@@ -36,7 +36,8 @@
 SYSENTRY_HIDDEN(vfork)
 	popl	%ecx		/* my rta into ecx */
 	movl	$(SYS_vfork),%eax
-	int	$0x80
+99:	int	$0x80
+	PINSYSCALL(SYS_vfork, 99b)
 	HANDLE_ERRNO()
 	jmp	*%ecx
 SYSCALL_END_HIDDEN(vfork)
Index: lib/libc/arch/i386/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/sys/brk.S,v
diff -u -p -u -r1.15 brk.S
--- lib/libc/arch/i386/sys/brk.S	4 Dec 2022 08:22:13 -0000	1.15
+++ lib/libc/arch/i386/sys/brk.S	4 Dec 2023 14:56:59 -0000
@@ -54,7 +54,8 @@ ENTRY_NB(brk)
 	movl	%ecx,4(%esp)
 1:
 	movl	$(SYS_break),%eax
-	int	$0x80
+99:	int	$0x80
+	PINSYSCALL(SYS_break, 99b)
 	jc	2f
 	PIC_PROLOGUE
 	movl	PIC_GOT(__curbrk),%edx	# set up GOT addressing
@@ -71,7 +72,8 @@ ENTRY_NB(brk)
 	movl	%ecx,4(%esp)
 1:
 	movl	$(SYS_break),%eax
-	int	$0x80
+98:	int	$0x80
+	PINSYSCALL(SYS_break, 98b)
 	jc	2f
 	xorl	%eax,%eax
 	movl	%ecx,__curbrk
Index: lib/libc/arch/i386/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/sys/sbrk.S,v
diff -u -p -u -r1.15 sbrk.S
--- lib/libc/arch/i386/sys/sbrk.S	4 Dec 2022 08:22:13 -0000	1.15
+++ lib/libc/arch/i386/sys/sbrk.S	4 Dec 2023 14:56:43 -0000
@@ -51,7 +51,8 @@ ENTRY_NB(sbrk)
 	movl	(%edx),%eax
 	addl	%eax,4(%esp)
 	movl	$(SYS_break),%eax
-	int	$0x80
+99:	int	$0x80
+	PINSYSCALL(SYS_break, 99b)
 	jc	2f
 	PIC_PROLOGUE
 	movl	PIC_GOT(__curbrk),%edx
@@ -65,7 +66,8 @@ ENTRY_NB(sbrk)
 	movl	__curbrk,%eax
 	addl	%eax,4(%esp)
 	movl	$(SYS_break),%eax
-	int	$0x80
+98:	int	$0x80
+	PINSYSCALL(SYS_break, 98b)
 	jc	2f
 	movl	__curbrk,%eax
 	addl	%ecx,__curbrk
Index: lib/libc/arch/i386/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/sys/sigprocmask.S,v
diff -u -p -u -r1.12 sigprocmask.S
--- lib/libc/arch/i386/sys/sigprocmask.S	7 May 2016 19:05:21 -0000	1.12
+++ lib/libc/arch/i386/sys/sigprocmask.S	4 Dec 2023 14:56:30 -0000
@@ -43,7 +43,8 @@ SYSENTRY_HIDDEN(sigprocmask)
 1:	movl	(%ecx),%ecx		# fetch indirect  ...
 	movl	%ecx,8(%esp)		# to new mask arg
 2:	movl	$(SYS_sigprocmask),%eax
-	int	$0x80
+99:	int	$0x80
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	jc	1f
 	movl	12(%esp),%ecx		# fetch old mask requested
 	testl	%ecx,%ecx		# test if old mask requested
Index: lib/libc/arch/i386/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/sys/sigsuspend.S,v
diff -u -p -u -r1.10 sigsuspend.S
--- lib/libc/arch/i386/sys/sigsuspend.S	7 May 2016 19:05:21 -0000	1.10
+++ lib/libc/arch/i386/sys/sigsuspend.S	4 Dec 2023 14:56:20 -0000
@@ -38,7 +38,8 @@ SYSENTRY_HIDDEN(sigsuspend)
 	movl	(%eax),%eax		# indirect to mask arg
 	movl	%eax,4(%esp)
 	movl	$(SYS_sigsuspend),%eax
-	int	$0x80
+99:	int	$0x80
+	PINSYSCALL(SYS_sigsuspend, 99b)
 	SET_ERRNO()
 	ret
 SYSCALL_END_HIDDEN(sigsuspend)
Index: lib/libc/arch/i386/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/i386/sys/tfork_thread.S,v
diff -u -p -u -r1.10 tfork_thread.S
--- lib/libc/arch/i386/sys/tfork_thread.S	18 Oct 2020 14:28:17 -0000	1.10
+++ lib/libc/arch/i386/sys/tfork_thread.S	4 Dec 2023 14:56:11 -0000
@@ -62,7 +62,8 @@ ENTRY(__tfork_thread)
 	pushl	8(%ebp)		# push param
 	pushl	$0		# slot for return address, ignored by kernel
 	movl	$SYS___tfork, %eax
-	int	$0x80
+99:	int	$0x80
+	PINSYSCALL(SYS___tfork, 99b)
 	jb 	2f
 
 	/*
@@ -98,7 +99,8 @@ ENTRY(__tfork_thread)
 	pushl	$0		# NULL pointer argument to __threxit
 	pushl	$0		# slot for return address, ignored by kernel
 	movl	$SYS___threxit, %eax
-	int	$0x80
+98:	int	$0x80
+	PINSYSCALL(SYS___threxit, 98b)
 	int3
 
 	/*
Index: lib/libc/arch/m88k/DEFS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/DEFS.h,v
diff -u -p -u -r1.3 DEFS.h
--- lib/libc/arch/m88k/DEFS.h	22 Sep 2016 18:19:59 -0000	1.3
+++ lib/libc/arch/m88k/DEFS.h	7 Dec 2023 19:26:51 -0000
@@ -23,3 +23,9 @@
  */
 #define	END_STRONG(x)	END(x); _HIDDEN_FALIAS(x,x); END(_HIDDEN(x))
 #define	END_WEAK(x)	END_STRONG(x); .weak x
+
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/m88k/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/SYS.h,v
diff -u -p -u -r1.25 SYS.h
--- lib/libc/arch/m88k/SYS.h	16 Jun 2018 16:06:03 -0000	1.25
+++ lib/libc/arch/m88k/SYS.h	4 Dec 2023 15:05:49 -0000
@@ -80,7 +80,9 @@
 
 #define	__DO_SYSCALL(x)							\
 	or %r13, %r0, __SYSCALLNAME(SYS_,x);				\
-	tb0 0, %r0, 450
+97:	tb0 0, %r0, 450;						\
+	PINSYSCALL(__SYSCALLNAME(SYS_,x), 97b)
+
 
 #define	__SYSCALL__NOERROR(p,x,y)					\
 	__ENTRY(p,x);							\
Index: lib/libc/arch/m88k/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/sys/brk.S,v
diff -u -p -u -r1.14 brk.S
--- lib/libc/arch/m88k/sys/brk.S	10 Sep 2015 13:29:09 -0000	1.14
+++ lib/libc/arch/m88k/sys/brk.S	4 Dec 2023 14:55:57 -0000
@@ -65,7 +65,8 @@ ENTRY(brk)
 1:
 	or	%r4,%r2,0
 	or	%r13,%r0,__SYSCALLNAME(SYS_,break)
-	tb0	0,%r0,450
+99:	tb0	0,%r0,450
+	PINSYSCALL(SYS_break, 99b)
 #ifdef __PIC__
 	br	9f
 #else
Index: lib/libc/arch/m88k/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/sys/sbrk.S,v
diff -u -p -u -r1.14 sbrk.S
--- lib/libc/arch/m88k/sys/sbrk.S	10 Sep 2015 13:29:09 -0000	1.14
+++ lib/libc/arch/m88k/sys/sbrk.S	4 Dec 2023 14:55:44 -0000
@@ -64,7 +64,8 @@ ENTRY(sbrk)
 	add	%r2,%r2,%r5
 	or	%r4,%r2,0
 	or	%r13,%r0,SYS_break
-	tb0	0,%r0,450
+99:	tb0	0,%r0,450
+	PINSYSCALL(SYS_break, 99b)
 #ifdef __PIC__
 	br	9f
 #else
Index: lib/libc/arch/m88k/sys/sigpending.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/sys/sigpending.S,v
diff -u -p -u -r1.10 sigpending.S
--- lib/libc/arch/m88k/sys/sigpending.S	10 Sep 2015 13:29:09 -0000	1.10
+++ lib/libc/arch/m88k/sys/sigpending.S	4 Dec 2023 14:55:36 -0000
@@ -38,7 +38,8 @@
 SYSENTRY(sigpending)
 	or	%r4,%r2,0		/* save r2 */
 	or	%r13,%r0,SYS_sigpending
-	tb0	0,%r0,450
+99:	tb0	0,%r0,450
+	PINSYSCALL(SYS_sigpending, 99b)
 	br	CERROR
 	st	%r2,%r4,0
 	jmp.n	%r1
Index: lib/libc/arch/m88k/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/sys/sigprocmask.S,v
diff -u -p -u -r1.12 sigprocmask.S
--- lib/libc/arch/m88k/sys/sigprocmask.S	23 Oct 2015 04:39:24 -0000	1.12
+++ lib/libc/arch/m88k/sys/sigprocmask.S	4 Dec 2023 14:55:29 -0000
@@ -43,7 +43,8 @@ SYSENTRY_HIDDEN(sigprocmask)
 	ld	%r3,%r3,0		/* else load set from *set and do it */
 2:
 	or	%r13,%r0,SYS_sigprocmask
-	tb0	0,%r0,450
+99:	tb0	0,%r0,450
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	br	CERROR
 	bcnd	eq0,%r4,3f		/* if old mask not requested, done */
 	st	%r2,%r4,0		/* otherwise, set it */
Index: lib/libc/arch/m88k/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/sys/sigsuspend.S,v
diff -u -p -u -r1.13 sigsuspend.S
--- lib/libc/arch/m88k/sys/sigsuspend.S	7 May 2016 19:05:21 -0000	1.13
+++ lib/libc/arch/m88k/sys/sigsuspend.S	4 Dec 2023 14:55:22 -0000
@@ -45,7 +45,8 @@
 SYSENTRY_HIDDEN(sigsuspend)
 	ld	%r2,%r2,0		/* dereference the pointer mask */
 	or	%r13,%r0,SYS_sigsuspend
-	tb0	0,%r0,450
+99:	tb0	0,%r0,450
+	PINSYSCALL(SYS_sigsuspend, 99b)
 	br	CERROR
 	jmp.n	%r1
 	 or	%r2,%r0,0
Index: lib/libc/arch/m88k/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/m88k/sys/tfork_thread.S,v
diff -u -p -u -r1.7 tfork_thread.S
--- lib/libc/arch/m88k/sys/tfork_thread.S	7 Nov 2020 02:52:08 -0000	1.7
+++ lib/libc/arch/m88k/sys/tfork_thread.S	4 Dec 2023 14:55:16 -0000
@@ -34,7 +34,8 @@
  */
 ENTRY(__tfork_thread)
 	or	%r13, %r0,  __SYSCALLNAME(SYS_,__tfork)
-	tb0	0,    %r0,  450	/* corrupts r2 and r3 in the child */
+99:	tb0	0,    %r0,  450	/* corrupts r2 and r3 in the child */
+	PINSYSCALL(SYS___tfork, 99b)
 	br	CERROR
 
 	bcnd	eq0,  %r2,  1f
@@ -52,7 +53,8 @@ ENTRY(__tfork_thread)
 	 or	%r2,  %r5,  %r0	/* arg */
 
 	or	%r13, %r0,  __SYSCALLNAME(SYS_,__threxit)
-	tb0	0,    %r0,  450
+98:	tb0	0,    %r0,  450
+	PINSYSCALL(SYS___threxit, 98b)
 	NOP
 	tb0     0, %r0, 130	/* breakpoint */
 END(__tfork_thread)
Index: lib/libc/arch/mips64/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/SYS.h,v
diff -u -p -u -r1.12 SYS.h
--- lib/libc/arch/mips64/SYS.h	7 May 2016 19:05:22 -0000	1.12
+++ lib/libc/arch/mips64/SYS.h	6 Dec 2023 16:38:10 -0000
@@ -59,15 +59,16 @@
 			.size _HIDDEN(x), . - _HIDDEN(x)
 #define	END_WEAK(x)	END_STRONG(x); .weak x
 
-
 #define CERROR		__cerror
 	.hidden	CERROR
 
 # define __ENTRY(p,x)		ENTRY(p ## x)
 
-# define __DO_SYSCALL(x)				\
-				li	v0,SYS_ ## x;	\
-				syscall
+# define __DO_SYSCALL(x)					\
+				li	v0,SYS_ ## x;		\
+			97:	syscall;			\
+				PINSYSCALL(SYS_ ## x, 97b)	\
+
 
 # define __LEAF2(p,x,sz)	LEAF(p ## x, sz) \
 				WEAK_ALIAS(x, p ## x);
@@ -124,3 +125,8 @@
 #define	SYSCALL_END(x)		__END2(_thread_sys_,x)
 #define	SYSCALL_END_HIDDEN(x)	__END2_HIDDEN(_thread_sys_,x)
 
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/mips64/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/gen/setjmp.S,v
diff -u -p -u -r1.12 setjmp.S
--- lib/libc/arch/mips64/gen/setjmp.S	8 Jan 2018 16:44:32 -0000	1.12
+++ lib/libc/arch/mips64/gen/setjmp.S	4 Dec 2023 14:54:53 -0000
@@ -60,7 +60,8 @@ LEAF(setjmp, FRAMESZ)
 	li	a0, 1				# how = SIG_BLOCK
 	move	a1, zero			# get current signal mask
 	li	v0, SYS_sigprocmask
-	syscall					# mask in v0
+99:	syscall				# mask in v0
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	bne	a3, zero, botch
 	REG_S	v0, _JB_MASK(a2)		# save sc_mask
 
@@ -132,7 +133,8 @@ LEAF(longjmp, FRAMESZ)
 	REG_L	a1, _JB_MASK(a2)		# load sc_mask
 	li	a0, 3				# how = SIG_SETMASK
 	li	v0, SYS_sigprocmask
-	syscall
+98:	syscall
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	bne	a3, zero, botch
 
 	REG_L	v0, _JB_REGS+ZERO*REGSZ(a2)
Index: lib/libc/arch/mips64/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/sys/brk.S,v
diff -u -p -u -r1.10 brk.S
--- lib/libc/arch/mips64/sys/brk.S	8 Dec 2022 01:25:43 -0000	1.10
+++ lib/libc/arch/mips64/sys/brk.S	4 Dec 2023 14:54:41 -0000
@@ -55,7 +55,8 @@ LEAF(brk, FRAMESZ)
 	move	a0, v0		# dont allow break < minbrk
 1:
 	li	v0, SYS_break
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_break, 99b)
 	bne	a3, zero, 2f
 	PTR_S	a0, __curbrk
 	move	v0, zero
Index: lib/libc/arch/mips64/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/sys/sbrk.S,v
diff -u -p -u -r1.10 sbrk.S
--- lib/libc/arch/mips64/sys/sbrk.S	8 Dec 2022 01:25:43 -0000	1.10
+++ lib/libc/arch/mips64/sys/sbrk.S	4 Dec 2023 14:54:36 -0000
@@ -52,7 +52,8 @@ LEAF(sbrk, FRAMESZ)
 	PTR_L	v1, __curbrk
 	li	v0, SYS_break
 	PTR_ADDU a0, a0, v1	# compute current break
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_break, 99b)
 
 	bne	a3, zero, 1f
 	move	v0, v1		# return old val of curbrk from above
Index: lib/libc/arch/mips64/sys/sigpending.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/sys/sigpending.S,v
diff -u -p -u -r1.7 sigpending.S
--- lib/libc/arch/mips64/sys/sigpending.S	23 Oct 2015 04:39:24 -0000	1.7
+++ lib/libc/arch/mips64/sys/sigpending.S	4 Dec 2023 14:54:28 -0000
@@ -41,7 +41,8 @@ SYSLEAF(sigpending, FRAMESZ)
 	SETUP_GP64(GPOFF, _HIDDEN(sigpending))
 	.set	reorder
 	li	v0, SYS_sigpending
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_sigpending, 99b)
 	bne	a3, zero, 1f
 	sw	v0, 0(a0)
 	move	v0, zero
Index: lib/libc/arch/mips64/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/sys/sigprocmask.S,v
diff -u -p -u -r1.7 sigprocmask.S
--- lib/libc/arch/mips64/sys/sigprocmask.S	23 Oct 2015 04:39:24 -0000	1.7
+++ lib/libc/arch/mips64/sys/sigprocmask.S	4 Dec 2023 14:54:18 -0000
@@ -47,7 +47,8 @@ SYSLEAF_HIDDEN(sigprocmask, FRAMESZ)
 	lw	a1, 0(a1)		# indirect to new mask arg
 .Ldoit:
 	li	v0, SYS_sigprocmask
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	bne	a3, zero, .Lerr
 	beq	a2, zero, .Lout		# test if old mask requested
 	sw	v0, 0(a2)		# store old mask
Index: lib/libc/arch/mips64/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/mips64/sys/sigsuspend.S,v
diff -u -p -u -r1.7 sigsuspend.S
--- lib/libc/arch/mips64/sys/sigsuspend.S	7 May 2016 19:05:22 -0000	1.7
+++ lib/libc/arch/mips64/sys/sigsuspend.S	4 Dec 2023 14:54:13 -0000
@@ -42,7 +42,8 @@ SYSLEAF_HIDDEN(sigsuspend, FRAMESZ)
 	.set	reorder
 	lw	a0, 0(a0)		# indirect to mask arg
 	li	v0, SYS_sigsuspend
-	syscall
+99:	syscall
+	PINSYSCALL(SYS_sigsuspend, 99b)
 	bne	a3, zero, 1f
 	move	v0, zero		# should not happen
 	RESTORE_GP64
Index: lib/libc/arch/powerpc/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/SYS.h,v
diff -u -p -u -r1.27 SYS.h
--- lib/libc/arch/powerpc/SYS.h	11 Feb 2023 06:10:39 -0000	1.27
+++ lib/libc/arch/powerpc/SYS.h	4 Dec 2023 15:03:27 -0000
@@ -64,7 +64,8 @@
 #define	PSEUDO_NOERROR(x,y)	SYSENTRY(x)				\
 				RETGUARD_SETUP(x, %r11, %r12);		\
 				li	%r0, SYS_ ## y ;		\
-				sc;					\
+			97:	sc;					\
+				PINSYSCALL(SYS_ ## y, 97b);		\
 				RETGUARD_CHECK(x, %r11, %r12);		\
 				blr;					\
 				__END(x)
@@ -72,7 +73,8 @@
 #define	PSEUDO_HIDDEN(x,y)	SYSENTRY_HIDDEN(x)			\
 				RETGUARD_SETUP(x, %r11, %r12);		\
 				li	%r0, SYS_ ## y;			\
-				sc;					\
+			97:	sc;					\
+				PINSYSCALL(SYS_ ## y, 97b);		\
 				cmpwi	%r0, 0;				\
 				beq+	.L_ret;				\
 				stw	%r0, R2_OFFSET_ERRNO(2);	\
Index: lib/libc/arch/powerpc/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/gen/setjmp.S,v
diff -u -p -u -r1.14 setjmp.S
--- lib/libc/arch/powerpc/gen/setjmp.S	10 Jun 2022 01:56:02 -0000	1.14
+++ lib/libc/arch/powerpc/gen/setjmp.S	4 Dec 2023 14:54:06 -0000
@@ -68,7 +68,9 @@ ENTRY(setjmp)
 	li	3, 1			/* how = SIG_BLOCK */
 	li	4, 0			/* oset = empty */
 	li	0, SYS_sigprocmask
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigprocmask, 99b)
+
 	stw	3, JMP_sig(5)
 	mr	3, 5
 ENTRY(_setjmp)
@@ -125,7 +127,8 @@ ENTRY(longjmp)
 	li	3, 3			/* how = SIG_SETMASK */
 	lwz	4, JMP_sig(5)		/* oset from the jmpbuf */
 	li	0, SYS_sigprocmask
-	sc
+98:	sc
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	mr	3, 5			/* restore jmpbuf and val to r3,r4 */
 	mr	4, 6
 
Index: lib/libc/arch/powerpc/gen/sigsetjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/gen/sigsetjmp.S,v
diff -u -p -u -r1.8 sigsetjmp.S
--- lib/libc/arch/powerpc/gen/sigsetjmp.S	10 Jun 2022 01:56:02 -0000	1.8
+++ lib/libc/arch/powerpc/gen/sigsetjmp.S	4 Dec 2023 14:53:53 -0000
@@ -63,7 +63,8 @@ ENTRY(sigsetjmp)
 	li	3, 1			/* how = SIG_BLOCK */
 	li	4, 0			/* oset = empty */
 	li	0, SYS_sigprocmask
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	stw	3, JMP_sigmask(5)
 1:	mflr	6
 	bcl	20, 31, 2f
@@ -122,7 +123,8 @@ ENTRY(siglongjmp)
 	li	3, 3			/* how = SIG_SETMASK */
 	lwz	4, JMP_sigmask(5)	/* oset from the jmpbuf */
 	li	0, SYS_sigprocmask
-	sc
+98:	sc
+	PINSYSCALL(SYS_sigprocmask, 98b)
 
 1:	bcl	20, 31, 2f
 2:	mflr	9
Index: lib/libc/arch/powerpc/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/sys/brk.S,v
diff -u -p -u -r1.18 brk.S
--- lib/libc/arch/powerpc/sys/brk.S	8 Dec 2022 01:25:43 -0000	1.18
+++ lib/libc/arch/powerpc/sys/brk.S	4 Dec 2023 14:53:39 -0000
@@ -60,7 +60,8 @@ ENTRY_NB(brk)
 #endif
 
 	li	0, SYS_break
-	sc
+99:	sc
+	PINSYSCALL(SYS_break, 99b)
 
 	/* check for error */
 	cmpwi	0, 0
Index: lib/libc/arch/powerpc/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/sys/sbrk.S,v
diff -u -p -u -r1.17 sbrk.S
--- lib/libc/arch/powerpc/sys/sbrk.S	8 Dec 2022 01:25:43 -0000	1.17
+++ lib/libc/arch/powerpc/sys/sbrk.S	4 Dec 2023 14:53:31 -0000
@@ -57,7 +57,8 @@ ENTRY_NB(sbrk)
 	mr	7, 3
 
 	li	0, SYS_break
-	sc
+99:	sc
+	PINSYSCALL(SYS_break, 99b)
 
 	/* check for error */
 	cmpwi	0, 0
Index: lib/libc/arch/powerpc/sys/sigpending.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/sys/sigpending.S,v
diff -u -p -u -r1.8 sigpending.S
--- lib/libc/arch/powerpc/sys/sigpending.S	28 Nov 2020 19:49:30 -0000	1.8
+++ lib/libc/arch/powerpc/sys/sigpending.S	4 Dec 2023 14:53:25 -0000
@@ -24,7 +24,8 @@ SYSENTRY(sigpending)
 	RETGUARD_SETUP(sigpending, %r11, %r12)
 	mr	%r5, %r3
 	li	%r0, SYS_sigpending
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigpending, 99b)
 	stw	%r3, 0(%r5)
 	li	%r3, 0
 	RETGUARD_CHECK(sigpending, %r11, %r12)
Index: lib/libc/arch/powerpc/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/sys/sigprocmask.S,v
diff -u -p -u -r1.14 sigprocmask.S
--- lib/libc/arch/powerpc/sys/sigprocmask.S	28 Nov 2020 19:49:30 -0000	1.14
+++ lib/libc/arch/powerpc/sys/sigprocmask.S	4 Dec 2023 14:53:20 -0000
@@ -46,8 +46,9 @@ SYSENTRY_HIDDEN(sigprocmask)
 .L_do_call:
 
 	li	0, SYS_sigprocmask
-	sc
-	
+99:	sc
+	PINSYSCALL(SYS_sigprocmask, 99b)
+
 	/* didnt work? */
 	cmpwi	0, 0
 	beq+	.L_sigprocmask_ok
Index: lib/libc/arch/powerpc/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/sys/sigsuspend.S,v
diff -u -p -u -r1.7 sigsuspend.S
--- lib/libc/arch/powerpc/sys/sigsuspend.S	28 Nov 2020 19:49:30 -0000	1.7
+++ lib/libc/arch/powerpc/sys/sigsuspend.S	4 Dec 2023 14:53:14 -0000
@@ -35,7 +35,8 @@ SYSENTRY_HIDDEN(sigsuspend)
 	li	%r0, SYS_sigsuspend
 
 	lwz	%r3, 0(%r3)		/* load the mask */
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigsuspend, 99b)
 
 	cmpwi	%r0, 0
 	beq+	.L_ret
Index: lib/libc/arch/powerpc/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc/sys/tfork_thread.S,v
diff -u -p -u -r1.10 tfork_thread.S
--- lib/libc/arch/powerpc/sys/tfork_thread.S	28 Nov 2020 19:49:30 -0000	1.10
+++ lib/libc/arch/powerpc/sys/tfork_thread.S	4 Dec 2023 14:53:07 -0000
@@ -22,7 +22,8 @@ ENTRY(__tfork_thread)
 	RETGUARD_SETUP(__tfork_thread, %r11, %r12)
 	/* call __tfork */
 	li	%r0, SYS___tfork
-	sc
+99:	sc
+	PINSYSCALL(SYS___tfork, 99b)
 	cmpwi	%r0, 0
 	bne	1f
 	
@@ -38,7 +39,8 @@ ENTRY(__tfork_thread)
 	
 	/* child returned, call __threxit */
 	li	%r0, SYS___threxit
-	sc
+98:	sc
+	PINSYSCALL(SYS___threxit, 98b)
 	.long	0		/* illegal */
 
 1:
Index: lib/libc/arch/powerpc64/DEFS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/DEFS.h,v
diff -u -p -u -r1.1 DEFS.h
--- lib/libc/arch/powerpc64/DEFS.h	25 Jun 2020 01:59:27 -0000	1.1
+++ lib/libc/arch/powerpc64/DEFS.h	7 Dec 2023 19:26:49 -0000
@@ -67,3 +67,9 @@
 #else
 #define END_BUILTIN(x)	END_STRONG(x)
 #endif
+
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/powerpc64/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/SYS.h,v
diff -u -p -u -r1.5 SYS.h
--- lib/libc/arch/powerpc64/SYS.h	7 Dec 2022 23:25:59 -0000	1.5
+++ lib/libc/arch/powerpc64/SYS.h	4 Dec 2023 15:03:10 -0000
@@ -69,7 +69,8 @@
 				ENTRY(_thread_sys_ ## x) \
 				RETGUARD_SETUP(_thread_sys_ ## x, %r11); \
 				li %r0, SYS_ ## y ; \
-				sc ; \
+			97:	sc ; \
+				PINSYSCALL(SYS_ ## y, 97b); \
 				RETGUARD_CHECK(_thread_sys_ ## x, %r11); \
 				blr; \
 				__END(_thread_sys_,x)
@@ -77,7 +78,8 @@
 #define PSEUDO_HIDDEN(x,y) 	ENTRY(_thread_sys_ ## x) \
 				RETGUARD_SETUP(_thread_sys_ ## x, %r11); \
 				li %r0, SYS_ ## y ; \
-				sc ; \
+			97:	sc ; \
+				PINSYSCALL(SYS_ ## y, 97b); \
 				cmpwi %r0, 0 ; \
 				beq .L_ret ; \
 				stw	%r0, R13_OFFSET_ERRNO(%r13); \
Index: lib/libc/arch/powerpc64/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/gen/setjmp.S,v
diff -u -p -u -r1.4 setjmp.S
--- lib/libc/arch/powerpc64/gen/setjmp.S	18 Oct 2020 17:51:39 -0000	1.4
+++ lib/libc/arch/powerpc64/gen/setjmp.S	4 Dec 2023 14:52:54 -0000
@@ -70,7 +70,8 @@ ENTRY(setjmp)
 	li	%r3, 1			/* how = SIG_BLOCK */
 	li	%r4, 0			/* oset = empty */
 	li	%r0, SYS_sigprocmask
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	std	%r3, JMP_sig(%r5)
 	b	1f
 	nop
@@ -130,7 +131,8 @@ ENTRY(longjmp)
 	li	%r3, 3			/* how = SIG_SETMASK */
 	ld	%r4, JMP_sig(%r5)	/* oset from the jmpbuf */
 	li	%r0, SYS_sigprocmask
-	sc
+98:	sc
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	nop
 	b	1f
 	nop
Index: lib/libc/arch/powerpc64/gen/sigsetjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/gen/sigsetjmp.S,v
diff -u -p -u -r1.3 sigsetjmp.S
--- lib/libc/arch/powerpc64/gen/sigsetjmp.S	19 Oct 2020 23:24:17 -0000	1.3
+++ lib/libc/arch/powerpc64/gen/sigsetjmp.S	4 Dec 2023 14:52:43 -0000
@@ -67,7 +67,8 @@ ENTRY(sigsetjmp)
 	li	%r3, 1			/* how = SIG_BLOCK */
 	li	%r4, 0			/* oset = empty */
 	li	%r0, SYS_sigprocmask
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	nop
 	std	%r3, JMP_sigmask(5)
 1:
@@ -126,7 +127,8 @@ ENTRY(siglongjmp)
 	li	%r3, 3			/* how = SIG_SETMASK */
 	ld	%r4, JMP_sigmask(%r5)	/* oset from the jmpbuf */
 	li	%r0, SYS_sigprocmask
-	sc
+98:	sc
+	PINSYSCALL(SYS_sigprocmask, 98b)
 1:
 	addis	%r9, %r2, __jmpxor@toc@ha
 	addi	%r9, %r9, __jmpxor@toc@l
Index: lib/libc/arch/powerpc64/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/sys/brk.S,v
diff -u -p -u -r1.5 brk.S
--- lib/libc/arch/powerpc64/sys/brk.S	7 Dec 2022 23:25:59 -0000	1.5
+++ lib/libc/arch/powerpc64/sys/brk.S	4 Dec 2023 14:52:31 -0000
@@ -50,7 +50,8 @@ SYSENTRY(brk)
 	addi	%r6, %r6, __curbrk@toc@l	/* # %r6 = &__curbrk */
 
 	li %r0, SYS_break
-	sc
+99:	sc
+	PINSYSCALL(SYS_break, 99b)
 
 	/* check for error */
 	cmpwi	%r0, 0
Index: lib/libc/arch/powerpc64/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/sys/sbrk.S,v
diff -u -p -u -r1.4 sbrk.S
--- lib/libc/arch/powerpc64/sys/sbrk.S	16 Oct 2020 23:42:16 -0000	1.4
+++ lib/libc/arch/powerpc64/sys/sbrk.S	4 Dec 2023 14:52:26 -0000
@@ -51,7 +51,8 @@ SYSENTRY(sbrk)
 	mr	%r7, %r3
 
 	li %r0, SYS_break
-	sc
+99:	sc
+	PINSYSCALL(SYS_break, 99b)
 
 	/* check for error */
 	cmpwi	%r0, 0
Index: lib/libc/arch/powerpc64/sys/sigpending.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/sys/sigpending.S,v
diff -u -p -u -r1.2 sigpending.S
--- lib/libc/arch/powerpc64/sys/sigpending.S	16 Oct 2020 23:42:16 -0000	1.2
+++ lib/libc/arch/powerpc64/sys/sigpending.S	4 Dec 2023 14:52:20 -0000
@@ -25,7 +25,8 @@ SYSENTRY(sigpending)
 	li	%r0, SYS_sigpending
 
 	mr	%r5, %r3
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigpending, 99b)
 	stw	%r3, 0(%r5)
 	li	%r3, 0
 	RETGUARD_CHECK(sigpending, %r11)
Index: lib/libc/arch/powerpc64/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/sys/sigprocmask.S,v
diff -u -p -u -r1.4 sigprocmask.S
--- lib/libc/arch/powerpc64/sys/sigprocmask.S	16 Oct 2020 23:42:16 -0000	1.4
+++ lib/libc/arch/powerpc64/sys/sigprocmask.S	4 Dec 2023 14:52:13 -0000
@@ -47,7 +47,8 @@ SYSENTRY_HIDDEN(sigprocmask)
 	lwz	%r4, 0(%r4)	/* get new mask */
 .L_do_call:
 	
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	
 	/* didnt work? */
 	cmpwi	%r0, 0
Index: lib/libc/arch/powerpc64/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/sys/sigsuspend.S,v
diff -u -p -u -r1.3 sigsuspend.S
--- lib/libc/arch/powerpc64/sys/sigsuspend.S	16 Oct 2020 23:42:16 -0000	1.3
+++ lib/libc/arch/powerpc64/sys/sigsuspend.S	4 Dec 2023 14:52:07 -0000
@@ -35,7 +35,8 @@ SYSENTRY(sigsuspend)
 	li	%r0, SYS_sigsuspend
 
 	lwz %r3, 0(%r3)		/* load the mask */
-	sc
+99:	sc
+	PINSYSCALL(SYS_sigsuspend, 99b)
 
 	cmpwi	%r0, 0
 	beq	.L_ret
Index: lib/libc/arch/powerpc64/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/powerpc64/sys/tfork_thread.S,v
diff -u -p -u -r1.4 tfork_thread.S
--- lib/libc/arch/powerpc64/sys/tfork_thread.S	19 Oct 2020 14:15:29 -0000	1.4
+++ lib/libc/arch/powerpc64/sys/tfork_thread.S	4 Dec 2023 14:51:58 -0000
@@ -22,7 +22,8 @@ ENTRY(__tfork_thread)
 	RETGUARD_SETUP(__tfork_thread, %r11)
 
 	li	%r0, SYS___tfork
-	sc
+99:	sc
+	PINSYSCALL(SYS___tfork, 99b)
 	cmpwi	%r0, 0
 	bne	1f
 	
@@ -39,7 +40,8 @@ ENTRY(__tfork_thread)
 	
 	/* child returned, call __threxit */
 	li	%r0, SYS___threxit
-	sc
+98:	sc
+	PINSYSCALL(SYS___threxit, 98b)
 	.long	0		/* illegal */
 1:
 	stw	%r0, R13_OFFSET_ERRNO(%r13)
Index: lib/libc/arch/riscv64/DEFS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/riscv64/DEFS.h,v
diff -u -p -u -r1.1 DEFS.h
--- lib/libc/arch/riscv64/DEFS.h	29 Apr 2021 18:39:53 -0000	1.1
+++ lib/libc/arch/riscv64/DEFS.h	7 Dec 2023 19:26:43 -0000
@@ -58,3 +58,8 @@
 #define	END_STRONG(x)	END(x); _HIDDEN_FALIAS(x,x); END(_HIDDEN(x))
 #define	END_WEAK(x)	END_STRONG(x); .weak x
 
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/riscv64/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/riscv64/SYS.h,v
diff -u -p -u -r1.4 SYS.h
--- lib/libc/arch/riscv64/SYS.h	2 Dec 2022 12:27:08 -0000	1.4
+++ lib/libc/arch/riscv64/SYS.h	8 Dec 2023 13:42:41 -0000
@@ -56,9 +56,10 @@
 #define __END(x)					\
 	__END_HIDDEN(x); END(x)
 
-#define SYSTRAP(x) \
-	li	t0, SYS_ ## x;		\
-	ecall
+#define SYSTRAP(x)					\
+	li	t0, SYS_ ## x;				\
+97:	ecall						\
+	PINSYSCALL(SYS_ ## x, 97b)
 
 #define HANDLE_ERROR()							\
 	beqz	t0, 200f;						\
Index: lib/libc/arch/riscv64/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/riscv64/sys/brk.S,v
diff -u -p -u -r1.4 brk.S
--- lib/libc/arch/riscv64/sys/brk.S	3 Dec 2022 15:02:30 -0000	1.4
+++ lib/libc/arch/riscv64/sys/brk.S	4 Dec 2023 14:51:44 -0000
@@ -38,7 +38,8 @@ ENTRY_NB(brk)
 	lla	t1, __curbrk
 
 	li t0, SYS_break
-	ecall
+99:	ecall
+	PINSYSCALL(SYS_break, 99b)
 
 	/* check for error */
 	beqz	t0, .L_brk_ok
Index: lib/libc/arch/sh/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/sh/SYS.h,v
diff -u -p -u -r1.13 SYS.h
--- lib/libc/arch/sh/SYS.h	11 Feb 2023 06:10:39 -0000	1.13
+++ lib/libc/arch/sh/SYS.h	6 Dec 2023 16:37:47 -0000
@@ -94,10 +94,12 @@
 .macro systrap num
 .iflt \num - 128
 	mov	# \num, r0
-	trapa	#0x80
+97:	trapa	#0x80
+	PINSYSCALL(\num, 97b)
 .else
 	mov.l	903f, r0
-	trapa	#0x80
+97:	trapa	#0x80
+	PINSYSCALL(\num, 97b)
 	bra	904f
 	 nop
 	.align	2
@@ -166,3 +168,9 @@
 #define RSYSCALL_HIDDEN(x)		PSEUDO_HIDDEN(x,x)
 #define SYSCALL_END(x)			__END(x)
 #define SYSCALL_END_HIDDEN(x)		__END_HIDDEN(x)
+
+#define PINSYSCALL(sysno, label)					\
+	.pushsection .openbsd.syscalls,"",@progbits;			\
+	.long label;							\
+	.long sysno;							\
+	.popsection;
Index: lib/libc/arch/sh/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sh/sys/brk.S,v
diff -u -p -u -r1.8 brk.S
--- lib/libc/arch/sh/sys/brk.S	8 Dec 2022 02:11:27 -0000	1.8
+++ lib/libc/arch/sh/sys/brk.S	4 Dec 2023 14:51:36 -0000
@@ -69,7 +69,8 @@ ENTRY(brk)
 #else
 	mov	#SYS_break, r0
 #endif
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(SYS_break, 99b)
 	bf	2f
 #ifdef __PIC__
 	mov.l	Lcurbrk, r0
Index: lib/libc/arch/sh/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sh/sys/sbrk.S,v
diff -u -p -u -r1.8 sbrk.S
--- lib/libc/arch/sh/sys/sbrk.S	8 Dec 2022 02:11:27 -0000	1.8
+++ lib/libc/arch/sh/sys/sbrk.S	4 Dec 2023 14:51:28 -0000
@@ -69,7 +69,8 @@ ENTRY(sbrk)
 #else
 	mov	#SYS_break, r0
 #endif
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(SYS_break, 99b)
 	bf	1f
 #ifdef __PIC__
 	mov.l	Lcurbrk, r0
Index: lib/libc/arch/sh/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sh/sys/sigprocmask.S,v
diff -u -p -u -r1.6 sigprocmask.S
--- lib/libc/arch/sh/sys/sigprocmask.S	2 Sep 2022 06:19:04 -0000	1.6
+++ lib/libc/arch/sh/sys/sigprocmask.S	4 Dec 2023 14:51:12 -0000
@@ -52,7 +52,8 @@ SYSENTRY_HIDDEN(sigprocmask)
 #else
 	mov	#SYS_sigprocmask, r0
 #endif
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(LSYS_sigprocmask, 99b)
 	bf	4f
 	mov	r6, r2			/* fetch old mask requested */
 	tst	r2, r2			/* test if old mask requested */
Index: lib/libc/arch/sh/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sh/sys/sigsuspend.S,v
diff -u -p -u -r1.5 sigsuspend.S
--- lib/libc/arch/sh/sys/sigsuspend.S	2 Sep 2022 06:19:04 -0000	1.5
+++ lib/libc/arch/sh/sys/sigsuspend.S	4 Dec 2023 14:51:04 -0000
@@ -46,7 +46,8 @@ SYSENTRY_HIDDEN(sigsuspend)
 #else
 	mov	#SYS_sigsuspend, r0
 #endif
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(SYS_sigsuspend, 99b)
 	SET_ERRNO_AND_RETURN
 
 	.align	2
Index: lib/libc/arch/sh/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sh/sys/tfork_thread.S,v
diff -u -p -u -r1.4 tfork_thread.S
--- lib/libc/arch/sh/sys/tfork_thread.S	2 Sep 2022 06:19:04 -0000	1.4
+++ lib/libc/arch/sh/sys/tfork_thread.S	4 Dec 2023 14:50:50 -0000
@@ -29,7 +29,8 @@ ENTRY(__tfork_thread)
 #else
 	mov	#SYS___tfork, r0
 #endif
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(SYS___tfork, 99b)
 	bf	9f
 
 	tst	r0, r0
@@ -53,7 +54,8 @@ ENTRY(__tfork_thread)
 #else
 	mov	#SYS___threxit, r0
 #endif
-	trapa	#0x80
+98:	trapa	#0x80
+	PINSYSCALL(SYS___threxit, 98b)
 
 9:
 	/*
Index: lib/libc/arch/sparc64/SYS.h
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/SYS.h,v
diff -u -p -u -r1.17 SYS.h
--- lib/libc/arch/sparc64/SYS.h	1 Jan 2022 23:47:14 -0000	1.17
+++ lib/libc/arch/sparc64/SYS.h	8 Dec 2023 13:41:12 -0000
@@ -49,8 +49,8 @@
 #define	__ENTRY(p,x)		ENTRY(_CAT(p,x)) ; .weak x; x = _CAT(p,x)
 #define	__ENTRY_HIDDEN(p,x)	ENTRY(_CAT(p,x))
 
-#define __END_HIDDEN(p,x)	END(_CAT(p,x));				\
-				_HIDDEN_FALIAS(x, _CAT(p,x));		\
+#define __END_HIDDEN(p,x)	END(_CAT(p,x));			\
+				_HIDDEN_FALIAS(x, _CAT(p,x));	\
 				END(_HIDDEN(x))
 #define __END(p,x)		__END_HIDDEN(p,x); END(x)
 
@@ -67,15 +67,30 @@
  * Note that it adds a `nop' over what we could do, if we only knew what
  * came at label 1....
  */
-#define	_SYSCALL(p,x,y) \
-	__ENTRY(p,x); mov _CAT(SYS_,y),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1:
-#define	_SYSCALL_HIDDEN(p,x,y) \
-	__ENTRY_HIDDEN(p,x); mov _CAT(SYS_,y),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1:
+#define	_SYSCALL(p,x,y)						\
+	__ENTRY(p,x);						\
+	mov _CAT(SYS_,y),%g1;					\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,y), 97b);				\
+	bcc 1f;							\
+	nop;							\
+	ERROR();						\
+1:
+
+#define	_SYSCALL_HIDDEN(p,x,y)					\
+	__ENTRY_HIDDEN(p,x);					\
+	mov _CAT(SYS_,y),%g1;					\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,y), 97b);				\
+	bcc 1f;							\
+	nop;							\
+	ERROR();						\
+1:
 
-#define	__SYSCALL(p,x) \
+#define	__SYSCALL(p,x)						\
 	_SYSCALL(p,x,x)
 
-#define	__SYSCALL_HIDDEN(p,x) \
+#define	__SYSCALL_HIDDEN(p,x)					\
 	_SYSCALL_HIDDEN(p,x,x)
 
 /*
@@ -83,19 +98,34 @@
  * we use the SYSCALL_G2RFLAG to put the `success' return address in %g2
  * and avoid a branch.
  */
-#define	__RSYSCALL(p,x) \
-	__ENTRY(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; \
-	add %o7,8,%g2; t ST_SYSCALL; ERROR(); __END(p,x)
-#define	__RSYSCALL_HIDDEN(p,x) \
-	__ENTRY_HIDDEN(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; \
-	add %o7,8,%g2; t ST_SYSCALL; ERROR(); __END_HIDDEN(p,x)
+#define	__RSYSCALL(p,x)						\
+	__ENTRY(p,x);						\
+	mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1;			\
+	add %o7,8,%g2;						\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,x), 97b);				\
+	ERROR();						\
+	__END(p,x)
+#define	__RSYSCALL_HIDDEN(p,x)					\
+	__ENTRY_HIDDEN(p,x);					\
+	mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1;			\
+	add %o7,8,%g2;						\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,x), 97b);				\
+	ERROR();						\
+	__END_HIDDEN(p,x)
 
 /*
  * PSEUDO(x,y) is like RSYSCALL(y) except that the name is x.
  */
-#define	__PSEUDO(p,x,y) \
-	__ENTRY(p,x); mov (_CAT(SYS_,y))|SYSCALL_G2RFLAG,%g1; add %o7,8,%g2; \
-	t ST_SYSCALL; ERROR(); __END(p,x)
+#define	__PSEUDO(p,x,y)						\
+	__ENTRY(p,x);						\
+	mov (_CAT(SYS_,y))|SYSCALL_G2RFLAG,%g1;			\
+	add %o7,8,%g2;						\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,y), 97b);				\
+	ERROR();						\
+	__END(p,x)
 
 /*
  * SYSCALL_NOERROR is like SYSCALL, except it's used for syscalls 
@@ -103,8 +133,11 @@
  *
  * XXX - This should be optimized.
  */
-#define __SYSCALL_NOERROR(p,x) \
-	__ENTRY(p,x); mov _CAT(SYS_,x),%g1; t ST_SYSCALL
+#define __SYSCALL_NOERROR(p,x)					\
+	__ENTRY(p,x);						\
+	mov _CAT(SYS_,x),%g1;					\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,x), 97b)
 
 /*
  * RSYSCALL_NOERROR is like RSYSCALL, except it's used for syscalls 
@@ -112,16 +145,24 @@
  *
  * XXX - This should be optimized.
  */
-#define __RSYSCALL_NOERROR(p,x) \
-	__ENTRY(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; add %o7,8,%g2; \
-	t ST_SYSCALL; __END(p,x)
+#define __RSYSCALL_NOERROR(p,x)					\
+	__ENTRY(p,x);						\
+	mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1;			\
+	add %o7,8,%g2;						\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,x), 97b);				\
+	__END(p,x)
 
 /*
  * PSEUDO_NOERROR(x,y) is like RSYSCALL_NOERROR(y) except that the name is x.
  */
-#define __PSEUDO_NOERROR(p,x,y) \
-	__ENTRY(p,x); mov (_CAT(SYS_,y))|SYSCALL_G2RFLAG,%g1; add %o7,8,%g2; \
-	t ST_SYSCALL; __END(p,x)
+#define __PSEUDO_NOERROR(p,x,y)					\
+	__ENTRY(p,x);						\
+	mov (_CAT(SYS_,y))|SYSCALL_G2RFLAG,%g1;			\
+	add %o7,8,%g2;						\
+97:	t ST_SYSCALL;						\
+	PINSYSCALL(_CAT(SYS_,y), 97b);				\
+	__END(p,x)
 
 /*
  * SYSENTRY is for functions that pretend to be syscalls.
Index: lib/libc/arch/sparc64/gen/setjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/gen/setjmp.S,v
diff -u -p -u -r1.6 setjmp.S
--- lib/libc/arch/sparc64/gen/setjmp.S	28 Apr 2016 12:53:47 -0000	1.6
+++ lib/libc/arch/sparc64/gen/setjmp.S	4 Dec 2023 14:50:26 -0000
@@ -53,7 +53,8 @@ ENTRY(setjmp)
 	mov	1, %o0			/* SIG_BLOCK */
 	mov	SYS_sigprocmask, %g1	
 	clr	%o1			/* sigprocmask(SIG_BLOCK, 0) */
-	t	ST_SYSCALL
+99:	t	ST_SYSCALL
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	stx	%o0, [%o3 + 0x10]
 
 	stx	%sp, [%o3 + 0x00]	/* store caller's stack pointer */
@@ -68,7 +69,8 @@ ENTRY(longjmp)
 	mov	3, %o0			/* SIG_SETMASK */
 	ldx	[%i0 + 0x10], %o1
 	mov	SYS_sigprocmask, %g1	
-	t	ST_SYSCALL
+98:	t	ST_SYSCALL
+	PINSYSCALL(SYS_sigprocmask, 98b)
 	
 	ldx	[%i0 + 0x00], %fp
 	ldx	[%i0 + 0x08], %i7
Index: lib/libc/arch/sparc64/gen/sigsetjmp.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/gen/sigsetjmp.S,v
diff -u -p -u -r1.4 sigsetjmp.S
--- lib/libc/arch/sparc64/gen/sigsetjmp.S	8 May 2016 18:29:34 -0000	1.4
+++ lib/libc/arch/sparc64/gen/sigsetjmp.S	4 Dec 2023 14:49:31 -0000
@@ -43,7 +43,8 @@ ENTRY(sigsetjmp)
 	mov	1, %o0			/* SIG_BLOCK */
 	mov	SYS_sigprocmask, %g1	
 	clr	%o1			/* sigprocmask(SIG_BLOCK, 0) */
-	t	ST_SYSCALL
+99:	t	ST_SYSCALL
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	stx	%o0, [%o3 + 0x10]
 
 1:	stx	%sp, [%o3 + 0x00]	/* store caller's stack pointer */
@@ -62,7 +63,8 @@ ENTRY(siglongjmp)
 	 mov	3, %o0			/* SIG_SETMASK */
 	ldx	[%i0 + 0x10], %o1
 	mov	SYS_sigprocmask, %g1	
-	t	ST_SYSCALL
+98:	t	ST_SYSCALL
+	PINSYSCALL(SYS_sigprocmask, 98b)
 
 1:	ldx	[%i0 + 0x00], %fp
 	ldx	[%i0 + 0x08], %i7
Index: lib/libc/arch/sparc64/sys/brk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/sys/brk.S,v
diff -u -p -u -r1.11 brk.S
--- lib/libc/arch/sparc64/sys/brk.S	13 Jan 2023 17:52:08 -0000	1.11
+++ lib/libc/arch/sparc64/sys/brk.S	4 Dec 2023 15:01:10 -0000
@@ -59,7 +59,8 @@ ENTRY_NB(brk)
 	movgu	%xcc, %o1, %o0		/*	%o0 = minbrk */
 	mov	%o0, %o2		/* save argument to syscall */
 	mov	SYS_break, %g1
-	t	ST_SYSCALL
+99:	t	ST_SYSCALL
+	PINSYSCALL(SYS_break, 99b)
 	set	__curbrk, %o3
 	bcc,a,pt	%icc, 1f
 	 ldx	[%o5 + %o3], %o4
@@ -74,7 +75,8 @@ ENTRY_NB(brk)
 	movgu	%xcc, %o1, %o0		/*	%o0 = minbrk */
 	mov	%o0, %o2		/* save argument to syscall */
 	mov	SYS_break, %g1
-	t	ST_SYSCALL
+98:	t	ST_SYSCALL
+	PINSYSCALL(SYS_break, 98b)
 	bcc,a,pt	%icc,1f
 	 sethi	%hi(__curbrk), %g1
 	ERROR()
Index: lib/libc/arch/sparc64/sys/sbrk.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/sys/sbrk.S,v
diff -u -p -u -r1.9 sbrk.S
--- lib/libc/arch/sparc64/sys/sbrk.S	13 Jan 2023 17:52:08 -0000	1.9
+++ lib/libc/arch/sparc64/sys/sbrk.S	4 Dec 2023 15:01:06 -0000
@@ -59,7 +59,8 @@ ENTRY_NB(sbrk)
 	add	%o3, %o0, %o4			/* %o4 = new break */
 	mov	%o4, %o0			/* copy for syscall */
 	mov	SYS_break, %g1
-	t	ST_SYSCALL			/* break(new_break) */
+99:	t	ST_SYSCALL			/* break(new_break) */
+	PINSYSCALL(SYS_break, 99b)
 	bcc,a	1f				/* if success, */
 	 mov	%o3, %o0			/*    set return value */
 	ERROR()
@@ -72,7 +73,8 @@ ENTRY_NB(sbrk)
 	add	%o3, %o0, %o4			/* %o4 = new break */
 	mov	%o4, %o0			/* copy for syscall */
 	mov	SYS_break, %g1
-	t	ST_SYSCALL			/* break(new_break) */
+98:	t	ST_SYSCALL			/* break(new_break) */
+	PINSYSCALL(SYS_break, 98b)
 	bcc,a	1f				/* if success, */
 	 mov	%o3, %o0			/*    set return value */
 	ERROR()
Index: lib/libc/arch/sparc64/sys/sigpending.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/sys/sigpending.S,v
diff -u -p -u -r1.3 sigpending.S
--- lib/libc/arch/sparc64/sys/sigpending.S	5 Sep 2015 06:22:47 -0000	1.3
+++ lib/libc/arch/sparc64/sys/sigpending.S	4 Dec 2023 15:01:02 -0000
@@ -38,7 +38,8 @@
 SYSENTRY(sigpending)
 	mov	%o0, %o2		/* save pointer */
 	mov	SYS_sigpending, %g1
-	t	ST_SYSCALL		/* sigpending() */
+99:	t	ST_SYSCALL		/* sigpending() */
+	PINSYSCALL(SYS_sigpending, 99b)
 	bcc,a	1f			/* if success, */
 	 st	%o0, [%o2]		/*    store return value */
 	ERROR()
Index: lib/libc/arch/sparc64/sys/sigprocmask.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/sys/sigprocmask.S,v
diff -u -p -u -r1.4 sigprocmask.S
--- lib/libc/arch/sparc64/sys/sigprocmask.S	23 Oct 2015 04:39:25 -0000	1.4
+++ lib/libc/arch/sparc64/sys/sigprocmask.S	4 Dec 2023 15:01:00 -0000
@@ -46,7 +46,8 @@ SYSENTRY_HIDDEN(sigprocmask)
 	mov	1, %o0		/* ... using sigprocmask(SIG_BLOCK) */
 1:
 	mov	SYS_sigprocmask, %g1
-	t	ST_SYSCALL
+99:	t	ST_SYSCALL
+	PINSYSCALL(SYS_sigprocmask, 99b)
 	bcc	2f		/* if success, */
 	 tst	%o2		/*    check to see if oset requested */
 	ERROR()
Index: lib/libc/arch/sparc64/sys/sigsuspend.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/sys/sigsuspend.S,v
diff -u -p -u -r1.4 sigsuspend.S
--- lib/libc/arch/sparc64/sys/sigsuspend.S	7 May 2016 19:05:22 -0000	1.4
+++ lib/libc/arch/sparc64/sys/sigsuspend.S	4 Dec 2023 15:00:55 -0000
@@ -39,6 +39,7 @@
 SYSENTRY_HIDDEN(sigsuspend)
 	ld	[%o0], %o0		/* indirect to mask argument */
 	mov	SYS_sigsuspend, %g1
-	t	ST_SYSCALL
+99:	t	ST_SYSCALL
+	PINSYSCALL(SYS_sigsuspend, 99b)
 	ERROR()				/* always terminates with EINTR */
 SYSCALL_END_HIDDEN(sigsuspend)
Index: lib/libc/arch/sparc64/sys/tfork_thread.S
===================================================================
RCS file: /cvs/src/lib/libc/arch/sparc64/sys/tfork_thread.S,v
diff -u -p -u -r1.4 tfork_thread.S
--- lib/libc/arch/sparc64/sys/tfork_thread.S	18 Oct 2020 14:28:18 -0000	1.4
+++ lib/libc/arch/sparc64/sys/tfork_thread.S	4 Dec 2023 14:48:16 -0000
@@ -36,7 +36,8 @@ ENTRY(__tfork_thread)
 	 * different return paths.
 	 */
 	mov	SYS___tfork, %g1
-	t	ST_SYSCALL
+99:	t	ST_SYSCALL
+	PINSYSCALL(SYS___tfork, 99b)
 	bcs	9f
 	 nop
 
@@ -59,7 +60,8 @@ ENTRY(__tfork_thread)
 
 	mov	SYS___threxit, %g1
 	clr	%o0
-	t	ST_SYSCALL	/* will not return */
+98:	t	ST_SYSCALL	/* will not return */
+	PINSYSCALL(SYS___threxit, 98b)
 	unimp
 
 9:
Index: lib/libc/sys/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/sys/Makefile.inc,v
diff -u -p -u -r1.174 Makefile.inc
--- lib/libc/sys/Makefile.inc	20 Aug 2023 15:17:53 -0000	1.174
+++ lib/libc/sys/Makefile.inc	5 Dec 2023 23:29:10 -0000
@@ -208,8 +208,8 @@ MAN+=	__get_tcb.2 __thrsigdivert.2 __thr
 	mimmutable.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 \
 	mlockall.2 mmap.2 mount.2 mprotect.2 mquery.2 msyscall.2 msgctl.2 \
 	msgget.2 msgrcv.2 msgsnd.2 msync.2 munmap.2 nanosleep.2 \
-	nfssvc.2 open.2 pathconf.2 pinsyscall.2 pipe.2 pledge.2 poll.2 \
-	profil.2 ptrace.2 quotactl.2 read.2 readlink.2 reboot.2 recv.2 \
+	nfssvc.2 open.2 pathconf.2 pinsyscall.2 pinsyscalls.2 pipe.2 pledge.2 \
+	poll.2 profil.2 ptrace.2 quotactl.2 read.2 readlink.2 reboot.2 recv.2 \
 	rename.2 revoke.2 rmdir.2 sched_yield.2 select.2 semctl.2 semget.2 \
 	semop.2 send.2 setgroups.2 setpgid.2 setregid.2 \
 	setresuid.2 setreuid.2 setsid.2 sendsyslog.2 setuid.2 shmat.2 \
Index: lib/libc/sys/pinsyscalls.2
===================================================================
RCS file: lib/libc/sys/pinsyscalls.2
diff -N lib/libc/sys/pinsyscalls.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ lib/libc/sys/pinsyscalls.2	6 Dec 2023 06:49:16 -0000
@@ -0,0 +1,73 @@
+.\" $OpenBSD: pinsyscall.2,v 1.5 2023/02/21 19:49:50 jmc Exp $
+.\"
+.\" Copyright (c) 2023 Theo de Raadt <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: February 21 2023 $
+.Dt PINSYSCALLS 2
+.Os
+.Sh NAME
+.Nm pinsyscalls
+.Nd pin system call entry to precise positions in the address space
+.Sh SYNOPSIS
+.In sys/types.h
+.Ft int
+.Fn pinsyscalls "void *start" "size_t len" "void *pintable" "size_t pintablesize"
+.Sh DESCRIPTION
+The
+.Fn pinsyscalls
+system call specifies the
+.Va start
+to
+.Va start + len
+range in the address space where the system call entry instructions are found,
+and furthermore provides a table (indexed by the system call number) providing
+the precise offset for the system call instruction required for that system call
+number.
+.Pp
+.Fn pinsyscalls
+is only called by the shared library linker
+.Xr ld.so 1
+to tell the kernel where system calls are found in the dynamic library
+.Pa libc.so
+(the filename is actually /usr/lib/libc.so.major.minor).
+.Pp
+A similar region of system call setup is done automatically by the kernel for
+the system calls found in
+.Xr ld.so 1
+and in static executables.
+.Pp
+Once the kernel knows the specific location in the address space where
+a specific system call must be entered from, any attempt to use a different
+system call entry instruction to perform a non-corresponding system call
+operation will fail with signal
+.Dv SIGABRT .
+.Pp
+This is called system call pinning.
+.Sh RETURN VALUES
+.Rv -std
+.Sh ERRORS
+.Fn pinsyscalls
+will fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Process already has a system call pinning table loaded.
+.It Bq Er ERANGE
+At least one system call offset is out of bounds.
+.El
+.Sh HISTORY
+The
+.Fn pinsyscalls
+system call first appeared in
+.Ox 7.4 .
Index: libexec/ld.so/Makefile
===================================================================
RCS file: /cvs/src/libexec/ld.so/Makefile,v
diff -u -p -u -r1.85 Makefile
--- libexec/ld.so/Makefile	8 Jul 2023 11:03:45 -0000	1.85
+++ libexec/ld.so/Makefile	26 Nov 2023 01:46:33 -0000
@@ -29,7 +29,8 @@ SRCS+=	malloc.c reallocarray.c tib.c ffs
 
 syscall=close exit fstat getdents getentropy getthrid issetugid kbind \
 	mimmutable mmap mprotect munmap msyscall open pledge pinsyscall \
-	read __realpath sendsyslog __set_tcb sysctl thrkill utrace write
+	pinsyscalls pread read __realpath sendsyslog __set_tcb sysctl thrkill \
+	utrace write
 
 .if (${MACHINE_ARCH} == "i386")
 syscall+=mquery
Index: libexec/ld.so/library.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library.c,v
diff -u -p -u -r1.92 library.c
--- libexec/ld.so/library.c	15 Aug 2023 06:23:31 -0000	1.92
+++ libexec/ld.so/library.c	8 Dec 2023 05:12:56 -0000
@@ -99,7 +99,7 @@ elf_object_t *
 _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
 {
 	struct range_vector imut, mut;
-	int	libfile, i;
+	int	libfile, libc = -1, i;
 	struct load_list *next_load, *load_list = NULL;
 	Elf_Addr maxva = 0, minva = ELF_NO_ADDR;
 	Elf_Addr libaddr, loff, align = _dl_pagesz - 1;
@@ -109,8 +109,8 @@ _dl_tryload_shlib(const char *libname, i
 	size_t exec_size = 0;
 	Elf_Dyn *dynp = NULL;
 	Elf_Ehdr *ehdr;
-	Elf_Phdr *phdp;
-	Elf_Phdr *ptls = NULL;
+	Elf_Phdr *phdp, *ptls = NULL;
+	Elf_Phdr *syscall_phdp = NULL;
 	struct stat sb;
 
 #define powerof2(x) ((((x) - 1) & (x)) == 0)
@@ -139,7 +139,6 @@ _dl_tryload_shlib(const char *libname, i
 	if (flags & DF_1_NOOPEN) {
 		_dl_close(libfile);
 		return NULL;
-
 	}
 
 	_dl_read(libfile, hbuf, sizeof(hbuf));
@@ -316,12 +315,30 @@ _dl_tryload_shlib(const char *libname, i
 			_dl_push_range_size(&mut, phdp->p_vaddr + loff,
 			    phdp->p_memsz);
 			break;
-
+		case PT_OPENBSD_SYSCALLS:
+			syscall_phdp = phdp;
+			break;
 		default:
 			break;
 		}
 	}
 
+	libc = _dl_islibc(dynp, loff);
+
+	if (libc) {
+		if (syscall_phdp)
+			_dl_pin(libfile, syscall_phdp, (void *)libaddr,
+			    (size_t)((exec_start + exec_size) - libaddr));
+
+		/*
+		 * XXX msyscall() can be removed once pinsyscalls()
+		 * is fully operational
+		 */
+		/* Request permission for system calls in libc.so's text segment */
+		if (_dl_msyscall(exec_start, exec_size) == -1)
+			_dl_printf("msyscall %lx %lx error\n",
+			    exec_start, exec_size);
+	}
 	_dl_close(libfile);
 
 	dynp = (Elf_Dyn *)((unsigned long)dynp + loff);
@@ -329,8 +346,6 @@ _dl_tryload_shlib(const char *libname, i
 	    (Elf_Phdr *)((char *)libaddr + ehdr->e_phoff), ehdr->e_phnum,type,
 	    libaddr, loff);
 	if (object) {
-		char *soname = (char *)object->Dyn.info[DT_SONAME];
-
 		object->load_size = maxva - minva;	/*XXX*/
 		object->load_list = load_list;
 		/* set inode, dev from stat info */
@@ -340,17 +355,10 @@ _dl_tryload_shlib(const char *libname, i
 		object->nodelete = nodelete;
 		object->relro_addr = relro_addr;
 		object->relro_size = relro_size;
+		object->islibc = libc;
 		_dl_set_sod(object->load_name, &object->sod);
 		if (ptls != NULL && ptls->p_memsz)
 			_dl_set_tls(object, ptls, libaddr, libname);
-
-		/* Request permission for system calls in libc.so's text segment */
-		if (soname != NULL && !_dl_traceld &&
-		    _dl_strncmp(soname, "libc.so.", 8) == 0) {
-			if (_dl_msyscall(exec_start, exec_size) == -1)
-				_dl_printf("msyscall %lx %lx error\n",
-				    exec_start, exec_size);
-		}
 		_dl_bcopy(&mut, &object->mut, sizeof mut);
 		_dl_bcopy(&imut, &object->imut, sizeof imut);
 	} else {
Index: libexec/ld.so/library_mquery.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/library_mquery.c,v
diff -u -p -u -r1.72 library_mquery.c
--- libexec/ld.so/library_mquery.c	15 Aug 2023 06:23:31 -0000	1.72
+++ libexec/ld.so/library_mquery.c	7 Dec 2023 21:40:23 -0000
@@ -60,7 +60,6 @@ _dl_load_list_free(struct load_list *loa
 	}
 }
 
-
 void
 _dl_unload_shlib(elf_object_t *object)
 {
@@ -99,20 +98,19 @@ unload:
 	}
 }
 
-
 elf_object_t *
 _dl_tryload_shlib(const char *libname, int type, int flags, int nodelete)
 {
 	struct range_vector imut, mut;
-	int libfile, i;
+	int libfile, libc = -1, i;
 	struct load_list *ld, *lowld = NULL;
 	elf_object_t *object;
 	Elf_Dyn *dynp = NULL;
 	Elf_Ehdr *ehdr;
-	Elf_Phdr *phdp;
+	Elf_Phdr *phdp, *ptls = NULL;
+	Elf_Phdr *syscall_phdp = NULL;
 	Elf_Addr load_end = 0;
 	Elf_Addr align = _dl_pagesz - 1, off, size;
-	Elf_Phdr *ptls = NULL;
 	Elf_Addr relro_addr = 0, relro_size = 0;
 	struct stat sb;
 	char hbuf[4096], *exec_start;
@@ -327,9 +325,28 @@ retry:
 			_dl_push_range_size(&mut, phdp->p_vaddr + LOFF,
 			    phdp->p_memsz);
 			break;
+		case PT_OPENBSD_SYSCALLS:
+			syscall_phdp = phdp;
+			break;
 		}
 	}
 
+	libc = _dl_islibc(dynp, LOFF);
+
+	if (libc) {
+		if (syscall_phdp)
+			_dl_pin(libfile, syscall_phdp, (void *)lowld,
+			    libsize = (size_t)((exec_start + exec_size) - LOFF));
+
+		/*
+		 * XXX msyscall() can be removed once pinsyscalls()
+		 * is fully operational
+		 */
+		/* Request permission for system calls in libc.so's text segment */
+		if (_dl_msyscall(exec_start, exec_size) == -1)
+			_dl_printf("msyscall %lx %lx error\n",
+			    exec_start, exec_size);
+	}
 	_dl_close(libfile);
 
 	dynp = (Elf_Dyn *)((unsigned long)dynp + LOFF);
@@ -337,8 +354,6 @@ retry:
 	    (Elf_Phdr *)((char *)lowld->start + ehdr->e_phoff), ehdr->e_phnum,
 	    type, (Elf_Addr)lowld->start, LOFF);
 	if (object) {
-		char *soname = (char *)object->Dyn.info[DT_SONAME];
-
 		object->load_size = (Elf_Addr)load_end - (Elf_Addr)lowld->start;
 		object->load_list = lowld;
 		/* set inode, dev from stat info */
@@ -348,18 +363,11 @@ retry:
 		object->nodelete = nodelete;
 		object->relro_addr = relro_addr;
 		object->relro_size = relro_size;
+		object->islibc = libc;
 		_dl_set_sod(object->load_name, &object->sod);
 		if (ptls != NULL && ptls->p_memsz)
 			_dl_set_tls(object, ptls, (Elf_Addr)lowld->start,
 			    libname);
-
-		/* Request permission for system calls in libc.so's text segment */
-		if (soname != NULL && !_dl_traceld &&
-		    _dl_strncmp(soname, "libc.so.", 8) == 0) {
-			if (_dl_msyscall(exec_start, exec_size) == -1)
-				_dl_printf("msyscall %lx %lx error\n",
-				    exec_start, exec_size);
-		}
 		_dl_bcopy(&mut, &object->mut, sizeof mut);
 		_dl_bcopy(&imut, &object->imut, sizeof imut);
 	} else {
Index: libexec/ld.so/loader.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/loader.c,v
diff -u -p -u -r1.214 loader.c
--- libexec/ld.so/loader.c	15 Aug 2023 06:26:34 -0000	1.214
+++ libexec/ld.so/loader.c	8 Dec 2023 05:58:42 -0000
@@ -411,11 +411,14 @@ _dl_load_dep_libs(elf_object_t *object, 
 
 	_dl_cache_grpsym_list_setup(object);
 
+	/*
+	 * XXX pinsyscall(SYS_execve,...) can be removed once pinsyscalls()
+	 * is fully operational
+	 */
 	for (obj = _dl_objects; booting && obj != NULL; obj = obj->next) {
-		char *soname = (char *)obj->Dyn.info[DT_SONAME];
 		struct sym_res sr;
 
-		if (!soname || _dl_strncmp(soname, "libc.so.", 8))
+		if (obj->islibc == 0)
 			continue;
 		sr = _dl_find_symbol("execve",
 		    SYM_SEARCH_SELF|SYM_PLT|SYM_WARNNOTFOUND, NULL, obj);
@@ -467,6 +470,19 @@ _dl_self_relro(long loff)
 		   (((X) & PF_X) ? PROT_EXEC : 0))
 
 /*
+ * To avoid kbind(2) becoming a gadget, it is called inline to a function and
+ * therefore we cannot create a precise pinsyscall label. So we create a
+ * duplicate entry to force the kernel's pinsyscall code to skip validation.
+ * kbind is safe because it self-protects by checking its calling address.
+ */
+#define __STRINGIFY(x)  #x
+#define STRINGIFY(x)    __STRINGIFY(x)
+__asm__(".pushsection openbsd.syscalls,\"\",@progbits;"
+    ".long 0;"
+    ".long " STRINGIFY(SYS_kbind) ";"
+    ".popsection");
+
+/*
  * This is the dynamic loader entrypoint. When entering here, depending
  * on architecture type, the stack and registers are set up according
  * to the architectures ABI specification. The first thing required
@@ -1116,5 +1132,4 @@ _dl_apply_immutable(elf_object_t *object
 		}
 
 	}
-
 }
Index: libexec/ld.so/resolve.c
===================================================================
RCS file: /cvs/src/libexec/ld.so/resolve.c,v
diff -u -p -u -r1.100 resolve.c
--- libexec/ld.so/resolve.c	8 Jul 2023 14:09:43 -0000	1.100
+++ libexec/ld.so/resolve.c	8 Dec 2023 05:36:03 -0000
@@ -36,6 +36,7 @@
 #include "util.h"
 #include "path.h"
 #include "resolve.h"
+#include "syscall.h"
 
 /* substitution types */
 typedef enum {
@@ -744,4 +745,69 @@ void
 _dl_debug_state(void)
 {
 	/* Debugger stub */
+}
+
+/*
+ * Search for DT_SONAME, and check if this is libc
+ */
+int
+_dl_islibc(Elf_Dyn *_dynp, Elf_Addr loff)
+{
+	Elf_Dyn *d, *dynp = (Elf_Dyn *)((unsigned long)_dynp + loff);
+	long base = 0;
+
+	for (d = dynp; d->d_tag != DT_NULL; d++)
+		if (d->d_tag == DT_STRTAB) {
+			base = d->d_un.d_ptr + loff;
+			break;
+		}
+	if (base == 0)
+		return 0;
+	for (d = dynp; d->d_tag != DT_NULL; d++)
+		if (d->d_tag == DT_SONAME) {
+			if (_dl_strncmp((char *)(base + d->d_un.d_ptr),
+			    "libc.so.", 8) == 0)
+				return 1;
+			break;
+		}
+	return 0;
+}
+
+void
+_dl_pin(int file, Elf_Phdr *phdp, void *base, size_t len)
+{
+	struct pinsyscalls {
+		u_int offset;
+		u_int sysno;
+	} *syscalls;
+	int npins = 0, *pins, nsyscalls, i;
+
+	nsyscalls = phdp->p_filesz / sizeof(*syscalls);
+	if (nsyscalls * sizeof(*syscalls) != phdp->p_filesz) {
+		_dl_printf("openbsd.pinsyscalls bad size\n");
+		return;
+	}
+
+	syscalls = _dl_malloc(phdp->p_filesz);
+	if (syscalls == NULL) {
+		_dl_printf("openbsd.pinsyscalls too big\n");
+		return;
+	}
+	_dl_pread(file, (void *)syscalls, phdp->p_filesz, phdp->p_offset);
+
+	for (i = 0; i < nsyscalls; i++)
+		npins = MAXIMUM(npins, syscalls[i].sysno);
+	npins++;
+
+	pins = _dl_calloc(npins, sizeof(int));
+	for (i = 0; i < nsyscalls; i++) {
+		if (pins[syscalls[i].sysno])
+			pins[syscalls[i].sysno] = -1;	/* duplicated */
+		else
+			pins[syscalls[i].sysno] = syscalls[i].offset;
+	}
+	_dl_free(syscalls);
+
+	_dl_pinsyscalls(base, len, pins, npins * sizeof(int));
+	_dl_free(pins);
 }
Index: libexec/ld.so/resolve.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/resolve.h,v
diff -u -p -u -r1.105 resolve.h
--- libexec/ld.so/resolve.h	15 Aug 2023 06:26:34 -0000	1.105
+++ libexec/ld.so/resolve.h	7 Dec 2023 21:32:08 -0000
@@ -245,6 +245,7 @@ struct elf_object {
 
 	struct range_vector imut;
 	struct range_vector mut;
+	int islibc;
 };
 
 struct dep_node {
@@ -339,6 +340,9 @@ void _dl_apply_immutable(elf_object_t *o
 typedef void lock_cb(int);
 void	_dl_thread_kern_go(lock_cb *);
 lock_cb	*_dl_thread_kern_stop(void);
+
+int _dl_islibc(Elf_Dyn *_dynp, Elf_Addr loff);
+void _dl_pin(int, Elf_Phdr *, void *, size_t);
 
 char	*_dl_getenv(const char *, char **) __boot;
 void	_dl_unsetenv(const char *, char **) __boot;
Index: libexec/ld.so/syscall.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/syscall.h,v
diff -u -p -u -r1.4 syscall.h
--- libexec/ld.so/syscall.h	18 Feb 2023 01:22:50 -0000	1.4
+++ libexec/ld.so/syscall.h	11 Nov 2023 15:56:16 -0000
@@ -52,11 +52,13 @@ int	_dl_mprotect(const void *, size_t, i
 void   *_dl_mquery(void *, size_t, int, int, int, off_t);
 int	_dl_msyscall(void *addr, size_t len);
 int	_dl_pinsyscall(int, void *addr, size_t len);
+int	_dl_pinsyscalls(void *base, size_t len, void *pin, size_t pinlen);
 int	_dl_munmap(const void *, size_t);
 int	_dl_mimmutable(const void *, size_t);
 int	_dl_open(const char *, int);
 int	_dl_pledge(const char *, const char **);
 ssize_t	_dl_read(int, const char *, size_t);
+ssize_t	_dl_pread(int, const char *, size_t, off_t);
 int	_dl_sendsyslog(const char *, size_t, int);
 void	_dl___set_tcb(void *);
 int	_dl_sysctl(const int *, u_int, void *, size_t *, void *, size_t);
Index: libexec/ld.so/aarch64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/aarch64/SYS.h,v
diff -u -p -u -r1.5 SYS.h
--- libexec/ld.so/aarch64/SYS.h	18 Feb 2020 12:19:11 -0000	1.5
+++ libexec/ld.so/aarch64/SYS.h	4 Dec 2023 14:46:46 -0000
@@ -29,18 +29,25 @@
 #include <machine/asm.h>
 #include <sys/syscall.h>
 
-#define SYSTRAP(x)					\
-	ldr	x8, =SYS_ ## x				;\
-	svc	0					;\
-	dsb	nsh					;\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
+#define SYSTRAP(x)						\
+	ldr	x8, =SYS_ ## x					;\
+99:	svc	0						;\
+	PINSYSCALL(SYS_ ## x, 99b)				;\
+	dsb	nsh						;\
 	isb
 
-#define DL_SYSCALL(n)					\
-	.global		__CONCAT(_dl_,n)		;\
-	.type		__CONCAT(_dl_,n)%function	;\
-__CONCAT(_dl_,n):					;\
-	RETGUARD_SETUP(__CONCAT(_dl_,n), x15)		;\
-	SYSTRAP(n)					;\
-	cneg	x0, x0, cs	/* r0 = -errno */	;\
-	RETGUARD_CHECK(__CONCAT(_dl_,n), x15)	 	;\
+#define DL_SYSCALL(n)						\
+	.global		__CONCAT(_dl_,n)			;\
+	.type		__CONCAT(_dl_,n)%function		;\
+__CONCAT(_dl_,n):						;\
+	RETGUARD_SETUP(__CONCAT(_dl_,n), x15)			;\
+	SYSTRAP(n)						;\
+	cneg	x0, x0, cs	/* r0 = -errno */		;\
+	RETGUARD_CHECK(__CONCAT(_dl_,n), x15)	 		;\
 	ret
Index: libexec/ld.so/aarch64/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/aarch64/ld.script,v
diff -u -p -u -r1.5 ld.script
--- libexec/ld.so/aarch64/ld.script	2 Feb 2023 00:44:08 -0000	1.5
+++ libexec/ld.so/aarch64/ld.script	28 Nov 2023 16:04:57 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000001);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -39,10 +40,19 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
     . = DATA_SEGMENT_RELRO_END (0, .);
+
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
 
     /* BOOTDATA */
     . = ALIGN(0x1000);
Index: libexec/ld.so/alpha/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/alpha/SYS.h,v
diff -u -p -u -r1.3 SYS.h
--- libexec/ld.so/alpha/SYS.h	6 Dec 2023 06:15:33 -0000	1.3
+++ libexec/ld.so/alpha/SYS.h	6 Dec 2023 06:59:38 -0000
@@ -61,10 +61,17 @@
  * further register saving.
  */
 
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
 #define	DL_SYSCALL(c)							\
 LEAF_NOPROFILE(_dl_##c, irrelevant);					\
 	ldiq	v0, SYS_##c;						\
-	call_pal PAL_OSF1_callsys;					\
+99:	call_pal PAL_OSF1_callsys;					\
+	PINSYSCALL(SYS_##c, 99b);					\
 	beq	a3, 1f;							\
 	subq	zero, v0, v0;	/* return -errno */			\
 1:									\
Index: libexec/ld.so/alpha/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/alpha/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/alpha/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/alpha/ld.script	28 Nov 2023 16:04:52 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -39,6 +40,10 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/amd64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/amd64/SYS.h,v
diff -u -p -u -r1.3 SYS.h
--- libexec/ld.so/amd64/SYS.h	25 Apr 2023 04:11:10 -0000	1.3
+++ libexec/ld.so/amd64/SYS.h	4 Dec 2023 14:46:31 -0000
@@ -30,19 +30,26 @@
 #include <sys/syscall.h>
 #include <machine/asm.h>
 
-#define	DL_SYSCALL(n)					\
-	.global	__CONCAT(_dl_,n)			;\
-	.type	__CONCAT(_dl_,n), @function		;\
-	.align	16,0xcc					;\
-__CONCAT(_dl_,n):					;\
-	endbr64						;\
-	RETGUARD_SETUP(_dl_##n, r11)			;\
-	RETGUARD_PUSH(r11)				;\
-	movl	$(__CONCAT(SYS_,n)), %eax		;\
-	movq	%rcx, %r10				;\
-	syscall						;\
-	jnc	1f					;\
-	neg	%rax					;\
-1:	RETGUARD_POP(r11)				;\
-	RETGUARD_CHECK(_dl_##n, r11)			;\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
+#define	DL_SYSCALL(n)						\
+	.global	__CONCAT(_dl_,n)				;\
+	.type	__CONCAT(_dl_,n), @function			;\
+	.align	16,0xcc						;\
+__CONCAT(_dl_,n):						;\
+	endbr64							;\
+	RETGUARD_SETUP(_dl_##n, r11)				;\
+	RETGUARD_PUSH(r11)					;\
+	movl	$(__CONCAT(SYS_,n)), %eax			;\
+	movq	%rcx, %r10					;\
+99:	syscall							;\
+	PINSYSCALL(__CONCAT(SYS_,n), 99b)			;\
+	jnc	1f						;\
+	neg	%rax						;\
+1:	RETGUARD_POP(r11)					;\
+	RETGUARD_CHECK(_dl_##n, r11)				;\
 	ret
Index: libexec/ld.so/amd64/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/amd64/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/amd64/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/amd64/ld.script	28 Nov 2023 16:03:46 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -42,6 +43,11 @@ SECTIONS
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
     . = DATA_SEGMENT_RELRO_END (0, .);
+
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
 
     /* BOOTDATA */
     . = ALIGN(0x1000);
Index: libexec/ld.so/arm/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/arm/SYS.h,v
diff -u -p -u -r1.3 SYS.h
--- libexec/ld.so/arm/SYS.h	13 Mar 2020 09:31:26 -0000	1.3
+++ libexec/ld.so/arm/SYS.h	4 Dec 2023 14:46:23 -0000
@@ -29,18 +29,25 @@
 #include <machine/asm.h>
 #include <sys/syscall.h>
 
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
 #define SYSTRAP(x) \
-	ldr	r12, =SYS_ ## x;			\
-	swi	0;					\
-	dsb	nsh;					\
+	ldr	r12, =SYS_ ## x					;\
+99:	swi	0						;\
+	PINSYSCALL(SYS_ ## x, 99b)				;\
+	dsb	nsh						;\
 	isb
 
-#define DL_SYSCALL(n)					\
-	.global		__CONCAT(_dl_,n)		;\
-	.type		__CONCAT(_dl_,n)%function	;\
-__CONCAT(_dl_,n):					;\
-	SYSTRAP(n)					;\
-	bcs	.L_cerr					;\
+#define DL_SYSCALL(n)						\
+	.global		__CONCAT(_dl_,n)			;\
+	.type		__CONCAT(_dl_,n)%function		;\
+__CONCAT(_dl_,n):						;\
+	SYSTRAP(n)						;\
+	bcs	.L_cerr						;\
 	mov	pc, lr
 
 .L_cerr:
Index: libexec/ld.so/arm/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/arm/ld.script,v
diff -u -p -u -r1.2 ld.script
--- libexec/ld.so/arm/ld.script	9 Nov 2022 18:39:35 -0000	1.2
+++ libexec/ld.so/arm/ld.script	28 Nov 2023 16:04:47 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -40,6 +41,11 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
+
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/hppa/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/hppa/SYS.h,v
diff -u -p -u -r1.1 SYS.h
--- libexec/ld.so/hppa/SYS.h	27 Aug 2017 21:59:52 -0000	1.1
+++ libexec/ld.so/hppa/SYS.h	4 Dec 2023 14:46:15 -0000
@@ -33,17 +33,24 @@
 #include <machine/vmparam.h>
 #undef  _LOCORE
 
-#define	DL_SYSCALL(x)				\
-ENTRY(__CONCAT(_dl_,x),0)			!\
-	stw	rp, HPPA_FRAME_ERP(sr0,sp)	!\
-	ldil	L%SYSCALLGATE, r1		!\
-	ble	4(sr7, r1)			!\
-	ldi	__CONCAT(SYS_,x), t1		!\
-	comb,<>	r0, t1, _dl_sysexit		!\
-	ldw	HPPA_FRAME_ERP(sr0,sp), rp	!\
-	bv	r0(rp)				!\
-	nop					!\
-_dl_sysexit					!\
-	bv	r0(rp)				!\
-	sub	r0, ret0, ret0			!\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		!\
+	.long label						!\
+	.long sysno						!\
+	.popsection
+
+#define	DL_SYSCALL(x)						\
+ENTRY(__CONCAT(_dl_,x),0)					!\
+	stw	rp, HPPA_FRAME_ERP(sr0,sp)			!\
+	ldil	L%SYSCALLGATE, r1				!\
+99:	ble	4(sr7, r1)					!\
+	PINSYSCALL(__CONCAT(SYS_,x), 99b)			!\
+	 ldi	__CONCAT(SYS_,x), t1				!\
+	comb,<>	r0, t1, _dl_sysexit				!\
+	ldw	HPPA_FRAME_ERP(sr0,sp), rp			!\
+	bv	r0(rp)						!\
+	nop							!\
+_dl_sysexit							!\
+	bv	r0(rp)						!\
+	sub	r0, ret0, ret0					!\
 EXIT(__CONCAT(_dl_,x))
Index: libexec/ld.so/hppa/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/hppa/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/hppa/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/hppa/ld.script	28 Nov 2023 16:03:06 -0000
@@ -6,6 +6,7 @@ PHDRS
 	pltgot	PT_LOAD;
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
Index: libexec/ld.so/i386/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/i386/SYS.h,v
diff -u -p -u -r1.1 SYS.h
--- libexec/ld.so/i386/SYS.h	27 Aug 2017 21:59:52 -0000	1.1
+++ libexec/ld.so/i386/SYS.h	4 Dec 2023 14:46:07 -0000
@@ -30,6 +30,12 @@
 #include <sys/syscall.h>
 #include <machine/asm.h>
 
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
 #define DL_SYSCALL(n)						\
 	.section	".text"					;\
 	.align		16,0xcc					;\
@@ -37,7 +43,8 @@
 	.type		__CONCAT(_dl_,n),@function		;\
 __CONCAT(_dl_,n):						;\
 	movl $__CONCAT(SYS_, n),%eax;				;\
-	int $0x80						;\
+99:	int $0x80						;\
+	PINSYSCALL(__CONCAT(SYS_, n), 99b)			;\
 	jb	.L_cerr						;\
 	ret
 
Index: libexec/ld.so/i386/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/i386/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/i386/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/i386/ld.script	28 Nov 2023 16:04:39 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -38,6 +39,11 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
+
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/m88k/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/m88k/SYS.h,v
diff -u -p -u -r1.4 SYS.h
--- libexec/ld.so/m88k/SYS.h	23 Oct 2019 19:55:09 -0000	1.4
+++ libexec/ld.so/m88k/SYS.h	7 Dec 2023 14:08:52 -0000
@@ -44,22 +44,29 @@
 #include <machine/asm.h>
 #include <sys/syscall.h>
 
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
 #define	__CONCAT(p,x)		p##x
 #define	__ENTRY(p,x)		ENTRY(__CONCAT(p,x))
 #define	__SYSCALLNAME(p,x)	__CONCAT(p,x)
 
-#define	__DO_SYSCALL(x)					\
-	or %r13, %r0, __SYSCALLNAME(SYS_,x);		\
-	tb0 0, %r0, 450
+#define	__DO_SYSCALL(x)						\
+	or %r13, %r0, __SYSCALLNAME(SYS_,x)			;\
+99:	tb0 0, %r0, 450						;\
+	PINSYSCALL(__SYSCALLNAME(SYS_,x), 99b)
 
 /*
  * m88k syscall return ABI requires the same amount of ASM
  * whether or not the syscall can possibly fail, so there's
  * no benefit to a DL_SYSCALL_NOERR() macro.
  */
-#define DL_SYSCALL(n)					\
-	__ENTRY(_dl_,n);				\
-	__DO_SYSCALL(n);				\
-	subu	%r2, %r0, %r2;	/* return -errno; */	\
-	jmp	%r1;					\
+#define DL_SYSCALL(n)						\
+	__ENTRY(_dl_,n)						;\
+	__DO_SYSCALL(n)						;\
+	subu	%r2, %r0, %r2	/* return -errno; */		;\
+	jmp	%r1						;\
 	END(_dl_##n)
Index: libexec/ld.so/m88k/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/m88k/ld.script,v
diff -u -p -u -r1.1 ld.script
--- libexec/ld.so/m88k/ld.script	11 Jan 2023 16:31:46 -0000	1.1
+++ libexec/ld.so/m88k/ld.script	28 Nov 2023 16:04:35 -0000
@@ -5,6 +5,7 @@ PHDRS
   btext   PT_LOAD FLAGS (0x08000005);
   data    PT_LOAD;
   random  PT_OPENBSD_RANDOMIZE;
+  scalls PT_OPENBSD_SYSCALLS;
   relro   PT_GNU_RELRO;
   dynamic PT_DYNAMIC;
   note    PT_NOTE;
@@ -36,6 +37,9 @@ SECTIONS
   . = DATA_SEGMENT_ALIGN (0x10000, 0x1000);
   .openbsd.randomdata : { *(.openbsd.randomdata .openbsd.randomdata.*) }
     :data :relro :random
+  .openbsd.syscalls :   { *(.openbsd.syscalls .openbsd.syscalls.*) }
+    :syscalls
+
   .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
   .dynamic : { *(.dynamic) } :data :relro :dynamic
   .got : { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/mips64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/mips64/SYS.h,v
diff -u -p -u -r1.1 SYS.h
--- libexec/ld.so/mips64/SYS.h	27 Aug 2017 21:59:52 -0000	1.1
+++ libexec/ld.so/mips64/SYS.h	7 Dec 2023 14:04:44 -0000
@@ -29,14 +29,21 @@
 #include <sys/syscall.h>
 #include <machine/asm.h>
 
-#define	DL_SYSCALL(c)							\
-NLEAF(_dl_##c,0)							\
-	li      v0,SYS_##c;						\
-	syscall;							\
-	bnez	a3, 1f;							\
-	j	ra;							\
-1:		;							\
-	subu	v0, zero, v0;						\
-	j	ra	;						\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
+#define	DL_SYSCALL(c)						\
+NLEAF(_dl_##c,0)						\
+	li      v0,SYS_##c;					\
+99:	syscall;						\
+	PINSYSCALL(SYS_##c, 99b);				\
+	bnez	a3, 1f;						\
+	j	ra;						\
+1:	;							\
+	subu	v0, zero, v0;					\
+	j	ra;						\
 END(_dl_##c)
 
Index: libexec/ld.so/mips64/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/mips64/ld.script,v
diff -u -p -u -r1.2 ld.script
--- libexec/ld.so/mips64/ld.script	11 Jan 2023 15:14:01 -0000	1.2
+++ libexec/ld.so/mips64/ld.script	28 Nov 2023 16:04:11 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -39,6 +40,11 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
+
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     _gp = ALIGN(16) + 0x7ff0;
Index: libexec/ld.so/powerpc/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/powerpc/SYS.h,v
diff -u -p -u -r1.4 SYS.h
--- libexec/ld.so/powerpc/SYS.h	28 Nov 2020 19:49:30 -0000	1.4
+++ libexec/ld.so/powerpc/SYS.h	7 Dec 2023 14:09:19 -0000
@@ -29,14 +29,21 @@
 #include <sys/syscall.h>
 #include <machine/asm.h>
 
-#define	DL_SYSCALL(n)							\
-ENTRY(_dl_##n)								\
-	RETGUARD_SETUP(_dl_##n, %r11, %r12)				;\
-	li	0, SYS_##n						;\
-	sc								;\
-	cmpwi	0, 0							;\
-	beq+	.L_end##n						;\
-	neg	3, 3							;\
-.L_end##n:								;\
-	RETGUARD_CHECK(_dl_##n, %r11, %r12)				;\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
+#define	DL_SYSCALL(n)						\
+ENTRY(_dl_##n)							\
+	RETGUARD_SETUP(_dl_##n, %r11, %r12)			;\
+	li	0, SYS_##n					;\
+99:	sc							;\
+	PINSYSCALL(SYS_##n, 99b)				;\
+	cmpwi	0, 0						;\
+	beq+	.L_end##n					;\
+	neg	3, 3						;\
+.L_end##n:							;\
+	RETGUARD_CHECK(_dl_##n, %r11, %r12)			;\
 	blr
Index: libexec/ld.so/powerpc/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/powerpc/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/powerpc/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/powerpc/ld.script	28 Nov 2023 16:04:07 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -39,6 +40,11 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
+
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/powerpc64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/powerpc64/SYS.h,v
diff -u -p -u -r1.2 SYS.h
--- libexec/ld.so/powerpc64/SYS.h	16 Oct 2020 23:42:53 -0000	1.2
+++ libexec/ld.so/powerpc64/SYS.h	4 Dec 2023 14:45:29 -0000
@@ -29,14 +29,21 @@
 #include <sys/syscall.h>
 #include <machine/asm.h>
 
-#define	DL_SYSCALL(n)							\
-ENTRY(_dl_##n)								\
-	RETGUARD_SETUP(_dl_##n, %r11)					;\
-	li	%r0, SYS_##n						;\
-	sc								;\
-	cmpdi	%r0, 0							;\
-	beq .L_end##n							;\
-	neg	%r3, %r3						;\
-.L_end##n:								;\
-	RETGUARD_CHECK(_dl_##n, %r11)					;\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
+#define	DL_SYSCALL(n)						\
+ENTRY(_dl_##n)							\
+	RETGUARD_SETUP(_dl_##n, %r11)				;\
+	li	%r0, SYS_##n					;\
+99:	sc							;\
+	PINSYSCALL(SYS_##n, 99b)				;\
+	cmpdi	%r0, 0						;\
+	beq .L_end##n						;\
+	neg	%r3, %r3					;\
+.L_end##n:							;\
+	RETGUARD_CHECK(_dl_##n, %r11)				;\
 	blr
Index: libexec/ld.so/powerpc64/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/powerpc64/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/powerpc64/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/powerpc64/ld.script	28 Nov 2023 16:04:04 -0000
@@ -5,6 +5,7 @@ PHDRS
 	text	PT_LOAD FLAGS (1);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -38,6 +39,11 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
+
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/riscv64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/riscv64/SYS.h,v
diff -u -p -u -r1.1 SYS.h
--- libexec/ld.so/riscv64/SYS.h	28 Apr 2021 15:16:26 -0000	1.1
+++ libexec/ld.so/riscv64/SYS.h	7 Dec 2023 14:09:05 -0000
@@ -29,19 +29,26 @@
 #include <machine/asm.h>
 #include <sys/syscall.h>
 
-#define SYSTRAP(x)					\
-	li	t0, SYS_ ## x				;\
-	ecall						;\
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
+#define SYSTRAP(x)						\
+	li	t0, SYS_ ## x					;\
+99:	ecall							;\
+	PINSYSCALL(SYS_ ## x, 99b)
 	/* XXX fence */
 
-#define DL_SYSCALL(n)					\
-	.global		__CONCAT(_dl_,n)		;\
-	.type		__CONCAT(_dl_,n)%function	;\
-__CONCAT(_dl_,n):					;\
-	RETGUARD_SETUP(__CONCAT(_dl_,n), x15)		;\
-	SYSTRAP(n)					;\
-	beqz	t0, 1f					;\
-	sub	a0, zero, a0	/* r0 = -errno */	;\
-1:							;\
-	RETGUARD_CHECK(__CONCAT(_dl_,n), x15)	 	;\
+#define DL_SYSCALL(n)						\
+	.global		__CONCAT(_dl_,n)			;\
+	.type		__CONCAT(_dl_,n)%function		;\
+__CONCAT(_dl_,n):						;\
+	RETGUARD_SETUP(__CONCAT(_dl_,n), x15)			;\
+	SYSTRAP(n)						;\
+	beqz	t0, 1f						;\
+	sub	a0, zero, a0	/* r0 = -errno */		;\
+1:								;\
+	RETGUARD_CHECK(__CONCAT(_dl_,n), x15)	 		;\
 	ret
Index: libexec/ld.so/riscv64/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/riscv64/ld.script,v
diff -u -p -u -r1.4 ld.script
--- libexec/ld.so/riscv64/ld.script	2 Feb 2023 00:44:08 -0000	1.4
+++ libexec/ld.so/riscv64/ld.script	28 Nov 2023 16:04:00 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -39,6 +40,11 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
+
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/sh/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/sh/SYS.h,v
diff -u -p -u -r1.2 SYS.h
--- libexec/ld.so/sh/SYS.h	2 Sep 2022 06:19:05 -0000	1.2
+++ libexec/ld.so/sh/SYS.h	4 Dec 2023 14:44:17 -0000
@@ -29,6 +29,12 @@
 #include <machine/asm.h>
 #include <sys/syscall.h>
 
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
 #ifdef __ASSEMBLER__
 /*
  * If the system call number fits in a 8-bit signed value (i.e. fits in 7 bits),
@@ -38,10 +44,12 @@
 .macro systrap num
 .iflt \num - 128
 	mov	# \num, r0
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(n, 99b)
 .else
 	mov.l	903f, r0
-	trapa	#0x80
+99:	trapa	#0x80
+	PINSYSCALL(n, 99b)
 	bra	904f
 	 nop
 	.align	2
@@ -51,17 +59,17 @@
 .endm
 #endif
 
-#define SYSTRAP(x)					\
-		systrap	SYS_ ## x
+#define SYSTRAP(x)						\
+	systrap	SYS_ ## x
 
-#define DL_SYSCALL(n)					\
-	.global		__CONCAT(_dl_,n)		;\
-	.type		__CONCAT(_dl_,n)%function	;\
-__CONCAT(_dl_,n):					;\
-	SYSTRAP(n)					;\
-	bf	.L_cerr					;\
-	 nop						;\
-	rts						;\
+#define DL_SYSCALL(n)						\
+	.global		__CONCAT(_dl_,n)			;\
+	.type		__CONCAT(_dl_,n)%function		;\
+__CONCAT(_dl_,n):						;\
+	SYSTRAP(n)						;\
+	bf	.L_cerr						;\
+	 nop							;\
+	rts							;\
 	 nop
 
 .L_cerr:
Index: libexec/ld.so/sh/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/sh/ld.script,v
diff -u -p -u -r1.2 ld.script
--- libexec/ld.so/sh/ld.script	10 Feb 2023 03:22:12 -0000	1.2
+++ libexec/ld.so/sh/ld.script	28 Nov 2023 16:05:20 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -35,6 +36,7 @@ SECTIONS
   . = DATA_SEGMENT_ALIGN (0x10000, 0x1000);
   .openbsd.randomdata     : { *(.openbsd.randomdata .openbsd.randomdata.*) }
     :data :relro :random
+  .openbsd.syscalls : { *(.openbsd.syscalls .openbsd.syscalls.*) } :syscalls
   .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
   .dynamic        : { *(.dynamic) } :data :relro :dynamic
   .got            : { *(.got.plt) *(.got) } :data :relro
Index: libexec/ld.so/sparc64/SYS.h
===================================================================
RCS file: /cvs/src/libexec/ld.so/sparc64/SYS.h,v
diff -u -p -u -r1.4 SYS.h
--- libexec/ld.so/sparc64/SYS.h	14 Dec 2021 07:20:16 -0000	1.4
+++ libexec/ld.so/sparc64/SYS.h	4 Dec 2023 14:43:58 -0000
@@ -68,14 +68,21 @@
 #include <machine/trap.h>
 #include <machine/asm.h>
 
+#define PINSYSCALL(sysno, label)				\
+	.pushsection .openbsd.syscalls,"",@progbits		;\
+	.long label						;\
+	.long sysno						;\
+	.popsection
+
 #define __CONCAT(x,y) x##y
 
-#define DL_SYSCALL(n)					\
-_ENTRY(__CONCAT(_dl_,n))				\
-	mov __CONCAT(SYS_,n) | SYSCALL_G2RFLAG, %g1	;\
-	add %o7, 8, %g2					;\
-	t ST_SYSCALL					;\
-	retl						;\
+#define DL_SYSCALL(n)						\
+_ENTRY(__CONCAT(_dl_,n))					\
+	mov __CONCAT(SYS_,n) | SYSCALL_G2RFLAG, %g1		;\
+	add %o7, 8, %g2						;\
+99:	t ST_SYSCALL						;\
+	PINSYSCALL(__CONCAT(SYS_,n), 99b)			;\
+	retl							;\
 	 sub %g0, %o0, %o0
 
 
Index: libexec/ld.so/sparc64/ld.script
===================================================================
RCS file: /cvs/src/libexec/ld.so/sparc64/ld.script,v
diff -u -p -u -r1.5 ld.script
--- libexec/ld.so/sparc64/ld.script	2 Feb 2023 00:44:08 -0000	1.5
+++ libexec/ld.so/sparc64/ld.script	28 Nov 2023 16:05:12 -0000
@@ -5,6 +5,7 @@ PHDRS
 	btext	PT_LOAD FLAGS (0x08000005);
 	data	PT_LOAD;
 	random	PT_OPENBSD_RANDOMIZE;
+	syscalls PT_OPENBSD_SYSCALLS;
 	relro	PT_GNU_RELRO;
 	dynamic	PT_DYNAMIC;
 	note	PT_NOTE;
@@ -39,6 +40,10 @@ SECTIONS
     {
 	*(.openbsd.randomdata .openbsd.randomdata.*)
     } :data :relro :random
+    .openbsd.syscalls :
+    {
+	*(.openbsd.syscalls .openbsd.syscalls.*)
+    } :syscalls
     .data.rel.ro : { *(.data.rel.ro.local*) *(.data.rel.ro*) } :data :relro
     .dynamic	: { *(.dynamic) } :data :relro :dynamic
     .got	: { *(.got.plt) *(.got) } :data :relro
Index: usr.bin/kdump/kdump.c
===================================================================
RCS file: /cvs/src/usr.bin/kdump/kdump.c,v
diff -u -p -u -r1.159 kdump.c
--- usr.bin/kdump/kdump.c	9 Nov 2023 15:43:28 -0000	1.159
+++ usr.bin/kdump/kdump.c	7 Dec 2023 14:27:52 -0000
@@ -133,6 +133,7 @@ static void ktrsysret(struct ktr_sysret 
 static void ktruser(struct ktr_user *, size_t);
 static void ktrexec(const char*, size_t);
 static void ktrpledge(struct ktr_pledge *, size_t);
+static void ktrpinsyscall(struct ktr_pinsyscall *, size_t);
 static void usage(void);
 static void ioctldecode(int);
 static void ptracedecode(int);
@@ -309,6 +310,9 @@ main(int argc, char *argv[])
 		case KTR_PLEDGE:
 			ktrpledge(m, ktrlen);
 			break;
+		case KTR_PINSYSCALL:
+			ktrpinsyscall(m, ktrlen);
+			break;
 		default:
 			printf("\n");
 			break;
@@ -369,6 +373,9 @@ dumpheader(struct ktr_header *kth)
 	case KTR_PLEDGE:
 		type = "PLDG";
 		break;
+	case KTR_PINSYSCALL:
+		type = "PINS";
+		break;
 	default:
 		/* htobe32() not guaranteed to work as case label */
 		if (kth->ktr_type == htobe32(KTR_START)) {
@@ -1488,6 +1495,27 @@ ktrpledge(struct ktr_pledge *pledge, siz
 	(void)printf(", errno %d", pledge->error);
 	if (fancy)
 		(void)printf(" %s", strerror(pledge->error));
+	printf("\n");
+}
+
+static void
+ktrpinsyscall(struct ktr_pinsyscall *pinsyscall, size_t len)
+{
+	const char *name = "";
+	int i;
+
+	if (len < sizeof(struct ktr_pinsyscall))
+		errx(1, "invalid ktr pinsyscall length %zu", len);
+
+	if (pinsyscall->syscall >= SYS_MAXSYSCALL || pinsyscall->syscall < 0)
+		(void)printf("[%d]", pinsyscall->syscall);
+	else
+		(void)printf("%s", syscallnames[pinsyscall->syscall]);
+	(void)printf(", addr %lx, errno %d", pinsyscall->addr,
+	    pinsyscall->error);
+	(void)printf(", errno %d", pinsyscall->error);
+	if (fancy)
+		(void)printf(" %s", strerror(pinsyscall->error));
 	printf("\n");
 }
 
Index: usr.bin/lastcomm/lastcomm.c
===================================================================
RCS file: /cvs/src/usr.bin/lastcomm/lastcomm.c,v
diff -u -p -u -r1.33 lastcomm.c
--- usr.bin/lastcomm/lastcomm.c	21 Feb 2023 14:31:07 -0000	1.33
+++ usr.bin/lastcomm/lastcomm.c	26 Nov 2023 01:31:45 -0000
@@ -178,6 +178,7 @@ flagbits(int f)
 	BIT(ATRAP, 'T');
 	BIT(AUNVEIL, 'U');
 	BIT(AEXECVE, 'E');
+	BIT(APINSYS, 'S');
 	*p = '\0';
 	return (flags);
 }
Index: bin/ps/print.c
===================================================================
RCS file: /cvs/src/bin/ps/print.c,v
diff -u -p -u -r1.86 print.c
--- bin/ps/print.c	8 Mar 2023 14:47:02 -0000	1.86
+++ bin/ps/print.c	6 Dec 2023 04:59:23 -0000
@@ -303,6 +303,10 @@ printstate(const struct pinfo *pi, VAREN
 		*cp++ = '+';
 	if (kp->p_psflags & PS_PLEDGE)
 		*cp++ = 'p';
+	if (kp->p_psflags & PS_PIN)
+		*cp++ = 'l';
+	if (kp->p_psflags & PS_LIBCPIN)
+		*cp++ = 'L';
 	if (kp->p_eflag & EPROC_UNVEIL) {
 		if (kp->p_eflag & EPROC_LKUNVEIL)
 			*cp++ = 'U';
Index: bin/ps/ps.1
===================================================================
RCS file: /cvs/src/bin/ps/ps.1,v
diff -u -p -u -r1.131 ps.1
--- bin/ps/ps.1	10 Nov 2023 09:17:02 -0000	1.131
+++ bin/ps/ps.1	6 Dec 2023 05:53:12 -0000
@@ -359,6 +359,9 @@ PS_EXECPLEDGE	0x00400000 has exec pledge
 PS_ORPHAN	0x00800000 process is on an orphan list
 PS_CHROOT	0x01000000 process is chrooted
 PS_NOBTCFI	0x02000000 no Branch Target CFI
+PS_PIN          0x08000000 ld.so or static executable that
+                           has syscalls pinned
+PS_LIBCPIN      0x10000000 libc.so has syscalls pinned
 .Ed
 .It Cm re
 Core residency time (in seconds; 127 = infinity).
@@ -475,6 +478,11 @@ scheduling priority.
 .It p
 The process has called
 .Xr pledge 2 .
+.It l
+.Xr ld.so 1
+or a static executable has syscall pinning.
+.It L
+libc.so has syscall pinning.
 .\" .It S
 .\" The process has asked for FIFO
 .\" page replacement

[prev in list] [next in list] [prev in thread] [next in thread] 


Configure |

About | News | Add a list | Sponsored by KoreLogic


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK