1 | // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 |
2 | // XFAIL: android |
3 | // XFAIL: target=mips{{.*}} |
4 | // |
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> |
15 | #include <sys/uio.h> // for iovec |
16 | #include <elf.h> // for NT_PRSTATUS |
17 | #if defined(__aarch64__) || defined(__loongarch__) |
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(__loongarch__) |
41 | typedef struct user_pt_regs regs_struct; |
42 | typedef struct user_fp_state fpregs_struct; |
43 | # define PRINT_REG_PC(__regs) printf("%lx\n", (unsigned long)(__regs.csr_era)) |
44 | # define PRINT_REG_FP(__fpregs) printf("%x\n", (unsigned)(__fpregs.fcsr)) |
45 | # define ARCH_IOVEC_FOR_GETREGSET |
46 | |
47 | #elif defined(__powerpc64__) |
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.nip)) |
51 | #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (elf_greg_t)fpregs[32]) |
52 | #define ARCH_IOVEC_FOR_GETREGSET |
53 | |
54 | #elif defined(__mips__) |
55 | typedef struct pt_regs regs_struct; |
56 | typedef elf_fpregset_t fpregs_struct; |
57 | #define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.cp0_epc)) |
58 | #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (elf_greg_t) (__fpregs[32])) |
59 | #define __PTRACE_FPREQUEST PTRACE_GETFPREGS |
60 | |
61 | #elif defined(__arm__) |
62 | # include <asm/ptrace.h> |
63 | # include <sys/procfs.h> |
64 | typedef struct pt_regs regs_struct; |
65 | typedef char fpregs_struct[ARM_VFPREGS_SIZE]; |
66 | #define PRINT_REG_PC(__regs) printf ("%x\n", (unsigned) (__regs.ARM_pc)) |
67 | #define PRINT_REG_FP(__fpregs) printf ("%x\n", (unsigned) (__fpregs + 32 * 8)) |
68 | #define __PTRACE_FPREQUEST PTRACE_GETVFPREGS |
69 | |
70 | #elif defined(__s390__) |
71 | typedef _user_regs_struct regs_struct; |
72 | typedef _user_fpregs_struct fpregs_struct; |
73 | #define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.psw.addr)) |
74 | #define PRINT_REG_FP(__fpregs) printf ("%lx\n", (unsigned long) (__fpregs.fpc)) |
75 | #define ARCH_IOVEC_FOR_GETREGSET |
76 | |
77 | #elif defined(__riscv) && (__riscv_xlen == 64) |
78 | #include <asm/ptrace.h> |
79 | typedef user_regs_struct regs_struct; |
80 | typedef __riscv_q_ext_state fpregs_struct; |
81 | #define PRINT_REG_PC(__regs) printf("%lx\n", (unsigned long)(__regs.pc)) |
82 | #define PRINT_REG_FP(__fpregs) printf("%lx\n", (unsigned long)(__fpregs.fcsr)) |
83 | #define ARCH_IOVEC_FOR_GETREGSET |
84 | #endif |
85 | |
86 | |
87 | int main(void) { |
88 | pid_t pid; |
89 | pid = fork(); |
90 | if (pid == 0) { // child |
91 | ptrace(request: PTRACE_TRACEME, 0, NULL, NULL); |
92 | execl(path: "/bin/true" , arg: "true" , NULL); |
93 | } else { |
94 | wait(NULL); |
95 | regs_struct regs; |
96 | regs_struct* volatile pregs = ®s; |
97 | #ifdef ARCH_IOVEC_FOR_GETREGSET |
98 | struct iovec regset_io; |
99 | #endif |
100 | int res; |
101 | |
102 | #ifdef POSITIVE |
103 | ++pregs; |
104 | #endif |
105 | |
106 | #ifdef ARCH_IOVEC_FOR_GETREGSET |
107 | # define __PTRACE_REQUEST PTRACE_GETREGSET |
108 | # define __PTRACE_ARGS (void*)NT_PRSTATUS, (void*)®set_io |
109 | regset_io.iov_base = pregs; |
110 | regset_io.iov_len = sizeof(regs_struct); |
111 | #else |
112 | # define __PTRACE_REQUEST PTRACE_GETREGS |
113 | # define __PTRACE_ARGS NULL, pregs |
114 | #endif |
115 | res = ptrace(request: (enum __ptrace_request)__PTRACE_REQUEST, pid, __PTRACE_ARGS); |
116 | // CHECK: AddressSanitizer: stack-buffer-overflow |
117 | // CHECK: {{.*ptrace.cpp:}}[[@LINE-2]] |
118 | assert(!res); |
119 | PRINT_REG_PC(regs); |
120 | |
121 | fpregs_struct fpregs; |
122 | #ifdef ARCH_IOVEC_FOR_GETREGSET |
123 | # define __PTRACE_FPREQUEST PTRACE_GETREGSET |
124 | # define __PTRACE_FPARGS (void*)NT_PRSTATUS, (void*)®set_io |
125 | regset_io.iov_base = &fpregs; |
126 | regset_io.iov_len = sizeof(fpregs_struct); |
127 | res = ptrace((enum __ptrace_request)PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, |
128 | (void*)®set_io); |
129 | #else |
130 | # define __PTRACE_FPARGS NULL, &fpregs |
131 | #endif |
132 | res = ptrace(request: (enum __ptrace_request)__PTRACE_FPREQUEST, pid, __PTRACE_FPARGS); |
133 | assert(!res); |
134 | PRINT_REG_FP(fpregs); |
135 | |
136 | #ifdef __i386__ |
137 | user_fpxregs_struct fpxregs; |
138 | res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs); |
139 | assert(!res); |
140 | printf("%lx\n" , (unsigned long)fpxregs.mxcsr); |
141 | #endif |
142 | |
143 | ptrace(request: PTRACE_CONT, pid, NULL, NULL); |
144 | wait(NULL); |
145 | } |
146 | return 0; |
147 | } |
148 | |