16a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
26a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// XFAIL: android
33d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar// XFAIL: mips
46a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines//
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %clangxx_asan -O0 %s -o %t && %run %t
62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
7341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
8341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <assert.h>
9341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <stdio.h>
10341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <sys/ptrace.h>
11341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <sys/types.h>
12341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <sys/user.h>
13341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <sys/wait.h>
14341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#include <unistd.h>
153d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include <sys/uio.h> // for iovec
163d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include <elf.h> // for NT_PRSTATUS
173d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#ifdef __aarch64__
183d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# include <asm/ptrace.h>
193d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
203d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
213d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if defined(__i386__) || defined(__x86_64__)
223d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef user_regs_struct   regs_struct;
233d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef user_fpregs_struct fpregs_struct;
243d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if defined(__i386__)
253d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define REG_IP  eip
263d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#else
273d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define REG_IP  rip
283d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
293d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.REG_IP))
303d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (unsigned long) (__fpregs.cwd))
313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define __PTRACE_FPREQUEST PTRACE_GETFPREGS
323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#elif defined(__aarch64__)
343d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef struct user_pt_regs      regs_struct;
353d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef struct user_fpsimd_state fpregs_struct;
363d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_PC(__regs)    printf ("%x\n", (unsigned) (__regs.pc))
373d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_FP(__fpregs)  printf ("%x\n", (unsigned) (__fpregs.fpsr))
383d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define ARCH_IOVEC_FOR_GETREGSET
393d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
403d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#elif defined(__powerpc64__)
413d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef struct pt_regs regs_struct;
423d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef elf_fpregset_t fpregs_struct;
433d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.nip))
443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (elf_greg_t)fpregs[32])
453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define ARCH_IOVEC_FOR_GETREGSET
463d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
473d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#elif defined(__mips__)
483d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef struct pt_regs regs_struct;
493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef elf_fpregset_t fpregs_struct;
503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_PC(__regs)    printf ("%lx\n", (unsigned long) (__regs.cp0_epc))
513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_FP(__fpregs)  printf ("%lx\n", (elf_greg_t) (__fpregs[32]))
523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define __PTRACE_FPREQUEST PTRACE_GETFPREGS
533d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#elif defined(__arm__)
553d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# include <asm/ptrace.h>
563d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# include <sys/procfs.h>
573d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef struct pt_regs regs_struct;
583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainartypedef char fpregs_struct[ARM_VFPREGS_SIZE];
593d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_PC(__regs)    printf ("%x\n", (unsigned) (__regs.ARM_pc))
603d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define PRINT_REG_FP(__fpregs)  printf ("%x\n", (unsigned) (__fpregs + 32 * 8))
613d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define __PTRACE_FPREQUEST PTRACE_GETVFPREGS
623d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
633d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
64341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
65341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanovint main(void) {
66341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  pid_t pid;
67341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  pid = fork();
68341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  if (pid == 0) { // child
69341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
70341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    execl("/bin/true", "true", NULL);
71341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  } else {
72341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    wait(NULL);
733d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    regs_struct regs;
743d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    regs_struct* volatile pregs = &regs;
753d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#ifdef ARCH_IOVEC_FOR_GETREGSET
763d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    struct iovec regset_io;
773d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
78341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    int res;
793d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
80341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#ifdef POSITIVE
81341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    ++pregs;
82341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#endif
833d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
843d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#ifdef ARCH_IOVEC_FOR_GETREGSET
853d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_REQUEST  PTRACE_GETREGSET
863d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_ARGS     (void*)NT_PRSTATUS, (void*)&regset_io
873d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    regset_io.iov_base = pregs;
883d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    regset_io.iov_len = sizeof(regs_struct);
893d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#else
903d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_REQUEST  PTRACE_GETREGS
913d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_ARGS     NULL, pregs
923d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
933d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    res = ptrace((enum __ptrace_request)__PTRACE_REQUEST, pid, __PTRACE_ARGS);
94341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    // CHECK: AddressSanitizer: stack-buffer-overflow
95341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    // CHECK: {{.*ptrace.cc:}}[[@LINE-2]]
96341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    assert(!res);
973d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    PRINT_REG_PC(regs);
983d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
993d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    fpregs_struct fpregs;
1003d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#ifdef ARCH_IOVEC_FOR_GETREGSET
1013d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_FPREQUEST  PTRACE_GETREGSET
1023d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_FPARGS     (void*)NT_PRSTATUS, (void*)&regset_io
1033d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    regset_io.iov_base = &fpregs;
1043d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    regset_io.iov_len = sizeof(fpregs_struct);
1053d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    res = ptrace((enum __ptrace_request)PTRACE_GETREGSET, pid, (void*)NT_FPREGSET,
1063d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar                 (void*)&regset_io);
107341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#else
1083d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar# define __PTRACE_FPARGS     NULL, &fpregs
109341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#endif
1103d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    res = ptrace((enum __ptrace_request)__PTRACE_FPREQUEST, pid, __PTRACE_FPARGS);
111341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    assert(!res);
1123d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    PRINT_REG_FP(fpregs);
113341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
1143d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#ifdef __i386__
115341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    user_fpxregs_struct fpxregs;
116341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs);
117341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    assert(!res);
118341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    printf("%lx\n", (unsigned long)fpxregs.mxcsr);
119341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov#endif
120341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov
121341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    ptrace(PTRACE_CONT, pid, NULL, NULL);
122341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov    wait(NULL);
123341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  }
124341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov  return 0;
125341b9e63f63a8eacf1b699d4c79edee55241ebe6Evgeniy Stepanov}
126