diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 33c90ef..eebf85b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -16171,7 +16171,10 @@ aarch64_split_dimode_const_store (rtx dst, rtx src)
 static unsigned HOST_WIDE_INT
 aarch64_asan_shadow_offset (void)
 {
-  return (HOST_WIDE_INT_1 << 36);
+  if (TARGET_ILP32)
+    return (HOST_WIDE_INT_1 << 29);
+  else
+    return (HOST_WIDE_INT_1 << 36);
 }
 
 static rtx
diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
index edd6a21..aef83c2 100644
--- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
@@ -117,9 +117,9 @@ typedef signed   long long sptr;  // NOLINT
 typedef unsigned long uptr;  // NOLINT
 typedef signed   long sptr;  // NOLINT
 #endif  // defined(_WIN64)
-#if defined(__x86_64__)
-// Since x32 uses ILP32 data model in 64-bit hardware mode, we must use
-// 64-bit pointer to unwind stack frame.
+#if defined(__x86_64__) || SANITIZER_AARCH64_ILP32
+// Since x32 adn AArch64 ILP32 use ILP32 data model in 64-bit hardware mode, 
+// we must use 64-bit pointer to unwind stack frame.
 typedef unsigned long long uhwptr;  // NOLINT
 #else
 typedef uptr uhwptr;   // NOLINT
@@ -144,7 +144,7 @@ typedef int error_t;
 typedef int pid_t;
 
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \
-    (SANITIZER_LINUX && defined(__x86_64__))
+    (SANITIZER_LINUX && (defined(__x86_64__) || SANITIZER_AARCH64_ILP32))
 typedef u64 OFF_T;
 #else
 typedef uptr OFF_T;
@@ -154,8 +154,8 @@ typedef u64  OFF64_T;
 #if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC
 typedef uptr operator_new_size_type;
 #else
-# if defined(__s390__) && !defined(__s390x__)
-// Special case: 31-bit s390 has unsigned long as size_t.
+# if (defined(__s390__) && !defined(__s390x__)) || SANITIZER_AARCH64_ILP32
+// Special case: 31-bit s390 and AArch64 ILP32 have unsigned long as size_t.
 typedef unsigned long operator_new_size_type;
 # else
 typedef u32 operator_new_size_type;
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc
index 2826cc8..31f60ff 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc
@@ -123,8 +123,16 @@ const int FUTEX_WAKE = 1;
 #if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \
     SANITIZER_WORDSIZE == 64)
 # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1
+# define SYSCALL_LL64(val) (val)
 #else
 # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+#  define SYSCALL_LL64(val) \
+  (long) ((OFF64_T)(val) & 0xffffffff), (long) ((OFF64_T)(val) >> 32)
+# else
+#  define SYSCALL_LL64(val) \
+  (long) ((OFF64_T)val >> 32), (long) ((OFF64_T)(val) & 0xffffffff)
+# endif
 #endif
 
 #if defined(__x86_64__) || SANITIZER_MIPS64
@@ -227,8 +235,13 @@ uptr internal_ftruncate(fd_t fd, uptr size) {
 #if SANITIZER_NETBSD
   HANDLE_EINTR(res, internal_syscall(SYSCALL(ftruncate), fd, 0, (s64)size));
 #else
+# if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 2
+  HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate64), fd,
+               SYSCALL_LL64((OFF_T)size)));
+# else
   HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd,
                (OFF_T)size));
+# endif
 #endif
   return res;
 }
@@ -304,9 +317,12 @@ uptr internal_stat(const char *path, void *buf) {
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
   return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
                           (uptr)buf, 0);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 1
   return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
                           (uptr)buf, 0);
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 2
+  return internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
+                          (uptr)buf, 0);
 #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
 # if defined(__mips64)
   // For mips64, stat syscall fills buffer in the format of kernel_stat
@@ -331,9 +347,12 @@ uptr internal_lstat(const char *path, void *buf) {
 #elif SANITIZER_FREEBSD
   return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
                           (uptr)buf, AT_SYMLINK_NOFOLLOW);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 1
   return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
                          (uptr)buf, AT_SYMLINK_NOFOLLOW);
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 2
+  return internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
+                          (uptr)buf, AT_SYMLINK_NOFOLLOW);
 #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
 # if SANITIZER_MIPS64
   // For mips64, lstat syscall fills buffer in the format of kernel_stat
