1 // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 2 // XFAIL: android 3 // XFAIL: 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 #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 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); 73 regs_struct regs; 74 regs_struct* volatile pregs = ®s; 75 #ifdef ARCH_IOVEC_FOR_GETREGSET 76 struct iovec regset_io; 77 #endif 78 int res; 79 80 #ifdef POSITIVE 81 ++pregs; 82 #endif 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); 94 // CHECK: AddressSanitizer: stack-buffer-overflow 95 // CHECK: {{.*ptrace.cc:}}[[@LINE-2]] 96 assert(!res); 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); 107 #else 108 # define __PTRACE_FPARGS NULL, &fpregs 109 #endif 110 res = ptrace((enum __ptrace_request)__PTRACE_FPREQUEST, pid, __PTRACE_FPARGS); 111 assert(!res); 112 PRINT_REG_FP(fpregs); 113 114 #ifdef __i386__ 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 } 126