[compiler-rt] Enable ptrace sanitizer for arm

This patch enables the ptrace syscall interceptors for arm and adds support
for both PTRACE_GETVFPREGS and PTRACE_SETVFPREGS used to get the VFP register
from ARM.

The ptrace tests is also updated with arm and PTRACE_GETVFPREGS tests.

llvm-svn: 251321
This commit is contained in:
Adhemerval Zanella 2015-10-26 18:15:14 +00:00
parent 5eb5ad09d5
commit 871d324799
5 changed files with 44 additions and 11 deletions

View File

@ -2454,6 +2454,8 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
else if (request == ptrace_setfpxregs)
COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
else if (request == ptrace_setvfpregs)
COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
else if (request == ptrace_setsiginfo)
COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
else if (request == ptrace_setregset) {
@ -2476,6 +2478,8 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
else if (request == ptrace_getfpxregs)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
else if (request == ptrace_getvfpregs)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
else if (request == ptrace_getsiginfo)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
else if (request == ptrace_geteventmsg)

View File

@ -133,7 +133,7 @@
#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_PTRACE SI_LINUX_NOT_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__))
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__))
#define SANITIZER_INTERCEPT_SETLOCALE SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GETCWD SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID

View File

@ -119,8 +119,11 @@
#if SANITIZER_LINUX || SANITIZER_FREEBSD
# include <utime.h>
# include <sys/ptrace.h>
# if defined(__mips64) || defined(__aarch64__)
# if defined(__mips64) || defined(__aarch64__) || defined(__arm__)
# include <asm/ptrace.h>
# ifdef __arm__
typedef struct user_fpregs elf_fpregset_t;
# endif
# endif
# include <semaphore.h>
#endif
@ -304,8 +307,8 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__))
#if defined(__mips64) || defined(__powerpc64__)
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__))
#if defined(__mips64) || defined(__powerpc64__) || defined(__arm__)
unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs);
unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t);
#elif defined(__aarch64__)
@ -316,11 +319,16 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);
#endif // __mips64 || __powerpc64__ || __aarch64__
#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \
defined(__aarch64__)
defined(__aarch64__) || defined(__arm__)
unsigned struct_user_fpxregs_struct_sz = 0;
#else
unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
#endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__
#endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__
#ifdef __arm__
unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE;
#else
unsigned struct_user_vfpregs_struct_sz = 0;
#endif
int ptrace_peektext = PTRACE_PEEKTEXT;
int ptrace_peekdata = PTRACE_PEEKDATA;
@ -346,6 +354,13 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
int ptrace_getfpxregs = -1;
int ptrace_setfpxregs = -1;
#endif // PTRACE_GETFPXREGS/PTRACE_SETFPXREGS
#if defined(PTRACE_GETVFPREGS) && defined(PTRACE_SETVFPREGS)
int ptrace_getvfpregs = PTRACE_GETVFPREGS;
int ptrace_setvfpregs = PTRACE_SETVFPREGS;
#else
int ptrace_getvfpregs = -1;
int ptrace_setvfpregs = -1;
#endif
int ptrace_geteventmsg = PTRACE_GETEVENTMSG;
#if (defined(PTRACE_GETSIGINFO) && defined(PTRACE_SETSIGINFO)) || \
(defined(PT_GETSIGINFO) && defined(PT_SETSIGINFO))

View File

@ -736,10 +736,11 @@ namespace __sanitizer {
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__))
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__))
extern unsigned struct_user_regs_struct_sz;
extern unsigned struct_user_fpregs_struct_sz;
extern unsigned struct_user_fpxregs_struct_sz;
extern unsigned struct_user_vfpregs_struct_sz;
extern int ptrace_peektext;
extern int ptrace_peekdata;
@ -750,6 +751,8 @@ namespace __sanitizer {
extern int ptrace_setfpregs;
extern int ptrace_getfpxregs;
extern int ptrace_setfpxregs;
extern int ptrace_getvfpregs;
extern int ptrace_setvfpregs;
extern int ptrace_getsiginfo;
extern int ptrace_setsiginfo;
extern int ptrace_getregset;

View File

@ -10,7 +10,7 @@
#include <sys/uio.h>
#include <unistd.h>
#include <elf.h>
#if __mips64
#if __mips64 || __arm__
#include <asm/ptrace.h>
#include <sys/procfs.h>
#endif
@ -43,23 +43,34 @@ int main(void) {
printf("%x\n", fpregs.mxcsr);
#endif // __x86_64__
#if (__powerpc64__ || __mips64)
#if (__powerpc64__ || __mips64 || __arm__)
struct pt_regs regs;
res = ptrace((enum __ptrace_request)PTRACE_GETREGS, pid, NULL, &regs);
assert(!res);
#if (__powerpc64__)
if (regs.nip)
printf("%lx\n", regs.nip);
#else
#elif (__mips64)
if (regs.cp0_epc)
printf("%lx\n", regs.cp0_epc);
#elif (__arm__)
if (regs.ARM_pc)
printf("%lx\n", regs.ARM_pc);
#endif
#if (__powerpc64 || __mips64)
elf_fpregset_t fpregs;
res = ptrace((enum __ptrace_request)PTRACE_GETFPREGS, pid, NULL, &fpregs);
assert(!res);
if ((elf_greg_t)fpregs[32]) // fpscr
printf("%lx\n", (elf_greg_t)fpregs[32]);
#endif // (__powerpc64__ || __mips64)
#elif (__arm__)
char regbuf[ARM_VFPREGS_SIZE];
res = ptrace((enum __ptrace_request)PTRACE_GETVFPREGS, pid, 0, regbuf);
assert(!res);
unsigned fpscr = *(unsigned*)(regbuf + (32 * 8));
printf ("%x\n", fpscr);
#endif
#endif // (__powerpc64__ || __mips64 || __arm__)
#if (__aarch64__)
struct iovec regset_io;