167 lines · cpp
1// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=3162// XFAIL: android3// XFAIL: target=mips{{.*}}4//5// RUN: %clangxx_asan -O0 %s -o %t && %run %t6// RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s7 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 iovec16#include <elf.h> // for NT_PRSTATUS17#if defined(__aarch64__) || defined(__loongarch__)18# include <asm/ptrace.h>19#endif20 21#if defined(__i386__) || defined(__x86_64__)22typedef user_regs_struct regs_struct;23typedef user_fpregs_struct fpregs_struct;24#if defined(__i386__)25#define REG_IP eip26#else27#define REG_IP rip28#endif29#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_GETFPREGS32 33#elif defined(__aarch64__)34typedef struct user_pt_regs regs_struct;35typedef 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_GETREGSET39 40#elif defined(__loongarch__)41typedef struct user_pt_regs regs_struct;42typedef 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_GETREGSET46 47#elif defined(__powerpc64__)48typedef struct pt_regs regs_struct;49typedef 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_GETREGSET53 54#elif defined(__mips__)55typedef struct pt_regs regs_struct;56typedef 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_GETFPREGS60 61#elif defined(__arm__)62# include <asm/ptrace.h>63# include <sys/procfs.h>64typedef struct pt_regs regs_struct;65typedef 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_GETVFPREGS69 70#elif defined(__s390__)71typedef _user_regs_struct regs_struct;72typedef _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_GETREGSET76 77#elif defined(__riscv) && (__riscv_xlen == 64)78#include <asm/ptrace.h>79typedef user_regs_struct regs_struct;80typedef __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_GETREGSET84 85#elif defined(__sparc__)86typedef sunos_regs regs_struct;87typedef 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_GETFPREGS91#endif92 93 94int main(void) {95 pid_t pid;96 pid = fork();97 if (pid == 0) { // child98 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_GETREGSET105 struct iovec regset_io;106#endif107 int res;108 109#ifdef POSITIVE110 ++pregs;111#endif112 113#ifdef ARCH_IOVEC_FOR_GETREGSET114# define __PTRACE_REQUEST PTRACE_GETREGSET115# define __PTRACE_ARGS (void*)NT_PRSTATUS, (void*)®set_io116 regset_io.iov_base = pregs;117 regset_io.iov_len = sizeof(regs_struct);118#else119# define __PTRACE_REQUEST PTRACE_GETREGS120# ifdef __sparc__121 // The meanings of addr and data are reversed for a few requests on122 // Linux/sparc64.123# define __PTRACE_ARGS pregs, NULL124# else125# define __PTRACE_ARGS NULL, pregs126# endif127#endif128 res = ptrace((enum __ptrace_request)__PTRACE_REQUEST, pid, __PTRACE_ARGS);129 // CHECK: AddressSanitizer: stack-buffer-overflow130 // CHECK: {{.*ptrace.cpp:}}[[@LINE-2]]131 assert(!res);132 PRINT_REG_PC(regs);133 134 fpregs_struct fpregs;135#ifdef ARCH_IOVEC_FOR_GETREGSET136# define __PTRACE_FPREQUEST PTRACE_GETREGSET137# define __PTRACE_FPARGS (void*)NT_PRSTATUS, (void*)®set_io138 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#else143 // The meanings of addr and data are reversed for a few requests on144 // Linux/sparc64.145# ifdef __sparc__146# define __PTRACE_FPARGS &fpregs, NULL147# else148# define __PTRACE_FPARGS NULL, &fpregs149# endif150#endif151 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#endif161 162 ptrace(PTRACE_CONT, pid, NULL, NULL);163 wait(NULL);164 }165 return 0;166}167