aboutsummaryrefslogtreecommitdiff
path: root/compiler-rt
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/cmake/Modules/CompilerRTUtils.cmake3
-rw-r--r--compiler-rt/cmake/base-config-ix.cmake2
-rw-r--r--compiler-rt/cmake/builtin-config-ix.cmake3
-rw-r--r--compiler-rt/cmake/config-ix.cmake4
-rw-r--r--compiler-rt/lib/builtins/CMakeLists.txt7
-rw-r--r--compiler-rt/lib/builtins/avr/exit.S18
-rw-r--r--compiler-rt/lib/builtins/avr/mulhi3.S58
-rw-r--r--compiler-rt/lib/builtins/avr/mulqi3.S31
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp4
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h2
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp94
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform.h12
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp3
13 files changed, 175 insertions, 66 deletions
diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
index b7bf2ba..27f68ea 100644
--- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
+++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake
@@ -153,6 +153,7 @@ endmacro()
macro(detect_target_arch)
check_symbol_exists(__arm__ "" __ARM)
+ check_symbol_exists(__AVR__ "" __AVR)
check_symbol_exists(__aarch64__ "" __AARCH64)
check_symbol_exists(__x86_64__ "" __X86_64)
check_symbol_exists(__i386__ "" __I386)
@@ -170,6 +171,8 @@ macro(detect_target_arch)
check_symbol_exists(__ve__ "" __VE)
if(__ARM)
add_default_target_arch(arm)
+ elseif(__AVR)
+ add_default_target_arch(avr)
elseif(__AARCH64)
add_default_target_arch(aarch64)
elseif(__X86_64)
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index 2576667..8a621956 100644
--- a/compiler-rt/cmake/base-config-ix.cmake
+++ b/compiler-rt/cmake/base-config-ix.cmake
@@ -234,6 +234,8 @@ macro(test_targets)
test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard")
test_target_arch(armv6m "" "-march=armv6m" "-mfloat-abi=soft")
endif()
+ elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "avr")
+ test_target_arch(avr "__AVR__" "--target=avr")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
test_target_arch(aarch32 "" "-march=armv8-a")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake
index 5ea5cc0..9cbadf3 100644
--- a/compiler-rt/cmake/builtin-config-ix.cmake
+++ b/compiler-rt/cmake/builtin-config-ix.cmake
@@ -38,6 +38,7 @@ asm(\"cas w0, w1, [x2]\");
set(ARM64 aarch64)
set(ARM32 arm armhf armv6m armv7m armv7em armv7 armv7s armv7k armv8m.main armv8.1m.main)
+set(AVR avr)
set(HEXAGON hexagon)
set(X86 i386)
set(X86_64 x86_64)
@@ -60,7 +61,7 @@ if(APPLE)
endif()
set(ALL_BUILTIN_SUPPORTED_ARCH
- ${X86} ${X86_64} ${ARM32} ${ARM64}
+ ${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR}
${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64}
${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9}
${WASM32} ${WASM64} ${VE})
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index 17e5156..8cd8059 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -203,8 +203,10 @@ file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <stdio.h>\nint main()
# Detect whether the current target platform is 32-bit or 64-bit, and setup
# the correct commandline flags needed to attempt to target 32-bit and 64-bit.
+# AVR and MSP430 are omitted since they have 16-bit pointers.
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND
- NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
+ NOT CMAKE_SIZEOF_VOID_P EQUAL 8 AND
+ NOT ${arch} MATCHES "avr|msp430")
message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.")
endif()
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index d9c317e..3146689 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -567,6 +567,13 @@ set(armv7em_SOURCES ${arm_SOURCES})
set(armv8m.main_SOURCES ${arm_SOURCES})
set(armv8.1m.main_SOURCES ${arm_SOURCES})
+# 8-bit AVR MCU
+set(avr_SOURCES
+ avr/mulqi3.S
+ avr/mulhi3.S
+ avr/exit.S
+)
+
# hexagon arch
set(hexagon_SOURCES
hexagon/common_entry_exit_abi1.S
diff --git a/compiler-rt/lib/builtins/avr/exit.S b/compiler-rt/lib/builtins/avr/exit.S
new file mode 100644
index 0000000..3cd9c5d
--- /dev/null
+++ b/compiler-rt/lib/builtins/avr/exit.S
@@ -0,0 +1,18 @@
+//===------------ exit.S - global terminator for AVR ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+ .text
+ .align 2
+
+ .globl _exit
+ .type _exit, @function
+
+_exit:
+ cli ; Disable all interrupts.
+__stop_program:
+ rjmp __stop_program ; Fall into an infinite loop.
diff --git a/compiler-rt/lib/builtins/avr/mulhi3.S b/compiler-rt/lib/builtins/avr/mulhi3.S
new file mode 100644
index 0000000..97e9bd1
--- /dev/null
+++ b/compiler-rt/lib/builtins/avr/mulhi3.S
@@ -0,0 +1,58 @@
+//===------------ mulhi3.S - int16 multiplication -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The corresponding C code is something like:
+//
+// int __mulhi3(int A, int B) {
+// int S = 0;
+// while (A != 0) {
+// if (A & 1)
+// S += B;
+// A = ((unsigned int) A) >> 1;
+// B <<= 1;
+// }
+// return S;
+// }
+//
+//===----------------------------------------------------------------------===//
+
+ .text
+ .align 2
+
+ .globl __mulhi3
+ .type __mulhi3, @function
+
+__mulhi3:
+ eor r28, r28
+ eor r20, r20
+ eor r21, r21 ; Initialize the result to 0: `S = 0;`.
+
+__mulhi3_loop:
+ cp r24, r28
+ cpc r25, r28 ; `while (A != 0) { ... }`
+ breq __mulhi3_end ; End the loop if A is 0.
+
+ mov r29, r24
+ andi r29, 1 ; `if (A & 1) { ... }`
+ breq __mulhi3_loop_a ; Omit the accumulation (`S += B;`) if A's LSB is 0.
+
+ add r20, r22
+ adc r21, r23 ; Do the accumulation: `S += B;`.
+
+__mulhi3_loop_a:
+ lsr r25
+ ror r24 ; `A = ((unsigned int) A) >> 1;`.
+ lsl r22
+ rol r23 ; `B <<= 1;`
+
+ rjmp __mulhi3_loop
+
+__mulhi3_end:
+ mov r24, r20
+ mov r25, r21
+ ret
diff --git a/compiler-rt/lib/builtins/avr/mulqi3.S b/compiler-rt/lib/builtins/avr/mulqi3.S
new file mode 100644
index 0000000..be0fa77
--- /dev/null
+++ b/compiler-rt/lib/builtins/avr/mulqi3.S
@@ -0,0 +1,31 @@
+//===------------ mulhi3.S - int8 multiplication --------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The corresponding C code is something like:
+//
+// int __mulqi3(char A, char B) {
+// return __mulhi3((int) A, (int) B);
+// }
+//
+//===----------------------------------------------------------------------===//
+
+ .text
+ .align 2
+
+ .globl __mulqi3
+ .type __mulqi3, @function
+
+__mulqi3:
+ mov r25, r24
+ lsl r25
+ sbc r25, r25 ; Promote A from char to int: `(int) A`.
+ mov r23, r22
+ lsl r23
+ sbc r23, r23 ; Promote B from char to int: `(int) B`.
+ rcall __mulhi3 ; `__mulhi3((int) A, (int) B);`.
+ ret
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
index 6cfce8a..8fd3985 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
@@ -98,15 +98,19 @@ void MaybeStartBackgroudThread() {
}
# if !SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
+# ifdef __clang__
# pragma clang diagnostic push
// We avoid global-constructors to be sure that globals are ready when
// sanitizers need them. This can happend before global constructors executed.
// Here we don't mind if thread is started on later stages.
# pragma clang diagnostic ignored "-Wglobal-constructors"
+# endif
static struct BackgroudThreadStarted {
BackgroudThreadStarted() { MaybeStartBackgroudThread(); }
} background_thread_strarter UNUSED;
+# ifdef __clang__
# pragma clang diagnostic pop
+# endif
# endif
#else
void MaybeStartBackgroudThread() {}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
index 924578b..ff65069 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -261,6 +261,8 @@ typedef u64 tid_t;
#if __has_cpp_attribute(clang::fallthrough)
# define FALLTHROUGH [[clang::fallthrough]]
+#elif __has_cpp_attribute(fallthrough)
+# define FALLTHROUGH [[fallthrough]]
#else
# define FALLTHROUGH
#endif
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index f591a5c..8e144a4 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -233,7 +233,7 @@ uptr internal_close(fd_t fd) {
}
uptr internal_open(const char *filename, int flags) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# if SANITIZER_LINUX
return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags);
#else
return internal_syscall(SYSCALL(open), (uptr)filename, flags);
@@ -241,7 +241,7 @@ uptr internal_open(const char *filename, int flags) {
}
uptr internal_open(const char *filename, int flags, u32 mode) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# if SANITIZER_LINUX
return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags,
mode);
#else
@@ -342,50 +342,46 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
uptr internal_stat(const char *path, void *buf) {
#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# elif SANITIZER_LINUX
+# if SANITIZER_WORDSIZE == 64
return internal_syscall(SYSCALL(newfstatat), 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
- struct kernel_stat kbuf;
- int res = internal_syscall(SYSCALL(stat), path, &kbuf);
- kernel_stat_to_stat(&kbuf, (struct stat *)buf);
+# else
+ struct stat64 buf64;
+ int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
+ (uptr)&buf64, 0);
+ stat64_to_stat(&buf64, (struct stat *)buf);
return res;
-# else
- return internal_syscall(SYSCALL(stat), (uptr)path, (uptr)buf);
-# endif
-#else
+# endif
+# else
struct stat64 buf64;
int res = internal_syscall(SYSCALL(stat64), path, &buf64);
stat64_to_stat(&buf64, (struct stat *)buf);
return res;
-#endif
+# endif
}
uptr internal_lstat(const char *path, void *buf) {
#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# elif SANITIZER_LINUX
+# if defined(_LP64)
return internal_syscall(SYSCALL(newfstatat), 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
- struct kernel_stat kbuf;
- int res = internal_syscall(SYSCALL(lstat), path, &kbuf);
- kernel_stat_to_stat(&kbuf, (struct stat *)buf);
+# else
+ struct stat64 buf64;
+ int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path,
+ (uptr)&buf64, AT_SYMLINK_NOFOLLOW);
+ stat64_to_stat(&buf64, (struct stat *)buf);
return res;
-# else
- return internal_syscall(SYSCALL(lstat), (uptr)path, (uptr)buf);
-# endif
-#else
+# endif
+# else
struct stat64 buf64;
int res = internal_syscall(SYSCALL(lstat64), path, &buf64);
stat64_to_stat(&buf64, (struct stat *)buf);
return res;
-#endif
+# endif
}
uptr internal_fstat(fd_t fd, void *buf) {
@@ -419,7 +415,7 @@ uptr internal_dup(int oldfd) {
}
uptr internal_dup2(int oldfd, int newfd) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# if SANITIZER_LINUX
return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0);
#else
return internal_syscall(SYSCALL(dup2), oldfd, newfd);
@@ -427,7 +423,7 @@ uptr internal_dup2(int oldfd, int newfd) {
}
uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# if SANITIZER_LINUX
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
bufsize);
#else
@@ -436,7 +432,7 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
}
uptr internal_unlink(const char *path) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# if SANITIZER_LINUX
return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
#else
return internal_syscall(SYSCALL(unlink), (uptr)path);
@@ -447,12 +443,12 @@ uptr internal_rename(const char *oldpath, const char *newpath) {
#if defined(__riscv) && defined(__linux__)
return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath, 0);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# elif SANITIZER_LINUX
return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath);
-#else
+# else
return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
-#endif
+# endif
}
uptr internal_sched_yield() {
@@ -489,11 +485,7 @@ bool FileExists(const char *filename) {
if (ShouldMockFailureToOpen(filename))
return false;
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);
@@ -501,11 +493,7 @@ bool FileExists(const char *filename) {
bool DirExists(const char *path) {
struct stat st;
-# if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
- if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, path, &st, 0))
-# else
if (internal_stat(path, &st))
-# endif
return false;
return S_ISDIR(st.st_mode);
}
@@ -709,17 +697,17 @@ void FutexWake(atomic_uint32_t *p, u32 count) {
// Not used
#else
struct linux_dirent {
-#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64
+# if SANITIZER_X32 || SANITIZER_LINUX
u64 d_ino;
u64 d_off;
-#else
+# else
unsigned long d_ino;
unsigned long d_off;
-#endif
+# endif
unsigned short d_reclen;
-#if defined(__aarch64__) || SANITIZER_RISCV64
+# if SANITIZER_LINUX
unsigned char d_type;
-#endif
+# endif
char d_name[256];
};
#endif
@@ -755,11 +743,11 @@ int internal_dlinfo(void *handle, int request, void *p) {
uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# elif SANITIZER_LINUX
return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count);
-#else
+# else
return internal_syscall(SYSCALL(getdents), fd, (uptr)dirp, count);
-#endif
+# endif
}
uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
@@ -777,11 +765,15 @@ uptr internal_sigaltstack(const void *ss, void *oss) {
}
int internal_fork() {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+# if SANITIZER_LINUX
+# if SANITIZER_S390
+ return internal_syscall(SYSCALL(clone), 0, SIGCHLD);
+# else
return internal_syscall(SYSCALL(clone), SIGCHLD, 0);
-#else
+# endif
+# else
return internal_syscall(SYSCALL(fork));
-#endif
+# endif
}
#if SANITIZER_FREEBSD
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index 4f2c551..8fe0d83 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -298,18 +298,6 @@
# define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
#endif
-// The AArch64 and RISC-V linux ports use 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
-# if (defined(__aarch64__) || defined(__riscv) || defined(__hexagon__)) && \
- SANITIZER_LINUX
-# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
-# else
-# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
-# endif
-#endif
-
// udi16 syscalls can only be used when the following conditions are
// met:
// * target is one of arm32, x86-32, sparc32, sh or m68k
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 8e40ea7..60ca963 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -1767,7 +1767,8 @@ TSAN_INTERCEPTOR(int, listen, int fd, int backlog) {
TSAN_INTERCEPTOR(int, close, int fd) {
SCOPED_INTERCEPTOR_RAW(close, fd);
- FdClose(thr, pc, fd);
+ if (!in_symbolizer())
+ FdClose(thr, pc, fd);
return REAL(close)(fd);
}