diff options
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/cmake/Modules/CompilerRTUtils.cmake | 3 | ||||
-rw-r--r-- | compiler-rt/cmake/base-config-ix.cmake | 2 | ||||
-rw-r--r-- | compiler-rt/cmake/builtin-config-ix.cmake | 3 | ||||
-rw-r--r-- | compiler-rt/cmake/config-ix.cmake | 4 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/CMakeLists.txt | 7 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/avr/exit.S | 18 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/avr/mulhi3.S | 58 | ||||
-rw-r--r-- | compiler-rt/lib/builtins/avr/mulqi3.S | 31 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp | 4 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h | 2 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp | 94 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_platform.h | 12 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 3 |
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); } |