]>
Commit | Line | Data |
---|---|---|
92a42be0 SL |
1 | // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 |
2 | // XFAIL: android | |
3 | // XFAIL: mips | |
4 | // | |
1a4d82fc JJ |
5 | // RUN: %clangxx_asan -O0 %s -o %t && %run %t |
6 | // RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s | |
7 | ||
8 | #include <assert.h> | |
9 | #include <stdio.h> | |
10 | #include <sys/ptrace.h> | |
11 | #include <sys/types.h> | |
12 | #include <sys/user.h> | |
13 | #include <sys/wait.h> | |
14 | #include <unistd.h> | |
92a42be0 SL |
15 | #include <sys/uio.h> // for iovec |
16 | #include <elf.h> // for NT_PRSTATUS | |
17 | #ifdef __aarch64__ | |
18 | # include <asm/ptrace.h> | |
19 | #endif | |
20 | ||
21 | #if defined(__i386__) || defined(__x86_64__) | |
22 | typedef user_regs_struct regs_struct; | |
23 | typedef user_fpregs_struct fpregs_struct; | |
24 | #if defined(__i386__) | |
25 | #define REG_IP eip | |
26 | #else | |
27 | #define REG_IP rip | |
28 | #endif | |
29 | #define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.REG_IP)) | |
30 | #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (unsigned long) (__fpregs.cwd)) | |
31 | #define __PTRACE_FPREQUEST PTRACE_GETFPREGS | |
32 | ||
33 | #elif defined(__aarch64__) | |
34 | typedef struct user_pt_regs regs_struct; | |
35 | typedef struct user_fpsimd_state fpregs_struct; | |
36 | #define PRINT_REG_PC(__regs) printf ("%x\n", (unsigned) (__regs.pc)) | |
37 | #define PRINT_REG_FP(__fpregs) printf ("%x\n", (unsigned) (__fpregs.fpsr)) | |
38 | #define ARCH_IOVEC_FOR_GETREGSET | |
39 | ||
40 | #elif defined(__powerpc64__) | |
41 | typedef struct pt_regs regs_struct; | |
42 | typedef elf_fpregset_t fpregs_struct; | |
43 | #define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.nip)) | |
44 | #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (elf_greg_t)fpregs[32]) | |
45 | #define ARCH_IOVEC_FOR_GETREGSET | |
46 | ||
47 | #elif defined(__mips__) | |
48 | typedef struct pt_regs regs_struct; | |
49 | typedef elf_fpregset_t fpregs_struct; | |
50 | #define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.cp0_epc)) | |
51 | #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (elf_greg_t) (__fpregs[32])) | |
52 | #define __PTRACE_FPREQUEST PTRACE_GETFPREGS | |
53 | ||
54 | #elif defined(__arm__) | |
55 | # include <asm/ptrace.h> | |
56 | # include <sys/procfs.h> | |
57 | typedef struct pt_regs regs_struct; | |
58 | typedef char fpregs_struct[ARM_VFPREGS_SIZE]; | |
59 | #define PRINT_REG_PC(__regs) printf ("%x\n", (unsigned) (__regs.ARM_pc)) | |
60 | #define PRINT_REG_FP(__fpregs) printf ("%x\n", (unsigned) (__fpregs + 32 * 8)) | |
61 | #define __PTRACE_FPREQUEST PTRACE_GETVFPREGS | |
62 | #endif | |
63 | ||
1a4d82fc JJ |
64 | |
65 | int main(void) { | |
66 | pid_t pid; | |
67 | pid = fork(); | |
68 | if (pid == 0) { // child | |
69 | ptrace(PTRACE_TRACEME, 0, NULL, NULL); | |
70 | execl("/bin/true", "true", NULL); | |
71 | } else { | |
72 | wait(NULL); | |
92a42be0 SL |
73 | regs_struct regs; |
74 | regs_struct* volatile pregs = ®s; | |
75 | #ifdef ARCH_IOVEC_FOR_GETREGSET | |
76 | struct iovec regset_io; | |
77 | #endif | |
1a4d82fc | 78 | int res; |
92a42be0 | 79 | |
1a4d82fc JJ |
80 | #ifdef POSITIVE |
81 | ++pregs; | |
82 | #endif | |
92a42be0 SL |
83 | |
84 | #ifdef ARCH_IOVEC_FOR_GETREGSET | |
85 | # define __PTRACE_REQUEST PTRACE_GETREGSET | |
86 | # define __PTRACE_ARGS (void*)NT_PRSTATUS, (void*)®set_io | |
87 | regset_io.iov_base = pregs; | |
88 | regset_io.iov_len = sizeof(regs_struct); | |
89 | #else | |
90 | # define __PTRACE_REQUEST PTRACE_GETREGS | |
91 | # define __PTRACE_ARGS NULL, pregs | |
92 | #endif | |
93 | res = ptrace((enum __ptrace_request)__PTRACE_REQUEST, pid, __PTRACE_ARGS); | |
1a4d82fc JJ |
94 | // CHECK: AddressSanitizer: stack-buffer-overflow |
95 | // CHECK: {{.*ptrace.cc:}}[[@LINE-2]] | |
96 | assert(!res); | |
92a42be0 SL |
97 | PRINT_REG_PC(regs); |
98 | ||
99 | fpregs_struct fpregs; | |
100 | #ifdef ARCH_IOVEC_FOR_GETREGSET | |
101 | # define __PTRACE_FPREQUEST PTRACE_GETREGSET | |
102 | # define __PTRACE_FPARGS (void*)NT_PRSTATUS, (void*)®set_io | |
103 | regset_io.iov_base = &fpregs; | |
104 | regset_io.iov_len = sizeof(fpregs_struct); | |
105 | res = ptrace((enum __ptrace_request)PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, | |
106 | (void*)®set_io); | |
1a4d82fc | 107 | #else |
92a42be0 | 108 | # define __PTRACE_FPARGS NULL, &fpregs |
1a4d82fc | 109 | #endif |
92a42be0 | 110 | res = ptrace((enum __ptrace_request)__PTRACE_FPREQUEST, pid, __PTRACE_FPARGS); |
1a4d82fc | 111 | assert(!res); |
92a42be0 | 112 | PRINT_REG_FP(fpregs); |
1a4d82fc | 113 | |
92a42be0 | 114 | #ifdef __i386__ |
1a4d82fc JJ |
115 | user_fpxregs_struct fpxregs; |
116 | res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs); | |
117 | assert(!res); | |
118 | printf("%lx\n", (unsigned long)fpxregs.mxcsr); | |
119 | #endif | |
120 | ||
121 | ptrace(PTRACE_CONT, pid, NULL, NULL); | |
122 | wait(NULL); | |
123 | } | |
124 | return 0; | |
125 | } |