summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/asan/asan_linux.cc5
-rw-r--r--lib/asan/asan_mapping.h5
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc40
-rw-r--r--lib/sanitizer_common/sanitizer_platform.h23
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_linux.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h6
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.h5
8 files changed, 79 insertions, 9 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
index 042e06ed9..4e7ca7e77 100644
--- a/lib/asan/asan_linux.cc
+++ b/lib/asan/asan_linux.cc
@@ -57,6 +57,11 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*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];
diff --git a/lib/asan/asan_mapping.h b/lib/asan/asan_mapping.h
index eac717518..93fa69acc 100644
--- a/lib/asan/asan_mapping.h
+++ b/lib/asan/asan_mapping.h
@@ -61,6 +61,7 @@ static const u64 kDefaultShadowScale = 3;
static const u64 kDefaultShadowOffset32 = 1ULL << 29;
static const u64 kDefaultShadowOffset64 = 1ULL << 44;
static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G.
+static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000;
#define SHADOW_SCALE kDefaultShadowScale
@@ -74,7 +75,9 @@ static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000;
# define SHADOW_OFFSET kDefaultShadowOffset32
# endif
# else
-# if SANITIZER_MAC
+# if defined(__aarch64__)
+# define SHADOW_OFFSET kAArch64_ShadowOffset64
+# elif SANITIZER_MAC
# define SHADOW_OFFSET kDefaultShadowOffset64
# else
# define SHADOW_OFFSET kDefaultShort64bitShadowOffset
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 73a35ca23..ea50acfcb 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -101,11 +101,19 @@ uptr internal_close(fd_t fd) {
}
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) {
@@ -146,7 +154,9 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) {
#endif
uptr internal_stat(const char *path, void *buf) {
-#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
+#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+ return internal_syscall(__NR_newfstatat, AT_FDCWD, (uptr)path, (uptr)buf, 0);
+#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
return internal_syscall(__NR_stat, (uptr)path, (uptr)buf);
#else
struct stat64 buf64;
@@ -157,7 +167,10 @@ uptr internal_stat(const char *path, void *buf) {
}
uptr internal_lstat(const char *path, void *buf) {
-#if SANITIZER_LINUX_USES_64BIT_SYSCALLS
+#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+ return internal_syscall(__NR_newfstatat, AT_FDCWD, (uptr)path,
+ (uptr)buf, AT_SYMLINK_NOFOLLOW);
+#elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
return internal_syscall(__NR_lstat, (uptr)path, (uptr)buf);
#else
struct stat64 buf64;
@@ -186,15 +199,28 @@ uptr internal_filesize(fd_t fd) {
}
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() {
@@ -213,11 +239,17 @@ uptr internal_execve(const char *filename, char *const argv[],
// ----------------- 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() {
@@ -389,7 +421,11 @@ uptr internal_getppid() {
}
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) {
diff --git a/lib/sanitizer_common/sanitizer_platform.h b/lib/sanitizer_common/sanitizer_platform.h
index 27ffaec99..c286097f6 100644
--- a/lib/sanitizer_common/sanitizer_platform.h
+++ b/lib/sanitizer_common/sanitizer_platform.h
@@ -68,13 +68,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
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_linux.cc b/lib/sanitizer_common/sanitizer_platform_limits_linux.cc
index 54c080925..66c6ab903 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_linux.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_linux.cc
@@ -64,7 +64,7 @@ namespace __sanitizer {
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
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 744e180d5..b82b4cfb1 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -63,6 +63,10 @@ namespace __sanitizer {
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;
@@ -343,7 +347,7 @@ namespace __sanitizer {
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
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index df5cbd465..833b7cf3d 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -38,6 +38,8 @@ uptr GetMaxVirtualAddress() {
// 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
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.h b/lib/sanitizer_common/sanitizer_stacktrace.h
index 9d067b1c9..c3ba193f4 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -19,8 +19,9 @@ namespace __sanitizer {
static const uptr kStackTraceMax = 256;
-#if SANITIZER_LINUX && (defined(__powerpc__) || defined(__powerpc64__) || \
- defined(__sparc__) || defined(__mips__))
+#if SANITIZER_LINUX && (defined(__aarch64__) || defined(__powerpc__) || \
+ defined(__powerpc64__) || defined(__sparc__) || \
+ defined(__mips__))
# define SANITIZER_CAN_FAST_UNWIND 0
#elif SANITIZER_WINDOWS
# define SANITIZER_CAN_FAST_UNWIND 0