Index: libsanitizer/asan/asan_linux.cc =================================================================== --- libsanitizer/asan/asan_linux.cc +++ libsanitizer/asan/asan_linux.cc @@ -56,6 +56,11 @@ *pc = ucontext->uc_mcontext.arm_pc; *bp = ucontext->uc_mcontext.arm_fp; *sp = ucontext->uc_mcontext.arm_sp; +# elif defined(__aarch64__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.regs[29]; + *sp = ucontext->uc_mcontext.sp; # elif defined(__hppa__) ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.sc_iaoq[0]; Index: libsanitizer/asan/asan_mapping.h =================================================================== --- libsanitizer/asan/asan_mapping.h +++ libsanitizer/asan/asan_mapping.h @@ -60,6 +60,7 @@ static const u64 kDefaultShadowOffset64 = 1ULL << 44; static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; +static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 @@ -81,6 +82,8 @@ # else # if defined(__powerpc64__) # define SHADOW_OFFSET kPPC64_ShadowOffset64 +# elif defined(__aarch64__) +# define SHADOW_OFFSET kAArch64_ShadowOffset64 # elif SANITIZER_MAC # define SHADOW_OFFSET kDefaultShadowOffset64 # else Index: libsanitizer/sanitizer_common/sanitizer_linux.cc =================================================================== --- libsanitizer/sanitizer_common/sanitizer_linux.cc +++ libsanitizer/sanitizer_common/sanitizer_linux.cc @@ -93,11 +93,19 @@ } uptr internal_open(const char *filename, int flags) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_openat, AT_FDCWD, (uptr)filename, flags); +#else return internal_syscall(__NR_open, (uptr)filename, flags); +#endif } uptr internal_open(const char *filename, int flags, u32 mode) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_openat, AT_FDCWD, (uptr)filename, flags, mode); +#else return internal_syscall(__NR_open, (uptr)filename, flags, mode); +#endif } uptr OpenFile(const char *filename, bool write) { @@ -138,6 +146,9 @@ #endif uptr internal_stat(const char *path, void *buf) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_newfstatat, AT_FDCWD, (uptr)path, (uptr)buf, 0); +#else #if SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(__NR_stat, (uptr)path, (uptr)buf); #else @@ -146,9 +157,14 @@ stat64_to_stat(&buf64, (struct stat *)buf); return res; #endif +#endif } uptr internal_lstat(const char *path, void *buf) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_newfstatat, AT_FDCWD, (uptr)path, + (uptr)buf, AT_SYMLINK_NOFOLLOW); +#else #if SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(__NR_lstat, (uptr)path, (uptr)buf); #else @@ -157,6 +173,7 @@ stat64_to_stat(&buf64, (struct stat *)buf); return res; #endif +#endif } uptr internal_fstat(fd_t fd, void *buf) { @@ -178,15 +195,28 @@ } uptr internal_dup2(int oldfd, int newfd) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_dup3, oldfd, newfd, 0); +#else return internal_syscall(__NR_dup2, oldfd, newfd); +#endif } uptr internal_readlink(const char *path, char *buf, uptr bufsize) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_readlinkat, AT_FDCWD, + (uptr)path, (uptr)buf, bufsize); +#else return internal_syscall(__NR_readlink, (uptr)path, (uptr)buf, bufsize); +#endif } uptr internal_unlink(const char *path) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_unlinkat, AT_FDCWD, (uptr)path, 0); +#else return internal_syscall(__NR_unlink, (uptr)path); +#endif } uptr internal_sched_yield() { @@ -205,11 +235,17 @@ // ----------------- sanitizer_common.h bool FileExists(const char *filename) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + struct stat st; + if (internal_syscall(__NR_newfstatat, AT_FDCWD, filename, &st, 0)) + return false; +#else struct stat st; if (internal_stat(filename, &st)) return false; // Sanity check: filename is a regular file. return S_ISREG(st.st_mode); +#endif } uptr GetTid() { @@ -588,7 +624,11 @@ } uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(__NR_getdents64, fd, (uptr)dirp, count); +#else return internal_syscall(__NR_getdents, fd, (uptr)dirp, count); +#endif } uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { Index: libsanitizer/sanitizer_common/sanitizer_platform.h =================================================================== --- libsanitizer/sanitizer_common/sanitizer_platform.h +++ libsanitizer/sanitizer_common/sanitizer_platform.h @@ -66,13 +66,32 @@ // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here. #ifndef SANITIZER_CAN_USE_ALLOCATOR64 -# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) +# if defined(__aarch64__) +# define SANITIZER_CAN_USE_ALLOCATOR64 0 +# else +# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) +# endif #endif // The range of addresses which can be returned my mmap. // FIXME: this value should be different on different platforms, // e.g. on AArch64 it is most likely (1ULL << 39). Larger values will still work // but will consume more memory for TwoLevelByteMap. -#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) +#if defined(__aarch64__) +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 39) +#else +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) +#endif + +// The AArch64 linux port uses the canonical syscall set as mandated by +// the upstream linux community for all new ports. Other ports may still +// use legacy syscalls. +#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +# ifdef __aarch64__ +# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1 +# else +# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0 +# endif +#endif #endif // SANITIZER_PLATFORM_H Index: libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc =================================================================== --- libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc +++ libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc @@ -62,7 +62,7 @@ unsigned struct_statfs64_sz = sizeof(struct statfs64); } // namespace __sanitizer -#if !defined(__powerpc64__) && !defined(__x86_64__) +#if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__) COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat)); #endif Index: libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -59,6 +59,10 @@ const unsigned struct___old_kernel_stat_sz = 32; const unsigned struct_kernel_stat_sz = 64; const unsigned struct_kernel_stat64_sz = 104; +#elif defined(__aarch64__) + const unsigned struct___old_kernel_stat_sz = 32; + const unsigned struct_kernel_stat_sz = 128; + const unsigned struct_kernel_stat64_sz = 104; #elif defined(__powerpc__) && !defined(__powerpc64__) const unsigned struct___old_kernel_stat_sz = 32; const unsigned struct_kernel_stat_sz = 72; @@ -326,7 +330,7 @@ typedef long __sanitizer___kernel_off_t; #endif -#if defined(__powerpc__) +#if defined(__powerpc__) || defined(__aarch64__) typedef unsigned int __sanitizer___kernel_old_uid_t; typedef unsigned int __sanitizer___kernel_old_gid_t; #else Index: libsanitizer/sanitizer_common/sanitizer_posix.cc =================================================================== --- libsanitizer/sanitizer_common/sanitizer_posix.cc +++ libsanitizer/sanitizer_common/sanitizer_posix.cc @@ -36,6 +36,8 @@ // Note that with 'ulimit -s unlimited' the stack is moved away from the top // of the address space, so simply checking the stack address is not enough. return (1ULL << 44) - 1; // 0x00000fffffffffffUL +# elif defined(__aarch64__) + return (1ULL << 39) - 1; # else return (1ULL << 47) - 1; // 0x00007fffffffffffUL; # endif Index: libsanitizer/sanitizer_common/sanitizer_stacktrace.h =================================================================== --- libsanitizer/sanitizer_common/sanitizer_stacktrace.h +++ libsanitizer/sanitizer_common/sanitizer_stacktrace.h @@ -18,6 +18,7 @@ static const uptr kStackTraceMax = 256; #if SANITIZER_LINUX && (defined(__arm__) || \ + defined(__aarch64__) || \ defined(__powerpc__) || defined(__powerpc64__) || \ defined(__sparc__) || \ defined(__mips__))