1 /*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright 2026 The FreeBSD Foundation
5 *
6 * This software were developed by
7 * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
8 * the FreeBSD Foundation.
9 */
10
11 #include <sys/syscall.h>
12 #include <err.h>
13 #include <signal.h>
14 #include <stdatomic.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19
20 #ifndef __amd64__
21 #error "amd64 only"
22 #endif
23
24 /*
25 * The check to see how "INT $0x80" behaves for amd64 native ABI
26 * processes. Before bd8edba0792b71be3f8ed5dea9c22287e95c986a it
27 * executed syscalls with amd64 calling conventions. After that
28 * revision, it should raise SIGBUS.
29 */
30
31 static uintptr_t int0x80_loc;
32 static int signo;
33 extern char after_int0x80[];
34
35 static void
sigill_action(int signo1,siginfo_t * si __unused,void * uctxv)36 sigill_action(int signo1, siginfo_t *si __unused, void *uctxv)
37 {
38 ucontext_t *uctx = uctxv;
39
40 signo = signo1;
41 int0x80_loc = uctx->uc_mcontext.mc_rip;
42 }
43
44 static int
fire(void)45 fire(void)
46 {
47 int res;
48
49 res = SYS_getpid;
50 asm volatile(
51 ".globl\tafter_int0x80\n"
52 "\tint\t$0x80\n"
53 "after_int0x80:"
54 : "+a" (res)
55 :
56 : "rdx", "memory", "cc");
57 return (res);
58 }
59
60 int
main(void)61 main(void)
62 {
63 struct sigaction sa;
64 char signame[SIG2STR_MAX];
65 int pid, res;
66
67 res = 0;
68
69 memset(&sa, 0, sizeof(sa));
70 sa.sa_sigaction = sigill_action;
71 sa.sa_flags = SA_SIGINFO;
72 if (sigaction(SIGBUS, &sa, NULL) == -1)
73 err(1, "catching SIGBUS");
74
75 pid = fire();
76 atomic_signal_fence(memory_order_seq_cst);
77 if (int0x80_loc == 0) {
78 printf("int $0x80 does not raise SIGBUS\n");
79 if (pid == getpid())
80 printf("and syscall worked\n");
81 else
82 printf("but syscall did not worked\n");
83 res = 1;
84 } else {
85 sig2str(signo, signame);
86 printf("int $0x80 raises SIG%s\n", signame);
87 if (int0x80_loc == (uintptr_t)after_int0x80) {
88 printf("at expected location\n");
89 } else {
90 printf("not at expected location\n");
91 res = 1;
92 }
93 }
94 exit(res);
95 }
96