These 4 patches fix libsanitizer build for x32. They will be checked into upstream:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59018#c4 In the meantime, OK to install to unblock x32 build? Thanks. H.J.
>From de59975f158501bc99b345c02687944a49c9d31c Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Tue, 5 Nov 2013 05:40:48 -0800 Subject: [PATCH 1/4] Cast pointers to uptr for 64-bit syscalls --- libsanitizer/ChangeLog.x32 | 20 +++++++++++++ libsanitizer/sanitizer_common/sanitizer_linux.cc | 38 ++++++++++++------------ 2 files changed, 39 insertions(+), 19 deletions(-) create mode 100644 libsanitizer/ChangeLog.x32 diff --git a/libsanitizer/ChangeLog.x32 b/libsanitizer/ChangeLog.x32 new file mode 100644 index 0000000..7b54005 --- /dev/null +++ b/libsanitizer/ChangeLog.x32 @@ -0,0 +1,20 @@ +2013-11-05 H.J. Lu <hongjiu...@intel.com> + + * sanitizer_common/sanitizer_linux.cc (internal_mmap): Cast + pointers to uptr for 64-bit syscalls. + (internal_munmap): Likewise. + (internal_open): Likewise. + (internal_read): Likewise. + (internal_write): Likewise. + (internal_stat): Likewise. + (internal_lstat): Likewise. + (internal_fstat): Likewise. + (internal_readlink): Likewise. + (internal_unlink): Likewise. + (internal_execve): Likewise. + (NanoTime): Likewise. + (BlockingMutex::Lock): Likewise. + (BlockingMutex::Unlock): Likewise. + (internal_ptrace): Likewise. + (internal_getdents): Likewise. + (internal_sigaltstack): Likewise. diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc index 666f15b..e48bee5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc @@ -77,14 +77,14 @@ namespace __sanitizer { uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, u64 offset) { #if SANITIZER_LINUX_USES_64BIT_SYSCALLS - return internal_syscall(__NR_mmap, addr, length, prot, flags, fd, offset); + return internal_syscall(__NR_mmap, (uptr)addr, length, prot, flags, fd, offset); #else return internal_syscall(__NR_mmap2, addr, length, prot, flags, fd, offset); #endif } uptr internal_munmap(void *addr, uptr length) { - return internal_syscall(__NR_munmap, addr, length); + return internal_syscall(__NR_munmap, (uptr)addr, length); } uptr internal_close(fd_t fd) { @@ -92,11 +92,11 @@ uptr internal_close(fd_t fd) { } uptr internal_open(const char *filename, int flags) { - return internal_syscall(__NR_open, filename, flags); + return internal_syscall(__NR_open, (uptr)filename, flags); } uptr internal_open(const char *filename, int flags, u32 mode) { - return internal_syscall(__NR_open, filename, flags, mode); + return internal_syscall(__NR_open, (uptr)filename, flags, mode); } uptr OpenFile(const char *filename, bool write) { @@ -106,13 +106,13 @@ uptr OpenFile(const char *filename, bool write) { uptr internal_read(fd_t fd, void *buf, uptr count) { sptr res; - HANDLE_EINTR(res, (sptr)internal_syscall(__NR_read, fd, buf, count)); + HANDLE_EINTR(res, (sptr)internal_syscall(__NR_read, fd, (uptr)buf, count)); return res; } uptr internal_write(fd_t fd, const void *buf, uptr count) { sptr res; - HANDLE_EINTR(res, (sptr)internal_syscall(__NR_write, fd, buf, count)); + HANDLE_EINTR(res, (sptr)internal_syscall(__NR_write, fd, (uptr)buf, count)); return res; } @@ -138,7 +138,7 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) { uptr internal_stat(const char *path, void *buf) { #if SANITIZER_LINUX_USES_64BIT_SYSCALLS - return internal_syscall(__NR_stat, path, buf); + return internal_syscall(__NR_stat, (uptr)path, (uptr)buf); #else struct stat64 buf64; int res = internal_syscall(__NR_stat64, path, &buf64); @@ -149,7 +149,7 @@ uptr internal_stat(const char *path, void *buf) { uptr internal_lstat(const char *path, void *buf) { #if SANITIZER_LINUX_USES_64BIT_SYSCALLS - return internal_syscall(__NR_lstat, path, buf); + return internal_syscall(__NR_lstat, (uptr)path, (uptr)buf); #else struct stat64 buf64; int res = internal_syscall(__NR_lstat64, path, &buf64); @@ -160,7 +160,7 @@ uptr internal_lstat(const char *path, void *buf) { uptr internal_fstat(fd_t fd, void *buf) { #if SANITIZER_LINUX_USES_64BIT_SYSCALLS - return internal_syscall(__NR_fstat, fd, buf); + return internal_syscall(__NR_fstat, fd, (uptr)buf); #else struct stat64 buf64; int res = internal_syscall(__NR_fstat64, fd, &buf64); @@ -181,11 +181,11 @@ uptr internal_dup2(int oldfd, int newfd) { } uptr internal_readlink(const char *path, char *buf, uptr bufsize) { - return internal_syscall(__NR_readlink, path, buf, bufsize); + return internal_syscall(__NR_readlink, (uptr)path, (uptr)buf, bufsize); } uptr internal_unlink(const char *path) { - return internal_syscall(__NR_unlink, path); + return internal_syscall(__NR_unlink, (uptr)path); } uptr internal_sched_yield() { @@ -199,7 +199,7 @@ void internal__exit(int exitcode) { uptr internal_execve(const char *filename, char *const argv[], char *const envp[]) { - return internal_syscall(__NR_execve, filename, argv, envp); + return internal_syscall(__NR_execve, (uptr)filename, (uptr)argv, (uptr)envp); } // ----------------- sanitizer_common.h @@ -217,7 +217,7 @@ uptr GetTid() { u64 NanoTime() { kernel_timeval tv = {}; - internal_syscall(__NR_gettimeofday, &tv, 0); + internal_syscall(__NR_gettimeofday, (uptr)&tv, 0); return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000; } @@ -539,7 +539,7 @@ void BlockingMutex::Lock() { if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked) return; while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) - internal_syscall(__NR_futex, m, FUTEX_WAIT, MtxSleeping, 0, 0, 0); + internal_syscall(__NR_futex, (uptr)m, FUTEX_WAIT, MtxSleeping, 0, 0, 0); } void BlockingMutex::Unlock() { @@ -547,7 +547,7 @@ void BlockingMutex::Unlock() { u32 v = atomic_exchange(m, MtxUnlocked, memory_order_relaxed); CHECK_NE(v, MtxUnlocked); if (v == MtxSleeping) - internal_syscall(__NR_futex, m, FUTEX_WAKE, 1, 0, 0, 0); + internal_syscall(__NR_futex, (uptr)m, FUTEX_WAKE, 1, 0, 0, 0); } void BlockingMutex::CheckLocked() { @@ -568,11 +568,11 @@ struct linux_dirent { // Syscall wrappers. uptr internal_ptrace(int request, int pid, void *addr, void *data) { - return internal_syscall(__NR_ptrace, request, pid, addr, data); + return internal_syscall(__NR_ptrace, request, pid, (uptr)addr, (uptr)data); } uptr internal_waitpid(int pid, int *status, int options) { - return internal_syscall(__NR_wait4, pid, status, options, 0 /* rusage */); + return internal_syscall(__NR_wait4, pid, (uptr)status, options, 0 /* rusage */); } uptr internal_getpid() { @@ -584,7 +584,7 @@ uptr internal_getppid() { } uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { - return internal_syscall(__NR_getdents, fd, dirp, count); + return internal_syscall(__NR_getdents, fd, (uptr)dirp, count); } uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { @@ -597,7 +597,7 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { uptr internal_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss) { - return internal_syscall(__NR_sigaltstack, ss, oss); + return internal_syscall(__NR_sigaltstack, (uptr)ss, (uptr)oss); } // ThreadLister implementation. -- 1.8.3.1
>From 19bea7c57ae78f8df05555dc559140fcae7f9392 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Tue, 5 Nov 2013 05:42:05 -0800 Subject: [PATCH 2/4] Fix internal_clone for x32 --- libsanitizer/ChangeLog.x32 | 6 ++++++ libsanitizer/sanitizer_common/sanitizer_linux.cc | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libsanitizer/ChangeLog.x32 b/libsanitizer/ChangeLog.x32 index 7b54005..40b185d 100644 --- a/libsanitizer/ChangeLog.x32 +++ b/libsanitizer/ChangeLog.x32 @@ -1,5 +1,11 @@ 2013-11-05 H.J. Lu <hongjiu...@intel.com> + * sanitizer_common/sanitizer_linux.cc (internal_clone): Allocate + 2 64-bit integers to save and restore fn and arg. Properly load + newtls/child_tidptr into r8/r10. + +2013-11-05 H.J. Lu <hongjiu...@intel.com> + * sanitizer_common/sanitizer_linux.cc (internal_mmap): Cast pointers to uptr for 64-bit syscalls. (internal_munmap): Likewise. diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc index e48bee5..bb43437 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc @@ -772,9 +772,11 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, if (!fn || !child_stack) return -EINVAL; CHECK_EQ(0, (uptr)child_stack % 16); - child_stack = (char *)child_stack - 2 * sizeof(void *); - ((void **)child_stack)[0] = (void *)(uptr)fn; - ((void **)child_stack)[1] = arg; + child_stack = (char *)child_stack - 2 * sizeof(unsigned long long); + ((unsigned long long *)child_stack)[0] = (uptr)fn; + ((unsigned long long *)child_stack)[1] = (uptr)arg; + register void *r8 __asm__ ("r8") = newtls; + register int *r10 __asm__ ("r10") = child_tidptr; __asm__ __volatile__( /* %rax = syscall(%rax = __NR_clone, * %rdi = flags, @@ -783,8 +785,6 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, * %r8 = new_tls, * %r10 = child_tidptr) */ - "movq %6,%%r8\n" - "movq %7,%%r10\n" ".cfi_endproc\n" "syscall\n" @@ -816,9 +816,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, "S"(child_stack), "D"(flags), "d"(parent_tidptr), - "r"(newtls), - "r"(child_tidptr) - : "rsp", "memory", "r8", "r10", "r11", "rcx"); + "r"(r8), + "r"(r10) + : "rsp", "memory", "r11", "rcx"); return res; } #endif // defined(__x86_64__) -- 1.8.3.1
>From aa40964f1dd75ff2207b115d201db65d450b6714 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Tue, 5 Nov 2013 05:46:04 -0800 Subject: [PATCH 3/4] Use 64-bit system types for x86-64 --- libsanitizer/ChangeLog.x32 | 14 ++++++++++++++ .../sanitizer_common/sanitizer_platform_limits_linux.cc | 2 +- .../sanitizer_common/sanitizer_platform_limits_posix.h | 7 ++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/libsanitizer/ChangeLog.x32 b/libsanitizer/ChangeLog.x32 index 40b185d..51d0fd4 100644 --- a/libsanitizer/ChangeLog.x32 +++ b/libsanitizer/ChangeLog.x32 @@ -1,5 +1,19 @@ 2013-11-05 H.J. Lu <hongjiu...@intel.com> + * sanitizer_common/sanitizer_platform_limits_linux.cc + (struct_kernel_stat64_sz): Initialize to 0 if __x86_64__ is + defined. + * sanitizer_common/sanitizer_platform_limits_posix.h + (__sanitizer_dirent): Use 64-bit d_ino/d_off if __x86_64__ is + defined. + (__sanitizer___kernel_uid_t): Typedef as unsigned if __x86_64__ + is defined. + (__sanitizer___kernel_gid_t): Likewise. + (__sanitizer___kernel_off_t): Typedef as long long if __x86_64__ + is defined. + +2013-11-05 H.J. Lu <hongjiu...@intel.com> + * sanitizer_common/sanitizer_linux.cc (internal_clone): Allocate 2 64-bit integers to save and restore fn and arg. Properly load newtls/child_tidptr into r8/r10. diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc index fbea596..9870243 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc @@ -31,7 +31,7 @@ namespace __sanitizer { unsigned struct_io_event_sz = sizeof(struct io_event); unsigned struct_iocb_sz = sizeof(struct iocb); -#ifndef _LP64 +#if !defined(_LP64) && !defined(__x86_64__) unsigned struct_kernel_stat64_sz = sizeof(struct stat64); #else unsigned struct_kernel_stat64_sz = 0; diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h index 007b4ec..67c459c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -133,7 +133,7 @@ namespace __sanitizer { unsigned short d_reclen; // more fields that we don't care about }; -#elif SANITIZER_ANDROID +#elif SANITIZER_ANDROID || defined(__x86_64__) struct __sanitizer_dirent { unsigned long long d_ino; unsigned long long d_off; @@ -159,16 +159,17 @@ namespace __sanitizer { #endif #if SANITIZER_LINUX -#ifdef _LP64 +#if defined(_LP64) || defined(__x86_64__) typedef unsigned __sanitizer___kernel_uid_t; typedef unsigned __sanitizer___kernel_gid_t; + typedef long long __sanitizer___kernel_off_t; #else typedef unsigned short __sanitizer___kernel_uid_t; typedef unsigned short __sanitizer___kernel_gid_t; + typedef long __sanitizer___kernel_off_t; #endif typedef unsigned short __sanitizer___kernel_old_uid_t; typedef unsigned short __sanitizer___kernel_old_gid_t; - typedef long __sanitizer___kernel_off_t; typedef long long __sanitizer___kernel_loff_t; typedef struct { unsigned long fds_bits[1024 / (8 * sizeof(long))]; -- 1.8.3.1
>From e9b0c9adfa3ad63e96870842ece7e39fcdcffb29 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> Date: Tue, 5 Nov 2013 05:47:30 -0800 Subject: [PATCH 4/4] Check __x86_64__ for FPU state --- libsanitizer/ChangeLog.x32 | 6 ++++++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libsanitizer/ChangeLog.x32 b/libsanitizer/ChangeLog.x32 index 51d0fd4..23b7fc9 100644 --- a/libsanitizer/ChangeLog.x32 +++ b/libsanitizer/ChangeLog.x32 @@ -1,5 +1,11 @@ 2013-11-05 H.J. Lu <hongjiu...@intel.com> + * sanitizer_common/sanitizer_platform_limits_posix.cc + (struct_user_fpxregs_struct_sz): Initialize to 0 if __x86_64__ is + defined. + +2013-11-05 H.J. Lu <hongjiu...@intel.com> + * sanitizer_common/sanitizer_platform_limits_linux.cc (struct_kernel_stat64_sz): Initialize to 0 if __x86_64__ is defined. diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc index 971a193..b771583 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -191,7 +191,7 @@ namespace __sanitizer { (defined(__i386) || defined (__x86_64)) // NOLINT unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct); unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct); -#if __WORDSIZE == 64 +#ifdef __x86_64 unsigned struct_user_fpxregs_struct_sz = 0; #else unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct); -- 1.8.3.1