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 85 #elif defined(__sparc__) 86 typedef sunos_regs regs_struct; 87 typedef sunos_fp fpregs_struct; 88 # define PRINT_REG_PC(__regs) printf("%x\n", (unsigned)(__regs.pc)) 89 # define PRINT_REG_FP(__fpregs) printf("%x\n", (unsigned)(__fpregs.fsr)) 90 # define __PTRACE_FPREQUEST PTRACE_GETFPREGS 91 #endif 92 93 94 int main(void) { 95 pid_t pid; 96 pid = fork(); 97 if (pid == 0) { // child 98 ptrace(PTRACE_TRACEME, 0, NULL, NULL); 99 execl("/bin/true", "true", NULL); 100 } else { 101 wait(NULL); 102 regs_struct regs; 103 regs_struct* volatile pregs = ®s; 104 #ifdef ARCH_IOVEC_FOR_GETREGSET 105 struct iovec regset_io; 106 #endif 107 int res; 108 109 #ifdef POSITIVE 110 ++pregs; 111 #endif 112 113 #ifdef ARCH_IOVEC_FOR_GETREGSET 114 # define __PTRACE_REQUEST PTRACE_GETREGSET 115 # define __PTRACE_ARGS (void*)NT_PRSTATUS, (void*)®set_io 116 regset_io.iov_base = pregs; 117 regset_io.iov_len = sizeof(regs_struct); 118 #else 119 # define __PTRACE_REQUEST PTRACE_GETREGS 120 # ifdef __sparc__ 121 // The meanings of addr and data are reversed for a few requests on 122 // Linux/sparc64. 123 # define __PTRACE_ARGS pregs, NULL 124 # else 125 # define __PTRACE_ARGS NULL, pregs 126 # endif 127 #endif 128 res = ptrace((enum __ptrace_request)__PTRACE_REQUEST, pid, __PTRACE_ARGS); 129 // CHECK: AddressSanitizer: stack-buffer-overflow 130 // CHECK: {{.*ptrace.cpp:}}[[@LINE-2]] 131 assert(!res); 132 PRINT_REG_PC(regs); 133 134 fpregs_struct fpregs; 135 #ifdef ARCH_IOVEC_FOR_GETREGSET 136 # define __PTRACE_FPREQUEST PTRACE_GETREGSET 137 # define __PTRACE_FPARGS (void*)NT_PRSTATUS, (void*)®set_io 138 regset_io.iov_base = &fpregs; 139 regset_io.iov_len = sizeof(fpregs_struct); 140 res = ptrace((enum __ptrace_request)PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, 141 (void*)®set_io); 142 #else 143 // The meanings of addr and data are reversed for a few requests on 144 // Linux/sparc64. 145 # ifdef __sparc__ 146 # define __PTRACE_FPARGS &fpregs, NULL 147 # else 148 # define __PTRACE_FPARGS NULL, &fpregs 149 # endif 150 #endif 151 res = ptrace((enum __ptrace_request)__PTRACE_FPREQUEST, pid, __PTRACE_FPARGS); 152 assert(!res); 153 PRINT_REG_FP(fpregs); 154 155 #ifdef __i386__ 156 user_fpxregs_struct fpxregs; 157 res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs); 158 assert(!res); 159 printf("%lx\n", (unsigned long)fpxregs.mxcsr); 160 #endif 161 162 ptrace(PTRACE_CONT, pid, NULL, NULL); 163 wait(NULL); 164 } 165 return 0; 166 } 167