diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake index c3e734f72392f..beccaa15bcca9 100644 --- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake +++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake @@ -582,6 +582,23 @@ macro(add_compiler_rt_script name) DESTINATION ${COMPILER_RT_INSTALL_BINARY_DIR}) endmacro(add_compiler_rt_script src name) +macro(add_compiler_rt_cfg target_name file_name component) + set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") + get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir) + set(dst_file "${output_dir}/${file_name}") + add_custom_command(OUTPUT ${dst_file} + DEPENDS ${src_file} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} + COMMENT "Copying ${file_name}...") + add_custom_target(${target_name} DEPENDS ${dst_file}) + install(FILES ${file_name} + DESTINATION ${COMPILER_RT_INSTALL_LIBRARY_DIR} + COMPONENT ${component}) + add_dependencies(${component} ${target_name}) + + set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc") +endmacro() + # Builds custom version of libc++ and installs it in . # Can be used to build sanitized versions of libc++ for running unit tests. # add_custom_libcxx( diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index 2683259e93e37..0816a05a7fbbd 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -28,11 +28,11 @@ if(WIN32) set(ARM32 ${ARM32} armv7) endif() -set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64} +set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC32} ${PPC64} ${RISCV64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} ${LOONGARCH64}) set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64} - ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} + ${MIPS32} ${MIPS64} ${PPC32} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON} ${LOONGARCH64}) set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32}) set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64}) diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake index d92bc0e71fa1a..953fa3983ecfc 100644 --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -14,7 +14,11 @@ include(CompilerRTDarwinUtils) check_include_file(unwind.h HAVE_UNWIND_H) # Used by sanitizer_common and tests. -check_include_file(rpc/xdr.h HAVE_RPC_XDR_H) +if (${CMAKE_SYSTEM_NAME} MATCHES AIX) + check_include_file(tirpc/rpc/xdr.h HAVE_RPC_XDR_H) +else() + check_include_file(rpc/xdr.h HAVE_RPC_XDR_H) +endif() if (NOT HAVE_RPC_XDR_H) set(HAVE_RPC_XDR_H 0) endif() diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index cf729c3adb1f5..075493feeadbd 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -141,6 +141,7 @@ check_cxx_compiler_flag("-Werror -Wgnu" COMPILER_RT_HAS_WGNU_FLAG check_cxx_compiler_flag("-Werror -Wgnu-anonymous-struct" COMPILER_RT_HAS_WGNU_ANONYMOUS_STRUCT_FLAG) check_cxx_compiler_flag("-Werror -Wvariadic-macros" COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG) check_cxx_compiler_flag("-Werror -Wunused-parameter" COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG) +check_cxx_compiler_flag("-Werror -Watomic-alignment" COMPILER_RT_HAS_WATOMIC_ALIGNMENT_FLAG) check_cxx_compiler_flag("-Werror -Wcovered-switch-default" COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG) check_cxx_compiler_flag("-Werror -Wsuggest-override" COMPILER_RT_HAS_WSUGGEST_OVERRIDE_FLAG) check_cxx_compiler_flag("-Werror -Wthread-safety" COMPILER_RT_HAS_WTHREAD_SAFETY_FLAG) @@ -760,7 +761,7 @@ set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS" OR + (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS|AIX" OR (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")))) set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt index e2f39f224df9c..6999180139562 100644 --- a/compiler-rt/lib/asan/CMakeLists.txt +++ b/compiler-rt/lib/asan/CMakeLists.txt @@ -1,6 +1,7 @@ # Build for the AddressSanitizer runtime support library. set(ASAN_SOURCES + asan_aix.cpp asan_allocator.cpp asan_activation.cpp asan_debugging.cpp @@ -281,6 +282,9 @@ else() PARENT_TARGET asan) endif() + # On AIX, we only need the static libraries. + if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX") + foreach(arch ${ASAN_SUPPORTED_ARCH}) if (COMPILER_RT_HAS_VERSION_SCRIPT) if(WIN32) @@ -382,10 +386,18 @@ else() endif() endif() endforeach() + endif() endif() add_compiler_rt_resource_file(asan_ignorelist asan_ignorelist.txt asan) +# On AIX, we need to put asan.link_with_main_exec.txt and asan_cxx.link_with_main_exec.txt +# to the build and install dir. +if (${CMAKE_SYSTEM_NAME} MATCHES "AIX") + add_compiler_rt_cfg(asan_symbols asan.link_with_main_exec.txt asan) + add_compiler_rt_cfg(asan_cxx_symbols asan_cxx.link_with_main_exec.txt asan) +endif() + add_subdirectory(scripts) if(COMPILER_RT_INCLUDE_TESTS) diff --git a/compiler-rt/lib/asan/asan.link_with_main_exec.txt b/compiler-rt/lib/asan/asan.link_with_main_exec.txt new file mode 100644 index 0000000000000..5efc48c262369 --- /dev/null +++ b/compiler-rt/lib/asan/asan.link_with_main_exec.txt @@ -0,0 +1,115 @@ +#! . +__asan_report_load_n +__asan_loadN +__asan_report_load1 +__asan_load1 +__asan_report_load2 +__asan_load2 +__asan_report_load4 +__asan_load4 +__asan_report_load8 +__asan_load8 +__asan_report_load16 +__asan_load16 +__asan_report_store_n +__asan_storeN +__asan_report_store1 +__asan_store1 +__asan_report_store2 +__asan_store2 +__asan_report_store4 +__asan_store4 +__asan_report_store8 +__asan_store8 +__asan_report_store16 +__asan_store16 +__asan_report_exp_load_n +__asan_exp_loadN +__asan_report_exp_load1 +__asan_exp_load1 +__asan_report_exp_load2 +__asan_exp_load2 +__asan_report_exp_load4 +__asan_exp_load4 +__asan_report_exp_load8 +__asan_exp_load8 +__asan_report_exp_load16 +__asan_exp_load16 +__asan_report_exp_store_n +__asan_exp_storeN +__asan_report_exp_store1 +__asan_exp_store1 +__asan_report_exp_store2 +__asan_exp_store2 +__asan_report_exp_store4 +__asan_exp_store4 +__asan_report_exp_store8 +__asan_exp_store8 +__asan_report_exp_store16 +__asan_exp_store16 +__asan_memmove +__asan_memcpy +__asan_memset +__asan_handle_no_return +__sanitizer_ptr_cmp +__sanitizer_ptr_sub +__asan_before_dynamic_init +__asan_after_dynamic_init +__asan_register_globals +__asan_unregister_globals +__asan_register_image_globals +__asan_unregister_image_globals +__asan_register_elf_globals +__asan_unregister_elf_globals +__asan_init +__asan_version_mismatch_check_v8 +__asan_stack_malloc_0 +__asan_stack_malloc_1 +__asan_stack_malloc_2 +__asan_stack_malloc_3 +__asan_stack_malloc_4 +__asan_stack_malloc_5 +__asan_stack_malloc_6 +__asan_stack_malloc_7 +__asan_stack_malloc_8 +__asan_stack_malloc_9 +__asan_stack_malloc_10 +__asan_stack_malloc_always_0 +__asan_stack_malloc_always_1 +__asan_stack_malloc_always_2 +__asan_stack_malloc_always_3 +__asan_stack_malloc_always_4 +__asan_stack_malloc_always_5 +__asan_stack_malloc_always_6 +__asan_stack_malloc_always_7 +__asan_stack_malloc_always_8 +__asan_stack_malloc_always_9 +__asan_stack_malloc_always_10 +__asan_stack_free_0 +__asan_stack_free_1 +__asan_stack_free_2 +__asan_stack_free_3 +__asan_stack_free_4 +__asan_stack_free_5 +__asan_stack_free_6 +__asan_stack_free_7 +__asan_stack_free_8 +__asan_stack_free_9 +__asan_stack_free_10 +__asan_set_shadow_00 +__asan_set_shadow_01 +__asan_set_shadow_02 +__asan_set_shadow_03 +__asan_set_shadow_04 +__asan_set_shadow_05 +__asan_set_shadow_06 +__asan_set_shadow_07 +__asan_set_shadow_f1 +__asan_set_shadow_f2 +__asan_set_shadow_f3 +__asan_set_shadow_f5 +__asan_set_shadow_f8 +__asan_poison_stack_memory +__asan_unpoison_stack_memory +__asan_option_detect_stack_use_after_return +__asan_shadow_memory_dynamic_address diff --git a/compiler-rt/lib/asan/asan_aix.cpp b/compiler-rt/lib/asan/asan_aix.cpp new file mode 100644 index 0000000000000..d1a8a5ac8e59d --- /dev/null +++ b/compiler-rt/lib/asan/asan_aix.cpp @@ -0,0 +1,44 @@ +//===-- asan_aix.cpp ------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// AIX-specific details. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_platform.h" + +#if SANITIZER_AIX +# include "asan_mapping.h" +# include "sanitizer_common/sanitizer_internal_defs.h" + +namespace __asan { + +void AsanCheckIncompatibleRT() {} + +void AsanCheckDynamicRTPrereqs() {} + +void InitializePlatformExceptionHandlers() {} + +void *AsanDoesNotSupportStaticLinkage() { return 0; } + +void InitializePlatformInterceptors() {} +void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {} + +uptr FindDynamicShadowStart() { + UNREACHABLE("AIX does not use dynamic shadow offset!"); + return 0; +} + +void FlushUnneededASanShadowMemory(uptr p, uptr size) { + ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); +} + +} // namespace __asan + +#endif // SANITIZER_AIX diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index 3a55c2af65653..fc826f6448325 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -770,11 +770,16 @@ struct Allocator { u8 chunk_state = atomic_load(&m->chunk_state, memory_order_acquire); if (chunk_state != CHUNK_ALLOCATED) ReportInvalidFree(old_ptr, chunk_state, stack); - CHECK_NE(REAL(memcpy), nullptr); uptr memcpy_size = Min(new_size, m->UsedSize()); // If realloc() races with free(), we may start copying freed memory. // However, we will report racy double-free later anyway. +#if !SANITIZER_AIX + CHECK_NE(REAL(memcpy), nullptr); REAL(memcpy)(new_ptr, old_ptr, memcpy_size); +#else + // AIX does not intercept memcpy, we have to use internal_memcpy here. + internal_memcpy(new_ptr, old_ptr, memcpy_size); +#endif Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC); } return new_ptr; @@ -797,8 +802,10 @@ struct Allocator { void ReportInvalidFree(void *ptr, u8 chunk_state, BufferedStackTrace *stack) { if (chunk_state == CHUNK_QUARANTINE) ReportDoubleFree((uptr)ptr, stack); - else - ReportFreeNotMalloced((uptr)ptr, stack); + else { + if (common_flags()->enable_unmalloced_free_check) + ReportFreeNotMalloced((uptr)ptr, stack); + } } void CommitBack(AsanThreadLocalMallocStorage *ms, BufferedStackTrace *stack) { diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index db8dc3bebfc62..46cd7b118cd9a 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -197,7 +197,11 @@ const uptr kAllocatorSpace = ~(uptr)0; # endif // SANITIZER_APPLE # if defined(__powerpc64__) +#if SANITIZER_AIX +const uptr kAllocatorSize = 1ULL << 38; // 256G. +#else const uptr kAllocatorSize = 0x20000000000ULL; // 2T. +#endif typedef DefaultSizeClassMap SizeClassMap; # elif defined(__aarch64__) && SANITIZER_ANDROID // Android needs to support 39, 42 and 48 bit VMA. diff --git a/compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt b/compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt new file mode 100644 index 0000000000000..7387f8173e859 --- /dev/null +++ b/compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt @@ -0,0 +1,21 @@ +#! . +_ZdaPv +_ZdaPvRKSt9nothrow_t +_ZdaPvSt11align_val_t +_ZdaPvSt11align_val_tRKSt9nothrow_t +_ZdaPvm +_ZdaPvmSt11align_val_t +_ZdlPv +_ZdlPvRKSt9nothrow_t +_ZdlPvSt11align_val_t +_ZdlPvSt11align_val_tRKSt9nothrow_t +_ZdlPvm +_ZdlPvmSt11align_val_t +_Znam +_ZnamRKSt9nothrow_t +_ZnamSt11align_val_t +_ZnamSt11align_val_tRKSt9nothrow_t +_Znwm +_ZnwmRKSt9nothrow_t +_ZnwmSt11align_val_t +_ZnwmSt11align_val_tRKSt9nothrow_t diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp index c9f3e4d682d95..6488d51b89a14 100644 --- a/compiler-rt/lib/asan/asan_descriptions.cpp +++ b/compiler-rt/lib/asan/asan_descriptions.cpp @@ -211,10 +211,10 @@ bool GetStackAddressInformation(uptr addr, uptr access_size, descr->frame_pc = access.frame_pc; descr->frame_descr = access.frame_descr; -#if SANITIZER_PPC64V1 - // On PowerPC64 ELFv1, the address of a function actually points to a - // three-doubleword data structure with the first field containing - // the address of the function's code. +#if SANITIZER_PPC64V1 || SANITIZER_AIX + // On PowerPC64 ELFv1 or AIX, the address of a function actually points to a + // three-doubleword (or three-word for 32-bit AIX) data structure with the + // first field containing the address of the function's code. descr->frame_pc = *reinterpret_cast(descr->frame_pc); #endif descr->frame_pc += 16; @@ -444,6 +444,15 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size, data.kind = kAddressKindShadow; return; } + + // Check global first. On AIX, some global data defined in shared libraries + // are put to the STACK region for unknown reasons. Check global first can + // workaround this issue. + if (GetGlobalAddressInformation(addr, access_size, &data.global)) { + data.kind = kAddressKindGlobal; + return; + } + if (GetHeapAddressInformation(addr, access_size, &data.heap)) { data.kind = kAddressKindHeap; return; @@ -461,10 +470,6 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size, return; } - if (GetGlobalAddressInformation(addr, access_size, &data.global)) { - data.kind = kAddressKindGlobal; - return; - } data.kind = kAddressKindWild; data.wild.addr = addr; data.wild.access_size = access_size; diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 247ea1b92f1f4..d55ebedafb086 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -56,6 +56,7 @@ namespace __asan { # define ASAN_READ_STRING(ctx, s, n) \ ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n)) +#if SANITIZER_INTERCEPT_STRCAT || SANITIZER_INTERCEPT_STRCPY static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { #if SANITIZER_INTERCEPT_STRNLEN if (REAL(strnlen)) { @@ -64,6 +65,7 @@ static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { #endif return internal_strnlen(s, maxlen); } +#endif void SetThreadName(const char *name) { AsanThread *t = GetCurrentThread(); @@ -275,7 +277,12 @@ INTERCEPTOR(int, pthread_create, void *thread, void *attr, # endif asanThreadArgRetval().Create(detached, {start_routine, arg}, [&]() -> uptr { result = REAL(pthread_create)(thread, attr, asan_thread_start, t); +// AIX pthread_t is unsigned int. +#if SANITIZER_AIX + return result ? 0 : *(unsigned int *)(thread); +#else return result ? 0 : *(uptr *)(thread); +#endif }); } if (result != 0) { @@ -432,10 +439,12 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, #define siglongjmp __siglongjmp14 #endif +#if ASAN_INTERCEPT_LONGJMP INTERCEPTOR(void, longjmp, void *env, int val) { __asan_handle_no_return(); REAL(longjmp)(env, val); } +#endif #if ASAN_INTERCEPT__LONGJMP INTERCEPTOR(void, _longjmp, void *env, int val) { @@ -508,6 +517,7 @@ DEFINE_REAL(char*, index, const char *string, int c) // For both strcat() and strncat() we need to check the validity of |to| // argument irrespective of the |from| length. +#if SANITIZER_INTERCEPT_STRCAT INTERCEPTOR(char *, strcat, char *to, const char *from) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strcat); @@ -547,7 +557,9 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, usize size) { } return REAL(strncat)(to, from, size); } +#endif +#if SANITIZER_INTERCEPT_STRCPY INTERCEPTOR(char *, strcpy, char *to, const char *from) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strcpy); @@ -569,6 +581,7 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) { } return REAL(strcpy)(to, from); } +#endif // Windows doesn't always define the strdup identifier, // and when it does it's a macro defined to either _strdup @@ -596,7 +609,13 @@ INTERCEPTOR(char*, strdup, const char *s) { GET_STACK_TRACE_MALLOC; void *new_mem = asan_malloc(length + 1, &stack); if (new_mem) { +# if SANITIZER_AIX + // memcpy is a static function defined in libc.a on AIX. It can not be + // intercepted, so REAL(memcpy) is null on AIX. Use internal_memcpy instead. + internal_memcpy(new_mem, s, length + 1); +# else REAL(memcpy)(new_mem, s, length + 1); +# endif } return reinterpret_cast(new_mem); } @@ -614,12 +633,17 @@ INTERCEPTOR(char*, __strdup, const char *s) { GET_STACK_TRACE_MALLOC; void *new_mem = asan_malloc(length + 1, &stack); if (new_mem) { +#if SANITIZER_AIX + internal_memcpy(new_mem, s, length + 1); +#else REAL(memcpy)(new_mem, s, length + 1); +#endif } return reinterpret_cast(new_mem); } #endif // ASAN_INTERCEPT___STRDUP +#if SANITIZER_INTERCEPT_STRCPY INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strncpy); @@ -632,6 +656,7 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) { } return REAL(strncpy)(to, from, size); } +#endif template static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr, @@ -743,6 +768,14 @@ static void AtCxaAtexit(void *unused) { } #endif +#if ASAN_INTERCEPT_EXIT +INTERCEPTOR(void, exit, int status) { + AsanInitFromRtl(); + StopInitOrderChecking(); + REAL(exit)(status); +} +#endif + #if ASAN_INTERCEPT___CXA_ATEXIT INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, void *dso_handle) { @@ -804,10 +837,14 @@ void InitializeAsanInterceptors() { InitializeSignalInterceptors(); // Intercept str* functions. +#if SANITIZER_INTERCEPT_STRCAT ASAN_INTERCEPT_FUNC(strcat); - ASAN_INTERCEPT_FUNC(strcpy); ASAN_INTERCEPT_FUNC(strncat); +#endif +#if SANITIZER_INTERCEPT_STRCPY + ASAN_INTERCEPT_FUNC(strcpy); ASAN_INTERCEPT_FUNC(strncpy); +#endif ASAN_INTERCEPT_FUNC(strdup); # if ASAN_INTERCEPT___STRDUP ASAN_INTERCEPT_FUNC(__strdup); @@ -827,7 +864,9 @@ void InitializeAsanInterceptors() { # endif // Intecept jump-related functions. +#if ASAN_INTERCEPT_LONGJMP ASAN_INTERCEPT_FUNC(longjmp); +#endif # if ASAN_INTERCEPT_SWAPCONTEXT ASAN_INTERCEPT_FUNC(swapcontext); @@ -894,6 +933,10 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(atexit); #endif +#if ASAN_INTERCEPT_EXIT + ASAN_INTERCEPT_FUNC(exit); +#endif + #if ASAN_INTERCEPT_PTHREAD_ATFORK ASAN_INTERCEPT_FUNC(pthread_atfork); #endif diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h index 3e2386eaf8092..2ca6bd45b6604 100644 --- a/compiler-rt/lib/asan/asan_interceptors.h +++ b/compiler-rt/lib/asan/asan_interceptors.h @@ -31,10 +31,20 @@ void InitializePlatformInterceptors(); // really defined to replace libc functions. #if !SANITIZER_FUCHSIA +#if !SANITIZER_AIX +# define ASAN_INTERCEPT_LONGJMP 1 +#else +# define ASAN_INTERCEPT_LONGJMP 0 +#endif + // Use macro to describe if specific function should be // intercepted on a given platform. #if !SANITIZER_WINDOWS +#if !SANITIZER_AIX # define ASAN_INTERCEPT__LONGJMP 1 +#else +# define ASAN_INTERCEPT__LONGJMP 0 +#endif # define ASAN_INTERCEPT_INDEX 1 # define ASAN_INTERCEPT_PTHREAD_CREATE 1 #else @@ -56,7 +66,7 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT_SWAPCONTEXT 0 #endif -#if !SANITIZER_WINDOWS +#if !SANITIZER_WINDOWS && !SANITIZER_AIX # define ASAN_INTERCEPT_SIGLONGJMP 1 #else # define ASAN_INTERCEPT_SIGLONGJMP 0 @@ -84,12 +94,18 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0 #endif -#if !SANITIZER_WINDOWS +#if !SANITIZER_WINDOWS && !SANITIZER_AIX # define ASAN_INTERCEPT___CXA_ATEXIT 1 #else # define ASAN_INTERCEPT___CXA_ATEXIT 0 #endif +#if SANITIZER_AIX +# define ASAN_INTERCEPT_EXIT 1 +#else +# define ASAN_INTERCEPT_EXIT 0 +#endif + #if SANITIZER_NETBSD # define ASAN_INTERCEPT_ATEXIT 1 #else @@ -110,6 +126,14 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT_TRYJOIN 0 #endif +#if SANITIZER_AIX +#define SANITIZER_INTERCEPT_STRCAT 0 +#define SANITIZER_INTERCEPT_STRCPY 0 +#else +#define SANITIZER_INTERCEPT_STRCAT 1 +#define SANITIZER_INTERCEPT_STRCPY 1 +#endif + #if SANITIZER_LINUX && \ (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \ defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64) diff --git a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp index bdf328f892063..170d91e47e4cc 100644 --- a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp +++ b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp @@ -25,6 +25,7 @@ using namespace __asan; // memcpy is called during __asan_init() from the internals of printf(...). // We do not treat memcpy with to==from as a bug. // See http://llvm.org/bugs/show_bug.cgi?id=11763. +// AIX does not intercept memcpy, so we have to use internal_memcpy. #define ASAN_MEMCPY_IMPL(ctx, to, from, size) \ do { \ if (LIKELY(replace_intrin_cached)) { \ @@ -36,7 +37,8 @@ using namespace __asan; } else if (UNLIKELY(!AsanInited())) { \ return internal_memcpy(to, from, size); \ } \ - return REAL(memcpy)(to, from, size); \ + return SANITIZER_AIX ? internal_memcpy(to, from, size) : \ + REAL(memcpy)(to, from, size); \ } while (0) // memset is called inside Printf. diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp index 3d6b03fefab70..5646a718d3ea0 100644 --- a/compiler-rt/lib/asan/asan_malloc_linux.cpp +++ b/compiler-rt/lib/asan/asan_malloc_linux.cpp @@ -14,8 +14,9 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" +// FIXME: rename this file, this is not just for Linux now, see FUCHSIA and AIX. #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS + SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_AIX # include "asan_allocator.h" # include "asan_interceptors.h" @@ -61,6 +62,24 @@ INTERCEPTOR(void, cfree, void *ptr) { } #endif // SANITIZER_INTERCEPT_CFREE +#if SANITIZER_AIX +INTERCEPTOR(void*, vec_malloc, uptr size) { + if (DlsymAlloc::Use()) + return DlsymAlloc::Allocate(size); + AsanInitFromRtl(); + GET_STACK_TRACE_MALLOC; + return asan_malloc(size, &stack); +} + +INTERCEPTOR(void*, vec_calloc, uptr nmemb, uptr size) { + if (DlsymAlloc::Use()) + return DlsymAlloc::Callocate(nmemb, size); + AsanInitFromRtl(); + GET_STACK_TRACE_MALLOC; + return asan_calloc(nmemb, size, &stack); +} +#endif + INTERCEPTOR(void*, malloc, uptr size) { if (DlsymAlloc::Use()) return DlsymAlloc::Allocate(size); diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h index 91fe60db6329a..ecd196e2a021e 100644 --- a/compiler-rt/lib/asan/asan_mapping.h +++ b/compiler-rt/lib/asan/asan_mapping.h @@ -178,6 +178,8 @@ # define ASAN_SHADOW_OFFSET_CONST 0x30000000 # elif SANITIZER_IOS # define ASAN_SHADOW_OFFSET_DYNAMIC +# elif SANITIZER_AIX +# define ASAN_SHADOW_OFFSET_CONST 0x40000000 # else # define ASAN_SHADOW_OFFSET_CONST 0x20000000 # endif @@ -193,7 +195,11 @@ # elif defined(__aarch64__) # define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000 # elif defined(__powerpc64__) -# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 +# if SANITIZER_AIX +# define ASAN_SHADOW_OFFSET_CONST 0x0a01000000000000 +# else +# define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000 +# endif # elif defined(__s390x__) # define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000 # elif SANITIZER_FREEBSD @@ -272,6 +278,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init. # if defined(__sparc__) && SANITIZER_WORDSIZE == 64 # include "asan_mapping_sparc64.h" +# elif SANITIZER_WORDSIZE == 64 && SANITIZER_AIX +# include "asan_mapping_aix64.h" # else # define MEM_TO_SHADOW(mem) \ (((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET)) diff --git a/compiler-rt/lib/asan/asan_mapping_aix64.h b/compiler-rt/lib/asan/asan_mapping_aix64.h new file mode 100644 index 0000000000000..38b97482ec1f4 --- /dev/null +++ b/compiler-rt/lib/asan/asan_mapping_aix64.h @@ -0,0 +1,184 @@ +//===-- asan_mapping_aix64.h ------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// AIX64-specific definitions for ASan memory mapping. +//===----------------------------------------------------------------------===// +#ifndef ASAN_MAPPING_AIX64_H +#define ASAN_MAPPING_AIX64_H + +// https://www.ibm.com/docs/en/aix/7.3?topic=concepts-system-memory-allocation-using-malloc-subsystem +// +// For 64-bit on AIX, +// - Data, heap, bss region is from 0x0000 0001 0000 0000 to +// 0x07ff ffff ffff ffff (1ULL << 59). +// - Shared library regions is from: +// 0x0900 0000 0000 0000 to 0x09ff ffff ffff ffff +// or 0x0800 0000 0000 0000 to 0x08ff ffff ffff ffff ((1ULL << 52) * 2) +// - mmap region is from 0x0a00 0000 0000 0000 to 0x0aff ffff ffff ffff +// (1ULL << 52). +// - Initial stack region is from 0x0f00 0000 0000 0000 to +// 0x0fff ffff ffff ffff (1ULL << 56). +// +// All above ranges are too big. And after verifying on AIX,(these datas are +// from experiments on AIX72, AIX OS may change this layout in future) +// - the biggest heap size is 1ULL << 47. +// - the biggest global variable size is 1ULL << 29. (Which may be put in shared +// library data regions because global variables may be compiled to shared +// libraries.) +// the related address range for shared library data regions is: +// 0x0900 1000 0000 0000 to 0x0900 1001 0000 0000 +// or 0x0800 1000 0000 0000 to 0x0800 1001 0000 0000 (when above range is +// used by system libraries.) +// - the biggest mmap size is 1ULL << 46. +// - the biggest stack size is 1ULL << 32. +// +// We don't need so big heap and mmap, calling mmap for shadow memory for such +// big heap and mmap is quite slow on AIX, so to balance runtime and examinable +// memory size, we use 1ULL << 39(512GB) as size for each region except mmap +// region. For mmap region, aix system mmap function may return a big range +// address, we allocate 1ULL << 41(2TB). +// +// So the reasonable user space region size is: +// - Data, heap, bss is from 0x0 to 0x0000 007f ffff ffff +// - Shared library data is from: +// 0x0900 1000 0000 0000 to 0x0900 107f ffff ffff +// or 0x0800 1000 0000 0000 to 0x0800 107f ffff ffff +// - mmap is from 0x0a00 0000 0000 0000 to 0x0a00 01ff ffff ffff +// - Stack is from 0x0fff ff80 0000 0000 to 0x0fff ffff ffff ffff +// +// AIX64 set ASAN_SHADOW_OFFSET_CONST at 0x0a01000000000000 because mmap +// memory starts at 0x0a00000000000000 and shadow memory should be allocated +// there. And we keep 0x0a00000000000000 to 0x0a01000000000000 For user mmap +// usage. + +// NOTE: Users are not expected to use `mmap` specifying fixed address which is +// inside the shadow memory ranges. + +// Default AIX64 mapping: +// || `[0x0fffff8000000000, 0x0fffffffffffffff]` || HighMem || +// || `[0x0a80fff000000000, 0x0a80ffffffffffff]` || HighShadow || +// || `[0x0a41000000000000, 0x0a41003fffffffff]` || MidShadow || +// || `[0x0a21020000000000, 0x0a21020fffffffff]` || Mid2Shadow || +// || `[0x0a01020000000000, 0x0a01020fffffffff]` || Mid3Shadow || +// || `[0x0a01000000000000, 0x0a01000fffffffff]` || LowShadow || +// || `[0x0a00000000000000, 0x0a0001ffffffffff]` || MidMem || +// || `[0x0900100000000000, 0x0900107fffffffff]` || Mid2Mem || +// || `[0x0800100000000000, 0x0800107fffffffff]` || Mid3Mem || +// || `[0x0000000000000000, 0x0000007fffffffff]` || LowMem || + +#define VMA_BITS 58 +#define HIGH_BITS (64 - VMA_BITS) + +#define MEM_TO_SHADOW(mem) \ + ((((mem) << HIGH_BITS) >> (HIGH_BITS + (ASAN_SHADOW_SCALE))) + \ + ASAN_SHADOW_OFFSET) + +#define SHADOW_TO_MEM(ptr) (__asan::ShadowToMemAIX64(ptr)) + +#define kLowMemBeg 0ULL +#define kLowMemEnd 0x0000007fffffffffULL + +#define kLowShadowBeg ASAN_SHADOW_OFFSET +#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) + +#define kHighMemBeg 0x0fffff8000000000ULL + +#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg) +#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd) + +#define kMidMemBeg 0x0a00000000000000ULL +#define kMidMemEnd 0x0a0001ffffffffffULL + +#define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg) +#define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd) + +#define kMid2MemBeg 0x0900100000000000ULL +#define kMid2MemEnd 0x0900107fffffffffULL + +#define kMid2ShadowBeg MEM_TO_SHADOW(kMid2MemBeg) +#define kMid2ShadowEnd MEM_TO_SHADOW(kMid2MemEnd) + +#define kMid3MemBeg 0x0800100000000000ULL +#define kMid3MemEnd 0x0800107fffffffffULL + +#define kMid3ShadowBeg MEM_TO_SHADOW(kMid3MemBeg) +#define kMid3ShadowEnd MEM_TO_SHADOW(kMid3MemEnd) + +// AIX does not care about the gaps. +#define kZeroBaseShadowStart 0 +#define kZeroBaseMaxShadowStart 0 + +#define kShadowGapBeg 0 +#define kShadowGapEnd 0 + +#define kShadowGap2Beg 0 +#define kShadowGap2End 0 + +#define kShadowGap3Beg 0 +#define kShadowGap3End 0 + +#define kShadowGap4Beg 0 +#define kShadowGap4End 0 + +namespace __asan { + +static inline bool AddrIsInLowMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return a <= kLowMemEnd; +} + +static inline bool AddrIsInLowShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return a >= kLowShadowBeg && a <= kLowShadowEnd; +} + +static inline bool AddrIsInMidMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return (a >= kMidMemBeg && a <= kMidMemEnd) || + (a >= kMid2MemBeg && a <= kMid2MemEnd) || + (a >= kMid3MemBeg && a <= kMid3MemEnd); +} + +static inline bool AddrIsInMidShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return (a >= kMidShadowBeg && a <= kMidShadowEnd) || + (a >= kMid2ShadowBeg && a <= kMid2ShadowEnd) || + (a >= kMid3ShadowBeg && a <= kMid3ShadowEnd); +} + +static inline bool AddrIsInHighMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd; +} + +static inline bool AddrIsInHighShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd; +} + +static inline bool AddrIsInShadowGap(uptr a) { return false; } + +static inline constexpr uptr ShadowToMemAIX64(uptr p) { + PROFILE_ASAN_MAPPING(); + p -= ASAN_SHADOW_OFFSET; + p <<= ASAN_SHADOW_SCALE; + if (p >= 0x3ffff8000000000ULL) { + // HighMem + p |= (0x03ULL << VMA_BITS); + } else if (p >= 0x100000000000ULL) { + // MidShadow/Mid2Shadow/Mid2Shadow + p |= (0x02ULL << VMA_BITS); + } + return p; +} + +} // namespace __asan + +#endif // ASAN_MAPPING_AIX64_H diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h index 600bd011f304c..85482158dda9f 100644 --- a/compiler-rt/lib/asan/asan_poisoning.h +++ b/compiler-rt/lib/asan/asan_poisoning.h @@ -50,7 +50,9 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, // for mapping shadow and zeroing out pages doesn't "just work", so we should // probably provide higher-level interface for these operations. // For now, just memset on Windows. - if (value || SANITIZER_WINDOWS == 1 || + // On aix, calling ReserveShadowMemoryRange() is not allowed to remap the + // memory, so just memset the memory. + if (value || SANITIZER_WINDOWS == 1 || SANITIZER_AIX == 1 || shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) { REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg); } else { diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp index 39685696a0d0d..624b2743e80cf 100644 --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -14,7 +14,11 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_POSIX +// tid_t is also defined in AIX header /usr/include/sys/types.h which is +// included by system pthread.h +# define tid_t tid_t_temp # include +# undef tid_t # include # include # include @@ -173,7 +177,7 @@ static void AfterFork(bool fork_child) { } void InstallAtForkHandler() { -# if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE || \ +# if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE || SANITIZER_AIX || \ (SANITIZER_LINUX && SANITIZER_SPARC) // While other Linux targets use clone in internal_fork which doesn't // trigger pthread_atfork handlers, Linux/sparc64 uses __fork, causing a diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp index 19c6c210b564c..92d8de36c82c6 100644 --- a/compiler-rt/lib/asan/asan_rtl.cpp +++ b/compiler-rt/lib/asan/asan_rtl.cpp @@ -55,13 +55,24 @@ static void AsanDie() { WaitForDebugger(flags()->sleep_before_dying, "before dying"); if (flags()->unmap_shadow_on_exit) { +#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64 + UnmapOrDie((void *)kHighShadowBeg, kHighShadowEnd - kHighShadowBeg); + UnmapOrDie((void *)kMidShadowBeg, kMidShadowEnd - kMidShadowBeg); + + UnmapOrDie((void *)kMid2ShadowBeg, kMid2ShadowEnd - kMid2ShadowBeg); + UnmapOrDie((void *)kMid3ShadowBeg, kMid3ShadowEnd - kMid3ShadowBeg); + + UnmapOrDie((void *)kLowShadowBeg, kLowShadowEnd - kLowShadowBeg); +#else if (kMidMemBeg) { - UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); - UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); + UnmapOrDie((void *)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); + UnmapOrDie((void *)kMidMemEnd, kHighShadowEnd - kMidMemEnd); } else { if (kHighShadowEnd) - UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); + UnmapOrDie((void *)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); + } +#endif } } @@ -85,7 +96,11 @@ bool AsanInited() { bool replace_intrin_cached; #if !ASAN_FIXED_MAPPING +#if !(SANITIZER_AIX && __powerpc64__) uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; +#else +uptr kHighMemEnd; +#endif #endif // -------------------------- Misc ---------------- {{{1 @@ -341,17 +356,29 @@ void PrintAddressSpaceLayout() { (void*)kHighShadowBeg, (void*)kHighShadowEnd); } if (kMidMemBeg) { + // AIX shadowgap is always set to 0 for 64-bit. +#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64 Printf("|| `[%p, %p]` || ShadowGap3 ||\n", (void*)kShadowGap3Beg, (void*)kShadowGap3End); +#endif Printf("|| `[%p, %p]` || MidMem ||\n", (void*)kMidMemBeg, (void*)kMidMemEnd); +#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64 Printf("|| `[%p, %p]` || ShadowGap2 ||\n", (void*)kShadowGap2Beg, (void*)kShadowGap2End); +#endif Printf("|| `[%p, %p]` || MidShadow ||\n", (void*)kMidShadowBeg, (void*)kMidShadowEnd); } +#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64 + Printf("|| `[%p, %p]` || Mid2Shadow ||\n", + (void*)kMid2ShadowBeg, (void*)kMid2ShadowEnd); + Printf("|| `[%p, %p]` || Mid3Shadow ||\n", + (void*)kMid3ShadowBeg, (void*)kMid3ShadowEnd); +#else Printf("|| `[%p, %p]` || ShadowGap ||\n", (void*)kShadowGapBeg, (void*)kShadowGapEnd); +#endif if (kLowShadowBeg) { Printf("|| `[%p, %p]` || LowShadow ||\n", (void*)kLowShadowBeg, (void*)kLowShadowEnd); @@ -371,6 +398,15 @@ void PrintAddressSpaceLayout() { (void*)MEM_TO_SHADOW(kMidShadowBeg), (void*)MEM_TO_SHADOW(kMidShadowEnd)); } +// On AIX, for 64-bit, there are totally 3 mid memory regions. +#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64 + Printf(" %p %p", + (void*)MEM_TO_SHADOW(kMid2ShadowBeg), + (void*)MEM_TO_SHADOW(kMid2ShadowEnd)); + Printf(" %p %p", + (void*)MEM_TO_SHADOW(kMid3ShadowBeg), + (void*)MEM_TO_SHADOW(kMid3ShadowEnd)); +#endif Printf("\n"); Printf("redzone=%zu\n", (uptr)flags()->redzone); Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone); @@ -386,7 +422,10 @@ void PrintAddressSpaceLayout() { CHECK(ASAN_SHADOW_SCALE >= 3 && ASAN_SHADOW_SCALE <= 7); if (kMidMemBeg) CHECK(kMidShadowBeg > kLowShadowEnd && +// On AIX 64-bit, we have a highly customized memory layout. +#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64 kMidMemBeg > kMidShadowEnd && +#endif kHighShadowBeg > kMidMemEnd); } diff --git a/compiler-rt/lib/asan/asan_shadow_setup.cpp b/compiler-rt/lib/asan/asan_shadow_setup.cpp index fc6de39622b51..c8416a2b0b7c7 100644 --- a/compiler-rt/lib/asan/asan_shadow_setup.cpp +++ b/compiler-rt/lib/asan/asan_shadow_setup.cpp @@ -91,9 +91,26 @@ void InitializeShadowMemory() { ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow"); // mmap the high shadow. ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow"); - // protect the gap. - ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); - CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1); + +# if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64 + // Fox 64-bit AIX, there is a very customized memory layout, we don't have + // the ability to protect all the shadow gaps. But we need to reserve + // shadow memory for middle memory. + if (kMidShadowBeg) + ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow"); + + if (kMid2ShadowBeg) + ReserveShadowMemoryRange(kMid2ShadowBeg, kMid2ShadowEnd, "mid2 shadow"); + + if (kMid3ShadowBeg) + ReserveShadowMemoryRange(kMid3ShadowBeg, kMid3ShadowEnd, "mid3 shadow"); +# else + if (kShadowGapBeg) { + // protect the gap. + ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); + CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1); + } +# endif } else if (kMidMemBeg && MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) && MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) { diff --git a/compiler-rt/lib/asan/scripts/asan_symbolize.py b/compiler-rt/lib/asan/scripts/asan_symbolize.py index 058a1614b55e6..8016d15e1cd64 100755 --- a/compiler-rt/lib/asan/scripts/asan_symbolize.py +++ b/compiler-rt/lib/asan/scripts/asan_symbolize.py @@ -59,6 +59,7 @@ def is_valid_arch(s): "armv7s", "armv7k", "arm64", + "powerpc" "powerpc64", "powerpc64le", "s390x", @@ -449,7 +450,7 @@ def __init__(self, plugin_proxy=None, dsym_hint_producer=None): # E.g. in Chrome several binaries may share a single .dSYM. self.dsym_hint_producer = dsym_hint_producer self.system = os.uname()[0] - if self.system not in ["Linux", "Darwin", "FreeBSD", "NetBSD", "SunOS"]: + if self.system not in ["Linux", "Darwin", "FreeBSD", "NetBSD", "SunOS", "AIX"]: raise Exception("Unknown system") self.llvm_symbolizers = {} self.last_llvm_symbolizer = None diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt index 00dcbf6534e28..4e556280d3e6e 100644 --- a/compiler-rt/lib/asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/asan/tests/CMakeLists.txt @@ -80,6 +80,11 @@ if(NOT MSVC) list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS --driver-mode=g++) endif() +# unittest will test asan sources which may require atomic library. +if (${CMAKE_SYSTEM_NAME} MATCHES "AIX") + list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -latomic) +endif() + # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE") list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS "-lc++") @@ -239,7 +244,8 @@ function(add_asan_tests arch test_runtime) LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS}) endfunction() -if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID) +# AIX can not run unittest because of shared library interception issue. +if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX") set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH}) if(APPLE) darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH) diff --git a/compiler-rt/lib/interception/CMakeLists.txt b/compiler-rt/lib/interception/CMakeLists.txt index fe7fa27fbc78b..57c8c8ba20141 100644 --- a/compiler-rt/lib/interception/CMakeLists.txt +++ b/compiler-rt/lib/interception/CMakeLists.txt @@ -1,6 +1,7 @@ # Build for the runtime interception helper library. set(INTERCEPTION_SOURCES + interception_aix.cpp interception_linux.cpp interception_mac.cpp interception_win.cpp @@ -9,6 +10,7 @@ set(INTERCEPTION_SOURCES set(INTERCEPTION_HEADERS interception.h + interception_aix.h interception_linux.h interception_mac.h interception_win.h diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index 3cb6b446638e0..3a20cfb04dcd6 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -19,7 +19,7 @@ #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ - !SANITIZER_SOLARIS + !SANITIZER_SOLARIS && !SANITIZER_AIX # error "Interception doesn't work on this operating system." #endif @@ -168,6 +168,16 @@ const interpose_substitution substitution_##func_name[] \ extern "C" ret_type func(__VA_ARGS__); # define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \ extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__); +#elif SANITIZER_AIX +# define WRAP(x) __interceptor_##x +# define TRAMPOLINE(x) WRAP(x) +// # define WRAPPER_NAME(x) "__interceptor_" #x +# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) +// AIX's linker will not select the weak symbol, so don't use weak for the +// interceptors. +# define DECLARE_WRAPPER(ret_type, func, ...) \ + extern "C" ret_type func(__VA_ARGS__) \ + __attribute__((alias("__interceptor_" #func), visibility("default"))); #elif !SANITIZER_FUCHSIA // LINUX, FREEBSD, NETBSD, SOLARIS # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) # if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT @@ -367,7 +377,12 @@ inline void DoesNotSupportStaticLinking() {} #define INCLUDED_FROM_INTERCEPTION_LIB -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ +#if SANITIZER_AIX +# include "interception_aix.h" +# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_AIX(func) +# define INTERCEPT_FUNCTION_VER(func, symver) INTERCEPT_FUNCTION_AIX(func) + +#elif SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ SANITIZER_SOLARIS # include "interception_linux.h" diff --git a/compiler-rt/lib/interception/interception_aix.cpp b/compiler-rt/lib/interception/interception_aix.cpp new file mode 100644 index 0000000000000..953bbad96eb47 --- /dev/null +++ b/compiler-rt/lib/interception/interception_aix.cpp @@ -0,0 +1,45 @@ +//===-- interception_aix.cpp ------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// AIX-specific interception methods. +//===----------------------------------------------------------------------===// + +#include "interception.h" +#include "sanitizer_common/sanitizer_common.h" + +#if SANITIZER_AIX + +# include // for dlsym() + +namespace __interception { + +static void *GetFuncAddr(const char *name, uptr wrapper_addr) { + // AIX dlsym can only defect the functions that are exported, so + // on AIX, we can not intercept some basic functions like memcpy. + // FIXME: if we are going to ship dynamic asan library, we may need to search + // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed. + void *addr = dlsym(RTLD_NEXT, name); + + // In case `name' is not loaded, dlsym ends up finding the actual wrapper. + // We don't want to intercept the wrapper and have it point to itself. + if ((uptr)addr == wrapper_addr) + addr = nullptr; + return addr; +} + +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper) { + void *addr = GetFuncAddr(name, wrapper); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} + +} // namespace __interception +#endif // SANITIZER_AIX diff --git a/compiler-rt/lib/interception/interception_aix.h b/compiler-rt/lib/interception/interception_aix.h new file mode 100644 index 0000000000000..08d17caeb6a8d --- /dev/null +++ b/compiler-rt/lib/interception/interception_aix.h @@ -0,0 +1,36 @@ +//===-- interception_aix.h --------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// AIX-specific interception methods. +//===----------------------------------------------------------------------===// + +#if SANITIZER_AIX + +# if !defined(INCLUDED_FROM_INTERCEPTION_LIB) +# error \ + "interception_aix.h should be included from interception library only" +# endif + +# ifndef INTERCEPTION_AIX_H +# define INTERCEPTION_AIX_H + +namespace __interception { +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper); +} // namespace __interception + +# define INTERCEPT_FUNCTION_AIX(func) \ + ::__interception::InterceptFunction( \ + #func, (::__interception::uptr *)&REAL(func), \ + (::__interception::uptr) & (func), \ + (::__interception::uptr)&WRAP(func)) + +# endif // INTERCEPTION_AIX_H +#endif // SANITIZER_AIX diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index 09391e4f5f370..3652ddbd28333 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -2,6 +2,7 @@ # These components are shared between AddressSanitizer and ThreadSanitizer. set(SANITIZER_SOURCES_NOTERMINATION + sanitizer_aix.cpp sanitizer_allocator.cpp sanitizer_common.cpp sanitizer_deadlock_detector1.cpp @@ -25,6 +26,7 @@ set(SANITIZER_SOURCES_NOTERMINATION sanitizer_platform_limits_solaris.cpp sanitizer_posix.cpp sanitizer_printf.cpp + sanitizer_procmaps_aix.cpp sanitizer_procmaps_common.cpp sanitizer_procmaps_bsd.cpp sanitizer_procmaps_fuchsia.cpp @@ -95,6 +97,7 @@ set(SANITIZER_SYMBOLIZER_SOURCES sanitizer_symbolizer_report_fuchsia.cpp sanitizer_symbolizer_win.cpp sanitizer_thread_history.cpp + sanitizer_unwind_aix.cpp sanitizer_unwind_linux_libcdep.cpp sanitizer_unwind_fuchsia.cpp sanitizer_unwind_win.cpp @@ -107,6 +110,7 @@ set(SANITIZER_IMPL_HEADERS sancov_flags.h sancov_flags.inc sanitizer_addrhashmap.h + sanitizer_aix.h sanitizer_allocator.h sanitizer_allocator_checks.h sanitizer_allocator_combined.h @@ -239,6 +243,11 @@ append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=570 append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors SANITIZER_CFLAGS) +# Suppress -Watomic-alignment warnings by not treating them as errors +if (CMAKE_SYSTEM_NAME MATCHES "AIX") + list(APPEND SANITIZER_CFLAGS "-Wno-error=atomic-alignment") +endif() + if(APPLE) set(OS_OPTION OS ${SANITIZER_COMMON_SUPPORTED_OS}) endif() diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp new file mode 100644 index 0000000000000..fac3d7b10829f --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp @@ -0,0 +1,499 @@ +//===-- sanitizer_aix.cpp -------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements AIX-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_AIX +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include "interception/interception.h" +# include "sanitizer_aix.h" +# include "sanitizer_common.h" +# include "sanitizer_file.h" +# include "sanitizer_libc.h" +# include "sanitizer_procmaps.h" + +extern char **p_xargv; + +namespace __sanitizer { + +# include "sanitizer_syscall_generic.inc" + +static void *GetFuncAddr(const char *name) { + // FIXME: if we are going to ship dynamic asan library, we may need to search + // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed. + void *addr = dlsym(RTLD_NEXT, name); + return addr; +} + +// Internal implementation for the libc functions are also calling to the same +// name function in libc. However because the same name function to libc may be +// intercepted, and in the interceptor function, it may call REAL(func). But the +// REAL(func) may be not assigned at this time, because internal_func may be +// called before interceptor init functions are called. So we need to call to +// libc function via function pointer. + +# define _REAL(func, ...) real##_##func(__VA_ARGS__) + +# define DEFINE__REAL(ret_type, func, ...) \ + static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ + if (!real_##func) { \ + real_##func = (ret_type(*)(__VA_ARGS__))GetFuncAddr(#func); \ + } \ + CHECK(real_##func); + +uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, + u64 offset) { + DEFINE__REAL(uptr, mmap, void *addr, uptr length, int prot, int flags, int fd, + u64 offset); + return _REAL(mmap, addr, length, prot, flags, fd, offset); +} + +uptr internal_munmap(void *addr, uptr length) { + DEFINE__REAL(uptr, munmap, void *addr, uptr length); + return _REAL(munmap, addr, length); +} + +int internal_mprotect(void *addr, uptr length, int prot) { + DEFINE__REAL(int, mprotect, void *addr, uptr length, int prot); + return _REAL(mprotect, addr, length, prot); +} + +int internal_madvise(uptr addr, uptr length, int advice) { + char *raddr = reinterpret_cast(addr); + DEFINE__REAL(int, madvise, char *raddr, uptr length, int advice) + return _REAL(madvise, raddr, length, advice); +} + +uptr internal_close(fd_t fd) { + DEFINE__REAL(uptr, close, fd_t fd); + return _REAL(close, fd); +} + +uptr internal_open(const char *filename, int flags) { + DEFINE__REAL(uptr, open, const char *filename, int flags); + return _REAL(open, filename, flags); +} + +uptr internal_open(const char *filename, int flags, u32 mode) { + DEFINE__REAL(uptr, open, const char *filename, int flags, u32 mode); + return _REAL(open, filename, flags, mode); +} + +__sanitizer_FILE *internal_popen(const char *command, const char *type) { + DEFINE__REAL(__sanitizer_FILE *, popen, const char *command, + const char *type); + return _REAL(popen, command, type); +} + +int internal_pclose(__sanitizer_FILE *file) { + FILE *rfile = reinterpret_cast(file); + DEFINE__REAL(int, pclose, FILE *file); + return _REAL(pclose, rfile); +} + +uptr internal_read(fd_t fd, void *buf, uptr count) { + DEFINE__REAL(uptr, read, fd_t fd, void *buf, uptr count); + return _REAL(read, fd, buf, count); +} + +uptr internal_write(fd_t fd, const void *buf, uptr count) { + DEFINE__REAL(uptr, write, fd_t fd, const void *buf, uptr count); + return _REAL(write, fd, buf, count); +} + +uptr internal_stat(const char *path, void *buf) { + DEFINE__REAL(uptr, stat, const char *path, void *buf); + return _REAL(stat, path, buf); +} + +uptr internal_lstat(const char *path, void *buf) { + DEFINE__REAL(uptr, lstat, const char *path, void *buf); + return _REAL(lstat, path, buf); +} + +uptr internal_fstat(fd_t fd, void *buf) { + DEFINE__REAL(uptr, fstat, fd_t fd, void *buf); + return _REAL(fstat, fd, buf); +} + +uptr internal_filesize(fd_t fd) { + struct stat st; + if (internal_fstat(fd, &st)) + return -1; + return (uptr)st.st_size; +} + +uptr internal_dup(int oldfd) { + DEFINE__REAL(uptr, dup, int oldfd); + return _REAL(dup, oldfd); +} + +uptr internal_dup2(int oldfd, int newfd) { + DEFINE__REAL(uptr, dup2, int oldfd, int newfd); + return _REAL(dup2, oldfd, newfd); +} + +uptr internal_readlink(const char *path, char *buf, uptr bufsize) { + DEFINE__REAL(uptr, readlink, const char *path, char *buf, uptr bufsize); + return _REAL(readlink, path, buf, bufsize); +} + +uptr internal_unlink(const char *path) { + DEFINE__REAL(uptr, unlink, const char *path); + return _REAL(unlink, path); +} + +uptr internal_sched_yield() { + DEFINE__REAL(uptr, sched_yield); + return _REAL(sched_yield); +} + +void FutexWait(atomic_uint32_t *p, u32 cmp) { internal_sched_yield(); } + +void FutexWake(atomic_uint32_t *p, u32 count) {} + +void internal__exit(int exitcode) { + DEFINE__REAL(void, _exit, int exitcode); + _REAL(_exit, exitcode); + Die(); // Unreachable. +} + +void internal_usleep(u64 useconds) { + DEFINE__REAL(void, usleep, u64 useconds); + _REAL(usleep, useconds); +} + +uptr internal_getpid() { + DEFINE__REAL(uptr, getpid); + return _REAL(getpid); +} + +int internal_dlinfo(void *handle, int request, void *p) { return 0; } + +int internal_sigaction(int signum, const void *act, void *oldact) { + DEFINE__REAL(int, sigaction, int signum, const void *act, void *oldact); + return _REAL(sigaction, signum, act, oldact); +} + +void internal_sigfillset(__sanitizer_sigset_t *set) { + sigset_t *rset = reinterpret_cast(set); + DEFINE__REAL(void, sigfillset, sigset_t *rset); + _REAL(sigfillset, rset); +} + +uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, + __sanitizer_sigset_t *oldset) { + sigset_t *rset = reinterpret_cast(set); + sigset_t *roldset = reinterpret_cast(oldset); + DEFINE__REAL(uptr, sigprocmask, int how, sigset_t *rset, sigset_t *roldset); + return _REAL(sigprocmask, how, rset, roldset); +} + +char *internal_getcwd(char *buf, uptr size) { + DEFINE__REAL(char *, getcwd, char *buf, uptr size); + return _REAL(getcwd, buf, size); +} + +int internal_fork() { + DEFINE__REAL(int, fork); + return _REAL(fork); +} + +uptr internal_execve(const char *filename, char *const argv[], + char *const envp[]) { + DEFINE__REAL(uptr, execve, const char *filename, char *const argv[], + char *const envp[]); + return _REAL(execve, filename, argv, envp); +} + +uptr internal_waitpid(int pid, int *status, int options) { + DEFINE__REAL(uptr, waitpid, int pid, int *status, int options); + return _REAL(waitpid, pid, status, options); +} + +int internal_pthread_join(pthread_t thread, void **status) { + DEFINE__REAL(int, pthread_join, pthread_t thread, void **status); + return _REAL(pthread_join, thread, status); +} + +int internal_pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg) { + DEFINE__REAL(int, pthread_create, pthread_t *thread, + const pthread_attr_t *attr, void *(*start_routine)(void *), + void *arg); + return _REAL(pthread_create, thread, attr, start_routine, arg); +} + +void *internal_start_thread(void *(*func)(void *arg), void *arg) { + // Start the thread with signals blocked, otherwise it can steal user signals. + __sanitizer_sigset_t set, old; + internal_sigfillset(&set); + internal_sigprocmask(SIG_SETMASK, &set, &old); + pthread_t th; + internal_pthread_create(&th, 0, func, arg); + internal_sigprocmask(SIG_SETMASK, &old, 0); + // pthread_t is unsinged int on AIX + return reinterpret_cast(th); +} + +void internal_join_thread(void *th) { + internal_pthread_join((pthread_t)(reinterpret_cast(th)), nullptr); +} + +uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { + clock_t rclk_id = reinterpret_cast(clk_id); + struct timespec *rtp = reinterpret_cast(tp); + DEFINE__REAL(uptr, clock_gettime, clock_t rclk_id, struct timespec * rtp); + return _REAL(clock_gettime, rclk_id, rtp); +} + +void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, + uptr *stack_bottom) { + CHECK(stack_top); + CHECK(stack_bottom); + if (at_initialization) { + // This is the main thread. Libpthread may not be initialized yet. + struct rlimit rl; + CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0); + + // Find the mapping that contains a stack variable. + MemoryMappingLayout proc_maps(/*cache_enabled*/ true); + if (proc_maps.Error()) { + *stack_top = *stack_bottom = 0; + return; + } + MemoryMappedSegment segment; + uptr prev_end = 0; + while (proc_maps.Next(&segment)) { + if ((uptr)&rl < segment.end) + break; + prev_end = segment.end; + } + + CHECK((uptr)&rl >= segment.start && (uptr)&rl < segment.end); + + // Get stacksize from rlimit, but clip it so that it does not overlap + // with other mappings. + uptr stacksize = rl.rlim_cur; + if (stacksize > segment.end - prev_end) + stacksize = segment.end - prev_end; + // When running with unlimited stack size, we still want to set some limit. + // The unlimited stack size is caused by 'ulimit -s unlimited'. + // Also, for some reason, GNU make spawns subprocesses with unlimited stack. + if (stacksize > kMaxThreadStackSize) + stacksize = kMaxThreadStackSize; + *stack_top = segment.end; + *stack_bottom = segment.end - stacksize; + return; + } + uptr stacksize = 0; + void *stackaddr = nullptr; + pthread_attr_t attr; + pthread_attr_init(&attr); + CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0); + internal_pthread_attr_getstack(&attr, &stackaddr, &stacksize); + pthread_attr_destroy(&attr); + + *stack_top = (uptr)stackaddr; + *stack_bottom = (uptr)stackaddr - stacksize; +} + +void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end, + uptr *tls_begin, uptr *tls_end) { + // FIXME: handle TLS related flag + *tls_begin = 0; + *tls_end = 0; + + uptr stack_top, stack_bottom; + GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom); + *stk_begin = stack_bottom; + *stk_end = stack_top; +} + +const char *GetEnv(const char *name) { return getenv(name); } + +tid_t GetTid() { return thread_self(); } + +uptr ReadBinaryName(char *buf, uptr buf_len) { + struct stat statData; + struct psinfo psinfoData; + + char FilePsinfo[100] = {}; + internal_snprintf(FilePsinfo, 100, "/proc/%d/psinfo", internal_getpid()); + CHECK_EQ(internal_stat(FilePsinfo, &statData), 0); + + const int fd = internal_open(FilePsinfo, O_RDONLY); + ssize_t readNum = internal_read(fd, &psinfoData, sizeof(psinfoData)); + CHECK_GE(readNum, 0); + + internal_close(fd); + char *binary_name = (reinterpret_cast(psinfoData.pr_argv))[0][0]; + + // This is an absulate path. + if (binary_name[0] == '/') + return internal_snprintf(buf, buf_len, "%s", binary_name); + + // This is a relative path to the binary, starts with ./ or ../ + if (binary_name[0] == '.') { + char *path = nullptr; + if ((path = internal_getcwd(buf, buf_len)) != nullptr) + return internal_snprintf(buf + internal_strlen(path), + buf_len - internal_strlen(path), "/%s", + binary_name) + + internal_strlen(path); + } + + // This is running a raw binary in the dir where it is from. + char *path = nullptr; + if ((path = internal_getcwd(buf, buf_len)) != nullptr) { + char fullName[kMaxPathLength] = {}; + internal_snprintf(fullName, kMaxPathLength, "%s/%s", path, binary_name); + if (FileExists(fullName)) + return internal_snprintf(buf + internal_strlen(path), + buf_len - internal_strlen(path), "/%s", + binary_name) + + internal_strlen(path); + } + + // Find the binary in the env PATH. + if ((path = FindPathToBinaryOrLibrary(binary_name)) != nullptr) + return internal_snprintf(buf, buf_len, "%s", path); + + return 0; +} + +// https://www.ibm.com/docs/en/aix/7.3?topic=concepts-system-memory-allocation-using-malloc-subsystem +uptr GetMaxVirtualAddress() { +# if SANITIZER_WORDSIZE == 64 + return (1ULL << 60) - 1; +# else + return 0xffffffff; +# endif +} + +uptr GetMaxUserVirtualAddress() { return GetMaxVirtualAddress(); } + +uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) { + return ReadBinaryName(buf, buf_len); +} + +void InitializePlatformCommonFlags(CommonFlags *cf) {} + +void InitializePlatformEarly() { + // Do nothing. +} + +uptr GetPageSize() { return getpagesize(); } + +void CheckASLR() { + // Do nothing +} + +HandleSignalMode GetHandleSignalMode(int signum) { + switch (signum) { + case SIGABRT: + return common_flags()->handle_abort; + case SIGILL: + return common_flags()->handle_sigill; + case SIGTRAP: + return common_flags()->handle_sigtrap; + case SIGFPE: + return common_flags()->handle_sigfpe; + case SIGSEGV: + return common_flags()->handle_segv; + case SIGBUS: + return common_flags()->handle_sigbus; + } + return kHandleSignalNo; +} + +void InitTlsSize() {} + +bool FileExists(const char *filename) { + struct stat st; + if (internal_stat(filename, &st)) + return false; + // Sanity check: filename is a regular file. + return S_ISREG(st.st_mode); +} + +bool DirExists(const char *path) { + struct stat st; + if (internal_stat(path, &st)) + return false; + return S_ISDIR(st.st_mode); +} + +uptr GetTlsSize() { + // FIXME: implement this interface. + return 0; +} + +SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + return SignalContext::Unknown; +} + +bool SignalContext::IsTrueFaultingAddress() const { return true; } + +void SignalContext::InitPcSpBp() { + ucontext_t *ucontext = (ucontext_t *)context; + pc = ucontext->uc_mcontext.jmp_context.iar; + sp = ucontext->uc_mcontext.jmp_context.gpr[1]; + // The powerpc{,64} ABIs do not specify r31 as the frame pointer, but compiler + // always uses r31 when we need a frame pointer. + bp = ucontext->uc_mcontext.jmp_context.gpr[31]; +} + +void SignalContext::DumpAllRegisters(void *context) {} + +char **GetEnviron() { return nullptr; } + +char **GetArgv() { return p_xargv; } + +void ListOfModules::init() { + clearOrInit(); + MemoryMappingLayout memory_mapping(false); + memory_mapping.DumpListOfModules(&modules_); +} + +void ListOfModules::fallbackInit() { clear(); } + +u64 MonotonicNanoTime() { + timespec ts; + internal_clock_gettime(CLOCK_MONOTONIC, &ts); + return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; +} + +// FIXME implement on this platform. +void GetMemoryProfile(fill_profile_f cb, uptr *stats) {} + +} // namespace __sanitizer + +#endif // SANITIZER_AIX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_aix.h b/compiler-rt/lib/sanitizer_common/sanitizer_aix.h new file mode 100644 index 0000000000000..5883d1f2e16de --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_aix.h @@ -0,0 +1,47 @@ +//===-- sanitizer_aix.h -----------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// provides definitions for AIX-specific functions. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_AIX_H +#define SANITIZER_AIX_H + +#include "sanitizer_platform.h" + +#if SANITIZER_AIX +#include "sanitizer_common.h" +# include "sanitizer_posix.h" + +namespace __sanitizer { + +#if SANITIZER_WORDSIZE == 32 +static const uptr InstructionStart = 0x10000000; +#else +static const uptr InstructionStart = 0x100000000; +#endif + +struct ProcSelfMapsBuff { + char *data; + uptr mmaped_size; + uptr len; +}; + +struct MemoryMappingLayoutData { + ProcSelfMapsBuff proc_self_maps; + const char *current; +}; + +void ReadProcMaps(ProcSelfMapsBuff *proc_maps); + +char *internal_getcwd(char *buf, uptr size); + +} // namespace __sanitizer + +#endif // SANITIZER_AIX +#endif // SANITIZER_AIX_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h index 62523c7ae187c..e5b912d70e61e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h @@ -23,7 +23,12 @@ namespace __sanitizer { typedef CompactSizeClassMap InternalSizeClassMap; struct AP32 { +// For AIX 64-bit, the mmap begin is at address 0x0a00000000000000ULL. +#if SANITIZER_AIX && SANITIZER_WORDSIZE == 64 + static const uptr kSpaceBeg = 0x0a00000000000000ULL; +#else static const uptr kSpaceBeg = 0; +#endif static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 0; typedef InternalSizeClassMap SizeClassMap; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h index 602b197c42ae3..0faf9b3c151a4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h @@ -288,6 +288,7 @@ class SizeClassAllocator32 { uptr ComputeRegionId(uptr mem) const { if (SANITIZER_SIGN_EXTENDED_ADDRESSES) mem &= (kSpaceSize - 1); + mem -= kSpaceBeg; const uptr res = mem >> kRegionSizeLog; CHECK_LT(res, kNumPossibleRegions); return res; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp index 6cd69a53093e7..3b5286bcf9be9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp @@ -275,6 +275,12 @@ const char *GetProcessName() { return process_name_cache_str; } +const char *GetBinaryName() { + if (binary_name_cache_str[0] == '\0') + ReadBinaryName(binary_name_cache_str, sizeof(binary_name_cache_str)); + return binary_name_cache_str; +} + static uptr ReadProcessName(/*out*/ char *buf, uptr buf_len) { ReadLongProcessName(buf, buf_len); char *s = const_cast(StripModuleName(buf)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index d9e7ded593feb..466790d335ac0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -290,6 +290,7 @@ uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len); uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len); uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len); const char *GetProcessName(); +const char *GetBinaryName(); void UpdateProcessName(); void CacheBinaryName(); void DisableCoreDumperIfNecessary(); @@ -835,7 +836,8 @@ class LoadedModule { max_address_(0), arch_(kModuleArchUnknown), uuid_size_(0), - instrumented_(false) { + instrumented_(false), + instr_start_(0) { internal_memset(uuid_, 0, kModuleUUIDSize); ranges_.clear(); } @@ -855,6 +857,8 @@ class LoadedModule { const u8 *uuid() const { return uuid_; } uptr uuid_size() const { return uuid_size_; } bool instrumented() const { return instrumented_; } + uptr get_instr_start() const { return instr_start_; } + void set_instr_start(uptr start) { instr_start_ = start; } struct AddressRange { AddressRange *next; @@ -885,6 +889,7 @@ class LoadedModule { uptr uuid_size_; u8 uuid_[kModuleUUIDSize]; bool instrumented_; + uptr instr_start_; IntrusiveList ranges_; }; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 24a8a2d4dc55b..a71981282f615 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -480,7 +480,7 @@ INTERCEPTOR(char*, textdomain, const char *domainname) { #define INIT_TEXTDOMAIN #endif -#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP +#if SANITIZER_INTERCEPT_MEMCMP static inline int CharCmpX(unsigned char c1, unsigned char c2) { return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; } @@ -953,7 +953,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) { #define INIT_FREXP #endif // SANITIZER_INTERCEPT_FREXP -#if SANITIZER_INTERCEPT_FREXPF_FREXPL +#if SANITIZER_INTERCEPT_FREXPF INTERCEPTOR(float, frexpf, float x, int *exp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); @@ -963,6 +963,12 @@ INTERCEPTOR(float, frexpf, float x, int *exp) { return res; } +#define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf); +#else +#define INIT_FREXPF +#endif + +#if SANITIZER_INTERCEPT_FREXPL INTERCEPTOR(long double, frexpl, long double x, int *exp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); @@ -972,12 +978,10 @@ INTERCEPTOR(long double, frexpl, long double x, int *exp) { return res; } -#define INIT_FREXPF_FREXPL \ - COMMON_INTERCEPT_FUNCTION(frexpf); \ - COMMON_INTERCEPT_FUNCTION_LDBL(frexpl) +#define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl) #else -#define INIT_FREXPF_FREXPL -#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL +#define INIT_FREXPL +#endif #if SI_POSIX static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, @@ -1346,7 +1350,8 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) { #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); -#if !SANITIZER_SOLARIS +// AIX tm struct does not have tm_zone field. +#if !SANITIZER_SOLARIS && !SANITIZER_AIX if (tm->tm_zone) { // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone // can point to shared memory and tsan would report a data race. @@ -1731,8 +1736,10 @@ INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to, VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) #endif +#if SANITIZER_INTERCEPT_VASPRINTF INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap) +#endif #if SANITIZER_INTERCEPT_ISOC99_PRINTF INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap) @@ -1783,8 +1790,10 @@ INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) #endif +#if SANITIZER_INTERCEPT_ASPRINTF INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format) +#endif #if SANITIZER_INTERCEPT_ISOC99_PRINTF INTERCEPTOR(int, __isoc99_printf, const char *format, ...) @@ -1807,17 +1816,29 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, #endif // SANITIZER_INTERCEPT_PRINTF #if SANITIZER_INTERCEPT_PRINTF +#if SANITIZER_AIX +#define INIT_PRINTF \ + COMMON_INTERCEPT_FUNCTION_LDBL(printf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf); +#else #define INIT_PRINTF \ COMMON_INTERCEPT_FUNCTION_LDBL(printf); \ COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \ - COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \ + COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \ COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf); +#endif #else #define INIT_PRINTF #endif @@ -3901,7 +3922,10 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { if (res != ((SIZE_T)-1)) { CHECK_LE(res, sizeof(local_dest)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res); - REAL(memcpy)(dest, local_dest, res); + if (!SANITIZER_AIX) + REAL(memcpy)(dest, local_dest, res); + else + internal_memcpy(dest, local_dest, res); } return res; } @@ -3923,7 +3947,10 @@ INTERCEPTOR(int, wctomb, char *dest, wchar_t src) { if (res != -1) { CHECK_LE(res, sizeof(local_dest)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res); - REAL(memcpy)(dest, local_dest, res); + if (!SANITIZER_AIX) + REAL(memcpy)(dest, local_dest, res); + else + internal_memcpy(dest, local_dest, res); } return res; } @@ -10329,7 +10356,8 @@ static void InitializeCommonInterceptors() { INIT_PRINTF_L; INIT_ISOC99_PRINTF; INIT_FREXP; - INIT_FREXPF_FREXPL; + INIT_FREXPF; + INIT_FREXPL; INIT_GETPWNAM_AND_FRIENDS; INIT_GETPWNAM_R_AND_FRIENDS; INIT_GETPWENT; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 49ec4097c900b..5b23039954a43 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -73,7 +73,9 @@ static void ioctl_table_fill() { _(TIOCNXCL, NONE, 0); _(TIOCOUTQ, WRITE, sizeof(int)); _(TIOCPKT, READ, sizeof(int)); +#if !SANITIZER_AIX _(TIOCSCTTY, NONE, 0); +#endif _(TIOCSETD, READ, sizeof(int)); _(TIOCSPGRP, READ, pid_t_sz); _(TIOCSTI, READ, sizeof(char)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc index 1565a494140f6..e542a6c7b438a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc @@ -36,6 +36,8 @@ #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 #elif SANITIZER_WINDOWS64 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 +#elif SANITIZER_AIX +#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0 #else #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1 #endif // SANITIZER_APPLE diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp index f275e81ff0416..a770c8cf656b3 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp @@ -169,7 +169,12 @@ void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name, : !MmapFixedNoReserve(beg, size, name)) { Report( "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " - "Perhaps you're using ulimit -v or ulimit -d\n", + "Perhaps you're using ulimit -v " +#if SANITIZER_AIX && SANITIZER_WORDSIZE == 32 + "or using large address-space model for 32-bit XCOFF by using ldedit " + "or setting LDR_CNTRL=MAXDATA or compiling the binary with -bmaxdata " +#endif + "\n", size); Die(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h index 46c85364cef56..cb31f02fcd88f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -29,6 +29,8 @@ # define __errno_location ___errno #elif SANITIZER_WINDOWS # define __errno_location _errno +#elif SANITIZER_AIX +# define __errno_location _Errno #endif extern "C" int *__errno_location(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp index 96af270f9d8b5..6684e54c1d510 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp @@ -203,12 +203,12 @@ bool ReadFileToVector(const char *file_name, static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':'; -char *FindPathToBinary(const char *name) { +char *FindPathToBinaryOrLibrary(const char *name, const char *env_string) { if (FileExists(name)) { return internal_strdup(name); } - const char *path = GetEnv("PATH"); + const char *path = GetEnv(env_string); if (!path) return nullptr; uptr name_len = internal_strlen(name); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.h b/compiler-rt/lib/sanitizer_common/sanitizer_file.h index bef2c842d9f24..000f437d126e5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_file.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.h @@ -79,7 +79,8 @@ bool SupportsColoredOutput(fd_t fd); const char *GetPwd(); bool FileExists(const char *filename); bool DirExists(const char *path); -char *FindPathToBinary(const char *name); +char *FindPathToBinaryOrLibrary(const char *name, + const char *env_string = "PATH"); bool IsPathSeparator(const char c); bool IsAbsolutePath(const char *path); // Returns true on success, false on failure. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index c1e3530618c20..a6c760b2387fb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -269,6 +269,9 @@ COMMON_FLAG(bool, detect_write_exec, false, COMMON_FLAG(bool, test_only_emulate_no_memorymap, false, "TEST ONLY fail to read memory mappings to emulate sanitized " "\"init\"") +COMMON_FLAG(bool, enable_unmalloced_free_check, !SANITIZER_AIX, + "if true, FreeNotMalloced error will be reported. Only disable " + "this error detecting on AIX by default for now.") // With static linking, dladdr((void*)pthread_join) or similar will return the // path to the main program. This flag will replace dlopen(
// with dlopen(NULL,...), which is the correct way to get a handle to the main diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 57966403c92a9..214d2865892df 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -14,7 +14,7 @@ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ - !(defined(__sun__) && defined(__svr4__)) + !(defined(__sun__) && defined(__svr4__)) && !defined(_AIX) # error "This operating system is not supported" #endif @@ -31,6 +31,12 @@ # define SANITIZER_LINUX 0 #endif +#if defined(_AIX) +# define SANITIZER_AIX 1 +#else +# define SANITIZER_AIX 0 +#endif + #if defined(__GLIBC__) # define SANITIZER_GLIBC 1 #else @@ -138,7 +144,7 @@ #define SANITIZER_POSIX \ (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS) + SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_AIX) #if __LP64__ || defined(_WIN64) # define SANITIZER_WORDSIZE 64 @@ -392,7 +398,9 @@ // (ie. same as double) to 128-bit long double. On those, glibc symbols // involving long doubles come in two versions, and we need to pass the // correct one to dlvsym when intercepting them. -#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1) +#if SANITIZER_LINUX && \ + (SANITIZER_S390 || (SANITIZER_PPC32 && !SANITIZER_AIX) || \ + SANITIZER_PPC64V1) # define SANITIZER_NLDBL_VERSION "GLIBC_2.4" #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index febd233bb1e3c..43a37037c971d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -139,6 +139,12 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SI_SOLARIS 0 #endif +#if SANITIZER_AIX +#define SI_NOT_AIX 0 +#else +#define SI_NOT_AIX 1 +#endif + #if SANITIZER_SOLARIS32 #define SI_SOLARIS32 1 #else @@ -159,20 +165,20 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_STRLEN SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRNLEN (SI_NOT_MAC && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_STRCMP SI_NOT_FUCHSIA +#define SANITIZER_INTERCEPT_STRCMP (SI_NOT_FUCHSIA && SI_NOT_AIX) #define SANITIZER_INTERCEPT_STRSTR SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_STRCASESTR SI_POSIX +#define SANITIZER_INTERCEPT_STRCASESTR (SI_POSIX && SI_NOT_AIX) #define SANITIZER_INTERCEPT_STRTOK SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRCHR SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_STRCHRNUL SI_POSIX_NOT_MAC +#define SANITIZER_INTERCEPT_STRCHRNUL (SI_POSIX_NOT_MAC && SI_NOT_AIX) #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX #define SANITIZER_INTERCEPT_MEMSET 1 -#define SANITIZER_INTERCEPT_MEMMOVE 1 -#define SANITIZER_INTERCEPT_MEMCPY 1 +#define SANITIZER_INTERCEPT_MEMMOVE SI_NOT_AIX +#define SANITIZER_INTERCEPT_MEMCPY SI_NOT_AIX #define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_BCMP \ SANITIZER_INTERCEPT_MEMCMP && \ @@ -231,6 +237,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_ISOC99_SCANF SI_GLIBC #ifndef SANITIZER_INTERCEPT_PRINTF +#define SANITIZER_INTERCEPT_ASPRINTF SI_NOT_AIX +#define SANITIZER_INTERCEPT_VASPRINTF SI_NOT_AIX #define SANITIZER_INTERCEPT_PRINTF SI_POSIX #define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD) #define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_GLIBC @@ -239,8 +247,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT___PRINTF_CHK \ (SANITIZER_INTERCEPT_PRINTF && SI_GLIBC) -#define SANITIZER_INTERCEPT_FREXP SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX +// AIX libc does not export FREXP and FREXP. +#define SANITIZER_INTERCEPT_FREXP (SI_NOT_FUCHSIA && SI_NOT_AIX) +#define SANITIZER_INTERCEPT_FREXPF (SI_POSIX && SI_NOT_AIX) +#define SANITIZER_INTERCEPT_FREXPL SI_POSIX #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX #define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \ @@ -289,7 +299,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_ACCEPT4 \ (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD -#define SANITIZER_INTERCEPT_MODF SI_POSIX +#define SANITIZER_INTERCEPT_MODF (SI_POSIX && SI_NOT_AIX) #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX #define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX @@ -324,8 +334,9 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX #define SANITIZER_INTERCEPT_WCSNRTOMBS \ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) -#define SANITIZER_INTERCEPT_WCRTOMB \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_WCRTOMB \ + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS || \ + !SI_NOT_AIX) #define SANITIZER_INTERCEPT_WCTOMB \ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS @@ -365,7 +376,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATFS \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) -#define SANITIZER_INTERCEPT_STATFS64 SI_GLIBC && SANITIZER_HAS_STATFS64 +#define SANITIZER_INTERCEPT_STATFS64 \ + ((SI_GLIBC || !SI_NOT_AIX) && SANITIZER_HAS_STATFS64) #define SANITIZER_INTERCEPT_STATVFS \ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS64 SI_GLIBC @@ -414,10 +426,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX #define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS -#define SANITIZER_INTERCEPT_REMQUO SI_POSIX -#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD) -#define SANITIZER_INTERCEPT_LGAMMA SI_POSIX -#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD) +#define SANITIZER_INTERCEPT_REMQUO (SI_POSIX && SI_NOT_AIX) +#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX) +#define SANITIZER_INTERCEPT_LGAMMA (SI_POSIX && SI_NOT_AIX) +#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX) #define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_DRAND48_R SI_GLIBC @@ -502,9 +514,11 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33)) #define SANITIZER_INTERCEPT_STAT \ (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS || \ - SI_STAT_LINUX) -#define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64 -#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX) + SI_STAT_LINUX || !SI_NOT_AIX) +#define SANITIZER_INTERCEPT_STAT64 \ + ((SI_STAT_LINUX || !SI_NOT_AIX) && SANITIZER_HAS_STAT64) +#define SANITIZER_INTERCEPT_LSTAT \ + (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX || !SI_NOT_AIX) #define SANITIZER_INTERCEPT___XSTAT \ ((!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX) #define SANITIZER_INTERCEPT___XSTAT64 SI_GLIBC @@ -572,7 +586,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment, #define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC #define SANITIZER_INTERCEPT_NETENT (SI_LINUX || SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_SETVBUF \ - (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC) + (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC || !SI_NOT_AIX) #define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC) #define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD #define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index a5311d266b0c4..09a2fce1d856e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -24,7 +24,7 @@ // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_APPLE +#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_AIX // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_glibc_version.h" @@ -61,7 +61,9 @@ #endif #if !SANITIZER_ANDROID +#if !SANITIZER_AIX #include +#endif #include #include #endif @@ -110,7 +112,11 @@ typedef struct user_fpregs elf_fpregset_t; #endif #if !SANITIZER_ANDROID +#if !SANITIZER_AIX #include +#else +#include +#endif #include #include #endif @@ -173,6 +179,17 @@ typedef struct user_fpregs elf_fpregset_t; #include #endif +#if SANITIZER_AIX +#include +#include +#include +#include +#include +#if HAVE_RPC_XDR_H +#include +#endif +#endif + // Include these after system headers to avoid name clashes and ambiguities. # include "sanitizer_common.h" # include "sanitizer_internal_defs.h" @@ -551,12 +568,39 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); const unsigned IOCTL_NOT_PRESENT = 0; + // On AIX, some variables are unsigned long types. +#if SANITIZER_AIX + uptr IOCTL_FIOASYNC = FIOASYNC; + uptr IOCTL_FIONBIO = FIONBIO; + uptr IOCTL_FIOSETOWN = FIOSETOWN; + uptr IOCTL_SIOCSPGRP = SIOCSPGRP; + uptr IOCTL_TIOCCONS = TIOCCONS; + uptr IOCTL_TIOCMBIC = TIOCMBIC; + uptr IOCTL_TIOCMBIS = TIOCMBIS; + uptr IOCTL_TIOCMSET = TIOCMSET; + uptr IOCTL_TIOCPKT = TIOCPKT; + uptr IOCTL_TIOCSETD = TIOCSETD; + uptr IOCTL_TIOCSPGRP = TIOCSPGRP; + uptr IOCTL_TIOCSTI = TIOCSTI; + uptr IOCTL_TIOCSWINSZ = TIOCSWINSZ; +#else unsigned IOCTL_FIOASYNC = FIOASYNC; + unsigned IOCTL_FIONBIO = FIONBIO; + unsigned IOCTL_FIOSETOWN = FIOSETOWN; + unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; + unsigned IOCTL_TIOCCONS = TIOCCONS; + unsigned IOCTL_TIOCMBIC = TIOCMBIC; + unsigned IOCTL_TIOCMBIS = TIOCMBIS; + unsigned IOCTL_TIOCMSET = TIOCMSET; + unsigned IOCTL_TIOCPKT = TIOCPKT; + unsigned IOCTL_TIOCSETD = TIOCSETD; + unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; + unsigned IOCTL_TIOCSTI = TIOCSTI; + unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; +#endif unsigned IOCTL_FIOCLEX = FIOCLEX; unsigned IOCTL_FIOGETOWN = FIOGETOWN; - unsigned IOCTL_FIONBIO = FIONBIO; unsigned IOCTL_FIONCLEX = FIONCLEX; - unsigned IOCTL_FIOSETOWN = FIOSETOWN; unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI; unsigned IOCTL_SIOCATMARK = SIOCATMARK; unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI; @@ -576,25 +620,17 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC; unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU; unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK; - unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; - unsigned IOCTL_TIOCCONS = TIOCCONS; unsigned IOCTL_TIOCEXCL = TIOCEXCL; unsigned IOCTL_TIOCGETD = TIOCGETD; unsigned IOCTL_TIOCGPGRP = TIOCGPGRP; unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ; - unsigned IOCTL_TIOCMBIC = TIOCMBIC; - unsigned IOCTL_TIOCMBIS = TIOCMBIS; unsigned IOCTL_TIOCMGET = TIOCMGET; - unsigned IOCTL_TIOCMSET = TIOCMSET; unsigned IOCTL_TIOCNOTTY = TIOCNOTTY; unsigned IOCTL_TIOCNXCL = TIOCNXCL; unsigned IOCTL_TIOCOUTQ = TIOCOUTQ; - unsigned IOCTL_TIOCPKT = TIOCPKT; +#if !SANITIZER_AIX unsigned IOCTL_TIOCSCTTY = TIOCSCTTY; - unsigned IOCTL_TIOCSETD = TIOCSETD; - unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; - unsigned IOCTL_TIOCSTI = TIOCSTI; - unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; +#endif #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; @@ -1103,6 +1139,8 @@ COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); CHECK_SIZE_AND_OFFSET(dirent, d_ino); #if SANITIZER_APPLE CHECK_SIZE_AND_OFFSET(dirent, d_seekoff); +#elif SANITIZER_AIX +CHECK_SIZE_AND_OFFSET(dirent, d_offset); #elif SANITIZER_FREEBSD // There is no 'd_off' field on FreeBSD. #else @@ -1191,8 +1229,10 @@ CHECK_SIZE_AND_OFFSET(tm, tm_year); CHECK_SIZE_AND_OFFSET(tm, tm_wday); CHECK_SIZE_AND_OFFSET(tm, tm_yday); CHECK_SIZE_AND_OFFSET(tm, tm_isdst); +#if !SANITIZER_AIX CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); CHECK_SIZE_AND_OFFSET(tm, tm_zone); +#endif #if SANITIZER_LINUX CHECK_TYPE_SIZE(mntent); @@ -1242,7 +1282,7 @@ CHECK_TYPE_SIZE(clock_t); CHECK_TYPE_SIZE(clockid_t); #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_AIX CHECK_TYPE_SIZE(ifaddrs); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 1a7d9e64048eb..4f5022a75d3cc 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -14,7 +14,7 @@ #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H #define SANITIZER_PLATFORM_LIMITS_POSIX_H -#if SANITIZER_LINUX || SANITIZER_APPLE +#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_AIX #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" @@ -29,7 +29,7 @@ #define SANITIZER_HAS_STAT64 0 #define SANITIZER_HAS_STATFS64 0 #endif -#elif SANITIZER_GLIBC || SANITIZER_ANDROID +#elif SANITIZER_GLIBC || SANITIZER_ANDROID || SANITIZER_AIX #define SANITIZER_HAS_STAT64 1 #define SANITIZER_HAS_STATFS64 1 #endif @@ -319,7 +319,7 @@ struct __sanitizer_iovec { usize iov_len; }; -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_AIX struct __sanitizer_ifaddrs { struct __sanitizer_ifaddrs *ifa_next; char *ifa_name; @@ -341,7 +341,7 @@ typedef unsigned long __sanitizer_pthread_key_t; typedef unsigned __sanitizer_pthread_key_t; #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_AIX struct __sanitizer_XDR { int x_op; @@ -433,8 +433,10 @@ struct __sanitizer_tm { int tm_wday; int tm_yday; int tm_isdst; +#if !SANITIZER_AIX long int tm_gmtoff; const char *tm_zone; +#endif }; #if SANITIZER_LINUX @@ -478,11 +480,19 @@ struct __sanitizer_msghdr { struct __sanitizer_iovec *msg_iov; uptr msg_iovlen; void *msg_control; +#if !SANITIZER_AIX uptr msg_controllen; +#else + unsigned msg_controllen; +#endif int msg_flags; }; struct __sanitizer_cmsghdr { +#if !SANITIZER_AIX uptr cmsg_len; +#else + unsigned cmsg_len; +#endif int cmsg_level; int cmsg_type; }; @@ -512,8 +522,13 @@ struct __sanitizer_dirent { }; # else struct __sanitizer_dirent { +#if SANITIZER_AIX + uptr d_offset; + uptr d_ino; +#else uptr d_ino; uptr d_off; +#endif unsigned short d_reclen; // more fields that we don't care about }; @@ -529,7 +544,10 @@ struct __sanitizer_dirent64 { extern unsigned struct_sock_fprog_sz; #endif -#if defined(__x86_64__) && !defined(_LP64) +#if SANITIZER_AIX +typedef int __sanitizer_clock_t; +typedef int __sanitizer_clockid_t; +#elif defined(__x86_64__) && !defined(_LP64) typedef long long __sanitizer_clock_t; #else typedef long __sanitizer_clock_t; @@ -589,6 +607,14 @@ struct __sanitizer_sigset_t { // The size is determined by looking at sizeof of real sigset_t on linux. uptr val[128 / sizeof(uptr)]; }; +#elif SANITIZER_AIX +struct __sanitizer_sigset_t { +#if SANITIZER_WORDSIZE == 64 + uptr val[4]; +#else + uptr val[2]; +#endif +}; #endif struct __sanitizer_siginfo_pad { @@ -779,8 +805,12 @@ struct __sanitizer_addrinfo { int ai_family; int ai_socktype; int ai_protocol; -#if SANITIZER_ANDROID || SANITIZER_APPLE +#if SANITIZER_ANDROID || SANITIZER_APPLE || SANITIZER_AIX +#if SANITIZER_AIX // AIX ai_addrlen type is size_t + uptr ai_addrlen; +#else unsigned ai_addrlen; +#endif char *ai_canonname; void *ai_addr; #else // LINUX @@ -789,6 +819,9 @@ struct __sanitizer_addrinfo { char *ai_canonname; #endif struct __sanitizer_addrinfo *ai_next; +#if SANITIZER_AIX + int ai_eflags; +#endif }; struct __sanitizer_hostent { @@ -805,7 +838,7 @@ struct __sanitizer_pollfd { short revents; }; -#if SANITIZER_ANDROID || SANITIZER_APPLE +#if SANITIZER_ANDROID || SANITIZER_APPLE || SANITIZER_AIX typedef unsigned __sanitizer_nfds_t; #else typedef unsigned long __sanitizer_nfds_t; @@ -843,6 +876,10 @@ struct __sanitizer_wordexp_t { uptr we_wordc; char **we_wordv; uptr we_offs; +#if SANITIZER_AIX + int we_sflags; + uptr we_soffs; +#endif }; #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -1102,12 +1139,39 @@ extern unsigned fpos_t_sz; // when it can not be determined without including any system headers. extern const unsigned IOCTL_NOT_PRESENT; +#if SANITIZER_AIX +extern uptr IOCTL_FIOASYNC; +extern uptr IOCTL_FIONBIO; +extern uptr IOCTL_FIOSETOWN; +extern uptr IOCTL_SIOCSPGRP; +extern uptr IOCTL_TIOCCONS; +extern uptr IOCTL_TIOCMBIC; +extern uptr IOCTL_TIOCMBIS; +extern uptr IOCTL_TIOCMSET; +extern uptr IOCTL_TIOCPKT; +extern uptr IOCTL_TIOCSETD; +extern uptr IOCTL_TIOCSPGRP; +extern uptr IOCTL_TIOCSTI; +extern uptr IOCTL_TIOCSWINSZ; +#else extern unsigned IOCTL_FIOASYNC; +extern unsigned IOCTL_FIONBIO; +extern unsigned IOCTL_FIOSETOWN; +extern unsigned IOCTL_SIOCSPGRP; +extern unsigned IOCTL_TIOCCONS; +extern unsigned IOCTL_TIOCMBIC; +extern unsigned IOCTL_TIOCMBIS; +extern unsigned IOCTL_TIOCMSET; +extern unsigned IOCTL_TIOCPKT; +extern unsigned IOCTL_TIOCSETD; +extern unsigned IOCTL_TIOCSPGRP; +extern unsigned IOCTL_TIOCSTI; +extern unsigned IOCTL_TIOCSWINSZ; +#endif + extern unsigned IOCTL_FIOCLEX; extern unsigned IOCTL_FIOGETOWN; -extern unsigned IOCTL_FIONBIO; extern unsigned IOCTL_FIONCLEX; -extern unsigned IOCTL_FIOSETOWN; extern unsigned IOCTL_SIOCADDMULTI; extern unsigned IOCTL_SIOCATMARK; extern unsigned IOCTL_SIOCDELMULTI; @@ -1127,25 +1191,17 @@ extern unsigned IOCTL_SIOCSIFFLAGS; extern unsigned IOCTL_SIOCSIFMETRIC; extern unsigned IOCTL_SIOCSIFMTU; extern unsigned IOCTL_SIOCSIFNETMASK; -extern unsigned IOCTL_SIOCSPGRP; -extern unsigned IOCTL_TIOCCONS; extern unsigned IOCTL_TIOCEXCL; extern unsigned IOCTL_TIOCGETD; extern unsigned IOCTL_TIOCGPGRP; extern unsigned IOCTL_TIOCGWINSZ; -extern unsigned IOCTL_TIOCMBIC; -extern unsigned IOCTL_TIOCMBIS; extern unsigned IOCTL_TIOCMGET; -extern unsigned IOCTL_TIOCMSET; extern unsigned IOCTL_TIOCNOTTY; extern unsigned IOCTL_TIOCNXCL; extern unsigned IOCTL_TIOCOUTQ; -extern unsigned IOCTL_TIOCPKT; +#if !SANITIZER_AIX extern unsigned IOCTL_TIOCSCTTY; -extern unsigned IOCTL_TIOCSETD; -extern unsigned IOCTL_TIOCSPGRP; -extern unsigned IOCTL_TIOCSTI; -extern unsigned IOCTL_TIOCSWINSZ; +#endif #if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned IOCTL_SIOCGETSGCNT; extern unsigned IOCTL_SIOCGETVIFCNT; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp index 69af6465a62c2..44c40036babb2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -27,7 +27,7 @@ #include #include -#if SANITIZER_FREEBSD +#if SANITIZER_FREEBSD || SANITIZER_AIX // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before // that, it was never implemented. So just define it to zero. #undef MAP_NORESERVE diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h index b5491c540dc08..da9cd92357145 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h @@ -33,6 +33,11 @@ uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags); # endif uptr internal_close(fd_t fd); +#if SANITIZER_AIX +__sanitizer_FILE* internal_popen(const char *command, const char *type); +int internal_pclose(__sanitizer_FILE* file); +#endif + uptr internal_read(fd_t fd, void *buf, uptr count); uptr internal_write(fd_t fd, const void *buf, uptr count); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index b1eb2009cf157..307d8c969a338 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -36,7 +36,7 @@ #include #include -#if SANITIZER_FREEBSD +#if SANITIZER_FREEBSD || SANITIZER_AIX // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before // that, it was never implemented. So just define it to zero. #undef MAP_NORESERVE @@ -416,8 +416,19 @@ bool MmapFixedSuperNoReserve(uptr fixed_addr, uptr size, const char *name) { } uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { + // AIX can not mmap on a mmaped memory, so init it as read/write so we won't + // mmap on this memory again. +# if SANITIZER_AIX + if (fixed_addr) { + MmapFixed(fixed_addr, size, MAP_PRIVATE | MAP_FIXED | MAP_ANON, name); + base_ = (void *)fixed_addr; + } else + base_ = (void *)internal_mmap(nullptr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); +# else base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size, name) : MmapNoAccess(size); +# endif size_ = size; name_ = name; (void)os_handle_; // unsupported @@ -427,13 +438,21 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { // Uses fixed_addr for now. // Will use offset instead once we've implemented this function for real. uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, const char *name) { +#if SANITIZER_AIX + return fixed_addr; +#else return reinterpret_cast( MmapFixedOrDieOnFatalError(fixed_addr, size, name)); +#endif } uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size, const char *name) { +#if SANITIZER_AIX + return fixed_addr; +#else return reinterpret_cast(MmapFixedOrDie(fixed_addr, size, name)); +#endif } void ReservedAddressRange::Unmap(uptr addr, uptr size) { @@ -465,11 +484,15 @@ real_pthread_attr_getstack(void *attr, void **addr, size_t *size); } // extern "C" int internal_pthread_attr_getstack(void *attr, void **addr, uptr *size) { -#if !SANITIZER_GO && !SANITIZER_APPLE +// AIX requires definition for weak symbols. real_pthread_attr_getstack defined +// in asan library which is not linked while compile with -fsanitize=undefined. +// So don't use use real_pthread_attr_getstack on AIX either in this sanitizer +// common file. +# if !SANITIZER_GO && !SANITIZER_APPLE && !SANITIZER_AIX if (&real_pthread_attr_getstack) return real_pthread_attr_getstack((pthread_attr_t *)attr, addr, (size_t *)size); -#endif +# endif return pthread_attr_getstack((pthread_attr_t *)attr, addr, (size_t *)size); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h index bf3c2c28e32e3..8e5162f40a55b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h @@ -17,7 +17,7 @@ #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ SANITIZER_APPLE || SANITIZER_SOLARIS || \ - SANITIZER_FUCHSIA + SANITIZER_FUCHSIA || SANITIZER_AIX #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" @@ -25,6 +25,7 @@ #include "sanitizer_linux.h" #include "sanitizer_mac.h" #include "sanitizer_mutex.h" +#include "sanitizer_aix.h" namespace __sanitizer { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp new file mode 100644 index 0000000000000..852aba2f169b8 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp @@ -0,0 +1,212 @@ +//===-- sanitizer_procmaps_aix.cpp ----------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Information about the process mappings (AIX-specific parts). +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_AIX +# include + +# include "sanitizer_common.h" +# include "sanitizer_procmaps.h" +# include "sanitizer_file.h" + +namespace __sanitizer { + +static bool IsOneOf(char c, char c1, char c2) { return c == c1 || c == c2; } + +void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { + uptr pid = internal_getpid(); + + // The mapping in /proc/id/map is not ordered by address, this will hit some + // issue when checking stack base and size. Howevern AIX procmap can generate + // sorted ranges. + char Command[100] = {}; + + internal_snprintf(Command, 100, "procmap -qX %d", pid); + // Open pipe to file + __sanitizer_FILE *pipe = internal_popen(Command, "r"); + + if (!pipe) { + proc_maps->data = nullptr; + proc_maps->mmaped_size = 0; + proc_maps->len = 0; + return; + } + + char buffer[512] = {}; + + InternalScopedString Data; + while (fgets(buffer, 512, reinterpret_cast(pipe)) != nullptr) + Data.Append(buffer); + + size_t MmapedSize = Data.length() * 4 / 3; + void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()"); + internal_memcpy(VmMap, Data.data(), Data.length()); + + proc_maps->data = (char *)VmMap; + proc_maps->mmaped_size = MmapedSize; + proc_maps->len = Data.length(); + + internal_pclose(pipe); +} + +bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + if (Error()) + return false; // simulate empty maps + char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; + if (data_.current >= last) + return false; + char *next_line = + (char *)internal_memchr(data_.current, '\n', last - data_.current); + + // Skip the first header line and the second kernel line + // pid : binary name + if (data_.current == data_.proc_self_maps.data) { + data_.current = next_line + 1; + next_line = + (char *)internal_memchr(next_line + 1, '\n', last - data_.current); + + data_.current = next_line + 1; + next_line = + (char *)internal_memchr(next_line + 1, '\n', last - data_.current); + } + + if (next_line == 0) + next_line = last; + + // Skip the last line: + // Total 533562K + if (!IsHex(*data_.current)) + return false; + + // Example: 10000000 10161fd9 1415K r-x s MAINTEXT 151ed82 a.out + segment->start = ParseHex(&data_.current); + while (data_.current < next_line && *data_.current == ' ') data_.current++; + + segment->end = ParseHex(&data_.current); + while (data_.current < next_line && *data_.current == ' ') data_.current++; + + // Ignore the size, we can get accurate size from end and start + while (IsDecimal(*data_.current)) data_.current++; + CHECK_EQ(*data_.current++, 'K'); + + while (data_.current < next_line && *data_.current == ' ') data_.current++; + segment->protection = 0; + + if (*data_.current++ == 'r') + segment->protection |= kProtectionRead; + CHECK(IsOneOf(*data_.current, '-', 'w')); + if (*data_.current++ == 'w') + segment->protection |= kProtectionWrite; + CHECK(IsOneOf(*data_.current, '-', 'x')); + if (*data_.current++ == 'x') + segment->protection |= kProtectionExecute; + + // Ignore the PSIZE(s/m/L/H) + while (data_.current < next_line && *data_.current == ' ') data_.current++; + data_.current += 4; + + // Get the region TYPE + while (data_.current < next_line && *data_.current == ' ') data_.current++; + char Type[16] = {}; + uptr len = 0; + while (*data_.current != ' ') Type[len++] = *data_.current++; + Type[len] = 0; + + if (!internal_strcmp(Type, "SLIBTEXT") || !internal_strcmp(Type, "PLIBDATA")) + segment->protection |= kProtectionShared; + + // Ignore the VSID + while (data_.current < next_line && *data_.current == ' ') data_.current++; + ParseHex(&data_.current); + + while (data_.current < next_line && *data_.current == ' ') data_.current++; + + if (segment->filename && data_.current != next_line) { + if (!internal_strcmp(Type, "MAINDATA") || + !internal_strcmp(Type, "MAINTEXT")) { + // AIX procmap does not print full name for the binary, however when using + // llvm-symbolizer, it requires the binary must be with full name. + const char *BinaryName = GetBinaryName(); + uptr len = + Min((uptr)(internal_strlen(BinaryName)), segment->filename_size - 1); + internal_strncpy(segment->filename, BinaryName, len); + segment->filename[len] = 0; + } else { + // AIX library may exist as xxx.a[yyy.o], to find the path to xxx.a, + // the [yyy.o] part needs to be removed. + char *NameEnd = (char *)internal_memchr(data_.current, '[', + next_line - data_.current); + if (!NameEnd) + NameEnd = next_line - 1; + + uptr len = Min((uptr)(NameEnd - data_.current), + segment->filename_size - 1); + internal_strncpy(segment->filename, data_.current, len); + segment->filename[len] = 0; + + // AIX procmap does not print full name for user's library , however when + // use llvm-symbolizer, it requires the library must be with full name. + if ((!internal_strcmp(Type, "SLIBTEXT") || + !internal_strcmp(Type, "PLIBDATA")) && + segment->filename[0] != '/') { + // First check if the library is in the directory where the binary is + // executed. On AIX, there is no need to put library in same dir with + // the binary to path search envs. + char *path = nullptr; + char buf[kMaxPathLength]; + unsigned buf_len = kMaxPathLength; + bool found = false; + if ((path = internal_getcwd(buf, buf_len)) != nullptr) { + // if the path is too long, don't do other search either. + if (internal_strlen(path) > segment->filename_size - 1) + found = true; + else { + internal_snprintf( + buf + internal_strlen(path), + segment->filename_size - 1 - internal_strlen(path), "/%s", + segment->filename); + if (FileExists(buf)) { + uptr len = + Min((uptr)(internal_strlen(buf)), segment->filename_size - 1); + internal_strncpy(segment->filename, buf, len); + segment->filename[len] = 0; + found = true; + } + } + } + if (!found) { + const char *LibName = + FindPathToBinaryOrLibrary(segment->filename, "LIBPATH"); + CHECK(LibName); + uptr len = + Min((uptr)(internal_strlen(LibName)), segment->filename_size - 1); + internal_strncpy(segment->filename, LibName, len); + segment->filename[len] = 0; + found = true; + } + CHECK(found); + } + } + } else if (segment->filename) { + segment->filename[0] = 0; + } + + segment->offset = 0; + + data_.current = next_line + 1; + + return true; +} + +} // namespace __sanitizer + +#endif // SANITIZER_AIX diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp index 7214a2b9ea468..4089420c8f63e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp @@ -12,7 +12,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_AIX #include "sanitizer_common.h" #include "sanitizer_placement_new.h" @@ -140,6 +140,11 @@ void MemoryMappingLayout::DumpListOfModules( uptr base_address = (i ? segment.start : 0) - segment.offset; LoadedModule cur_module; cur_module.set(cur_name, base_address); +#if SANITIZER_AIX + // Instructions in AIX shared libraries don't start 0x0. + if (segment.IsShared() && segment.IsExecutable()) + cur_module.set_instr_start(InstructionStart); +#endif segment.AddAddressRanges(&cur_module); modules->push_back(cur_module); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h index 41e0613d6fc13..bda0f04687693 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h @@ -15,7 +15,7 @@ # define SANITIZER_REDEFINE_BUILTINS_H // The asm hack only works with GCC and Clang. -# if !defined(_WIN32) +# if !defined(_WIN32) && !defined(_AIX) asm(R"( .set memcpy, __sanitizer_internal_memcpy diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp index d24fae98213aa..824fa3ead5b81 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -111,13 +111,14 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, IsAligned((uptr)frame, sizeof(*frame)) && size < max_depth) { #ifdef __powerpc__ - // PowerPC ABIs specify that the return address is saved at offset - // 16 of the *caller's* stack frame. Thus we must dereference the - // back chain to find the caller frame before extracting it. uhwptr *caller_frame = (uhwptr*)frame[0]; if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) || !IsAligned((uptr)caller_frame, sizeof(uhwptr))) break; + // PowerPC ABIs(64-bit LE, 64-bit AIX, 32-bit AIX) specify that the return + // address is saved at offsettwo ptr size(16 for 64-bit, 8 for 32-bit) of + // the *caller's* stack frame. Thus we must dereference the back chain to + // find the caller frame before extracting it. uhwptr pc1 = caller_frame[2]; #elif defined(__s390__) uhwptr pc1 = frame[14]; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp index 519f768f89694..3370feb7f17c6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp @@ -46,7 +46,10 @@ void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset, void AddressInfo::FillModuleInfo(const LoadedModule &mod) { module = internal_strdup(mod.full_name()); - module_offset = address - mod.base_address(); + // On some platforms, like on AIX, the first instructions does not start from + // 0x0, we need to addd the start back to get correct instruction offset in + // the objects. + module_offset = address - mod.base_address() + mod.get_instr_start(); module_arch = mod.arch(); if (mod.uuid_size()) internal_memcpy(uuid, mod.uuid(), mod.uuid_size()); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp index 74458028ae8f5..9695f9a408ce2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -179,7 +179,13 @@ bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address, if (!module) return false; *module_name = module->full_name(); + // On AIX, the address for the data in the object is the same with the runtime one. + // So, we don't need to sub the base address. +#if SANITIZER_AIX + *module_offset = address; +#else *module_offset = address - module->base_address(); +#endif *module_arch = module->arch(); return true; } @@ -274,6 +280,8 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess { const char* const kSymbolizerArch = "--default-arch=arm64"; #elif defined(__arm__) const char* const kSymbolizerArch = "--default-arch=arm"; +#elif defined(__powerpc__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + const char* const kSymbolizerArch = "--default-arch=powerpc"; #elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ const char* const kSymbolizerArch = "--default-arch=powerpc64"; #elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -468,7 +476,6 @@ const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix, Report("WARNING: Command buffer too small"); return nullptr; } - return symbolizer_process_->SendCommand(buffer_); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index 0ddc24802d216..f5858860c5aa5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -38,9 +38,35 @@ // because we do not require a C++ ABI library to be linked to a program // using sanitizers; if it's not present, we'll just use the mangled name. namespace __cxxabiv1 { +// `weak` attribute without definition on AIX will cause linking time undefined +// symbol error, we use dlopen/dlsym here to find related symbol. +# if SANITIZER_AIX +typedef char *__cxa_demangle_t(const char *mangled, char *buffer, + size_t *length, int *status); + +char *__cxa_demangle(const char *mangled, char *buffer, size_t *length, + int *status) { + // Use NULL as the module name, so if the libc++abi module is linked into the + // main executable, we are able to find the __cxa_demangle symbol and this + // impelemtation will not force libc++abi to be loaded to the executable. + void *Handler = dlopen(0, RTLD_NOW); + if (!Handler) { + return nullptr; + } + + auto FooPtr = + reinterpret_cast<__cxa_demangle_t *>(dlsym(Handler, "__cxa_demangle")); + if (!FooPtr) { + return nullptr; + } + + return FooPtr(mangled, buffer, length, status); +} +# else extern "C" SANITIZER_WEAK_ATTRIBUTE char *__cxa_demangle(const char *mangled, char *buffer, size_t *length, int *status); +# endif } namespace __sanitizer { @@ -445,17 +471,17 @@ static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) { // Otherwise symbolizer program is unknown, let's search $PATH CHECK(path == nullptr); #if SANITIZER_APPLE - if (const char *found_path = FindPathToBinary("atos")) { + if (const char *found_path = FindPathToBinaryOrLibrary("atos")) { VReport(2, "Using atos found at: %s\n", found_path); return new(*allocator) AtosSymbolizer(found_path, allocator); } #endif // SANITIZER_APPLE - if (const char *found_path = FindPathToBinary("llvm-symbolizer")) { + if (const char *found_path = FindPathToBinaryOrLibrary("llvm-symbolizer")) { VReport(2, "Using llvm-symbolizer found at: %s\n", found_path); return new(*allocator) LLVMSymbolizer(found_path, allocator); } if (common_flags()->allow_addr2line) { - if (const char *found_path = FindPathToBinary("addr2line")) { + if (const char *found_path = FindPathToBinaryOrLibrary("addr2line")) { VReport(2, "Using addr2line found at: %s\n", found_path); return new(*allocator) Addr2LinePool(found_path, allocator); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp index 1ff8b8f1bab48..531632c65fa6b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp @@ -289,7 +289,7 @@ static void ChooseSymbolizerTools(IntrusiveList *list, } const char *path = - user_path ? user_path : FindPathToBinary("llvm-symbolizer.exe"); + user_path ? user_path : FindPathToBinaryOrLibrary("llvm-symbolizer.exe"); if (path) { if (user_path && user_path[0] == '\0') { VReport(2, "External symbolizer is explicitly disabled.\n"); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp new file mode 100644 index 0000000000000..45b4b1f3d5c9d --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp @@ -0,0 +1,66 @@ +//===-- sanitizer_unwind_aix.cpp ------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This file contains the unwind.h-based (aka "slow") stack unwinding routines +// available to the tools on AIX. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_AIX +# include + +# include "sanitizer_common.h" +# include "sanitizer_stacktrace.h" + +namespace __sanitizer { + +struct UnwindTraceArg { + BufferedStackTrace *stack; + u32 max_depth; +}; + +_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { + UnwindTraceArg *arg = (UnwindTraceArg *)param; + CHECK_LT(arg->stack->size, arg->max_depth); + uptr pc = _Unwind_GetIP(ctx); + // On AIX 32-bit and 64-bit, address smaller than 0x0fffffff is for kernel. + if (pc <= 0x0fffffff) + return _URC_NORMAL_STOP; + arg->stack->trace_buffer[arg->stack->size++] = pc; + if (arg->stack->size == arg->max_depth) + return _URC_NORMAL_STOP; + return _URC_NO_REASON; +} + +void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { + CHECK_GE(max_depth, 2); + size = 0; + UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; + _Unwind_Backtrace(Unwind_Trace, &arg); + // We need to pop a few frames so that pc is on top. + uptr to_pop = LocatePcInTrace(pc); + // trace_buffer[0] belongs to the current function so we always pop it, + // unless there is only 1 frame in the stack trace (1 frame is always better + // than 0!). + // 1-frame stacks don't normally happen, but this depends on the actual + // unwinder implementation (libgcc, libunwind, etc) which is outside of our + // control. + if (to_pop == 0 && size > 1) + to_pop = 1; + + PopStackFrames(to_pop); + trace_buffer[0] = pc; +} + +void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { + UnwindSlow(pc, max_depth); +} +} // namespace __sanitizer + +#endif // SANITIZER_AIX diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt index fef8bb772e0e0..231a95c21d8fb 100644 --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -100,6 +100,10 @@ if(NOT MSVC) list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++) endif() +if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") + list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -latomic) +endif() + if(ANDROID) list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -pie) endif() diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h b/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h index 5fd94a0281391..245164caa8a8f 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h @@ -101,7 +101,7 @@ static inline uint32_t my_rand() { #endif #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__ANDROID__) && \ - !defined(__NetBSD__) && !defined(_WIN32) + !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) # define SANITIZER_TEST_HAS_MEMALIGN 1 #else # define SANITIZER_TEST_HAS_MEMALIGN 0 diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt index 414a6cc9496ed..9a8283f68d07e 100644 --- a/compiler-rt/test/asan/CMakeLists.txt +++ b/compiler-rt/test/asan/CMakeLists.txt @@ -16,7 +16,7 @@ endif() macro(get_bits_for_arch arch bits) if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64|loongarch64") set(${bits} 64) - elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc") + elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc|powerpc") set(${bits} 32) else() message(FATAL_ERROR "Unknown target architecture: ${arch}") diff --git a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp index c53a932a2e9ed..51a7887e16ff6 100644 --- a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp @@ -11,6 +11,10 @@ // CHECK-BAD-ADDR: #0 0xabcdabcd // CHECK-BAD-ADDR-EMPTY: +// AIX does not have a system symbolizer which will return result like expected. +// llvm-symbolizer will not generate expected result either, an error will be emitted indicating "No such file or directory". +// UNSUPPORTED: target={{.*aix.*}} + int main() { return 0; } diff --git a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp index 5d3e7a767e45a..07a3b268846b3 100644 --- a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp @@ -38,11 +38,11 @@ int main(int argc, char *argv[]) { inc2(array, -1); // BOOM // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow // CHECK: READ of size 4 at 0x{{.*}} - // CHECK: #0 {{.*}} in inc2 {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE+21]] - // CHECK: #1 {{.*}} in main {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-4]] + // CHECK: #0 {{.*}} in {{inc2|.inc2}} {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE+21]] + // CHECK: #1 {{.*}} in {{main|.main}} {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-4]] // CHECK: allocated by thread T{{.*}} here: - // CHECK: #{{.*}} in {{(wrap_|_?__interceptor_)?}}malloc - // CHECK: #{{.*}} in main {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-9]] + // CHECK: #{{.*}} in {{(wrap_|_?__interceptor_)?}}{{malloc|.vec_malloc}} + // CHECK: #{{.*}} in {{main|.main}} {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-9]] return 0; } #else // SHARED_LIBS diff --git a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp index c3383d6082b44..a41477f92dc4a 100644 --- a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp @@ -46,5 +46,5 @@ int main(int argc, char** argv) { // CHECK: AddressSanitizer: heap-use-after-free // CHECK-NEXT: WRITE of size // CHECK-NEXT: #0 0x{{[0-9a-fA-F]+}} -// CHECK-NEXT: #1 0x{{[0-9a-fA-F]+}} in do_access -// CHECK-NEXT: #2 0x{{[0-9a-fA-F]+}} in main +// CHECK-NEXT: #1 0x{{[0-9a-fA-F]+}} in {{do_access|.do_access}} +// CHECK-NEXT: #2 0x{{[0-9a-fA-F]+}} in {{main|.main}} diff --git a/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp b/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp index 6946e5013d2cb..c83112423f3ed 100644 --- a/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp @@ -1,6 +1,9 @@ // RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s +// AIX libc does not define asprintf. +// UNSUPPORTED: target={{.*aix.*}} + #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif diff --git a/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp b/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp index c18653bc29ef0..230ca078ec093 100644 --- a/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp @@ -30,6 +30,6 @@ int main(int argc, char **argv) { // CHECK-FILE: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} // CHECK-FILE: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} // CHECK-FILE: {{WRITE of size 1 at 0x.* thread T0}} - // CHECK-FILE: {{ #0 0x.* in main .*closed-fds.cpp:}}[[@LINE-4]] + // CHECK-FILE: {{ #0 0x.* in (main|.main) .*closed-fds.cpp:}}[[@LINE-4]] return 0; } diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp index a8768479de2f6..9f2507defcf2b 100644 --- a/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp @@ -6,6 +6,8 @@ // UNSUPPORTED: android // UNSUPPORTED: iossim // +// UNSUPPORTED: target={{.*aix.*}} + // Ideally a forked-subprocess should only report it's own coverage, // not parent's one. But trace-pc-guard currently does nothing special for fork, // and thus this test is relaxed. diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp index d301bb5c7838d..8250752290172 100644 --- a/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp @@ -11,6 +11,9 @@ // XFAIL: android // UNSUPPORTED: ios +// FIXME: support -fsanitize-coverage on AIX +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp index e89181cc6c376..6781d8e59db18 100644 --- a/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp @@ -5,6 +5,8 @@ // // UNSUPPORTED: ios +// UNSUPPORTED: target={{.*aix.*}} + #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage.cpp index 12a88402eb5aa..25f1a0fa98495 100644 --- a/compiler-rt/test/asan/TestCases/Posix/coverage.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/coverage.cpp @@ -20,6 +20,9 @@ // XFAIL: android // UNSUPPORTED: ios +// FIXME: support -fsanitize-coverage on AIX. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp b/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp index 37aa7b11a231a..ffea7a7d86b78 100644 --- a/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp @@ -1,7 +1,8 @@ // Check that UAR mode can handle very deep recusrion. +// On AIX, we need a large stack size to contain all the 15000 frames and its callees. // REQUIRES: shell // RUN: %clangxx_asan -O2 %s -o %t -// RUN: ulimit -s 4096 +// RUN: ulimit -s 8192 // RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s // Also check that use_sigaltstack+verbosity doesn't crash. diff --git a/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp b/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp index 36fdf81120b59..d28b7d9abe94e 100644 --- a/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp @@ -7,6 +7,9 @@ // (https://github.com/llvm/llvm-project/issues/64942). // UNSUPPORTED: iossim +// FIXME: investigate this failure on AIX. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp b/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp index 34c952f2e02ef..30c06fee171ba 100644 --- a/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp @@ -47,8 +47,8 @@ int main(int argc, char *argv[]) { } // CHECK-FGETS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} -// CHECK-FGETS: #{{.*}} in {{(wrap_|__interceptor_)?}}fgets +// CHECK-FGETS: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fgets|.fgets}} // CHECK-FPUTS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} -// CHECK-FPUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}fputs +// CHECK-FPUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fputs|.fputs}} // CHECK-PUTS: {{.*ERROR: AddressSanitizer: heap-use-after-free}} -// CHECK-PUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}puts +// CHECK-PUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}{{puts|.puts}} diff --git a/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp b/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp index c0629260418a3..f6cc8dc60c3f7 100644 --- a/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp @@ -29,6 +29,6 @@ int main(int argc, char *argv[]) { } // CHECK-FREAD: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} -// CHECK-FREAD: #{{.*}} in {{(wrap_|__interceptor_)?}}fread +// CHECK-FREAD: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fread|.fread}} // CHECK-FWRITE: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} -// CHECK-FWRITE: #{{.*}} in {{(wrap_|__interceptor_)?}}fwrite +// CHECK-FWRITE: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fwrite|.fwrite}} diff --git a/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp b/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp index b592edb9f3df0..67010cd6948f4 100644 --- a/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) { my_memset(buf, 11); // CHECK: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} // CHECK: {{WRITE of size 11 at 0x.* thread T0}} - // CHECK: {{0x.* in my_memset .*interception-in-shared-lib-test.cpp:}}[[@LINE-10]] + // CHECK: {{0x.* in (my_memset|.my_memset) .*interception-in-shared-lib-test.cpp:}}[[@LINE-10]] return 0; } #endif diff --git a/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp b/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp index d32dae9c01e87..3498c7c2a14fd 100644 --- a/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp @@ -1,6 +1,14 @@ +// On AIX, for 32 bit, the stack of main thread contains all other thread's stack. +// So we should be able to check invalid pointer based on the main thread stack, because +// all the stack address are in main thread's stack. +// However this is not true for 64 bit, for 64 bit, main thread stack does not overlap with +// other thread stack. This is same with other targets. +// See GetStackVariableShadowStart() for details. + // RUN: %clangxx_asan -O0 %s -pthread -o %t -mllvm -asan-detect-invalid-pointer-pair -// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty +// RUN: %if target={{.*aix.*}} && asan-32-bits %{ %env_asan_opts=detect_invalid_pointer_pairs=2 not %run %t a 2>&1 | FileCheck %s -check-prefix=AIX %} %else \ +// RUN: %{ %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty %} // RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 not %run %t b 2>&1 | FileCheck %s -check-prefix=B // pthread barriers are not available on OS X @@ -38,13 +46,15 @@ int main(int argc, char **argv) { if (t == 'a') { // OK-NOT: not handled yet + // AIX: ERROR: AddressSanitizer: invalid-pointer-pair + // AIX: #{{[0-9]+ .*}} in .main {{.*}}invalid-pointer-pairs-threads.cpp:[[@LINE+1]] unsigned r = pointers[0] - pointers[1]; } else { char local; char *parent_pointer = &local; // B: ERROR: AddressSanitizer: invalid-pointer-pair - // B: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-threads.cpp:[[@LINE+1]] + // B: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-threads.cpp:[[@LINE+1]] unsigned r = parent_pointer - pointers[0]; } diff --git a/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp b/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp index 01e9843619b7f..d10e711214829 100644 --- a/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp @@ -21,7 +21,7 @@ int main(int argc, char **argv) { int res = ioctl(fd, FIONBIO, &nonblock + 1); // CHECK: AddressSanitizer: stack-buffer-overflow // CHECK: READ of size 4 at - // CHECK: {{#.* in main .*ioctl.cpp:}}[[@LINE-3]] + // CHECK: {{#.* in (main|.main) .*ioctl.cpp:}}[[@LINE-3]] assert(res == 0); close(fd); return 0; diff --git a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp index edbdb4016d86e..614569b00f28a 100644 --- a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp @@ -20,7 +20,7 @@ int main(int argc, char **argv) { C *buffer = new C[argc]; buffer[-2].x = 10; // CHECK: AddressSanitizer: heap-buffer-overflow -// CHECK: in main {{.*}}new_array_cookie_test.cpp:[[@LINE-2]] +// CHECK: in {{main|.main}} {{.*}}new_array_cookie_test.cpp:[[@LINE-2]] // CHECK: is located 0 bytes inside of 12-byte region // NO_COOKIE: ZZZZZZZZ delete [] buffer; diff --git a/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c b/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c index 994f827974be9..136f150c94c7f 100644 --- a/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c +++ b/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c @@ -3,7 +3,10 @@ // Make sure ___asan_gen_* strings do not end up in the symbol table. // RUN: %clang_asan %s -o %t.exe -// RUN: nm %t.exe | FileCheck %s +// RUN: nm %if target={{.*aix.*}} %{ -X32_64 %} %t.exe | FileCheck %s + +// UNSUPPORTED: target={{.*aix.*}} + int x, y, z; int main() { return 0; } diff --git a/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp b/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp index 6f0a9f74a1978..b68d20bbb0a02 100644 --- a/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp @@ -30,11 +30,11 @@ int main(int argc, char *argv[]) { if (!inc) return 1; printf("ok\n"); inc(1); - inc(-1); // BOOM + inc(11); // BOOM, 11 is more robust than -1 as -1 requires the GLOB and pad are stored adjacent. // CHECK: {{.*ERROR: AddressSanitizer: global-buffer-overflow}} // CHECK: {{READ of size 4 at 0x.* thread T0}} // CHECK: {{ #0 0x.*}} - // CHECK: {{ #1 0x.* in main .*shared-lib-test.cpp:}}[[@LINE-4]] + // CHECK: {{ #1 0x.* in (main|.main) .*shared-lib-test.cpp:}}[[@LINE-4]] return 0; } #else // SHARED_LIB diff --git a/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp b/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp index 3d95a4ba273db..0a54c75ca2a1c 100644 --- a/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp @@ -21,6 +21,8 @@ // UNSUPPORTED: ios +// XFAIL: target={{powerpc-.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp b/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp index 4ddfd423167d3..f9bdb5cc85178 100644 --- a/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp @@ -4,6 +4,10 @@ // Fails with debug checks: https://bugs.llvm.org/show_bug.cgi?id=46862 // XFAIL: !compiler-rt-optimized +// For this case, do_another_bad_thing(which calls malloc) is compiled to a shared library, +// and intercepting symbols in a shared library is still unsupported. +// UNSUPPORTED: target={{.*aix.*}} + // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -std=c++11 -fPIC -shared -o %t-so.so // RUN: %clangxx -O0 %s -std=c++11 -c -o %t.o // RUN: %clangxx_asan -O0 %t.o %libdl -o %t @@ -83,27 +87,27 @@ int main(int argc, char *argv[]) { // After this line ASan is activated and starts detecting errors. void *fn = dlsym(dso, "do_another_bad_thing"); if (!fn) { - fprintf(stderr, "dlsym failed: %s\n", dlerror()); - return 1; + fprintf(stderr, "dlsym failed: %s\n", dlerror()); + return 1; } // After activation: redzones. for (int i = 1; i < HoneyPotSize; ++i) { - honeyPot[i] = (char *)malloc(HoneyPotBlockSize); - test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, true); + honeyPot[i] = (char *)malloc(HoneyPotBlockSize); + test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, true); } { - char *p = (char *)malloc(HoneyPotBlockSize); - test_malloc_shadow(p, HoneyPotBlockSize, true); - free(p); + char *p = (char *)malloc(HoneyPotBlockSize); + test_malloc_shadow(p, HoneyPotBlockSize, true); + free(p); } for (int i = 1; i < HoneyPotSize; ++i) - free(honeyPot[i]); + free(honeyPot[i]); // Pre-existing allocations got redzones, too. for (size_t sz = 1; sz < nPtrs; ++sz) { - test_malloc_shadow(ptrs[sz], sz, true); - free(ptrs[sz]); + test_malloc_shadow(ptrs[sz], sz, true); + free(ptrs[sz]); } // Test that ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 has effect. @@ -116,7 +120,7 @@ int main(int argc, char *argv[]) { // CHECK: READ of size 1 // CHECK: {{#0 .* in do_another_bad_thing}} // CHECK: is located 5 bytes after 100-byte region - // CHECK: in do_another_bad_thing + // CHECK: in {{do_another_bad_thing|.do_another_bad_thing}} return 0; } diff --git a/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp b/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp index 8e7d5082d0b5d..eb66a3631a953 100644 --- a/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp @@ -6,6 +6,9 @@ // RUN: %clangxx_asan -fexceptions -O0 %s -o %t -pthread // RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t +// This will hang on AIX +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/Posix/wait.cpp b/compiler-rt/test/asan/TestCases/Posix/wait.cpp index 7ca1c57a2edd9..5438249df65bc 100644 --- a/compiler-rt/test/asan/TestCases/Posix/wait.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/wait.cpp @@ -24,9 +24,9 @@ int main(int argc, char **argv) { // CHECK: stack-buffer-overflow // CHECK: {{WRITE of size .* at 0x.* thread T0}} // CHECK: {{in .*wait}} - // CHECK: {{in main .*wait.cpp:}} + // CHECK: {{in (main|.main) .*wait.cpp:}} // CHECK: is located in stack of thread T0 at offset - // CHECK: {{in main}} + // CHECK: {{in (main|.main)}} return res == -1 ? 1 : 0; } // child diff --git a/compiler-rt/test/asan/TestCases/Posix/wait3.cpp b/compiler-rt/test/asan/TestCases/Posix/wait3.cpp index 7fb4d65122592..77e89921cec4e 100644 --- a/compiler-rt/test/asan/TestCases/Posix/wait3.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/wait3.cpp @@ -26,9 +26,9 @@ int main(int argc, char **argv) { // CHECK: stack-buffer-overflow // CHECK: {{WRITE of size .* at 0x.* thread T0}} // CHECK: {{in .*wait}} - // CHECK: {{in main .*wait3.cpp:}} + // CHECK: {{in (main|.main) .*wait3.cpp:}} // CHECK: is located in stack of thread T0 at offset - // CHECK: {{in main}} + // CHECK: {{in (main|.main)}} return res == -1 ? 1 : 0; } // child diff --git a/compiler-rt/test/asan/TestCases/Posix/wait4.cpp b/compiler-rt/test/asan/TestCases/Posix/wait4.cpp index 1e574d99fe00c..a91c9e88c8959 100644 --- a/compiler-rt/test/asan/TestCases/Posix/wait4.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/wait4.cpp @@ -34,9 +34,9 @@ int main(int argc, char **argv) { // CHECK: stack-buffer-overflow // CHECK: {{WRITE of size .* at 0x.* thread T0}} // CHECK: {{in .*wait}} - // CHECK: {{in main .*wait4.cpp:}} + // CHECK: {{in (main|.main) .*wait4.cpp:}} // CHECK: is located in stack of thread T0 at offset - // CHECK: {{in main}} + // CHECK: {{in (main|.main)}} return res == -1 ? 1 : 0; } // child diff --git a/compiler-rt/test/asan/TestCases/Posix/waitid.cpp b/compiler-rt/test/asan/TestCases/Posix/waitid.cpp index 96b91f94765c3..0e1a068907dd8 100644 --- a/compiler-rt/test/asan/TestCases/Posix/waitid.cpp +++ b/compiler-rt/test/asan/TestCases/Posix/waitid.cpp @@ -20,9 +20,9 @@ int main(int argc, char **argv) { // CHECK: stack-buffer-overflow // CHECK: {{WRITE of size .* at 0x.* thread T0}} // CHECK: {{in .*waitid}} - // CHECK: {{in main .*waitid.cpp:}} + // CHECK: {{in (main|.main) .*waitid.cpp:}} // CHECK: is located in stack of thread T0 at offset - // CHECK: {{in main}} + // CHECK: {{in (main|.main)}} return res != -1; } // child diff --git a/compiler-rt/test/asan/TestCases/calloc-overflow.cpp b/compiler-rt/test/asan/TestCases/calloc-overflow.cpp index b930b65cd8c3b..ceebdd3faa0bf 100644 --- a/compiler-rt/test/asan/TestCases/calloc-overflow.cpp +++ b/compiler-rt/test/asan/TestCases/calloc-overflow.cpp @@ -11,7 +11,7 @@ int main() { void *p = calloc(-1, 1000); // CHECK: {{ERROR: AddressSanitizer: calloc parameters overflow: count \* size \(.* \* 1000\) cannot be represented in type size_t}} // CHECK: {{#0 0x.* in .*calloc}} - // CHECK: {{#[1-3] 0x.* in main .*calloc-overflow.cpp:}}[[@LINE-3]] + // CHECK: {{#[1-3] 0x.* in (main|.main) .*calloc-overflow.cpp:}}[[@LINE-3]] // CHECK: SUMMARY: AddressSanitizer: calloc-overflow printf("calloc returned: %zu\n", (size_t)p); diff --git a/compiler-rt/test/asan/TestCases/coverage-disabled.cpp b/compiler-rt/test/asan/TestCases/coverage-disabled.cpp index 2a283b4652121..b8f4d7e3b3514 100644 --- a/compiler-rt/test/asan/TestCases/coverage-disabled.cpp +++ b/compiler-rt/test/asan/TestCases/coverage-disabled.cpp @@ -10,6 +10,9 @@ // // UNSUPPORTED: android +// FIXME: support -fsanitize-coverage on AIX +// UNSUPPORTED: target={{.*aix.*}} + int main(int argc, char **argv) { return 0; } diff --git a/compiler-rt/test/asan/TestCases/debug_double_free.cpp b/compiler-rt/test/asan/TestCases/debug_double_free.cpp index c1cc383b3c1e3..e4afaf0cf1821 100644 --- a/compiler-rt/test/asan/TestCases/debug_double_free.cpp +++ b/compiler-rt/test/asan/TestCases/debug_double_free.cpp @@ -13,7 +13,7 @@ # define PTR_FMT "0x%08x" # endif // Solaris libc omits the leading 0x. -#elif defined(__sun__) && defined(__svr4__) +#elif (defined(__sun__) && defined(__svr4__)) || defined(_AIX) # define PTR_FMT "0x%p" #else # define PTR_FMT "%p" diff --git a/compiler-rt/test/asan/TestCases/debug_locate.cpp b/compiler-rt/test/asan/TestCases/debug_locate.cpp index 93d1af8b83916..e4769a3bec1df 100644 --- a/compiler-rt/test/asan/TestCases/debug_locate.cpp +++ b/compiler-rt/test/asan/TestCases/debug_locate.cpp @@ -61,6 +61,9 @@ int main() { assert(region_address == heap_ptr); assert(10 == region_size); +// AIX 64-bit has a highly customized memory layout, it has no shadow gap and +// 3 mid memory regions. +#if !defined(__LP64__) || !defined(_AIX) size_t shadow_scale; size_t shadow_offset; __asan_get_shadow_mapping(&shadow_scale, &shadow_offset); @@ -73,6 +76,7 @@ int main() { uintptr_t shadow_gap = (shadow_ptr >> shadow_scale) + shadow_offset; type = __asan_locate_address((void *)shadow_gap, NULL, 0, NULL, NULL); assert(0 == strcmp(type, "shadow gap")); +#endif free(heap_ptr); diff --git a/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp b/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp index a67804023c0cd..813c85a4b8ae9 100644 --- a/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp +++ b/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp @@ -1,7 +1,7 @@ // RUN: %clang_asan -O0 %s -o %t // RUN: %env_asan_opts=verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0 // RUN: %env_asan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64 -// REQUIRES: powerpc64-target-arch +// REQUIRES: powerpc64-linux- #include diff --git a/compiler-rt/test/asan/TestCases/debug_report.cpp b/compiler-rt/test/asan/TestCases/debug_report.cpp index 0dbb9f2fb9988..80cd9624523dd 100644 --- a/compiler-rt/test/asan/TestCases/debug_report.cpp +++ b/compiler-rt/test/asan/TestCases/debug_report.cpp @@ -28,7 +28,7 @@ int main() { # define PTR_FMT "0x%08x" # endif // Solaris libc omits the leading 0x. -#elif defined(__sun__) && defined(__svr4__) +#elif (defined(__sun__) && defined(__svr4__)) || defined(_AIX) # define PTR_FMT "0x%p" #else # define PTR_FMT "%p" diff --git a/compiler-rt/test/asan/TestCases/double-free.cpp b/compiler-rt/test/asan/TestCases/double-free.cpp index 7b61df0715afa..9fbeb0ad3cd3b 100644 --- a/compiler-rt/test/asan/TestCases/double-free.cpp +++ b/compiler-rt/test/asan/TestCases/double-free.cpp @@ -19,10 +19,10 @@ int main(int argc, char **argv) { free(x + argc - 1); // BOOM // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0 // CHECK: #0 0x{{.*}} in {{.*}}free - // CHECK: #{{[1-3]}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-3]] + // CHECK: #{{[1-3]}} 0x{{.*}} in {{main|.main}} {{.*}}double-free.cpp:[[@LINE-3]] // CHECK: freed by thread T0 here: // MALLOC-CTX: #0 0x{{.*}} in {{.*}}free - // MALLOC-CTX: #{{[1-3]}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-7]] + // MALLOC-CTX: #{{[1-3]}} 0x{{.*}} in {{main|.main}} {{.*}}double-free.cpp:[[@LINE-7]] // CHECK: allocated by thread T0 here: // MALLOC-CTX: double-free.cpp:[[@LINE-12]] // CHECK-RECOVER: AddressSanitizer: attempting double-free{{.*}}in thread T0 diff --git a/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp index d75ba992b650b..5e21b392667c4 100644 --- a/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp +++ b/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp @@ -2,6 +2,9 @@ // Test the frexp() interceptor. +// AIX does not intercept frexp +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp index 91da09a6880cf..18fb71b9a89a8 100644 --- a/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp +++ b/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp @@ -2,6 +2,9 @@ // Test the frexpf() interceptor. +// AIX can not intercept frexpf because libc does not export this symbol. +// UNSUPPORTED: aix + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp index 721eecc6f82a3..2df5e431024cc 100644 --- a/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp +++ b/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp @@ -6,6 +6,10 @@ // interceptor seems to not work. // XFAIL: target={{.*-windows-gnu}} +// clang will expand frexpl to a function(with mangle name) that calls frexp. +// On AIX, frexp can not be intercepted. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp b/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp index 07c8e63f439da..641854c13f494 100644 --- a/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp +++ b/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp @@ -10,7 +10,8 @@ /// Solaris ld -S has different semantics, so enforce -fuse-ld= for /// configurations that default to GNU ld. -// XFAIL: target={{.*solaris.*}} +/// AIX ld -S has different semnatics. +// XFAIL: target={{.*solaris.*|.*aix.*}} // CHECK: AddressSanitizer: global-buffer-overflow // CLASS_STATIC-NO-G: 0x{{.*}} is located 4 bytes after global variable '{{.*}}C::array{{.*}}' defined in '{{.*}}global-location.cpp' {{.*}} of size 40 diff --git a/compiler-rt/test/asan/TestCases/global-overflow.cpp b/compiler-rt/test/asan/TestCases/global-overflow.cpp index ed276ca44aa26..ffc311b614f7c 100644 --- a/compiler-rt/test/asan/TestCases/global-overflow.cpp +++ b/compiler-rt/test/asan/TestCases/global-overflow.cpp @@ -16,7 +16,7 @@ int main(int argc, char **argv) { memset(ZZZ, 0, 10); int res = YYY[argc * 10]; // BOOOM // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in main .*global-overflow.cpp:}}[[@LINE-2]] + // CHECK: {{ #0 0x.* in (main|.main) .*global-overflow.cpp:}}[[@LINE-2]] // CHECK: {{0x.* is located 0 bytes after global variable}} // CHECK: {{.*YYY.* of size 10}} res += XXX[argc] + ZZZ[argc]; diff --git a/compiler-rt/test/asan/TestCases/global-underflow.cpp b/compiler-rt/test/asan/TestCases/global-underflow.cpp index 32b4ce82f9b04..cde8b59fbe565 100644 --- a/compiler-rt/test/asan/TestCases/global-underflow.cpp +++ b/compiler-rt/test/asan/TestCases/global-underflow.cpp @@ -3,6 +3,11 @@ // RUN: %clangxx_asan -O2 %s %p/Helpers/underflow.cpp -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O3 %s %p/Helpers/underflow.cpp -o %t && not %run %t 2>&1 | FileCheck %s +// aix puts XXX and YYY at very different addresses. For example YYY is 0x20004340, XXX is 0x20000c20 +// This address allocation does not match the assumption in https://reviews.llvm.org/D38056. +// It was awared that this case may be not reliable on other OS. +// UNSUPPORTED: target={{.*aix.*}} + int XXX[2] = {2, 3}; extern int YYY[]; #include diff --git a/compiler-rt/test/asan/TestCases/heap-overflow.cpp b/compiler-rt/test/asan/TestCases/heap-overflow.cpp index f5bdcd5386373..102f5eafcb16e 100644 --- a/compiler-rt/test/asan/TestCases/heap-overflow.cpp +++ b/compiler-rt/test/asan/TestCases/heap-overflow.cpp @@ -14,7 +14,7 @@ int main(int argc, char **argv) { memset(x, 0, 10); int res = x[argc * 10]; // BOOOM // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in main .*heap-overflow.cpp:}}[[@LINE-2]] + // CHECK: {{ #0 0x.* in (main|.main) .*heap-overflow.cpp:}}[[@LINE-2]] // CHECK: {{0x.* is located 0 bytes after 10-byte region}} // CHECK: {{allocated by thread T0 here:}} diff --git a/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp b/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp index 661867260d260..d14d70ca05704 100644 --- a/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp +++ b/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp @@ -72,7 +72,7 @@ int main(int argc, char **argv) { stale_stack[100]++; // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame - // CHECK: in LeakStack{{.*}}heavy_uar_test.cpp: + // CHECK: in {{(LeakStack|.LeakStack).*}}heavy_uar_test.cpp: // CHECK: [{{16|32}}, {{1040|1056}}) 'x' return 0; } diff --git a/compiler-rt/test/asan/TestCases/initialization-bug.cpp b/compiler-rt/test/asan/TestCases/initialization-bug.cpp index 2775f6ce356dd..666fb887bc445 100644 --- a/compiler-rt/test/asan/TestCases/initialization-bug.cpp +++ b/compiler-rt/test/asan/TestCases/initialization-bug.cpp @@ -33,7 +33,7 @@ int __attribute__((noinline)) initX() { // CHECK: {{READ of size .* at 0x.* thread T0}} // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}} // CHECK: registered at: - // CHECK: 0x{{.*}} in __asan_register_globals + // CHECK: 0x{{.*}} in {{__asan_register_globals|.__asan_register_globals}} } // This initializer begins our initialization order problems. diff --git a/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp b/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp index bf51eed41fddf..19e1eebfe6a77 100644 --- a/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp +++ b/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp @@ -15,6 +15,10 @@ // https://reviews.llvm.org/D111703 made compiler incompatible with released NDK. // UNSUPPORTED: android && arm-target-arch +// make_exception_ptr on AIX will call __cxa_throw, and __cxa_throw will call malloc +// and memset, these function call will change shadow memory unexpectly. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/invalid-free.cpp b/compiler-rt/test/asan/TestCases/invalid-free.cpp index f550dc14a5a68..09228dc8ab69e 100644 --- a/compiler-rt/test/asan/TestCases/invalid-free.cpp +++ b/compiler-rt/test/asan/TestCases/invalid-free.cpp @@ -1,9 +1,12 @@ // RUN: %clangxx_asan -O0 %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX +// RUN: %if target={{.*aix.*}} %{ %env_asan_opts=enable_unmalloced_free_check=1 %} not %run %t 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX // Also works if no malloc context is available. -// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s -// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s +// RUN: %if target={{.*aix.*}} %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0:enable_unmalloced_free_check=1 %} %else \ +// RUN: %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0 %} not %run %t 2>&1 | FileCheck %s +// RUN: %if target={{.*aix.*}} %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1:enable_unmalloced_free_check=1 %} %else \ +// RUN: %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1 %} not %run %t 2>&1 | FileCheck %s // REQUIRES: stable-runtime #include diff --git a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp index 7b1479e2d05bd..a924bdada2e9e 100644 --- a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp +++ b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp @@ -23,82 +23,82 @@ int main() { char *heap2 = (char *)malloc(42); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(heap1, heap2); free(heap1); free(heap2); heap1 = (char *)malloc(1024); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(heap1, heap1 + 1025); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(heap1 + 1024, heap1 + 1025); free(heap1); heap1 = (char *)malloc(4096); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(heap1, heap1 + 4097); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(heap1, 0); // Global variables. // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(&global1[0], &global2[10]); char *p = &small_global[0]; foo(p, p); // OK foo(p, p + 7); // OK // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p, p + 8); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p - 1, p); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p, p - 1); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p - 1, p + 8); p = &large_global[0]; // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p - 1, p); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p, p - 1); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p, &global1[0]); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p, &small_global[0]); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(p, 0); // Stack variables. char stack1, stack2; // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(&stack1, &stack2); // Mixtures. // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(heap1, &stack1); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair foo(heap1, &global1[0]); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair foo(&stack1, &global1[0]); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]] foo(&stack1, 0); free(heap1); diff --git a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp index 535833d05c89a..d8157f86e2f45 100644 --- a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp +++ b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp @@ -17,29 +17,29 @@ int main() { char *heap2 = (char *)malloc(42); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] foo(heap1, heap2); // Global variables. // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] foo(&global1[0], &global2[10]); // Stack variables. char stack1, stack2; // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] foo(&stack1, &stack2); // Mixtures. // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] foo(heap1, &stack1); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] foo(heap1, &global1[0]); // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair - // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] + // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]] foo(&stack1, &global1[0]); free(heap1); diff --git a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp index accd9b7704d51..cb2fecbb8a512 100644 --- a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp +++ b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp @@ -13,10 +13,10 @@ int f(char c, char *p, char *q) { // [[PTR1:0x[0-9a-f]+]] [[PTR2:0x[0-9a-f]+]] switch (c) { case 'g': - // CMP: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]] + // CMP: #{{[0-9]+ .*}} in {{f|.f}}({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]] return p > q; case 's': - // SUB: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]] + // SUB: #{{[0-9]+ .*}} in {{f|.f}}({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]] return p - q; case 'k': { // OK-NOT: ERROR @@ -26,7 +26,7 @@ int f(char c, char *p, char *q) { case 'f': { char *p3 = p + 20; free(p); - // FREE: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+2]] + // FREE: #{{[0-9]+ .*}} in {{f|.f}}({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+2]] // FREE: freed by thread return p < p3; } diff --git a/compiler-rt/test/asan/TestCases/large_func_test.cpp b/compiler-rt/test/asan/TestCases/large_func_test.cpp index c64fc7d3c7aa7..e7572029022b9 100644 --- a/compiler-rt/test/asan/TestCases/large_func_test.cpp +++ b/compiler-rt/test/asan/TestCases/large_func_test.cpp @@ -32,6 +32,7 @@ static void LargeFunction(int *x, int zero) { // CHECK-Windows:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-5]] // CHECK-FreeBSD:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-6]] // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-7]] + // CHECK-AIX: {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-8]] x[10]++; x[11]++; @@ -48,7 +49,7 @@ static void LargeFunction(int *x, int zero) { int main(int argc, char **argv) { int *x = new int[100]; LargeFunction(x, argc - 1); - // CHECK: {{ #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-1]] + // CHECK: {{ #1 0x.* in (main|.main) .*large_func_test.cpp:}}[[@LINE-1]] // CHECK: {{0x.* is located 12 bytes after 400-byte region}} // CHECK: {{allocated by thread T0 here:}} // CHECK-Linux: {{ #0 0x.* in operator new}} @@ -56,7 +57,10 @@ int main(int argc, char **argv) { // CHECK-Windows:{{ #0 0x.* in operator new}} // CHECK-FreeBSD:{{ #0 0x.* in operator new}} // CHECK-Darwin: {{ #0 0x.* in .*_Zna}} - // CHECK-NEXT: {{ #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-10]] + // AIX currently have some issue while symbolizing operator new. + // FIXME: fix this symbolizer issue on aix. + // CHECK-AIX: {{ #0 0x.* }} + // CHECK-NEXT: {{ #1 0x.* in (main|.main) .*large_func_test.cpp:}}[[@LINE-13]] int y = x[argc]; delete[] x; return y; diff --git a/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp b/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp index 771640a4ac08d..e3d0d57920242 100644 --- a/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp +++ b/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp @@ -18,7 +18,7 @@ int main() { void *p = malloc(kMaxAllowedMallocSizePlusOne); // CHECK: {{ERROR: AddressSanitizer: requested allocation size .* \(.* after adjustments for alignment, red zones etc\.\) exceeds maximum supported size}} // CHECK: {{#0 0x.* in .*malloc}} - // CHECK: {{#[1-3] 0x.* in main .*malloc-size-too-big.cpp:}}[[@LINE-3]] + // CHECK: {{#[1-3] 0x.* in (main|.main) .*malloc-size-too-big.cpp:}}[[@LINE-3]] // CHECK: SUMMARY: AddressSanitizer: allocation-size-too-big printf("malloc returned: %zu\n", (size_t)p); diff --git a/compiler-rt/test/asan/TestCases/malloc_context_size.cpp b/compiler-rt/test/asan/TestCases/malloc_context_size.cpp index e75bc48793ad1..a249df54b8cb5 100644 --- a/compiler-rt/test/asan/TestCases/malloc_context_size.cpp +++ b/compiler-rt/test/asan/TestCases/malloc_context_size.cpp @@ -11,17 +11,19 @@ int main() { return x[0]; // CHECK: freed by thread T{{.*}} here: - // CHECK-NEXT: #0 0x{{.*}} in {{operator delete( )?\[\]|_ZdaPv}} + // FIXME: aix currently can not symbolize operator delete inside asan library. + // CHECK-NEXT: #0 0x{{.*}} {{(in operator delete( )?\[\]|wrap__ZdaPv|.*)}} // CHECK-NOT: #1 0x{{.*}} // CHECK: previously allocated by thread T{{.*}} here: - // CHECK-NEXT: #0 0x{{.*}} in {{operator new( )?\[\]|_Znam}} + // FIXME: aix currently can not symbolize operator delete inside asan library. + // CHECK-NEXT: #0 0x{{.*}} {{(in operator new( )?\[\]|wrap__Znam|.*)}} // CHECK-NOT: #1 0x{{.*}} // CHECK: SUMMARY: AddressSanitizer: heap-use-after-free // TWO: previously allocated by thread T{{.*}} here: // TWO-NEXT: #0 0x{{.*}} - // TWO-NEXT: #1 0x{{.*}} in main {{.*}}malloc_context_size.cpp + // TWO-NEXT: #1 0x{{.*}} in {{main|.main}} {{.*}}malloc_context_size.cpp // TWO: SUMMARY: AddressSanitizer: heap-use-after-free } diff --git a/compiler-rt/test/asan/TestCases/memset_test.cpp b/compiler-rt/test/asan/TestCases/memset_test.cpp index 0530c8483d72f..7c3a3064e76f3 100644 --- a/compiler-rt/test/asan/TestCases/memset_test.cpp +++ b/compiler-rt/test/asan/TestCases/memset_test.cpp @@ -9,26 +9,28 @@ // RUN: %clangxx_asan -O3 -DTEST_MEMSET %s -o %t && not %run %t 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK-MEMSET -// RUN: %clangxx_asan -O0 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY -// RUN: %clangxx_asan -O1 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY -// RUN: %clangxx_asan -O2 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY -// RUN: %clangxx_asan -O3 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY +// AIX can not intercept memcpy +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O0 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY %} +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O1 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY %} +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O2 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY %} +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O3 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY %} -// RUN: %clangxx_asan -O0 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE -// RUN: %clangxx_asan -O1 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE -// RUN: %clangxx_asan -O2 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE -// RUN: %clangxx_asan -O3 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE +// AIX can not intercept memmove +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O0 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE %} +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O1 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE %} +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O2 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE %} +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O3 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE %} -// RUN: %clangxx_asan -O2 -DTEST_MEMCPY_SIZE_OVERFLOW %s -o %t && not %run %t 2>&1 | \ -// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY_SIZE_OVERFLOW +// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O2 -DTEST_MEMCPY_SIZE_OVERFLOW %s -o %t && not %run %t 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK-MEMCPY_SIZE_OVERFLOW %} #include #include diff --git a/compiler-rt/test/asan/TestCases/null_deref.cpp b/compiler-rt/test/asan/TestCases/null_deref.cpp index a8947a4378032..8859c9be770c5 100644 --- a/compiler-rt/test/asan/TestCases/null_deref.cpp +++ b/compiler-rt/test/asan/TestCases/null_deref.cpp @@ -19,6 +19,6 @@ void NullDeref(int *ptr) { } int main() { NullDeref((int*)0); - // CHECK: {{ #1 0x.* in main.*null_deref.cpp}} + // CHECK: {{ #1 0x.* in (main|.main).*null_deref.cpp}} // CHECK: AddressSanitizer can not provide additional info. } diff --git a/compiler-rt/test/asan/TestCases/print_summary.cpp b/compiler-rt/test/asan/TestCases/print_summary.cpp index f3f7697056eab..ec407855304b8 100644 --- a/compiler-rt/test/asan/TestCases/print_summary.cpp +++ b/compiler-rt/test/asan/TestCases/print_summary.cpp @@ -8,7 +8,7 @@ int main() { delete[] x; return x[0]; // SOURCE: ERROR: AddressSanitizer: heap-use-after-free - // SOURCE: SUMMARY: AddressSanitizer: heap-use-after-free {{.*}}print_summary.cpp:[[@LINE-2]]{{.*}} main + // SOURCE: SUMMARY: AddressSanitizer: heap-use-after-free {{.*}}print_summary.cpp:[[@LINE-2]]{{.*}} {{main|.main}} // MODULE: ERROR: AddressSanitizer: heap-use-after-free // MODULE: SUMMARY: AddressSanitizer: heap-use-after-free ({{.*}}+0x{{.*}}) // MISSING: ERROR: AddressSanitizer: heap-use-after-free diff --git a/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp b/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp index 6a78ebb3489b9..5302c3d71a108 100644 --- a/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp +++ b/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp @@ -3,7 +3,8 @@ // FIXME: Weak symbols aren't supported on Windows, although some code in // compiler-rt already exists to solve this problem. We should probably define // the new/delete interceptors as "weak" using those workarounds as well. -// UNSUPPORTED: target={{.*windows.*}} +// AIX does not support shared sanitizer libraries. +// UNSUPPORTED: target={{.*(windows|aix).*}} // RUN: %clangxx %s -o %t -fsanitize=address -shared-libsan && not %run %t 2>&1 | FileCheck %s diff --git a/compiler-rt/test/asan/TestCases/set_shadow_test.c b/compiler-rt/test/asan/TestCases/set_shadow_test.c index f1c96502eba7e..39368ae3d3188 100644 --- a/compiler-rt/test/asan/TestCases/set_shadow_test.c +++ b/compiler-rt/test/asan/TestCases/set_shadow_test.c @@ -32,7 +32,11 @@ void f(long arg) { size_t shadow_offset; size_t shadow_scale; __asan_get_shadow_mapping(&shadow_scale, &shadow_offset); +#if !defined(__LP64__) || !defined(_AIX) size_t addr = (((size_t)a) >> shadow_scale) + shadow_offset; +#else + size_t addr = (((size_t)a << 6) >> (6 + shadow_scale)) + shadow_offset; +#endif switch (arg) { // X00-NOT: AddressSanitizer diff --git a/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp b/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp index 07cf39433b458..341003750b674 100644 --- a/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp +++ b/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp @@ -9,7 +9,7 @@ int main(int argc, char **argv) { memset(x, 0, 10); int res = x[argc * 10]; // BOOOM // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in main .*stack-buffer-overflow.cpp:}}[[@LINE-2]] + // CHECK: {{ #0 0x.* in (main|.main) .*stack-buffer-overflow.cpp:}}[[@LINE-2]] // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}} // CHECK-NEXT: in{{.*}}main{{.*}}stack-buffer-overflow.cpp return res; diff --git a/compiler-rt/test/asan/TestCases/strcasestr-1.c b/compiler-rt/test/asan/TestCases/strcasestr-1.c index 9fa4a2b31b97f..832178378ab30 100644 --- a/compiler-rt/test/asan/TestCases/strcasestr-1.c +++ b/compiler-rt/test/asan/TestCases/strcasestr-1.c @@ -8,6 +8,9 @@ // There's no interceptor for strcasestr on Windows // XFAIL: target={{.*windows-(msvc.*|gnu)}} +// AIX does not define strcasestr +// UNSUPPORTED: target={{.*aix.*}} + #define _GNU_SOURCE #include #include diff --git a/compiler-rt/test/asan/TestCases/strcasestr-2.c b/compiler-rt/test/asan/TestCases/strcasestr-2.c index 920d11e275c6a..2f530cda44484 100644 --- a/compiler-rt/test/asan/TestCases/strcasestr-2.c +++ b/compiler-rt/test/asan/TestCases/strcasestr-2.c @@ -8,6 +8,9 @@ // There's no interceptor for strcasestr on Windows // XFAIL: target={{.*windows-(msvc.*|gnu)}} +// AIX does not define strcasestr. +// UNSUPPORTED: target={{.*aix.*}} + #define _GNU_SOURCE #include #include diff --git a/compiler-rt/test/asan/TestCases/strcasestr_strict.c b/compiler-rt/test/asan/TestCases/strcasestr_strict.c index 16efae72ada4e..268e63860242d 100644 --- a/compiler-rt/test/asan/TestCases/strcasestr_strict.c +++ b/compiler-rt/test/asan/TestCases/strcasestr_strict.c @@ -6,6 +6,9 @@ // There's no interceptor for strcasestr on Windows // XFAIL: target={{.*windows-(msvc.*|gnu)}} +// AIX does not define strcasestr. +// UNSUPPORTED: target={{.*aix.*}} + #define _GNU_SOURCE #include #include diff --git a/compiler-rt/test/asan/TestCases/strcat_strict.c b/compiler-rt/test/asan/TestCases/strcat_strict.c index 6e9bd8eb08602..55324624f3238 100644 --- a/compiler-rt/test/asan/TestCases/strcat_strict.c +++ b/compiler-rt/test/asan/TestCases/strcat_strict.c @@ -7,6 +7,9 @@ // RUN: %env_asan_opts=strict_string_checks=false not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2 // RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2 +// AIX does not intercept strcat. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/strcmp.c b/compiler-rt/test/asan/TestCases/strcmp.c index 417bd491ebe02..eba27d2cfa77b 100644 --- a/compiler-rt/test/asan/TestCases/strcmp.c +++ b/compiler-rt/test/asan/TestCases/strcmp.c @@ -3,6 +3,9 @@ // RUN: %env_asan_opts=intercept_strcmp=true not %run %t 2>&1 | FileCheck %s // RUN: not %run %t 2>&1 | FileCheck %s +// AIX does not intercept strcmp. +//UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/strcmp_strict.c b/compiler-rt/test/asan/TestCases/strcmp_strict.c index e168923749ce2..654cccd4dc5ac 100644 --- a/compiler-rt/test/asan/TestCases/strcmp_strict.c +++ b/compiler-rt/test/asan/TestCases/strcmp_strict.c @@ -3,6 +3,9 @@ // RUN: %env_asan_opts=strict_string_checks=false %run %t 2>&1 // RUN: %env_asan_opts=strict_string_checks=true not %run %t 2>&1 | FileCheck %s +// AIX does not intercept strcmp. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp b/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp index efd2e6b7521ef..31fe1fe469799 100644 --- a/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp +++ b/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp @@ -28,6 +28,9 @@ // UNSUPPORTED: android +// AIX does not intercept strcpy +// UNSUPPORTED: target={{.*aix.*}} + #include diff --git a/compiler-rt/test/asan/TestCases/strip_path_prefix.c b/compiler-rt/test/asan/TestCases/strip_path_prefix.c index e77f1d5ddaf42..0534bb1d09167 100644 --- a/compiler-rt/test/asan/TestCases/strip_path_prefix.c +++ b/compiler-rt/test/asan/TestCases/strip_path_prefix.c @@ -8,5 +8,5 @@ int main() { return x[5]; // Check that paths in error report don't start with slash. // CHECK: heap-use-after-free - // CHECK: #0 0x{{.*}} in main {{.*}}strip_path_prefix.c:[[@LINE-3]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}strip_path_prefix.c:[[@LINE-3]] } diff --git a/compiler-rt/test/asan/TestCases/strncat-overlap.cpp b/compiler-rt/test/asan/TestCases/strncat-overlap.cpp index 3e3f7ee2723f5..ff04127ecd9c6 100644 --- a/compiler-rt/test/asan/TestCases/strncat-overlap.cpp +++ b/compiler-rt/test/asan/TestCases/strncat-overlap.cpp @@ -28,6 +28,9 @@ // UNSUPPORTED: android +// AIX does not intercept strncat. +// UNSUPPORTED: target={{.*aix.*}} + #include diff --git a/compiler-rt/test/asan/TestCases/strncat_strict.c b/compiler-rt/test/asan/TestCases/strncat_strict.c index 2b44b565a5e4f..2f61af491536e 100644 --- a/compiler-rt/test/asan/TestCases/strncat_strict.c +++ b/compiler-rt/test/asan/TestCases/strncat_strict.c @@ -7,6 +7,9 @@ // RUN: %env_asan_opts=strict_string_checks=false not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2 // RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2 +// aix does not intercept strncat. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/strncmp_strict.c b/compiler-rt/test/asan/TestCases/strncmp_strict.c index e06d1475b96f5..35bda6f7df020 100644 --- a/compiler-rt/test/asan/TestCases/strncmp_strict.c +++ b/compiler-rt/test/asan/TestCases/strncmp_strict.c @@ -14,6 +14,9 @@ // RUN: %env_asan_opts=strict_string_checks=false %run %t i 2>&1 // RUN: %env_asan_opts=strict_string_checks=true not %run %t i 2>&1 | FileCheck %s +// AIX does not intercept strncmp. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp b/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp index ff84052a94987..12d6bca00f556 100644 --- a/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp +++ b/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp @@ -6,6 +6,9 @@ // REQUIRES: compiler-rt-optimized // REQUIRES: stable-runtime +// AIX does not intercept strncpy. +// UNSUPPORTED: target={{.*aix.*}} + #include #include diff --git a/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp b/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp index 860fc5d304e0e..85fd1a9b41e72 100644 --- a/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp +++ b/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp @@ -28,6 +28,9 @@ // UNSUPPORTED: android +// AIX does not intercept strncpy. +// UNSUPPORTED: target={{.*aix.*}} + #include diff --git a/compiler-rt/test/asan/TestCases/suppressions-library.cpp b/compiler-rt/test/asan/TestCases/suppressions-library.cpp index 5427122eaa92f..78a1235c83c5b 100644 --- a/compiler-rt/test/asan/TestCases/suppressions-library.cpp +++ b/compiler-rt/test/asan/TestCases/suppressions-library.cpp @@ -12,6 +12,12 @@ // FIXME: Upload suppressions to device. // XFAIL: android +// For this case, crash_function(which calls malloc/free) is compiled to a shared library, +// However intercepting symbols in a shared library is still unsupported. + +// UNSUPPORTED: target={{.*aix.*}} + + #include #include #include diff --git a/compiler-rt/test/asan/TestCases/use-after-delete.cpp b/compiler-rt/test/asan/TestCases/use-after-delete.cpp index 4d0c055368bb0..ee8146cff99dc 100644 --- a/compiler-rt/test/asan/TestCases/use-after-delete.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-delete.cpp @@ -4,6 +4,9 @@ // RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK // REQUIRES: stable-runtime +// AIX currently have some issue while symbolizing operator new/delete. +// FIXME: fix this symbolizer issue on aix. + #include int main() { char * volatile x = new char[10]; @@ -12,7 +15,7 @@ int main() { // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in main .*use-after-delete.cpp:}}[[@LINE-4]] + // CHECK: {{ #0 0x.* in (main|.main) .*use-after-delete.cpp:}}[[@LINE-4]] // CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}} // CHECK: {{freed by thread T0 here:}} @@ -21,7 +24,8 @@ int main() { // CHECK-Windows:{{ #0 0x.* in operator delete\[\]}} // CHECK-FreeBSD:{{ #0 0x.* in operator delete\[\]}} // CHECK-Darwin: {{ #0 0x.* in .*_Zda}} - // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-14]] + // CHECK-AIX: {{ #0 0x.*}} + // CHECK-NEXT: {{ #1 0x.* in (main|.main) .*use-after-delete.cpp:}}[[@LINE-15]] // CHECK: {{previously allocated by thread T0 here:}} // CHECK-Linux: {{ #0 0x.* in operator new\[\]}} @@ -29,8 +33,8 @@ int main() { // CHECK-Windows:{{ #0 0x.* in operator new\[\]}} // CHECK-FreeBSD:{{ #0 0x.* in operator new\[\]}} // CHECK-Darwin: {{ #0 0x.* in .*_Zna}} - // CHECK-NEXT: {{ #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-23]] - + // CHECK-AIX: {{ #0 0x.*}} + // CHECK-NEXT: {{ #1 0x.* in (main|.main) .*use-after-delete.cpp:}}[[@LINE-25]] // CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes): // CHECK: Global redzone: diff --git a/compiler-rt/test/asan/TestCases/use-after-free-right.cpp b/compiler-rt/test/asan/TestCases/use-after-free-right.cpp index 11011e4b4fb1a..90e8c61d740e1 100644 --- a/compiler-rt/test/asan/TestCases/use-after-free-right.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-free-right.cpp @@ -15,13 +15,13 @@ int main() { // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} // CHECK: {{WRITE of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-4]] + // CHECK: {{ #0 0x.* in (main|.main) .*use-after-free-right.cpp:}}[[@LINE-4]] // CHECK: {{0x.* is located 0 bytes inside of 1-byte region .0x.*,0x.*}} // CHECK: {{freed by thread T0 here:}} // CHECK: {{ #0 0x.* in .*free}} - // CHECK: {{ #[1-3] 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-9]] + // CHECK: {{ #[1-3] 0x.* in (main|.main) .*use-after-free-right.cpp:}}[[@LINE-9]] // CHECK: {{previously allocated by thread T0 here:}} // CHECK: {{ #0 0x.* in .*malloc}} - // CHECK: {{ #[1-3] 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-14]] + // CHECK: {{ #[1-3] 0x.* in (main|.main) .*use-after-free-right.cpp:}}[[@LINE-14]] } diff --git a/compiler-rt/test/asan/TestCases/use-after-free.cpp b/compiler-rt/test/asan/TestCases/use-after-free.cpp index f19c461960d36..7d02d97a6678c 100644 --- a/compiler-rt/test/asan/TestCases/use-after-free.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-free.cpp @@ -12,15 +12,15 @@ int main() { // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in main .*use-after-free.cpp:}}[[@LINE-4]] + // CHECK: {{ #0 0x.* in (main|.main) .*use-after-free.cpp:}}[[@LINE-4]] // CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}} // CHECK: {{freed by thread T0 here:}} // CHECK: {{ #0 0x.* in .*free}} - // CHECK: {{ #[1-3] 0x.* in main .*use-after-free.cpp:}}[[@LINE-9]] + // CHECK: {{ #[1-3] 0x.* in (main|.main) .*use-after-free.cpp:}}[[@LINE-9]] // CHECK: {{previously allocated by thread T0 here:}} // CHECK: {{ #0 0x.* in .*malloc}} - // CHECK: {{ #[1-3] 0x.* in main .*use-after-free.cpp:}}[[@LINE-14]] + // CHECK: {{ #[1-3] 0x.* in (main|.main) .*use-after-free.cpp:}}[[@LINE-14]] // CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes): // CHECK: Global redzone: // CHECK: ASan internal: diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp index 42f62c72397ec..916b6d52f7085 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp @@ -7,7 +7,7 @@ struct IntHolder { __attribute__((noinline)) ~IntHolder() { printf("Value: %d\n", *val_); // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in IntHolder::~IntHolder{{.*}}.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{(IntHolder::~IntHolder|.IntHolder::~IntHolder).*}}.cpp:[[@LINE-2]] } void set(int *val) { val_ = val; } int *get() { return val_; } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp index 4c6cf34eaa9fd..d94bc03754078 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp @@ -10,5 +10,5 @@ int main() { } return *p; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}.cpp:[[@LINE-2]] } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp index 1014ff919b9ef..3492125264de4 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp @@ -18,10 +18,10 @@ int main(int argc, char *argv[]) { return arr[argc - 1]; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope // CHECK: READ of size 4 at 0x{{.*}} thread T0 - // CHECK: #0 0x{{.*}} in main + // CHECK: #0 0x{{.*}} in {{main|.main}} // CHECK: {{.*}}use-after-scope-inlined.cpp:[[@LINE-4]] // CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset [[OFFSET:[^ ]*]] in frame - // CHECK: {{.*}} in main + // CHECK: {{.*}} in {{main|.main}} // CHECK: This frame has // CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x.i' (line [[@LINE-15]]) } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp index 286b6441a5698..8b5dbfdd18f0e 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp @@ -10,7 +10,7 @@ int main() { } return *p; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-loop-bug.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-loop-bug.cpp:[[@LINE-2]] // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x' } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp index 8a8a7b60deb6b..9f9372f053bec 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp @@ -11,7 +11,7 @@ int main() { } return *p; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-loop-removed.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-loop-removed.cpp:[[@LINE-2]] // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x' } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp index 3e199056930cb..e1a739bdcc33b 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp @@ -9,5 +9,5 @@ int main() { } return **p; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}.cpp:[[@LINE-2]] } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp index 29680f37bfa53..07aa98b5b6063 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp @@ -14,6 +14,6 @@ int main(int argc, char *argv[]) { save({argc}); int x = saved->val; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-temp.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-temp.cpp:[[@LINE-2]] return x; } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp index b98d6f12911a7..45ffd24ba4e30 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp @@ -13,6 +13,6 @@ int main(int argc, char *argv[]) { saved = &IntHolder().Self(); int x = saved->val; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-temp2.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-temp2.cpp:[[@LINE-2]] return x; } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp index 5751a0a09bb4e..90ce1f45a8080 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp @@ -41,7 +41,7 @@ template __attribute__((noinline)) void test() { ptr.Access(); // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #{{[0-9]+}} 0x{{.*}} in {{(void )?test.*\((void)?\) .*}}use-after-scope-types.cpp + // CHECK: #{{[0-9]+}} 0x{{.*}} in {{(void |.void )?test.*\((void)?\) .*}}use-after-scope-types.cpp // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x' } diff --git a/compiler-rt/test/asan/TestCases/use-after-scope.cpp b/compiler-rt/test/asan/TestCases/use-after-scope.cpp index eb61679d2b2aa..746788823e333 100644 --- a/compiler-rt/test/asan/TestCases/use-after-scope.cpp +++ b/compiler-rt/test/asan/TestCases/use-after-scope.cpp @@ -9,7 +9,7 @@ int main() { } *p = 5; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope - // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope.cpp:[[@LINE-2]] + // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope.cpp:[[@LINE-2]] // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x' return 0; diff --git a/compiler-rt/test/asan/TestCases/zero_page_pc.cpp b/compiler-rt/test/asan/TestCases/zero_page_pc.cpp index a7d00ce9b6988..71339f4ddb46f 100644 --- a/compiler-rt/test/asan/TestCases/zero_page_pc.cpp +++ b/compiler-rt/test/asan/TestCases/zero_page_pc.cpp @@ -5,6 +5,9 @@ # include #endif ++// AIX reports illegal instruction error instead of SEGV while accesses address 0x4. ++// UNSUPPORTED: aix + typedef void void_f(); int main() { void_f *func = (void_f *)0x4; diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py index c57f5ca0fa652..4103d80a57fdd 100644 --- a/compiler-rt/test/asan/lit.cfg.py +++ b/compiler-rt/test/asan/lit.cfg.py @@ -40,7 +40,7 @@ def get_required_attr(config, attr_name): # Setup source root. config.test_source_root = os.path.dirname(__file__) -if config.host_os not in ["FreeBSD", "NetBSD"]: +if config.host_os not in ["FreeBSD", "NetBSD", "AIX"]: libdl_flag = "-ldl" else: libdl_flag = "" diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py index c6f27748ccb76..ab190a1ffb523 100644 --- a/compiler-rt/test/lit.common.cfg.py +++ b/compiler-rt/test/lit.common.cfg.py @@ -880,17 +880,35 @@ def is_windows_lto_supported(): ) ) config.substitutions.append(("%ld_flags_rpath_so" + postfix, "")) + elif config.host_os == "AIX": + config.substitutions.append( + ( + "%ld_flags_rpath_exe" + postfix, + "-L%T -l%xdynamiclib_namespec" + postfix, + ) + ) + config.substitutions.append(("%ld_flags_rpath_so" + postfix, "")) # Must be defined after the substitutions that use %dynamiclib. config.substitutions.append( ("%dynamiclib" + postfix, "%T/%xdynamiclib_filename" + postfix) ) - config.substitutions.append( - ( - "%xdynamiclib_filename" + postfix, - "lib%xdynamiclib_namespec{}.so".format(postfix), - ) - ) + + if config.host_os == "AIX": + config.substitutions.append( + ( + "%xdynamiclib_filename" + postfix, + "lib%xdynamiclib_namespec{}.a".format(postfix) + ) + ) + else: + config.substitutions.append( + ( + "%xdynamiclib_filename" + postfix, + "lib%xdynamiclib_namespec{}.so".format(postfix), + ) + ) + config.substitutions.append(("%xdynamiclib_namespec", "%basename_t.dynamic")) config.default_sanitizer_opts = [] diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp index 5e95cbc331424..138c3b497d8ee 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: target={{.*(linux|solaris).*}} +// aix does not define arc4random(). +// UNSUPPORTED: target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp index 8ed9b4ccf16c2..afb412368ec85 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp @@ -4,6 +4,9 @@ // pthread_create with lsan i386 does not fail here. // UNSUPPORTED: i386-linux && lsan +// pthread_create on AIX does not fail here. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp index deedbba76cdeb..d375a92a4c6a8 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp @@ -33,6 +33,6 @@ int main(int argc, char **argv) { } // CHECK0-NOT: DEDUP_TOKEN: -// CHECK1: DEDUP_TOKEN: void Xyz::Abc() -// CHECK2: DEDUP_TOKEN: void Xyz::Abc()--bar -// CHECK3: DEDUP_TOKEN: void Xyz::Abc()--bar--FOO() +// CHECK1: DEDUP_TOKEN: {{void|.void}} Xyz::Abc() +// CHECK2: DEDUP_TOKEN: {{void|.void}} Xyz::Abc()--{{bar|.bar}} +// CHECK3: DEDUP_TOKEN: {{void|.void}} Xyz::Abc()--{{bar|.bar}}--{{FOO|.FOO}}() diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp index 8a34de5e31061..aaa461fe2aea0 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp @@ -1,5 +1,6 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s -// UNSUPPORTED: target={{.*(linux|solaris).*}} +// AIX does not define devname_r() +// UNSUPPORTED: target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp index 5f0968e2be55b..017dbdcae3fe0 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp @@ -1,5 +1,6 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s -// UNSUPPORTED: target={{.*(linux|solaris).*}} +// AIX does not define devname_r. +// UNSUPPORTED: target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp index 68b4ad5b887d1..59996e7d17e44 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp @@ -1,6 +1,6 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t // fgetln is BSD-only. -// UNSUPPORTED: target={{.*(linux|solaris).*}} +// UNSUPPORTED: target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp index 5de879d2392e2..ee8feced542a6 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}} +// on AIX, fail even without -fsanitize=address +// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp index 795bc11a39e60..fbbca187ebb70 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}} +// Header fts.h is not available on AIX. +// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp index 052cc19dff286..2523317af529b 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp @@ -11,7 +11,8 @@ // CHECK-NEXT: READ CALLED; len={{[0-9]*}} // CHECK-NEXT: READ: test // -// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}} +// AIX does not define strlcpy. +// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c index e382cb5f714ed..6b422f6c6bdd4 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c @@ -1,6 +1,7 @@ // RUN: %clang -pthread %s -Wl,-as-needed -o %t && %run %t // -// UNSUPPORTED: darwin, target={{.*solaris.*}} +// as-needed is not a supported linker option on AIX. +// UNSUPPORTED: darwin, target={{.*(solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp index 8df8b5726148b..6ab3170097f7e 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}} +// The usage of getfsspec() on aix is not right in this file. +// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp index 25d6310df2fb1..4a33288b11402 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: target={{.*(linux|solaris).*}} +// AIX does not have header sys/mount.h. +// UNSUPPORTED: target={{.*(linux|solaris|aix).*}} #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp index 2711cfb112959..f0a3d183f2eea 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp @@ -7,7 +7,8 @@ // XFAIL: android && asan // No libutil. -// UNSUPPORTED: target={{.*solaris.*}} +// AIX does not have util.h +// UNSUPPORTED: target={{.*(solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp index 848774a8909bd..7d614e748e597 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp @@ -81,7 +81,7 @@ int main(int argc, const char *argv[]) { setgrent(); test(&getgrent); -#if !defined(__APPLE__) && !(defined(__sun__) && defined(__svr4__)) +#if !defined(__APPLE__) && !(defined(__sun__) && defined(__svr4__)) && !defined(_AIX) setpwent(); test_r(&getpwent_r); setgrent(); diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c index 16ebeda5315e0..883ea6261bb41 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c @@ -15,6 +15,9 @@ // FIXME: Something wrong with MADV_FREE or MAP_NORESERVE there. // UNSUPPORTED: target={{.*solaris.*}} +// Large calloc causes AIX kill all bash processes. +// UNSUPPORTED: target={{.*aix.*}} + void *p; int main(int argc, char **argv) { diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp index 45d3f256378fc..3c770064b2646 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp @@ -4,7 +4,7 @@ // RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s // REQUIRES: stable-runtime -// XFAIL: target={{(powerpc64|s390x).*}} +// XFAIL: target={{(powerpc|powerpc64|s390x).*}} volatile int *null = 0; volatile int a; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp index 9b94b8d0237ce..5995f0760601b 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp @@ -4,7 +4,7 @@ // RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s // REQUIRES: stable-runtime -// XFAIL: target={{(powerpc64|s390x).*}} +// XFAIL: target={{(powerpc|powerpc64|s390x).*}} volatile int *null = 0; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c index ea58b92af6097..838dc89a86b88 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c @@ -3,6 +3,9 @@ // Older versions of Android do not have certain posix_spawn* functions. // UNSUPPORTED: android +// AIX reports EINVAL for the posix_spawnp() even without asan. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp index b7bcdf15499d2..20db3166032a1 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp @@ -2,6 +2,9 @@ // UNSUPPORTED: target={{.*solaris.*}} +// AIX can get "setvbuf" printed but after `FileCheck` can not find it after "2>&1 |" +// UNSUPPORTED: target={{.*aix.*}} + #include void print_something() { diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp index e96717f3b267c..26f5f366e06dc 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp @@ -1,5 +1,8 @@ // RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// line 73 signal(SIGRTMAX + 1, &signal_handler) will not fail on AIX, SIGRTMAX + 1 is a valid signal. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp index 6c14add8c4078..dc6e04bb81986 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}} +// AIX does not have stringlist.h. +// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp index b026f12f35fca..4ed823bc4c053 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t -// UNSUPPORTED: target={{.*linux.*}} +// AIX does not define strlcat. +// UNSUPPORTED: target={{.*(linux|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp index d7a5d1d3a51e9..a3ad20d897335 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t -// UNSUPPORTED: target={{.*linux.*}} +// AIX does not define strlcpy. +// UNSUPPORTED: target={{.*(linux|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp index a4f013096c596..0052d8103f464 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}} +// AIX does not define strtonum +// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}} #define _OPENBSD_SOURCE diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp index 38c34259bbae0..0f4e94dd9f562 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: linux, target={{.*solaris.*}} +// AIX does not have sys/sysctl.h +// UNSUPPORTED: linux, target={{.*(solaris|aix).*}} #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp index 0d31082f92b25..96b9e4270fcbf 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // -// UNSUPPORTED: target={{.*(linux|solaris).*}}, darwin +// AIX does not have err.h +// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}, darwin #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c index e26aad855621c..36b7a574775a1 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c @@ -1,5 +1,12 @@ // RUN: %clang %s -o %t && %run %t 2>&1 +// wcsdup internally calls malloc defined in libc library, however +// aix sanitizers can not intercept functions used in shared libraries, +// so the malloc is not intercepted and this case get error for the free: +// AddressSanitizer: attempting free on address which was not malloc()-ed: +// +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp index e95de739fe784..21fd18090c7dd 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp @@ -7,6 +7,9 @@ // FIXME: Implement. // XFAIL: hwasan +// AIX does not define strcasestr. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #if defined(_GNU_SOURCE) diff --git a/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp b/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp index ca6f637b9a3f5..0be4099e2a2c0 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp @@ -38,6 +38,9 @@ // TODO(alekseyshl): win32 is disabled due to failing errno tests, fix it there. // UNSUPPORTED: ubsan, target={{.*windows-msvc.*}} +// The llvm-symbolizer on AIX can not symbolize the pc to asan's source. +// XFAIL: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp index 4eb2247b1d38f..343c1edbfb181 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp @@ -17,6 +17,9 @@ // THUMB starts background thead only for Asan. // XFAIL: target=thumb{{.*}} && !asan +// AIX does not use background thread. +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp index 2fde16fbed3d2..eb7ad6c68e644 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp @@ -46,6 +46,9 @@ // Symbolizer needs to allocated memory when reporting. // UNSUPPORTED: internal_symbolizer +// The llvm-symbolizer on AIX can not symbolize the pc to asan's source. +// XFAIL: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp index 9d7d03d81b531..c35a5cb59e129 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp @@ -19,15 +19,15 @@ int main() { FooBarBaz(); return 0; } -// CHECK: {{ #0 0x.* in __sanitizer_print_stack_trace}} -// CHECK: {{ #1 0x.* in FooBarBaz(\(\))? .*}}print-stack-trace.cpp:[[@LINE-8]] -// CHECK: {{ #2 0x.* in main.*}}print-stack-trace.cpp:[[@LINE-5]] +// CHECK: {{ #0 0x.* in (__sanitizer_print_stack_trace|.__sanitizer_print_stack_trace)}} +// CHECK: {{ #1 0x.* in (FooBarBaz|.FooBarBaz)(\(\))? .*}}print-stack-trace.cpp:[[@LINE-8]] +// CHECK: {{ #2 0x.* in (main|.main).*}}print-stack-trace.cpp:[[@LINE-5]] // CUSTOM: frame1_lineno[[@LINE-11]] // CUSTOM: frame2_lineno[[@LINE-8]] -// NOINLINE: #0 0x{{.*}} in __sanitizer_print_stack_trace -// NOINLINE: #1 0x{{.*}} in main{{.*}}print-stack-trace.cpp:[[@LINE-15]] +// NOINLINE: #0 0x{{.*}} in {{__sanitizer_print_stack_trace|.__sanitizer_print_stack_trace}} +// NOINLINE: #1 0x{{.*}} in {{main|.main}}{{.*}}print-stack-trace.cpp:[[@LINE-15]] // NOSYMBOLIZE: frame:0 address:{{0x.*}} // NOSYMBOLIZE: frame:1 address:{{0x.*}} diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp index 6fdd23b84432f..72590ad3d6343 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp @@ -7,6 +7,9 @@ // XFAIL: ubsan,tsan // XFAIL: android && asan +// FIXME: support -fsanitize-coverage on AIX +// UNSUPPORTED: target={{.*aix.*}} + // RUN: rm -rf %t_workdir // RUN: mkdir -p %t_workdir // RUN: cd %t_workdir diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp index 5223af07f18ae..7cda2275cfbd7 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp @@ -6,6 +6,8 @@ // RUN: %clangxx -O0 -std=c++11 -fsanitize-coverage=control-flow %s -o %t // RUN: %run %t 2>&1 | FileCheck %s +// XFAIL: target={{.*aix.*}} + #include #include #if __has_feature(ptrauth_calls) diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp index 68eca85eb4d42..4579a8a8ee646 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp @@ -6,6 +6,8 @@ // RUN: %clangxx -O0 %s -fsanitize-coverage=inline-8bit-counters,pc-table -o %t // RUN: %run %t 2>&1 | FileCheck %s +// XFAIL: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp index d62ffe613b5b0..94b4cd3e93094 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp @@ -6,6 +6,8 @@ // RUN: %clangxx -O0 %s -fsanitize-coverage=inline-bool-flag,pc-table -o %t // RUN: %run %t 2>&1 | FileCheck %s +// XFAIL: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp index 29a63c0a92f32..889125421db6b 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp @@ -6,6 +6,8 @@ // RUN: %s -o %t // RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not Assertion{{.*}}failed +// UNSUPPORTED: target={{.*aix.*}} + #include #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp index f6ccbb6981352..8986dc1adca4c 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp @@ -6,6 +6,9 @@ // XFAIL: tsan,darwin // XFAIL: android && asan +// FIXME: support -fsanitize-coverage on AIX +// UNSUPPORTED: target={{.*aix.*}} + // RUN: rm -rf %t_workdir // RUN: mkdir -p %t_workdir // RUN: cd %t_workdir diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp index 84c28e82f04ac..94508a939340a 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp @@ -7,6 +7,9 @@ // XFAIL: tsan // XFAIL: android && asan +// FIXME: support -fsanitize-coverage on AIX +// UNSUPPORTED: target={{.*aix.*}} + // RUN: rm -rf %t_workdir // RUN: mkdir -p %t_workdir // RUN: cd %t_workdir diff --git a/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c b/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c index 8831977569b84..f3280a87dde93 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c +++ b/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c @@ -3,6 +3,9 @@ // There's no interceptor for strcasestr on Windows // XFAIL: target={{.*windows-msvc.*}} +// AIX does not define strcasestr +// UNSUPPORTED: target={{.*aix.*}} + #define _GNU_SOURCE #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c b/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c index 8e131054c2d4d..2bf5782db623c 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c +++ b/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c @@ -19,4 +19,4 @@ int main(int argc, char **argv) { __sanitizer_print_stack_trace(); return 0; } -// CHECK: #{{.*}} main +// CHECK: #{{.*}} {{main|.main}} diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp index f495e2cefdd74..0bcb4115385c9 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp @@ -72,12 +72,12 @@ int main() { // CHECK: PARTIAL '0x{{.*}}' SymbolizeSmallBuffer(); - // CHECK: FIRST_FORMAT 0x{{.*}} in main symbolize_pc.cpp:[[@LINE+2]] - // CHECK: SECOND_FORMAT FUNC:main LINE:[[@LINE+1]] FILE:symbolize_pc.cpp + // CHECK: FIRST_FORMAT 0x{{.*}} in {{main|.main}} symbolize_pc.cpp:[[@LINE+2]] + // CHECK: SECOND_FORMAT FUNC:{{main|.main}} LINE:[[@LINE+1]] FILE:symbolize_pc.cpp SymbolizeCaller(); struct s s; - // CHECK: SRET: FUNC:main LINE:[[@LINE+1]] FILE:symbolize_pc.cpp + // CHECK: SRET: FUNC:{{main|.main}} LINE:[[@LINE+1]] FILE:symbolize_pc.cpp s = SymbolizeSRet(); // CHECK: GLOBAL: GLOBAL_VAR_ABC diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp index 6e035c16a3045..4133aacf9dc0a 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp @@ -22,8 +22,8 @@ struct Symbolizer { __attribute__((noinline)) ~Symbolizer() { Symbolize(); } }; -// NODEMANGLE: in _ZN10SymbolizerD2Ev -// CHECK: in Symbolizer::~Symbolizer +// NODEMANGLE: in {{_ZN10SymbolizerD2Ev|._ZN10SymbolizerD2Ev}} +// CHECK: in {{Symbolizer::~Symbolizer|.Symbolizer::~Symbolizer}} int main() { Symbolizer(); return 0; diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp index e95ef324db652..5baf695f1f99b 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp @@ -18,7 +18,7 @@ __attribute__((noinline)) static void Symbolize() { printf("%s\n", p); } -// NOINLINE: {{0x[0-9a-f]+}} in main symbolize_pc_inline.cpp:[[@LINE+2]] +// NOINLINE: {{0x[0-9a-f]+}} in {{main|.main}} symbolize_pc_inline.cpp:[[@LINE+2]] // CHECK: [[ADDR:0x[0-9a-f]+]] in C2 symbolize_pc_inline.cpp:[[@LINE+1]] static inline void C2() { Symbolize(); } @@ -28,5 +28,5 @@ static inline void C3() { C2(); } // CHECK: [[ADDR]] in C4 symbolize_pc_inline.cpp:[[@LINE+1]] static inline void C4() { C3(); } -// CHECK: [[ADDR]] in main symbolize_pc_inline.cpp:[[@LINE+1]] +// CHECK: [[ADDR]] in {{main|.main}} symbolize_pc_inline.cpp:[[@LINE+1]] int main() { C4(); }