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