1 // RUN: %clangxx -O0 %s -o %t && %run %t 2 3 // UNSUPPORTED: android 4 5 #include <assert.h> 6 #include <signal.h> 7 #include <stdio.h> 8 #include <sys/ptrace.h> 9 #include <sys/types.h> 10 #include <sys/user.h> 11 #include <sys/wait.h> 12 #include <sys/uio.h> 13 #include <unistd.h> 14 #include <elf.h> 15 #if __mips64 || __arm__ 16 #include <asm/ptrace.h> 17 #include <sys/procfs.h> 18 #endif 19 #ifdef __aarch64__ 20 // GLIBC 2.20+ sys/user does not include asm/ptrace.h 21 #include <asm/ptrace.h> 22 #endif 23 24 int main(void) { 25 pid_t pid; 26 pid = fork(); 27 if (pid == 0) { // child 28 ptrace(PTRACE_TRACEME, 0, NULL, NULL); 29 execl("/bin/true", "true", NULL); 30 } else { 31 wait(NULL); 32 int res; 33 34 #if __x86_64__ 35 user_regs_struct regs; 36 res = ptrace(PTRACE_GETREGS, pid, NULL, ®s); 37 assert(!res); 38 if (regs.rip) 39 printf("%zx\n", regs.rip); 40 41 user_fpregs_struct fpregs; 42 res = ptrace(PTRACE_GETFPREGS, pid, NULL, &fpregs); 43 assert(!res); 44 if (fpregs.mxcsr) 45 printf("%x\n", fpregs.mxcsr); 46 #endif // __x86_64__ 47 48 #if (__powerpc64__ || __mips64 || __arm__) 49 struct pt_regs regs; 50 res = ptrace((enum __ptrace_request)PTRACE_GETREGS, pid, NULL, ®s); 51 assert(!res); 52 #if (__powerpc64__) 53 if (regs.nip) 54 printf("%lx\n", regs.nip); 55 #elif (__mips64) 56 if (regs.cp0_epc) 57 printf("%lx\n", regs.cp0_epc); 58 #elif (__arm__) 59 if (regs.ARM_pc) 60 printf("%lx\n", regs.ARM_pc); 61 #endif 62 #if (__powerpc64 || __mips64) 63 elf_fpregset_t fpregs; 64 res = ptrace((enum __ptrace_request)PTRACE_GETFPREGS, pid, NULL, &fpregs); 65 assert(!res); 66 if ((elf_greg_t)fpregs[32]) // fpscr 67 printf("%lx\n", (elf_greg_t)fpregs[32]); 68 #elif (__arm__) 69 char regbuf[ARM_VFPREGS_SIZE]; 70 res = ptrace((enum __ptrace_request)PTRACE_GETVFPREGS, pid, 0, regbuf); 71 assert(!res); 72 unsigned fpscr = *(unsigned*)(regbuf + (32 * 8)); 73 printf ("%x\n", fpscr); 74 #endif 75 #endif // (__powerpc64__ || __mips64 || __arm__) 76 77 #if (__aarch64__) 78 struct iovec regset_io; 79 80 struct user_pt_regs regs; 81 regset_io.iov_base = ®s; 82 regset_io.iov_len = sizeof(regs); 83 res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, (void*)®set_io); 84 assert(!res); 85 if (regs.pc) 86 printf("%llx\n", regs.pc); 87 88 struct user_fpsimd_state fpregs; 89 regset_io.iov_base = &fpregs; 90 regset_io.iov_len = sizeof(fpregs); 91 res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, (void*)®set_io); 92 assert(!res); 93 if (fpregs.fpsr) 94 printf("%x\n", fpregs.fpsr); 95 #endif // (__aarch64__) 96 97 #if (__s390__) 98 struct iovec regset_io; 99 100 struct _user_regs_struct regs; 101 regset_io.iov_base = ®s; 102 regset_io.iov_len = sizeof(regs); 103 res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, (void*)®set_io); 104 assert(!res); 105 if (regs.psw.addr) 106 printf("%lx\n", regs.psw.addr); 107 108 struct _user_fpregs_struct fpregs; 109 regset_io.iov_base = &fpregs; 110 regset_io.iov_len = sizeof(fpregs); 111 res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, (void*)®set_io); 112 assert(!res); 113 if (fpregs.fpc) 114 printf("%x\n", fpregs.fpc); 115 #endif // (__s390__) 116 117 siginfo_t siginfo; 118 res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo); 119 assert(!res); 120 assert(siginfo.si_pid == pid); 121 122 ptrace(PTRACE_CONT, pid, NULL, NULL); 123 124 wait(NULL); 125 } 126 return 0; 127 } 128