1309466Sngie/* $NetBSD: t_siginfo.c,v 1.30 2015/12/22 14:25:58 christos Exp $ */
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2010 The NetBSD Foundation, Inc.
5272343Sngie * All rights reserved.
6272343Sngie *
7272343Sngie * Redistribution and use in source and binary forms, with or without
8272343Sngie * modification, are permitted provided that the following conditions
9272343Sngie * are met:
10272343Sngie * 1. Redistributions of source code must retain the above copyright
11272343Sngie *    notice, this list of conditions and the following disclaimer.
12272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
13272343Sngie *    notice, this list of conditions and the following disclaimer in the
14272343Sngie *    documentation and/or other materials provided with the distribution.
15272343Sngie *
16272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19272343Sngie * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26272343Sngie * POSSIBILITY OF SUCH DAMAGE.
27272343Sngie */
28272343Sngie
29272343Sngie#include <atf-c.h>
30272343Sngie
31274626Sngie#ifdef __NetBSD__
32272343Sngie#include <sys/inttypes.h>
33273389Sngie#endif
34272343Sngie#include <sys/resource.h>
35272343Sngie#include <sys/sysctl.h>
36272343Sngie#include <sys/time.h>
37272343Sngie#include <sys/ucontext.h>
38272343Sngie#include <sys/wait.h>
39272343Sngie
40272343Sngie#include <assert.h>
41272343Sngie#include <signal.h>
42272343Sngie#include <stdio.h>
43272343Sngie#include <stdlib.h>
44272343Sngie#include <string.h>
45272343Sngie#include <unistd.h>
46272343Sngie#include <setjmp.h>
47272343Sngie#include <float.h>
48272343Sngie
49272343Sngie#include <fenv.h>
50309466Sngie#ifdef __HAVE_FENV
51309466Sngie#include <ieeefp.h>	/* only need for ARM Cortex/Neon hack */
52272343Sngie#elif defined(_FLOAT_IEEE754)
53272343Sngie#include <ieeefp.h>
54272343Sngie#endif
55272343Sngie
56272343Sngie#include "isqemu.h"
57272343Sngie
58272343Sngie/* for sigbus */
59272343Sngievolatile char *addr;
60272343Sngie
61272343Sngie/* for sigchild */
62272343Sngiepid_t child;
63272343Sngieint code;
64272343Sngieint status;
65272343Sngie
66272343Sngie/* for sigfpe */
67272343Sngiesig_atomic_t fltdiv_signalled = 0;
68272343Sngiesig_atomic_t intdiv_signalled = 0;
69272343Sngie
70272343Sngiestatic void
71272343Sngiesig_debug(int signo, siginfo_t *info, ucontext_t *ctx)
72272343Sngie{
73272343Sngie	unsigned int i;
74272343Sngie
75272343Sngie	printf("%d %p %p\n", signo, info, ctx);
76272343Sngie	if (info != NULL) {
77272343Sngie		printf("si_signo=%d\n", info->si_signo);
78272343Sngie		printf("si_errno=%d\n", info->si_errno);
79272343Sngie		printf("si_code=%d\n", info->si_code);
80272343Sngie		printf("si_value.sival_int=%d\n", info->si_value.sival_int);
81272343Sngie	}
82272343Sngie	if (ctx != NULL) {
83272343Sngie		printf("uc_flags 0x%x\n", ctx->uc_flags);
84272343Sngie		printf("uc_link %p\n", ctx->uc_link);
85272343Sngie		for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++)
86272343Sngie			printf("uc_sigmask[%d] 0x%x\n", i,
87272343Sngie			    ctx->uc_sigmask.__bits[i]);
88272343Sngie		printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp,
89272343Sngie		    (unsigned long)ctx->uc_stack.ss_size,
90272343Sngie		    ctx->uc_stack.ss_flags);
91274626Sngie#ifdef __NetBSD__
92272343Sngie		for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++)
93272343Sngie			printf("uc_mcontext.greg[%d] 0x%lx\n", i,
94272343Sngie			    (long)ctx->uc_mcontext.__gregs[i]);
95273389Sngie#endif
96272343Sngie	}
97272343Sngie}
98272343Sngie
99272343Sngiestatic void
100272343Sngiesigalrm_action(int signo, siginfo_t *info, void *ptr)
101272343Sngie{
102272343Sngie
103272343Sngie	sig_debug(signo, info, (ucontext_t *)ptr);
104272343Sngie
105272343Sngie	ATF_REQUIRE_EQ(info->si_signo, SIGALRM);
106272343Sngie	ATF_REQUIRE_EQ(info->si_code, SI_TIMER);
107272343Sngie	ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL);
108272343Sngie
109272343Sngie	atf_tc_pass();
110272343Sngie	/* NOTREACHED */
111272343Sngie}
112272343Sngie
113272343SngieATF_TC(sigalarm);
114272343Sngie
115272343SngieATF_TC_HEAD(sigalarm, tc)
116272343Sngie{
117272343Sngie
118272343Sngie	atf_tc_set_md_var(tc, "descr",
119272343Sngie	    "Checks that signal trampoline correctly calls SIGALRM handler");
120272343Sngie}
121272343Sngie
122272343SngieATF_TC_BODY(sigalarm, tc)
123272343Sngie{
124272343Sngie	struct sigaction sa;
125272343Sngie	sa.sa_flags = SA_SIGINFO;
126272343Sngie	sa.sa_sigaction = sigalrm_action;
127272343Sngie	sigemptyset(&sa.sa_mask);
128272343Sngie	sigaction(SIGALRM, &sa, NULL);
129272343Sngie	for (;;) {
130272343Sngie		alarm(1);
131272343Sngie		sleep(1);
132272343Sngie	}
133272343Sngie	atf_tc_fail("SIGALRM handler wasn't called");
134272343Sngie}
135272343Sngie
136272343Sngiestatic void
137272343Sngiesigchild_action(int signo, siginfo_t *info, void *ptr)
138272343Sngie{
139272343Sngie	if (info != NULL) {
140272343Sngie		printf("info=%p\n", info);
141272343Sngie		printf("ptr=%p\n", ptr);
142272343Sngie		printf("si_signo=%d\n", info->si_signo);
143272343Sngie		printf("si_errno=%d\n", info->si_errno);
144272343Sngie		printf("si_code=%d\n", info->si_code);
145272343Sngie		printf("si_uid=%d\n", info->si_uid);
146272343Sngie		printf("si_pid=%d\n", info->si_pid);
147272343Sngie		printf("si_status=%d\n", info->si_status);
148274626Sngie#ifdef __NetBSD__
149272343Sngie		printf("si_utime=%lu\n", (unsigned long int)info->si_utime);
150272343Sngie		printf("si_stime=%lu\n", (unsigned long int)info->si_stime);
151273389Sngie#endif
152272343Sngie	}
153272343Sngie	ATF_REQUIRE_EQ(info->si_code, code);
154272343Sngie	ATF_REQUIRE_EQ(info->si_signo, SIGCHLD);
155272343Sngie	ATF_REQUIRE_EQ(info->si_uid, getuid());
156272343Sngie	ATF_REQUIRE_EQ(info->si_pid, child);
157272343Sngie	if (WIFEXITED(info->si_status))
158272343Sngie		ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status);
159272343Sngie	else if (WIFSTOPPED(info->si_status))
160272343Sngie		ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status);
161272343Sngie	else if (WIFSIGNALED(info->si_status))
162272343Sngie		ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status);
163272343Sngie}
164272343Sngie
165272343Sngiestatic void
166272343Sngiesetchildhandler(void (*action)(int, siginfo_t *, void *))
167272343Sngie{
168272343Sngie	struct sigaction sa;
169272343Sngie	sa.sa_flags = SA_SIGINFO;
170272343Sngie	sa.sa_sigaction = action;
171272343Sngie	sigemptyset(&sa.sa_mask);
172272343Sngie	sigaction(SIGCHLD, &sa, NULL);
173272343Sngie}
174272343Sngie
175272343Sngiestatic void
176272343Sngiesigchild_setup(void)
177272343Sngie{
178272343Sngie	sigset_t set;
179272343Sngie	struct rlimit rlim;
180272343Sngie
181272343Sngie	(void)getrlimit(RLIMIT_CORE, &rlim);
182272343Sngie	rlim.rlim_cur = rlim.rlim_max;
183272343Sngie	(void)setrlimit(RLIMIT_CORE, &rlim);
184272343Sngie
185272343Sngie	setchildhandler(sigchild_action);
186272343Sngie	sigemptyset(&set);
187272343Sngie	sigaddset(&set, SIGCHLD);
188272343Sngie	sigprocmask(SIG_BLOCK, &set, NULL);
189272343Sngie}
190272343Sngie
191272343SngieATF_TC(sigchild_normal);
192272343SngieATF_TC_HEAD(sigchild_normal, tc)
193272343Sngie{
194272343Sngie
195272343Sngie	atf_tc_set_md_var(tc, "descr",
196272343Sngie	    "Checks that signal trampoline correctly calls SIGCHLD handler "
197272343Sngie	    "when child exits normally");
198272343Sngie}
199272343Sngie
200272343SngieATF_TC_BODY(sigchild_normal, tc)
201272343Sngie{
202272343Sngie	sigset_t set;
203272343Sngie
204272343Sngie	sigchild_setup();
205272343Sngie
206272343Sngie	status = 25;
207272343Sngie	code = CLD_EXITED;
208272343Sngie
209272343Sngie	switch ((child = fork())) {
210272343Sngie	case 0:
211272343Sngie		sleep(1);
212272343Sngie		exit(status);
213272343Sngie	case -1:
214272343Sngie		atf_tc_fail("fork failed");
215272343Sngie	default:
216272343Sngie		sigemptyset(&set);
217272343Sngie		sigsuspend(&set);
218272343Sngie	}
219272343Sngie}
220272343Sngie
221272343SngieATF_TC(sigchild_dump);
222272343SngieATF_TC_HEAD(sigchild_dump, tc)
223272343Sngie{
224272343Sngie
225272343Sngie	atf_tc_set_md_var(tc, "descr",
226272343Sngie	    "Checks that signal trampoline correctly calls SIGCHLD handler "
227272343Sngie	    "when child segfaults");
228272343Sngie}
229272343Sngie
230272343SngieATF_TC_BODY(sigchild_dump, tc)
231272343Sngie{
232272343Sngie	sigset_t set;
233272343Sngie
234272343Sngie	sigchild_setup();
235272343Sngie
236272343Sngie	status = SIGSEGV;
237272343Sngie	code = CLD_DUMPED;
238272343Sngie
239272343Sngie	switch ((child = fork())) {
240272343Sngie	case 0:
241272343Sngie		sleep(1);
242272343Sngie		*(volatile long *)0 = 0;
243272343Sngie		atf_tc_fail("Child did not segfault");
244272343Sngie		/* NOTREACHED */
245272343Sngie	case -1:
246272343Sngie		atf_tc_fail("fork failed");
247272343Sngie	default:
248272343Sngie		sigemptyset(&set);
249272343Sngie		sigsuspend(&set);
250272343Sngie	}
251272343Sngie}
252272343Sngie
253272343SngieATF_TC(sigchild_kill);
254272343SngieATF_TC_HEAD(sigchild_kill, tc)
255272343Sngie{
256272343Sngie
257272343Sngie	atf_tc_set_md_var(tc, "descr",
258272343Sngie	    "Checks that signal trampoline correctly calls SIGCHLD handler "
259272343Sngie	    "when child is killed");
260272343Sngie}
261272343Sngie
262272343SngieATF_TC_BODY(sigchild_kill, tc)
263272343Sngie{
264272343Sngie	sigset_t set;
265272343Sngie
266272343Sngie	sigchild_setup();
267272343Sngie
268272343Sngie	status = SIGPIPE;
269272343Sngie	code = CLD_KILLED;
270272343Sngie
271272343Sngie	switch ((child = fork())) {
272272343Sngie	case 0:
273272343Sngie		sigemptyset(&set);
274272343Sngie		sigsuspend(&set);
275272343Sngie		break;
276272343Sngie	case -1:
277272343Sngie		atf_tc_fail("fork failed");
278272343Sngie	default:
279272343Sngie		kill(child, SIGPIPE);
280272343Sngie		sigemptyset(&set);
281272343Sngie		sigsuspend(&set);
282272343Sngie	}
283272343Sngie}
284272343Sngie
285272343Sngiestatic sigjmp_buf sigfpe_flt_env;
286272343Sngiestatic void
287272343Sngiesigfpe_flt_action(int signo, siginfo_t *info, void *ptr)
288272343Sngie{
289272343Sngie
290272343Sngie	sig_debug(signo, info, (ucontext_t *)ptr);
291272343Sngie
292272343Sngie	if (fltdiv_signalled++ != 0)
293272343Sngie		atf_tc_fail("FPE handler called more than once");
294272343Sngie
295272343Sngie	ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
296272343Sngie	ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV);
297272343Sngie	ATF_REQUIRE_EQ(info->si_errno, 0);
298272343Sngie
299272343Sngie	siglongjmp(sigfpe_flt_env, 1);
300272343Sngie}
301272343Sngie
302272343SngieATF_TC(sigfpe_flt);
303272343SngieATF_TC_HEAD(sigfpe_flt, tc)
304272343Sngie{
305272343Sngie
306272343Sngie	atf_tc_set_md_var(tc, "descr",
307272343Sngie	    "Checks that signal trampoline correctly calls SIGFPE handler "
308272343Sngie	    "for floating div-by-zero");
309272343Sngie}
310272343Sngie
311272343SngieATF_TC_BODY(sigfpe_flt, tc)
312272343Sngie{
313272343Sngie	struct sigaction sa;
314272343Sngie	double d = strtod("0", NULL);
315272343Sngie
316272343Sngie	if (isQEMU())
317272343Sngie		atf_tc_skip("Test does not run correctly under QEMU");
318272343Sngie#if defined(__powerpc__)
319272343Sngie	atf_tc_skip("Test not valid on powerpc");
320309466Sngie#elif defined(__arm__) && !__SOFTFP__
321309466Sngie	/*
322309466Sngie	 * Some NEON fpus do not implement IEEE exception handling,
323309466Sngie	 * skip these tests if running on them and compiled for
324309466Sngie	 * hard float.
325309466Sngie	 */
326309466Sngie	if (0 == fpsetmask(fpsetmask(FP_X_INV)))
327309466Sngie		atf_tc_skip("FPU does not implement exception handling");
328272343Sngie#endif
329272343Sngie	if (sigsetjmp(sigfpe_flt_env, 0) == 0) {
330272343Sngie		sa.sa_flags = SA_SIGINFO;
331272343Sngie		sa.sa_sigaction = sigfpe_flt_action;
332272343Sngie		sigemptyset(&sa.sa_mask);
333272343Sngie		sigaction(SIGFPE, &sa, NULL);
334309466Sngie#ifdef __HAVE_FENV
335272343Sngie		feenableexcept(FE_ALL_EXCEPT);
336272343Sngie#elif defined(_FLOAT_IEEE754)
337272343Sngie		fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
338272343Sngie#endif
339272343Sngie		printf("%g\n", 1 / d);
340272343Sngie	}
341272343Sngie	if (fltdiv_signalled == 0)
342272343Sngie		atf_tc_fail("FPE signal handler was not invoked");
343272343Sngie}
344272343Sngie
345272343Sngiestatic sigjmp_buf sigfpe_int_env;
346272343Sngiestatic void
347272343Sngiesigfpe_int_action(int signo, siginfo_t *info, void *ptr)
348272343Sngie{
349272343Sngie
350272343Sngie	sig_debug(signo, info, (ucontext_t *)ptr);
351272343Sngie
352272343Sngie	if (intdiv_signalled++ != 0)
353272343Sngie		atf_tc_fail("INTDIV handler called more than once");
354272343Sngie
355272343Sngie	ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
356272343Sngie	ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV);
357272343Sngie	atf_tc_expect_pass();
358272343Sngie	ATF_REQUIRE_EQ(info->si_errno, 0);
359272343Sngie
360272343Sngie	siglongjmp(sigfpe_int_env, 1);
361272343Sngie}
362272343Sngie
363272343SngieATF_TC(sigfpe_int);
364272343SngieATF_TC_HEAD(sigfpe_int, tc)
365272343Sngie{
366272343Sngie
367272343Sngie	atf_tc_set_md_var(tc, "descr",
368272343Sngie	    "Checks that signal trampoline correctly calls SIGFPE handler "
369272343Sngie	    "for integer div-by-zero (PR port-i386/43655)");
370272343Sngie}
371272343Sngie
372272343SngieATF_TC_BODY(sigfpe_int, tc)
373272343Sngie{
374272343Sngie	struct sigaction sa;
375272343Sngie	long l = strtol("0", NULL, 10);
376272343Sngie
377272343Sngie#if defined(__powerpc__)
378272343Sngie	atf_tc_skip("Test not valid on powerpc");
379272343Sngie#endif
380272343Sngie	if (sigsetjmp(sigfpe_int_env, 0) == 0) {
381272343Sngie		sa.sa_flags = SA_SIGINFO;
382272343Sngie		sa.sa_sigaction = sigfpe_int_action;
383272343Sngie		sigemptyset(&sa.sa_mask);
384272343Sngie		sigaction(SIGFPE, &sa, NULL);
385309466Sngie#ifdef __HAVE_FENV
386272343Sngie		feenableexcept(FE_ALL_EXCEPT);
387272343Sngie#elif defined(_FLOAT_IEEE754)
388272343Sngie		fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
389272343Sngie#endif
390272343Sngie		printf("%ld\n", 1 / l);
391272343Sngie	}
392272343Sngie	if (intdiv_signalled == 0)
393272343Sngie		atf_tc_fail("FPE signal handler was not invoked");
394272343Sngie}
395272343Sngie
396272343Sngiestatic void
397272343Sngiesigsegv_action(int signo, siginfo_t *info, void *ptr)
398272343Sngie{
399272343Sngie
400272343Sngie	sig_debug(signo, info, (ucontext_t *)ptr);
401272343Sngie
402272343Sngie	ATF_REQUIRE_EQ(info->si_signo, SIGSEGV);
403272343Sngie	ATF_REQUIRE_EQ(info->si_errno, 0);
404272343Sngie	ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR);
405272343Sngie	ATF_REQUIRE_EQ(info->si_addr, (void *)0);
406272343Sngie
407272343Sngie	atf_tc_pass();
408272343Sngie	/* NOTREACHED */
409272343Sngie}
410272343Sngie
411272343SngieATF_TC(sigsegv);
412272343SngieATF_TC_HEAD(sigsegv, tc)
413272343Sngie{
414272343Sngie
415272343Sngie	atf_tc_set_md_var(tc, "descr",
416272343Sngie	    "Checks that signal trampoline correctly calls SIGSEGV handler");
417272343Sngie}
418272343Sngie
419272343SngieATF_TC_BODY(sigsegv, tc)
420272343Sngie{
421272343Sngie	struct sigaction sa;
422272343Sngie
423272343Sngie	sa.sa_flags = SA_SIGINFO;
424272343Sngie	sa.sa_sigaction = sigsegv_action;
425272343Sngie	sigemptyset(&sa.sa_mask);
426272343Sngie	sigaction(SIGSEGV, &sa, NULL);
427272343Sngie
428272343Sngie	*(volatile long *)0 = 0;
429272343Sngie	atf_tc_fail("Test did not fault as expected");
430272343Sngie}
431272343Sngie
432272343Sngiestatic void
433272343Sngiesigbus_action(int signo, siginfo_t *info, void *ptr)
434272343Sngie{
435272343Sngie
436272343Sngie	printf("si_addr = %p\n", info->si_addr);
437272343Sngie	sig_debug(signo, info, (ucontext_t *)ptr);
438272343Sngie
439272343Sngie	ATF_REQUIRE_EQ(info->si_signo, SIGBUS);
440272343Sngie	ATF_REQUIRE_EQ(info->si_errno, 0);
441272343Sngie	ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN);
442272343Sngie
443272343Sngie#if defined(__i386__) || defined(__x86_64__)
444272343Sngie	atf_tc_expect_fail("x86 architecture does not correctly "
445272343Sngie	    "report the address where the unaligned access occured");
446272343Sngie#endif
447272343Sngie	ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr);
448272343Sngie
449272343Sngie	atf_tc_pass();
450272343Sngie	/* NOTREACHED */
451272343Sngie}
452272343Sngie
453272343SngieATF_TC(sigbus_adraln);
454272343SngieATF_TC_HEAD(sigbus_adraln, tc)
455272343Sngie{
456272343Sngie
457272343Sngie	atf_tc_set_md_var(tc, "descr",
458272343Sngie	    "Checks that signal trampoline correctly calls SIGBUS handler "
459272343Sngie	    "for invalid address alignment");
460272343Sngie}
461272343Sngie
462272343SngieATF_TC_BODY(sigbus_adraln, tc)
463272343Sngie{
464272343Sngie	struct sigaction sa;
465272343Sngie
466309466Sngie#if defined(__alpha__) || defined(__arm__)
467272343Sngie	int rv, val;
468272343Sngie	size_t len = sizeof(val);
469272343Sngie	rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0);
470272343Sngie	ATF_REQUIRE(rv == 0);
471272343Sngie	if (val == 0)
472309466Sngie		atf_tc_skip("No SIGBUS signal for unaligned accesses");
473272343Sngie#endif
474272343Sngie
475309466Sngie	/* m68k (except sun2) never issue SIGBUS (PR lib/49653) */
476309466Sngie	if (strcmp(MACHINE_ARCH, "m68k") == 0)
477309466Sngie		atf_tc_skip("No SIGBUS signal for unaligned accesses");
478309466Sngie
479272343Sngie	sa.sa_flags = SA_SIGINFO;
480272343Sngie	sa.sa_sigaction = sigbus_action;
481272343Sngie	sigemptyset(&sa.sa_mask);
482272343Sngie	sigaction(SIGBUS, &sa, NULL);
483272343Sngie
484272343Sngie	/* Enable alignment checks for x86. 0x40000 is PSL_AC. */
485272343Sngie#if defined(__i386__)
486272343Sngie	__asm__("pushf; orl $0x40000, (%esp); popf");
487272343Sngie#elif defined(__amd64__)
488272343Sngie	__asm__("pushf; orl $0x40000, (%rsp); popf");
489272343Sngie#endif
490272343Sngie
491272343Sngie	addr = calloc(2, sizeof(int));
492272343Sngie	ATF_REQUIRE(addr != NULL);
493272343Sngie
494272343Sngie	if (isQEMU())
495272343Sngie		atf_tc_expect_fail("QEMU fails to trap unaligned accesses");
496272343Sngie
497272343Sngie	/* Force an unaligned access */
498272343Sngie	addr++;
499272343Sngie	printf("now trying to access unaligned address %p\n", addr);
500272343Sngie	ATF_REQUIRE_EQ(*(volatile int *)addr, 0);
501272343Sngie
502272343Sngie	atf_tc_fail("Test did not fault as expected");
503272343Sngie}
504272343Sngie
505272343SngieATF_TP_ADD_TCS(tp)
506272343Sngie{
507272343Sngie
508272343Sngie	ATF_TP_ADD_TC(tp, sigalarm);
509272343Sngie	ATF_TP_ADD_TC(tp, sigchild_normal);
510272343Sngie	ATF_TP_ADD_TC(tp, sigchild_dump);
511272343Sngie	ATF_TP_ADD_TC(tp, sigchild_kill);
512272343Sngie	ATF_TP_ADD_TC(tp, sigfpe_flt);
513272343Sngie	ATF_TP_ADD_TC(tp, sigfpe_int);
514272343Sngie	ATF_TP_ADD_TC(tp, sigsegv);
515272343Sngie	ATF_TP_ADD_TC(tp, sigbus_adraln);
516272343Sngie
517272343Sngie	return atf_no_error();
518272343Sngie}
519