@@ -406,9 +425,12 @@ uptr internal_unlink(const char *path) {
 }
 
 uptr internal_rename(const char *oldpath, const char *newpath) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 1
   return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
                           (uptr)newpath);
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 2
+  return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
+                          (uptr)newpath, 0);
 #else
   return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
 #endif
@@ -445,11 +467,7 @@ uptr internal_execve(const char *filename, char *const argv[],
 // ----------------- sanitizer_common.h
 bool FileExists(const char *filename) {
   struct stat st;
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
-  if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0))
-#else
   if (internal_stat(filename, &st))
-#endif
     return false;
   // Sanity check: filename is a regular file.
   return S_ISREG(st.st_mode);
@@ -729,7 +747,15 @@ uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
 #if SANITIZER_NETBSD
   return internal_syscall64(SYSCALL(lseek), fd, 0, offset, whence);
 #else
+# if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS == 2
+  int64_t res;
+  int rc = internal_syscall(SYSCALL(llseek), fd,
+                                    (long) (((u64)(offset)) >> 32),
+                                    (long) offset, &res, whence);
+  return rc ? rc : res;
+# else
   return internal_syscall(SYSCALL(lseek), fd, offset, whence);
+# endif
 #endif
 }
 
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h
index 1eb4d0c..3963d09 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform.h
@@ -179,6 +179,12 @@
 # define SANITIZER_ARM 0
 #endif
 
+#if defined(__aarch64__) && defined(__ILP32__)
+# define SANITIZER_AARCH64_ILP32 1
+#else
+# define SANITIZER_AARCH64_ILP32 0
+#endif
+
 // By default we allow to use SizeClassAllocator64 on 64-bit platform.
 // But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64
 // does not work well and we need to fallback to SizeClassAllocator32.
@@ -207,10 +213,15 @@
 
 // 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.
+// use legacy syscalls.  Also AArch64 ILP32 uses canonical syscall set
+// 32 bits ports.
 #ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
 # if defined(__aarch64__) && SANITIZER_LINUX
-# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
+#  if defined(__ILP32__)
+#   define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 2
+#  else
+#   define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
+#  endif
 # else
 # define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
 # endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
index 858bb21..ee4f74f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -1136,7 +1136,8 @@ CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
-#if !defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)
+#if !defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21) \
+    && !defined(__ILP32__)
 /* On aarch64 glibc 2.20 and earlier provided incorrect mode field.  */
 CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
 #endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
index 4d11d07..fbdf3d5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -74,7 +74,10 @@ namespace __sanitizer {
 #elif defined(__arm__)
   const unsigned struct_kernel_stat_sz = 64;
   const unsigned struct_kernel_stat64_sz = 104;
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) && defined(__ILP32__)
+  const unsigned struct_kernel_stat_sz = 80;
+  const unsigned struct_kernel_stat64_sz = 104;
+#elif defined(__aarch64__) && defined(__LP64__)
   const unsigned struct_kernel_stat_sz = 128;
   const unsigned struct_kernel_stat64_sz = 104;
 #elif defined(__powerpc__) && !defined(__powerpc64__)
@@ -506,8 +509,13 @@ namespace __sanitizer {
   };
 #else
   struct __sanitizer_dirent {
+# if SANITIZER_AARCH64_ILP32
+    unsigned long long d_ino;
+    unsigned long long d_off;
+# else
     uptr d_ino;
     uptr d_off;
+# endif
     unsigned short d_reclen;
     // more fields that we don't care about
   };
@@ -537,7 +545,8 @@ namespace __sanitizer {
 
 #if SANITIZER_LINUX || SANITIZER_FREEBSD
 #if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\
-                   || defined(__mips__)
+                   || defined(__mips__) \
+                   || (defined(__aarch64__) && defined(__ILP32__))
   typedef unsigned __sanitizer___kernel_uid_t;
   typedef unsigned __sanitizer___kernel_gid_t;
 #else
