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