10 extern char __start___ex_table
[];
11 extern char __stop___ex_table
[];
13 #if defined(__powerpc64__)
14 #define UCONTEXT_NIA(UC) (UC)->uc_mcontext.gp_regs[PT_NIP]
15 #elif defined(__powerpc__)
16 #define UCONTEXT_NIA(UC) (UC)->uc_mcontext.uc_regs->gregs[PT_NIP]
18 #error implement UCONTEXT_NIA
21 static void segv_handler(int signr
, siginfo_t
*info
, void *ptr
)
23 ucontext_t
*uc
= (ucontext_t
*)ptr
;
24 unsigned long addr
= (unsigned long)info
->si_addr
;
25 unsigned long *ip
= &UCONTEXT_NIA(uc
);
26 unsigned long *ex_p
= (unsigned long *)__start___ex_table
;
28 while (ex_p
< (unsigned long *)__stop___ex_table
) {
29 unsigned long insn
, fixup
;
40 printf("No exception table match for NIA %lx ADDR %lx\n", *ip
, addr
);
44 static void setup_segv_handler(void)
46 struct sigaction action
;
48 memset(&action
, 0, sizeof(action
));
49 action
.sa_sigaction
= segv_handler
;
50 action
.sa_flags
= SA_SIGINFO
;
51 sigaction(SIGSEGV
, &action
, NULL
);
54 unsigned long COPY_LOOP(void *to
, const void *from
, unsigned long size
);
55 unsigned long test_copy_tofrom_user_reference(void *to
, const void *from
, unsigned long size
);
57 static int total_passed
;
58 static int total_failed
;
60 static void do_one_test(char *dstp
, char *srcp
, unsigned long len
)
62 unsigned long got
, expected
;
64 got
= COPY_LOOP(dstp
, srcp
, len
);
65 expected
= test_copy_tofrom_user_reference(dstp
, srcp
, len
);
67 if (got
!= expected
) {
69 printf("FAIL from=%p to=%p len=%ld returned %ld, expected %ld\n",
70 srcp
, dstp
, len
, got
, expected
);
79 int test_copy_exception(void)
83 unsigned long src
, dst
, len
;
85 page_size
= getpagesize();
86 p
= mmap(NULL
, page_size
* 2, PROT_READ
|PROT_WRITE
,
87 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
89 if (p
== MAP_FAILED
) {
94 memset(p
, 0, page_size
);
98 if (mprotect(p
+ page_size
, page_size
, PROT_NONE
)) {
103 q
= p
+ page_size
- MAX_LEN
;
105 for (src
= 0; src
< MAX_LEN
; src
++) {
106 for (dst
= 0; dst
< MAX_LEN
; dst
++) {
107 for (len
= 0; len
< MAX_LEN
+1; len
++) {
108 // printf("from=%p to=%p len=%ld\n", q+dst, q+src, len);
109 do_one_test(q
+dst
, q
+src
, len
);
115 printf(" Pass: %d\n", total_passed
);
116 printf(" Fail: %d\n", total_failed
);
123 return test_harness(test_copy_exception
, str(COPY_LOOP
));