0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <stdbool.h>
0011 #include <stdio.h>
0012 #include <stdlib.h>
0013 #include <string.h>
0014 #include <unistd.h>
0015 #include <signal.h>
0016 #include <sys/mman.h>
0017 #include <assert.h>
0018 #include <ucontext.h>
0019
0020 #include "utils.h"
0021
0022 static bool faulted;
0023 static int si_code;
0024
0025 static void segv_handler(int n, siginfo_t *info, void *ctxt_v)
0026 {
0027 ucontext_t *ctxt = (ucontext_t *)ctxt_v;
0028 struct pt_regs *regs = ctxt->uc_mcontext.regs;
0029
0030 faulted = true;
0031 si_code = info->si_code;
0032 regs->nip += 4;
0033 }
0034
0035 int test_segv_errors(void)
0036 {
0037 struct sigaction act = {
0038 .sa_sigaction = segv_handler,
0039 .sa_flags = SA_SIGINFO,
0040 };
0041 char c, *p = NULL;
0042
0043 p = mmap(NULL, getpagesize(), 0, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
0044 FAIL_IF(p == MAP_FAILED);
0045
0046 FAIL_IF(sigaction(SIGSEGV, &act, NULL) != 0);
0047
0048 faulted = false;
0049 si_code = 0;
0050
0051
0052
0053
0054
0055 mb();
0056 c = *p;
0057 mb();
0058
0059 FAIL_IF(!faulted);
0060 FAIL_IF(si_code != SEGV_ACCERR);
0061
0062 faulted = false;
0063 si_code = 0;
0064
0065 mb();
0066 *p = c;
0067 mb();
0068
0069 FAIL_IF(!faulted);
0070 FAIL_IF(si_code != SEGV_ACCERR);
0071
0072 return 0;
0073 }
0074
0075 int main(void)
0076 {
0077 return test_harness(test_segv_errors, "segv_errors");
0078 }