diff options
36 files changed, 505 insertions, 256 deletions
diff --git a/cmake/Modules/CompilerRTDarwinUtils.cmake b/cmake/Modules/CompilerRTDarwinUtils.cmake index 511361b49a7a..8be28d9a8aa9 100644 --- a/cmake/Modules/CompilerRTDarwinUtils.cmake +++ b/cmake/Modules/CompilerRTDarwinUtils.cmake @@ -282,7 +282,8 @@ macro(darwin_add_builtin_libraries) set(PROFILE_SOURCES ../profile/InstrProfiling ../profile/InstrProfilingBuffer - ../profile/InstrProfilingPlatformDarwin) + ../profile/InstrProfilingPlatformDarwin + ../profile/InstrProfilingWriter) foreach (os ${ARGN}) list_union(DARWIN_BUILTIN_ARCHS DARWIN_${os}_ARCHS BUILTIN_SUPPORTED_ARCH) foreach (arch ${DARWIN_BUILTIN_ARCHS}) diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index ba21238623a5..057642b05bdd 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -150,6 +150,8 @@ macro(detect_target_arch) check_symbol_exists(__i386__ "" __I386) check_symbol_exists(__mips__ "" __MIPS) check_symbol_exists(__mips64__ "" __MIPS64) + check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32) + check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64) if(__ARM) add_default_target_arch(arm) elseif(__AARCH64) @@ -164,6 +166,10 @@ macro(detect_target_arch) add_default_target_arch(mips64) elseif(__MIPS) add_default_target_arch(mips) + elseif(__WEBASSEMBLY32) + add_default_target_arch(wasm32) + elseif(__WEBASSEMBLY64) + add_default_target_arch(wasm64) endif() endmacro() @@ -220,6 +226,10 @@ elseif(NOT APPLE) # Supported archs for Apple platforms are generated later test_target_arch(aarch32 "" "-march=armv8-a") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64") test_target_arch(aarch64 "" "-march=armv8-a") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32") + test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown") + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64") + test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown") endif() set(COMPILER_RT_OS_SUFFIX "") endif() @@ -260,6 +270,8 @@ set(X86_64 x86_64) set(MIPS32 mips mipsel) set(MIPS64 mips64 mips64el) set(PPC64 powerpc64 powerpc64le) +set(WASM32 wasm32) +set(WASM64 wasm64) if(APPLE) set(ARM64 arm64) @@ -268,7 +280,7 @@ if(APPLE) endif() set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} - ${MIPS32} ${MIPS64}) + ${MIPS32} ${MIPS64} ${WASM32} ${WASM64}) set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64}) set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} @@ -299,10 +311,44 @@ if(APPLE) endif() option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off) + option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off) + option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off) find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx) find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator) find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos) + find_darwin_sdk_dir(DARWIN_watchossim_SYSROOT watchsimulator) + find_darwin_sdk_dir(DARWIN_watchos_SYSROOT watchos) + find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator) + find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos) + + if(COMPILER_RT_ENABLE_IOS) + list(APPEND DARWIN_EMBEDDED_PLATFORMS ios) + set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min) + set(DARWIN_ios_SANITIZER_MIN_VER_FLAG + ${DARWIN_ios_MIN_VER_FLAG}=7.0) + set(DARWIN_ios_BUILTIN_MIN_VER 6.0) + set(DARWIN_ios_BUILTIN_MIN_VER_FLAG + ${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_BUILTIN_MIN_VER}) + endif() + if(COMPILER_RT_ENABLE_WATCHOS) + list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos) + set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min) + set(DARWIN_watchos_SANITIZER_MIN_VER_FLAG + ${DARWIN_watchos_MIN_VER_FLAG}=2.0) + set(DARWIN_watchos_BUILTIN_MIN_VER 2.0) + set(DARWIN_watchos_BUILTIN_MIN_VER_FLAG + ${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_BUILTIN_MIN_VER}) + endif() + if(COMPILER_RT_ENABLE_TVOS) + list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos) + set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min) + set(DARWIN_tvos_SANITIZER_MIN_VER_FLAG + ${DARWIN_tvos_MIN_VER_FLAG}=9.0) + set(DARWIN_tvos_BUILTIN_MIN_VER 9.0) + set(DARWIN_tvos_BUILTIN_MIN_VER_FLAG + ${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_BUILTIN_MIN_VER}) + endif() # Note: In order to target x86_64h on OS X the minimum deployment target must # be 10.8 or higher. @@ -334,6 +380,11 @@ if(APPLE) -lc++ -lc++abi) + check_linker_flag("-fapplication-extension" COMPILER_RT_HAS_APP_EXTENSION) + if(COMPILER_RT_HAS_APP_EXTENSION) + list(APPEND DARWIN_COMMON_LINKFLAGS "-fapplication-extension") + endif() + set(DARWIN_osx_CFLAGS ${DARWIN_COMMON_CFLAGS} -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) @@ -379,62 +430,62 @@ if(APPLE) list(APPEND BUILTIN_SUPPORTED_OS 10.4) endif() - if(DARWIN_iossim_SYSROOT) - set(DARWIN_iossim_CFLAGS - ${DARWIN_COMMON_CFLAGS} - -mios-simulator-version-min=7.0 - -isysroot ${DARWIN_iossim_SYSROOT}) - set(DARWIN_iossim_LINKFLAGS - ${DARWIN_COMMON_LINKFLAGS} - -mios-simulator-version-min=7.0 - -isysroot ${DARWIN_iossim_SYSROOT}) - set(DARWIN_iossim_BUILTIN_MIN_VER 6.0) - set(DARWIN_iossim_BUILTIN_MIN_VER_FLAG - -mios-simulator-version-min=${DARWIN_iossim_BUILTIN_MIN_VER}) - - set(DARWIN_iossim_SKIP_CC_KEXT On) - darwin_test_archs(iossim - DARWIN_iossim_ARCHS - ${toolchain_arches}) - message(STATUS "iOS Simulator supported arches: ${DARWIN_iossim_ARCHS}") - if(DARWIN_iossim_ARCHS) - list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim) - list(APPEND BUILTIN_SUPPORTED_OS iossim) - list(APPEND PROFILE_SUPPORTED_OS iossim) + foreach(platform ${DARWIN_EMBEDDED_PLATFORMS}) + if(DARWIN_${platform}sim_SYSROOT) + set(DARWIN_${platform}sim_CFLAGS + ${DARWIN_COMMON_CFLAGS} + ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG} + -isysroot ${DARWIN_iossim_SYSROOT}) + set(DARWIN_${platform}sim_LINKFLAGS + ${DARWIN_COMMON_LINKFLAGS} + ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG} + -isysroot ${DARWIN_${platform}sim_SYSROOT}) + set(DARWIN_${platform}sim_BUILTIN_MIN_VER + ${DARWIN_${platform}_BUILTIN_MIN_VER}) + set(DARWIN_${platform}sim_BUILTIN_MIN_VER_FLAG + ${DARWIN_${platform}_BUILTIN_MIN_VER_FLAG}) + + set(DARWIN_${platform}sim_SKIP_CC_KEXT On) + darwin_test_archs(${platform}sim + DARWIN_${platform}sim_ARCHS + ${toolchain_arches}) + message(STATUS "${platform} Simulator supported arches: ${DARWIN_${platform}sim_ARCHS}") + if(DARWIN_iossim_ARCHS) + list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform}sim) + list(APPEND BUILTIN_SUPPORTED_OS ${platform}sim) + list(APPEND PROFILE_SUPPORTED_OS ${platform}sim) + endif() + foreach(arch ${DARWIN_${platform}sim_ARCHS}) + list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) + set(CAN_TARGET_${arch} 1) + endforeach() endif() - foreach(arch ${DARWIN_iossim_ARCHS}) - list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) - set(CAN_TARGET_${arch} 1) - endforeach() - endif() - if(DARWIN_ios_SYSROOT AND COMPILER_RT_ENABLE_IOS) - set(DARWIN_ios_CFLAGS - ${DARWIN_COMMON_CFLAGS} - -miphoneos-version-min=7.0 - -isysroot ${DARWIN_ios_SYSROOT}) - set(DARWIN_ios_LINKFLAGS - ${DARWIN_COMMON_LINKFLAGS} - -miphoneos-version-min=7.0 - -isysroot ${DARWIN_ios_SYSROOT}) - set(DARWIN_ios_BUILTIN_MIN_VER 6.0) - set(DARWIN_ios_BUILTIN_MIN_VER_FLAG - -miphoneos-version-min=${DARWIN_ios_BUILTIN_MIN_VER}) - - darwin_test_archs(ios - DARWIN_ios_ARCHS - ${toolchain_arches}) - message(STATUS "iOS supported arches: ${DARWIN_ios_ARCHS}") - if(DARWIN_ios_ARCHS) - list(APPEND SANITIZER_COMMON_SUPPORTED_OS ios) - list(APPEND BUILTIN_SUPPORTED_OS ios) - list(APPEND PROFILE_SUPPORTED_OS ios) + if(DARWIN_${platform}_SYSROOT) + set(DARWIN_${platform}_CFLAGS + ${DARWIN_COMMON_CFLAGS} + ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG} + -isysroot ${DARWIN_${platform}_SYSROOT}) + set(DARWIN_${platform}_LINKFLAGS + ${DARWIN_COMMON_LINKFLAGS} + ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG} + -isysroot ${DARWIN_${platform}_SYSROOT}) + + darwin_test_archs(${platform} + DARWIN_${platform}_ARCHS + ${toolchain_arches}) + message(STATUS "${platform} supported arches: ${DARWIN_${platform}_ARCHS}") + if(DARWIN_${platform}_ARCHS) + list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform}) + list(APPEND BUILTIN_SUPPORTED_OS ${platform}) + list(APPEND PROFILE_SUPPORTED_OS ${platform}) + endif() + foreach(arch ${DARWIN_${platform}_ARCHS}) + list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) + set(CAN_TARGET_${arch} 1) + endforeach() endif() - foreach(arch ${DARWIN_ios_ARCHS}) - list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch}) - set(CAN_TARGET_${arch} 1) - endforeach() - endif() + endforeach() endif() # for list_union diff --git a/include/sanitizer/common_interface_defs.h b/include/sanitizer/common_interface_defs.h index b736ed9e5235..b2a4bb7b89ee 100644 --- a/include/sanitizer/common_interface_defs.h +++ b/include/sanitizer/common_interface_defs.h @@ -125,9 +125,11 @@ extern "C" { // to know what is being passed to libc functions, e.g. memcmp. // FIXME: implement more hooks. void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1, - const void *s2, size_t n); + const void *s2, size_t n, int result); void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1, - const char *s2, size_t n); + const char *s2, size_t n, int result); + void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1, + const char *s2, int result); #ifdef __cplusplus } // extern "C" #endif diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc index 0fb60846c3b4..bb7e36e84652 100644 --- a/lib/asan/asan_report.cc +++ b/lib/asan/asan_report.cc @@ -696,9 +696,6 @@ class ScopedInErrorReport { error_message_buffer, kErrorMessageBufferSize); } - // Remove color sequences since logs cannot print them. - RemoveANSIEscapeSequencesFromString(buffer_copy.data()); - LogFullErrorReport(buffer_copy.data()); if (error_report_callback) { diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index 5ffad1d47b17..7ac4eea02624 100644 --- a/lib/builtins/CMakeLists.txt +++ b/lib/builtins/CMakeLists.txt @@ -353,6 +353,9 @@ set(mipsel_SOURCES ${mips_SOURCES}) set(mips64_SOURCES ${mips_SOURCES}) set(mips64el_SOURCES ${mips_SOURCES}) +set(wasm32_SOURCES ${GENERIC_SOURCES}) +set(wasm64_SOURCES ${GENERIC_SOURCES}) + add_custom_target(builtins) if (APPLE) diff --git a/lib/builtins/int_types.h b/lib/builtins/int_types.h index 2dad43bc7389..660385ecd6ae 100644 --- a/lib/builtins/int_types.h +++ b/lib/builtins/int_types.h @@ -61,7 +61,8 @@ typedef union } udwords; /* MIPS64 issue: PR 20098 */ -#if defined(__LP64__) && !(defined(__mips__) && defined(__clang__)) +#if (defined(__LP64__) || defined(__wasm__)) && \ + !(defined(__mips__) && defined(__clang__)) #define CRT_HAS_128BIT #endif diff --git a/lib/cfi/cfi.cc b/lib/cfi/cfi.cc index 0e2a09190699..711866f3fa0c 100644 --- a/lib/cfi/cfi.cc +++ b/lib/cfi/cfi.cc @@ -42,7 +42,7 @@ static uint16_t *mem_to_shadow(uptr x) { return (uint16_t *)(__cfi_shadow + ((x >> kShadowGranularity) << 1)); } -typedef int (*CFICheckFn)(uptr, void *); +typedef int (*CFICheckFn)(u64, void *); class ShadowValue { uptr addr; @@ -189,9 +189,9 @@ static void init_shadow() { } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -void __cfi_slowpath(uptr CallSiteTypeId, void *Ptr) { +void __cfi_slowpath(u64 CallSiteTypeId, void *Ptr) { uptr Addr = (uptr)Ptr; - VReport(3, "__cfi_slowpath: %zx, %p\n", CallSiteTypeId, Ptr); + VReport(3, "__cfi_slowpath: %llx, %p\n", CallSiteTypeId, Ptr); ShadowValue sv = ShadowValue::load(Addr); if (sv.is_invalid()) { VReport(2, "CFI: invalid memory region for a function pointer (shadow==0): %p\n", Ptr); diff --git a/lib/profile/CMakeLists.txt b/lib/profile/CMakeLists.txt index 3f84c0e6db35..17eb48a5b279 100644 --- a/lib/profile/CMakeLists.txt +++ b/lib/profile/CMakeLists.txt @@ -35,16 +35,16 @@ set(PROFILE_SOURCES InstrProfilingPlatformLinux.c InstrProfilingPlatformOther.c InstrProfilingRuntime.cc - InstrProfilingUtil.c - WindowsMMap.c) + InstrProfilingUtil.c) + +if(WIN32) + list(APPEND PROFILE_SOURCES WindowsMMap.c) +endif() if(UNIX) set(EXTRA_FLAGS -fPIC -Wno-pedantic) -else() - set(EXTRA_FLAGS - -fPIC) endif() if(COMPILER_RT_TARGET_HAS_ATOMICS) diff --git a/lib/profile/InstrProfData.inc b/lib/profile/InstrProfData.inc index 3a7c0c5f2773..33c7d94aea2a 100644 --- a/lib/profile/InstrProfData.inc +++ b/lib/profile/InstrProfData.inc @@ -28,7 +28,7 @@ * * Examples of how the template is used to instantiate structure definition: * 1. To declare a structure: - * + * * struct ProfData { * #define INSTR_PROF_DATA(Type, LLVMType, Name, Initializer) \ * Type Name; @@ -155,7 +155,7 @@ VALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget) #endif COVMAP_FUNC_RECORD(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), \ NamePtr, llvm::ConstantExpr::getBitCast(NamePtr, \ - llvm::Type::getInt8PtrTy(Ctx))) + llvm::Type::getInt8PtrTy(Ctx))) COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \ llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\ NameValue.size())) @@ -182,7 +182,7 @@ COVMAP_HEADER(uint32_t, Int32Ty, FilenamesSize, \ COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \ llvm::ConstantInt::get(Int32Ty, CoverageMappingSize)) COVMAP_HEADER(uint32_t, Int32Ty, Version, \ - llvm::ConstantInt::get(Int32Ty, CoverageMappingVersion1)) + llvm::ConstantInt::get(Int32Ty, CoverageMappingCurrentVersion)) #undef COVMAP_HEADER /* COVMAP_HEADER end. */ @@ -190,7 +190,8 @@ COVMAP_HEADER(uint32_t, Int32Ty, Version, \ #ifdef INSTR_PROF_VALUE_PROF_DATA #define INSTR_PROF_DATA_DEFINED -/*! +#define INSTR_PROF_MAX_NUM_VAL_PER_SITE 255 +/*! * This is the header of the data structure that defines the on-disk * layout of the value profile data of a particular kind for one function. */ @@ -202,7 +203,7 @@ typedef struct ValueProfRecord { * otherwise the record for this kind won't be emitted. */ uint32_t NumValueSites; - /* + /* * The first element of the array that stores the number of profiled * values for each value site. The size of the array is NumValueSites. * Since NumValueSites is greater than zero, there is at least one @@ -226,7 +227,7 @@ typedef struct ValueProfRecord { * \brief Return the number of value sites. */ uint32_t getNumValueSites() const { return NumValueSites; } - /*! + /*! * \brief Read data from this record and save it to Record. */ void deserializeTo(InstrProfRecord &Record, @@ -247,10 +248,10 @@ typedef struct ValueProfRecord { typedef struct ValueProfData { /* * Total size in bytes including this field. It must be a multiple - * of sizeof(uint64_t). + * of sizeof(uint64_t). */ uint32_t TotalSize; - /* + /* *The number of value profile kinds that has value profile data. * In this implementation, a value profile kind is considered to * have profile data if the number of value profile sites for the @@ -260,7 +261,7 @@ typedef struct ValueProfData { */ uint32_t NumValueKinds; - /* + /* * Following are a sequence of variable length records. The prefix/header * of each record is defined by ValueProfRecord type. The number of * records is NumValueKinds. @@ -314,7 +315,7 @@ typedef struct ValueProfData { #endif } ValueProfData; -/* +/* * The closure is designed to abstact away two types of value profile data: * - InstrProfRecord which is the primary data structure used to * represent profile data in host tools (reader, writer, and profile-use) @@ -335,7 +336,7 @@ typedef struct ValueProfRecordClosure { uint32_t (*GetNumValueData)(const void *Record, uint32_t VKind); uint32_t (*GetNumValueDataForSite)(const void *R, uint32_t VK, uint32_t S); - /* + /* * After extracting the value profile data from the value profile record, * this method is used to map the in-memory value to on-disk value. If * the method is null, value will be written out untranslated. @@ -346,7 +347,7 @@ typedef struct ValueProfRecordClosure { ValueProfData *(*AllocValueProfData)(size_t TotalSizeInBytes); } ValueProfRecordClosure; -/* +/* * A wrapper struct that represents value profile runtime data. * Like InstrProfRecord class which is used by profiling host tools, * ValueProfRuntimeRecord also implements the abstract intefaces defined in @@ -384,7 +385,7 @@ serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record, uint32_t getNumValueKindsRT(const void *R); #undef INSTR_PROF_VALUE_PROF_DATA -#endif /* INSTR_PROF_VALUE_PROF_DATA */ +#endif /* INSTR_PROF_VALUE_PROF_DATA */ #ifdef INSTR_PROF_COMMON_API_IMPL @@ -412,7 +413,7 @@ uint32_t getValueProfRecordHeaderSize(uint32_t NumValueSites) { return Size; } -/*! +/*! * \brief Return the total size of the value profile record including the * header and the value data. */ @@ -432,7 +433,7 @@ InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) { This->NumValueSites)); } -/*! +/*! * \brief Return the total number of value data for \c This record. */ INSTR_PROF_INLINE @@ -444,7 +445,7 @@ uint32_t getValueProfRecordNumValueData(ValueProfRecord *This) { return NumValueData; } -/*! +/*! * \brief Use this method to advance to the next \c This \c ValueProfRecord. */ INSTR_PROF_INLINE @@ -465,7 +466,7 @@ ValueProfRecord *getFirstValueProfRecord(ValueProfData *This) { /* Closure based interfaces. */ -/*! +/*! * Return the total size in bytes of the on-disk value profile data * given the data stored in Record. */ @@ -535,7 +536,7 @@ ValueProfData *serializeValueProfDataFrom(ValueProfRecordClosure *Closure, return VPD; } -/* +/* * The value profiler runtime library stores the value profile data * for a given function in \c NumValueSites and \c Nodes structures. * \c ValueProfRuntimeRecord class is used to encapsulate the runtime @@ -639,7 +640,7 @@ static ValueProfRecordClosure RTRecordClosure = {0, getValueForSiteRT, allocValueProfDataRT}; -/* +/* * Return the size of ValueProfData structure to store data * recorded in the runtime record. */ @@ -648,7 +649,7 @@ uint32_t getValueProfDataSizeRT(const ValueProfRuntimeRecord *Record) { return getValueProfDataSize(&RTRecordClosure); } -/* +/* * Return a ValueProfData instance that stores the data collected * from runtime. If \c DstData is provided by the caller, the value * profile data will be store in *DstData and DstData is returned, @@ -696,18 +697,31 @@ serializeValueProfDataFromRT(const ValueProfRuntimeRecord *Record, /* Raw profile format version. */ #define INSTR_PROF_RAW_VERSION 2 +#define INSTR_PROF_INDEX_VERSION 3 +#define INSTR_PROF_COVMAP_VERSION 0 + +/* Profile version is always of type uint_64_t. Reserve the upper 8 bits in the + * version for other variants of profile. We set the lowest bit of the upper 8 + * bits (i.e. bit 56) to 1 to indicate if this is an IR-level instrumentaiton + * generated profile, and 0 if this is a Clang FE generated profile. +*/ +#define VARIANT_MASKS_ALL 0xff00000000000000ULL +#define GET_VERSION(V) ((V) & ~VARIANT_MASKS_ALL) /* Runtime section names and name strings. */ #define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data #define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names #define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts +#define INSTR_PROF_COVMAP_SECT_NAME __llvm_covmap -#define INSTR_PROF_DATA_SECT_NAME_STR \ - INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME) -#define INSTR_PROF_NAME_SECT_NAME_STR \ - INSTR_PROF_QUOTE(INSTR_PROF_NAME_SECT_NAME) -#define INSTR_PROF_CNTS_SECT_NAME_STR \ - INSTR_PROF_QUOTE(INSTR_PROF_CNTS_SECT_NAME) +#define INSTR_PROF_DATA_SECT_NAME_STR \ + INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME) +#define INSTR_PROF_NAME_SECT_NAME_STR \ + INSTR_PROF_QUOTE(INSTR_PROF_NAME_SECT_NAME) +#define INSTR_PROF_CNTS_SECT_NAME_STR \ + INSTR_PROF_QUOTE(INSTR_PROF_CNTS_SECT_NAME) +#define INSTR_PROF_COVMAP_SECT_NAME_STR \ + INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_SECT_NAME) /* Macros to define start/stop section symbol for a given * section on Linux. For instance @@ -751,4 +765,3 @@ typedef struct ValueProfNode { #else #undef INSTR_PROF_DATA_DEFINED #endif - diff --git a/lib/profile/InstrProfiling.c b/lib/profile/InstrProfiling.c index 58778aeec16a..711f2b608a5f 100644 --- a/lib/profile/InstrProfiling.c +++ b/lib/profile/InstrProfiling.c @@ -18,6 +18,8 @@ char *(*GetEnvHook)(const char *) = 0; +COMPILER_RT_WEAK uint64_t __llvm_profile_raw_version = INSTR_PROF_RAW_VERSION; + COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_magic(void) { return sizeof(void *) == sizeof(uint64_t) ? (INSTR_PROF_RAW_MAGIC_64) : (INSTR_PROF_RAW_MAGIC_32); @@ -32,7 +34,7 @@ __llvm_profile_get_num_padding_bytes(uint64_t SizeInBytes) { } COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_version(void) { - return INSTR_PROF_RAW_VERSION; + return __llvm_profile_raw_version; } COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) { @@ -65,4 +67,3 @@ COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) { } } } - diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c index bf50c02761d3..68d088a1956a 100644 --- a/lib/profile/InstrProfilingFile.c +++ b/lib/profile/InstrProfilingFile.c @@ -214,6 +214,15 @@ int __llvm_profile_write_file(void) { return -1; } + /* Check if there is llvm/runtime version mismatch. */ + if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) { + PROF_ERR("LLVM Profile: runtime and instrumentation version mismatch : " + "expected %d, but get %d\n", + INSTR_PROF_RAW_VERSION, + (int)GET_VERSION(__llvm_profile_get_version())); + return -1; + } + /* Write the file. */ rc = writeFileWithName(__llvm_profile_CurrentFilename); if (rc) diff --git a/lib/profile/InstrProfilingPort.h b/lib/profile/InstrProfilingPort.h index 5da814a4a3d7..e07f59878730 100644 --- a/lib/profile/InstrProfilingPort.h +++ b/lib/profile/InstrProfilingPort.h @@ -29,16 +29,16 @@ #define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV) \ (InterlockedCompareExchange64((LONGLONG volatile *)Ptr, (LONGLONG)NewV, \ (LONGLONG)OldV) == (LONGLONG)OldV) -#else +#else /* !defined(_WIN64) */ #define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV) \ (InterlockedCompareExchange((LONG volatile *)Ptr, (LONG)NewV, (LONG)OldV) == \ (LONG)OldV) #endif -#else +#else /* !defined(_MSC_VER) */ #define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV) \ __sync_bool_compare_and_swap(Ptr, OldV, NewV) #endif -#else +#else /* COMPILER_RT_HAS_ATOMICS != 1 */ #define COMPILER_RT_BOOL_CMPXCHG(Ptr, OldV, NewV) \ BoolCmpXchg((void **)Ptr, OldV, NewV) #endif diff --git a/lib/profile/InstrProfilingValue.c b/lib/profile/InstrProfilingValue.c index 39b4da446a81..68e16cff9cbc 100644 --- a/lib/profile/InstrProfilingValue.c +++ b/lib/profile/InstrProfilingValue.c @@ -107,7 +107,7 @@ __llvm_profile_instrument_target(uint64_t TargetValue, void *Data, ++VDataCount; } - if (VDataCount >= UCHAR_MAX) + if (VDataCount >= INSTR_PROF_MAX_NUM_VAL_PER_SITE) return; CurrentVNode = (ValueProfNode *)calloc(1, sizeof(ValueProfNode)); diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index 0585f6b15b87..7e80507ba0cf 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -665,17 +665,17 @@ INLINE void LogFullErrorReport(const char *buffer) {} #if SANITIZER_LINUX || SANITIZER_MAC void WriteOneLineToSyslog(const char *s); +void LogMessageOnPrintf(const char *str); #else INLINE void WriteOneLineToSyslog(const char *s) {} +INLINE void LogMessageOnPrintf(const char *str) {} #endif #if SANITIZER_LINUX // Initialize Android logging. Any writes before this are silently lost. void AndroidLogInit(); -bool ShouldLogAfterPrintf(); #else INLINE void AndroidLogInit() {} -INLINE bool ShouldLogAfterPrintf() { return false; } #endif #if SANITIZER_ANDROID diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 4639ddc92c6c..2a748cdc6852 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -214,13 +214,11 @@ static inline int CharCmpX(unsigned char c1, unsigned char c2) { } DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc, - const char *s1, const char *s2) + const char *s1, const char *s2, int result) INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); - CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1, - s2); unsigned char c1, c2; uptr i; for (i = 0;; i++) { @@ -230,19 +228,21 @@ INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { } COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); - return CharCmpX(c1, c2); + int result = CharCmpX(c1, c2); + CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1, + s2, result); + return result; } DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc, - const char *s1, const char *s2, uptr n) + const char *s1, const char *s2, uptr n, + int result) INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_strncmp(s1, s2, size); void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); - CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1, - s2, size); unsigned char c1 = 0, c2 = 0; uptr i; for (i = 0; i < size; i++) { @@ -252,7 +252,10 @@ INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { } COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); - return CharCmpX(c1, c2); + int result = CharCmpX(c1, c2); + CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1, + s2, size, result); + return result; } #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp) @@ -400,15 +403,14 @@ INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) { #if SANITIZER_INTERCEPT_MEMCMP DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc, - const void *s1, const void *s2, uptr n) + const void *s1, const void *s2, uptr n, + int result) INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_memcmp(a1, a2, size); void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size); - CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1, - a2, size); if (common_flags()->intercept_memcmp) { if (common_flags()->strict_memcmp) { // Check the entire regions even if the first bytes of the buffers are @@ -428,10 +430,16 @@ INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { } COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); - return CharCmpX(c1, c2); + int r = CharCmpX(c1, c2); + CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), + a1, a2, size, r); + return r; } } - return REAL(memcmp(a1, a2, size)); + int result = REAL(memcmp(a1, a2, size)); + CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1, + a2, size, result); + return result; } #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp) diff --git a/lib/sanitizer_common/sanitizer_common_libcdep.cc b/lib/sanitizer_common/sanitizer_common_libcdep.cc index b5d46f244f66..596f5bcd3173 100644 --- a/lib/sanitizer_common/sanitizer_common_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_common_libcdep.cc @@ -125,9 +125,6 @@ void WriteToSyslog(const char *msg) { char *p = msg_copy.data(); char *q; - // Remove color sequences since syslogs cannot print them. - RemoveANSIEscapeSequencesFromString(p); - // Print one line at a time. // syslog, at least on Android, has an implicit message length limit. do { diff --git a/lib/sanitizer_common/sanitizer_common_nolibc.cc b/lib/sanitizer_common/sanitizer_common_nolibc.cc index 89c17e0797ef..9f4f97224e18 100644 --- a/lib/sanitizer_common/sanitizer_common_nolibc.cc +++ b/lib/sanitizer_common/sanitizer_common_nolibc.cc @@ -19,6 +19,7 @@ namespace __sanitizer { #if SANITIZER_LINUX bool ShouldLogAfterPrintf() { return false; } +void LogMessageOnPrintf(const char *str) {} #endif void WriteToSyslog(const char *buffer) {} void Abort() { internal__exit(1); } diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 0bb66c9d634e..8cf2c73b1d53 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -524,13 +524,13 @@ void AndroidLogInit() { atomic_store(&android_log_initialized, 1, memory_order_release); } -bool ShouldLogAfterPrintf() { +static bool ShouldLogAfterPrintf() { return atomic_load(&android_log_initialized, memory_order_acquire); } #else void AndroidLogInit() {} -bool ShouldLogAfterPrintf() { return true; } +static bool ShouldLogAfterPrintf() { return true; } #endif // SANITIZER_ANDROID void WriteOneLineToSyslog(const char *s) { @@ -541,6 +541,11 @@ void WriteOneLineToSyslog(const char *s) { #endif } +void LogMessageOnPrintf(const char *str) { + if (common_flags()->log_to_syslog && ShouldLogAfterPrintf()) + WriteToSyslog(str); +} + #endif // SANITIZER_LINUX } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc index 1c96a6b95621..715509d30746 100644 --- a/lib/sanitizer_common/sanitizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_mac.cc @@ -430,6 +430,12 @@ void WriteOneLineToSyslog(const char *s) { asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", s); } +void LogMessageOnPrintf(const char *str) { + // Log all printf output to CrashLog. + if (common_flags()->abort_on_error) + CRAppendCrashLogMessage(str); +} + void LogFullErrorReport(const char *buffer) { // Log with os_trace. This will make it into the crash log. #if SANITIZER_OS_TRACE @@ -463,9 +469,7 @@ void LogFullErrorReport(const char *buffer) { if (common_flags()->log_to_syslog) WriteToSyslog(buffer); - // Log to CrashLog. - if (common_flags()->abort_on_error) - CRSetCrashLogMessage(buffer); + // The report is added to CrashLog as part of logging all of Printf output. } void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { diff --git a/lib/sanitizer_common/sanitizer_mac.h b/lib/sanitizer_common/sanitizer_mac.h index 86a9956683d0..6e2b84f432e5 100644 --- a/lib/sanitizer_common/sanitizer_mac.h +++ b/lib/sanitizer_common/sanitizer_mac.h @@ -44,9 +44,11 @@ static const char *__crashreporter_info__ __attribute__((__used__)) = &__crashreporter_info_buff__[0]; asm(".desc ___crashreporter_info__, 0x10"); } // extern "C" +static BlockingMutex crashreporter_info_mutex(LINKER_INITIALIZED); -INLINE void CRSetCrashLogMessage(const char *msg) { - internal_strlcpy(__crashreporter_info_buff__, msg, +INLINE void CRAppendCrashLogMessage(const char *msg) { + BlockingMutexLock l(&crashreporter_info_mutex); + internal_strlcat(__crashreporter_info_buff__, msg, sizeof(__crashreporter_info_buff__)); } #endif // SANITIZER_MAC diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cc index 2794e667e697..434ebb93dffa 100644 --- a/lib/sanitizer_common/sanitizer_printf.cc +++ b/lib/sanitizer_common/sanitizer_printf.cc @@ -278,9 +278,12 @@ static void SharedPrintfCode(bool append_pid, const char *format, # undef CHECK_NEEDED_LENGTH } RawWrite(buffer); - if (common_flags()->log_to_syslog && ShouldLogAfterPrintf()) - WriteToSyslog(buffer); + + // Remove color sequences from the message. + RemoveANSIEscapeSequencesFromString(buffer); CallPrintfAndReportCallback(buffer); + LogMessageOnPrintf(buffer); + // If we had mapped any memory, clean up. if (buffer != local_buffer) UnmapOrDie((void *)buffer, buffer_size); diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 62c96cb42047..7c835c6dc7df 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -1892,8 +1892,10 @@ TSAN_INTERCEPTOR(int, rmdir, char *path) { TSAN_INTERCEPTOR(int, closedir, void *dirp) { SCOPED_TSAN_INTERCEPTOR(closedir, dirp); - int fd = dirfd(dirp); - FdClose(thr, pc, fd); + if (dirp) { + int fd = dirfd(dirp); + FdClose(thr, pc, fd); + } return REAL(closedir)(dirp); } diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt index c4f7eb92c524..5626a6e50ed7 100644 --- a/test/cfi/CMakeLists.txt +++ b/test/cfi/CMakeLists.txt @@ -6,10 +6,12 @@ configure_lit_site_cfg( set(CFI_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) if(NOT COMPILER_RT_STANDALONE_BUILD) list(APPEND CFI_TEST_DEPS - cfi opt ubsan ) + if(COMPILER_RT_HAS_CFI) + list(APPEND CFI_TEST_DEPS cfi) + endif() if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR) list(APPEND CFI_TEST_DEPS LLVMgold diff --git a/test/msan/insertvalue_origin.cc b/test/msan/insertvalue_origin.cc index 96d27f08937e..a0c70023f2f6 100644 --- a/test/msan/insertvalue_origin.cc +++ b/test/msan/insertvalue_origin.cc @@ -4,7 +4,6 @@ // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out // Test origin propagation through insertvalue IR instruction. -// REQUIRES: stable-runtime #include <stdio.h> #include <stdint.h> diff --git a/test/profile/Linux/instrprof-basic.c b/test/profile/Linux/instrprof-basic.c new file mode 100644 index 000000000000..7ae683d9bd9e --- /dev/null +++ b/test/profile/Linux/instrprof-basic.c @@ -0,0 +1,31 @@ +// RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t -O3 %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata merge -o %t.profdata %t.profraw +// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s + +int begin(int i) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + if (i) + return 0; + return 1; +} + +int end(int i) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD2:[0-9]+]] + if (i) + return 0; + return 1; +} + +int main(int argc, const char *argv[]) { + begin(0); + end(1); + + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD2:[0-9]+]] + if (argc) + return 0; + return 1; +} + +// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} +// CHECK: ![[PD2]] = !{!"branch_weights", i32 2, i32 1} diff --git a/test/profile/Linux/instrprof-dlopen.test b/test/profile/Linux/instrprof-dlopen.test new file mode 100644 index 000000000000..618367c5defb --- /dev/null +++ b/test/profile/Linux/instrprof-dlopen.test @@ -0,0 +1,34 @@ +RUN: mkdir -p %t.d +RUN: %clang_profgen -o %t.d/func.shared -fPIC -shared -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections %S/../Inputs/instrprof-dlopen-func.c +RUN: %clang_profgen -o %t.d/func2.shared -fPIC -shared -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections %S/../Inputs/instrprof-dlopen-func2.c +RUN: %clang -o %t-local -fPIC -DDLOPEN_FUNC_DIR=\"%t.d\" -DDLOPEN_FLAGS="RTLD_LAZY | RTLD_LOCAL" %S/../Inputs/instrprof-dlopen-main.c +RUN: %clang -o %t-global -fPIC -DDLOPEN_FUNC_DIR=\"%t.d\" -DDLOPEN_FLAGS="RTLD_LAZY | RTLD_GLOBAL" %S/../Inputs/instrprof-dlopen-main.c + +RUN: %clang -c -o %t.d/main.o %S/../Inputs/instrprof-dlopen-main.c +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t-static %S/../Inputs/instrprof-dlopen-func.c %S/../Inputs/instrprof-dlopen-func2.c %t.d/main.o + +RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static +RUN: env LLVM_PROFILE_FILE=%t-local.profraw %run %t-local +RUN: env LLVM_PROFILE_FILE=%t-global.profraw %run %t-global + +RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw +RUN: llvm-profdata merge -o %t-local.profdata %t-local.profraw +RUN: llvm-profdata merge -o %t-global.profdata %t-global.profraw + +RUN: %clang_profuse=%t-static.profdata -o %t-func.static.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-func.c +RUN: %clang_profuse=%t-local.profdata -o %t-func.local.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-func.c +RUN: %clang_profuse=%t-global.profdata -o %t-func.global.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-func.c +RUN: diff %t-func.static.ll %t-func.local.ll +RUN: diff %t-func.static.ll %t-func.global.ll + +RUN: %clang_profuse=%t-static.profdata -o %t-func2.static.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-func2.c +RUN: %clang_profuse=%t-local.profdata -o %t-func2.local.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-func2.c +RUN: %clang_profuse=%t-global.profdata -o %t-func2.global.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-func2.c +RUN: diff %t-func2.static.ll %t-func2.local.ll +RUN: diff %t-func2.static.ll %t-func2.global.ll + +RUN: %clang_profuse=%t-static.profdata -o %t-main.static.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-main.c +RUN: %clang_profuse=%t-local.profdata -o %t-main.local.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-main.c +RUN: %clang_profuse=%t-local.profdata -o %t-main.global.ll -S -emit-llvm %S/../Inputs/instrprof-dlopen-main.c +RUN: diff %t-main.static.ll %t-main.local.ll +RUN: diff %t-main.static.ll %t-main.global.ll diff --git a/test/profile/Linux/instrprof-dynamic-one-shared.test b/test/profile/Linux/instrprof-dynamic-one-shared.test new file mode 100644 index 000000000000..52f40bf9bee1 --- /dev/null +++ b/test/profile/Linux/instrprof-dynamic-one-shared.test @@ -0,0 +1,23 @@ +RUN: mkdir -p %t.d +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t.d/a.shared -fPIC -shared %S/../Inputs/instrprof-dynamic-a.cpp +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t-shared -fPIC -rpath %t.d %t.d/a.shared %S/../Inputs/instrprof-dynamic-b.cpp %S/../Inputs/instrprof-dynamic-main.cpp + +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t-static %S/../Inputs/instrprof-dynamic-a.cpp %S/../Inputs/instrprof-dynamic-b.cpp %S/../Inputs/instrprof-dynamic-main.cpp + +RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static +RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared + +RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw +RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw + +RUN: %clang_profuse=%t-static.profdata -o %t-a.static.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-a.cpp +RUN: %clang_profuse=%t-shared.profdata -o %t-a.shared.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-a.cpp +RUN: diff %t-a.static.ll %t-a.shared.ll + +RUN: %clang_profuse=%t-static.profdata -o %t-b.static.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-b.cpp +RUN: %clang_profuse=%t-shared.profdata -o %t-b.shared.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-b.cpp +RUN: diff %t-b.static.ll %t-b.shared.ll + +RUN: %clang_profuse=%t-static.profdata -o %t-main.static.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-main.cpp +RUN: %clang_profuse=%t-shared.profdata -o %t-main.shared.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-main.cpp +RUN: diff %t-main.static.ll %t-main.shared.ll diff --git a/test/profile/Linux/instrprof-dynamic-two-shared.test b/test/profile/Linux/instrprof-dynamic-two-shared.test new file mode 100644 index 000000000000..949914603ba4 --- /dev/null +++ b/test/profile/Linux/instrprof-dynamic-two-shared.test @@ -0,0 +1,24 @@ +RUN: mkdir -p %t.d +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t.d/a.shared -fPIC -shared %S/../Inputs/instrprof-dynamic-a.cpp +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t.d/b.shared -fPIC -shared %S/../Inputs/instrprof-dynamic-b.cpp +RUN: %clang_profgen -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections -o %t-shared -fPIC -rpath %t.d %t.d/a.shared %t.d/b.shared %S/../Inputs/instrprof-dynamic-main.cpp + +RUN: %clang_profgen -o %t-static %S/../Inputs/instrprof-dynamic-a.cpp %S/../Inputs/instrprof-dynamic-b.cpp %S/../Inputs/instrprof-dynamic-main.cpp + +RUN: env LLVM_PROFILE_FILE=%t-static.profraw %run %t-static +RUN: env LLVM_PROFILE_FILE=%t-shared.profraw %run %t-shared + +RUN: llvm-profdata merge -o %t-static.profdata %t-static.profraw +RUN: llvm-profdata merge -o %t-shared.profdata %t-shared.profraw + +RUN: %clang_profuse=%t-static.profdata -o %t-a.static.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-a.cpp +RUN: %clang_profuse=%t-shared.profdata -o %t-a.shared.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-a.cpp +RUN: diff %t-a.static.ll %t-a.shared.ll + +RUN: %clang_profuse=%t-static.profdata -o %t-b.static.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-b.cpp +RUN: %clang_profuse=%t-shared.profdata -o %t-b.shared.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-b.cpp +RUN: diff %t-b.static.ll %t-b.shared.ll + +RUN: %clang_profuse=%t-static.profdata -o %t-main.static.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-main.cpp +RUN: %clang_profuse=%t-shared.profdata -o %t-main.shared.ll -S -emit-llvm %S/../Inputs/instrprof-dynamic-main.cpp +RUN: diff %t-main.static.ll %t-main.shared.ll diff --git a/test/profile/Linux/lit.local.cfg b/test/profile/Linux/lit.local.cfg new file mode 100644 index 000000000000..c8c79fc7d8a7 --- /dev/null +++ b/test/profile/Linux/lit.local.cfg @@ -0,0 +1,37 @@ +import subprocess + +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + + +def is_gold_linker_available(): + + if not config.gold_executable: + return False + try: + ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE) + ld_out = ld_cmd.stdout.read().decode() + ld_cmd.wait() + except: + return False + + if not '-plugin' in ld_out: + return False + + clang_cmd = subprocess.Popen([config.clang, '-fuse-ld=gold', '-xc', '-'], + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE) + clang_err = clang_cmd.communicate('int main() { return 0; }')[1] + + if not 'invalid linker' in clang_err: + return True + + return False + +root = getRoot(config) + +if root.host_os not in ['Linux'] or not is_gold_linker_available(): + config.unsupported = True diff --git a/test/profile/instrprof-shared.test b/test/profile/instrprof-shared.test index 851578b0f2c0..b3f0b9ab4bcc 100644 --- a/test/profile/instrprof-shared.test +++ b/test/profile/instrprof-shared.test @@ -3,7 +3,7 @@ This test produces three shared libraries: 1. libt-instr.so is instrumented 2. libt-no-instr1.so is not instrumented -3. libt-no-instr2.so is compiled with instrumentation enabled, but the object file is built +3. libt-no-instr2.so is built with profile rt linked in (via -u<hook>), but the object file is built with instrumentation turned off. After the libraries are built, the main program is then built with/without instrumentation and linked diff --git a/test/profile/instrprof-value-prof.c b/test/profile/instrprof-value-prof.c index 3ccecbe75593..f09e1ac432f1 100644 --- a/test/profile/instrprof-value-prof.c +++ b/test/profile/instrprof-value-prof.c @@ -6,9 +6,7 @@ // RUN: llvm-profdata merge -o %t-merged.profdata %t.profraw %t-2.profdata // RUN: llvm-profdata show --all-functions -ic-targets %t-2.profdata | FileCheck %s -check-prefix=NO-VALUE // RUN: llvm-profdata show --all-functions -ic-targets %t.profdata | FileCheck %s -// value profile merging current do sorting based on target values -- this will destroy the order of the target -// in the list leading to comparison problem. For now just check a small subset of output. -// RUN: llvm-profdata show --all-functions -ic-targets %t-merged.profdata | FileCheck %s -check-prefix=MERGE +// RUN: llvm-profdata show --all-functions -ic-targets %t-merged.profdata | FileCheck %s // // RUN: env LLVM_PROFILE_FILE=%t-3.profraw LLVM_VP_BUFFER_SIZE=1 %run %t 1 // RUN: env LLVM_PROFILE_FILE=%t-4.profraw LLVM_VP_BUFFER_SIZE=8 %run %t 1 @@ -126,128 +124,102 @@ int main(int argc, const char *argv[]) { // NO-VALUE: Indirect Call Site Count: 127 // NO-VALUE-NEXT: Indirect Target Results: -// MERGE-LABEL: caller_1_1_1_1_2_2_1: -// MERGE: Indirect Call Site Count: 6 -// MERGE: Indirect Target Results: -// MERGE: [ 1, callee_1_1_1, 1 ] -// MERGE: [ 2, callee_1_1_1, 1 ] -// MERGE: [ 2, callee_1_1_2, 2 ] -// MERGE: [ 3, callee_1_1_1, 1 ] -// MERGE: [ 3, callee_1_1_2, 2 ] -// MERGE: [ 3, callee_1_2_1, 3 ] -// MERGE: [ 4, callee_1_1_1, 1 ] -// MERGE: [ 4, callee_1_1_2, 2 ] -// MERGE: [ 4, callee_1_2_1, 3 ] -// MERGE: [ 4, callee_1_2_2, 4 ] -// MERGE: [ 5, callee_1_1_1, 1 ] -// MERGE: [ 5, callee_1_1_2, 2 ] -// MERGE: [ 5, callee_1_2_1, 3 ] -// MERGE: [ 5, callee_1_2_2, 4 ] -// MERGE: [ 5, callee_2_1_1, 5 ] -// MERGE-LABEL: caller_2_2_2_2_2_2_2: -// MERGE: Indirect Call Site Count: 127 -// MERGE-NEXT: Indirect Target Results: -// MERGE-NEXT: [ 1, callee_1_1_1, 1 ] -// MERGE: [ 2, callee_1_1_1, 1 ] -// MERGE: [ 2, callee_1_1_2, 2 ] -// MERGE: [ 3, callee_1_1_1, 1 ] -// MERGE: [ 3, callee_1_1_2, 2 ] -// MERGE: [ 3, callee_1_2_1, 3 ] // CHECK-LABEL: caller_1_1_1_1_2_2_1: // CHECK: Indirect Call Site Count: 6 // CHECK-NEXT: Indirect Target Results: // CHECK-NEXT: [ 1, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 2, callee_1_1_1, 1 ] // CHECK-NEXT: [ 2, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 3, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 3, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 2, callee_1_1_1, 1 ] // CHECK-NEXT: [ 3, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 4, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 4, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 4, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 3, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 3, callee_1_1_1, 1 ] // CHECK-NEXT: [ 4, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 5, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 5, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 5, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 5, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 4, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 4, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 4, callee_1_1_1, 1 ] // CHECK-NEXT: [ 5, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 5, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 5, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 5, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 5, callee_1_1_1, 1 ] // CHECK-LABEL: caller_2_2_2_2_2_2_2: // CHECK: Indirect Call Site Count: 127 // CHECK-NEXT: Indirect Target Results: // CHECK-NEXT: [ 1, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 2, callee_1_1_1, 1 ] // CHECK-NEXT: [ 2, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 3, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 3, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 2, callee_1_1_1, 1 ] // CHECK-NEXT: [ 3, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 4, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 4, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 4, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 3, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 3, callee_1_1_1, 1 ] // CHECK-NEXT: [ 4, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 5, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 5, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 5, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 5, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 4, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 4, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 4, callee_1_1_1, 1 ] // CHECK-NEXT: [ 5, callee_2_1_1, 5 ] -// CHECK-NEXT: [ 6, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 6, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 6, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 6, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 6, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 5, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 5, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 5, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 5, callee_1_1_1, 1 ] // CHECK-NEXT: [ 6, callee_2_1_2, 6 ] -// CHECK-NEXT: [ 7, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 7, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 7, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 7, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 7, callee_2_1_1, 5 ] -// CHECK-NEXT: [ 7, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 6, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 6, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 6, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 6, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 6, callee_1_1_1, 1 ] // CHECK-NEXT: [ 7, callee_2_2_1, 7 ] +// CHECK-NEXT: [ 7, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 7, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 7, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 7, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 7, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 7, callee_1_1_1, 1 ] // CHECK-NEXT: [ 9, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 10, callee_1_1_1, 1 ] // CHECK-NEXT: [ 10, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 11, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 11, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 10, callee_1_1_1, 1 ] // CHECK-NEXT: [ 11, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 12, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 12, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 12, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 11, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 11, callee_1_1_1, 1 ] // CHECK-NEXT: [ 12, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 13, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 13, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 13, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 13, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 12, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 12, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 12, callee_1_1_1, 1 ] // CHECK-NEXT: [ 13, callee_2_1_1, 5 ] -// CHECK-NEXT: [ 14, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 14, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 14, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 14, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 14, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 13, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 13, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 13, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 13, callee_1_1_1, 1 ] // CHECK-NEXT: [ 14, callee_2_1_2, 6 ] -// CHECK-NEXT: [ 15, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 15, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 15, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 15, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 15, callee_2_1_1, 5 ] -// CHECK-NEXT: [ 15, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 14, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 14, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 14, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 14, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 14, callee_1_1_1, 1 ] // CHECK-NEXT: [ 15, callee_2_2_1, 7 ] +// CHECK-NEXT: [ 15, callee_2_1_2, 6 ] +// CHECK-NEXT: [ 15, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 15, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 15, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 15, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 15, callee_1_1_1, 1 ] // CHECK-NEXT: [ 17, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 18, callee_1_1_1, 1 ] // CHECK-NEXT: [ 18, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 19, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 19, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 18, callee_1_1_1, 1 ] // CHECK-NEXT: [ 19, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 20, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 20, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 20, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 19, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 19, callee_1_1_1, 1 ] // CHECK-NEXT: [ 20, callee_1_2_2, 4 ] -// CHECK-NEXT: [ 21, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 21, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 21, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 21, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 20, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 20, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 20, callee_1_1_1, 1 ] // CHECK-NEXT: [ 21, callee_2_1_1, 5 ] -// CHECK-NEXT: [ 22, callee_1_1_1, 1 ] -// CHECK-NEXT: [ 22, callee_1_1_2, 2 ] -// CHECK-NEXT: [ 22, callee_1_2_1, 3 ] -// CHECK-NEXT: [ 22, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 21, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 21, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 21, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 21, callee_1_1_1, 1 ] +// CHECK-NEXT: [ 22, callee_2_1_2, 6 ] // CHECK-NEXT: [ 22, callee_2_1_1, 5 ] +// CHECK-NEXT: [ 22, callee_1_2_2, 4 ] +// CHECK-NEXT: [ 22, callee_1_2_1, 3 ] +// CHECK-NEXT: [ 22, callee_1_1_2, 2 ] +// CHECK-NEXT: [ 22, callee_1_1_1, 1 ] diff --git a/test/profile/instrprof-version-mismatch.c b/test/profile/instrprof-version-mismatch.c new file mode 100644 index 000000000000..49ce41177d3a --- /dev/null +++ b/test/profile/instrprof-version-mismatch.c @@ -0,0 +1,11 @@ +// RUN: %clang_profgen -o %t -O3 %s +// RUN: LLVM_PROFILE_VERBOSE_ERRORS=1 %run %t 1 2>&1 | FileCheck %s + +// override the version variable with a bogus version: +unsigned long long __llvm_profile_raw_version = 10000; +int main(int argc, const char *argv[]) { + if (argc < 2) + return 1; + return 0; +} +// CHECK: LLVM Profile: runtime and instrumentation version mismatch diff --git a/test/safestack/overflow.c b/test/safestack/overflow.c index 27436947e49c..62f86536916e 100644 --- a/test/safestack/overflow.c +++ b/test/safestack/overflow.c @@ -17,9 +17,13 @@ void fct(volatile int *buffer) int main(int argc, char **argv) { + int prebuf[7]; int value1 = 42; int buffer[5]; int value2 = 42; + int postbuf[7]; + fct(prebuf + 1); + fct(postbuf + 1); fct(buffer); return value1 != 42 || value2 != 42; } diff --git a/test/sanitizer_common/TestCases/Linux/closedir.c b/test/sanitizer_common/TestCases/Linux/closedir.c new file mode 100644 index 000000000000..990628db4027 --- /dev/null +++ b/test/sanitizer_common/TestCases/Linux/closedir.c @@ -0,0 +1,5 @@ +// Check that closedir(NULL) is ok. +// RUN: %clang -O2 %s -o %t && %run %t +#include <sys/types.h> +#include <dirent.h> +int main() { closedir(0); } diff --git a/test/tsan/mmap_stress.cc b/test/tsan/mmap_stress.cc index 5e3904adf90b..e01e7e92b8f9 100644 --- a/test/tsan/mmap_stress.cc +++ b/test/tsan/mmap_stress.cc @@ -9,8 +9,11 @@ void *SubWorker(void *arg) { for (int i = 0; i < 500; i++) { int *ptr = (int*)mmap(0, kMmapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) + exit(printf("mmap failed: %d\n", errno)); *ptr = 42; - munmap(ptr, kMmapSize); + if (munmap(ptr, kMmapSize)) + exit(printf("munmap failed: %d\n", errno)); } return 0; } @@ -18,29 +21,41 @@ void *SubWorker(void *arg) { void *Worker1(void *arg) { (void)arg; pthread_t th[4]; - for (int i = 0; i < 4; i++) - pthread_create(&th[i], 0, SubWorker, 0); - for (int i = 0; i < 4; i++) - pthread_join(th[i], 0); + for (int i = 0; i < 4; i++) { + if (pthread_create(&th[i], 0, SubWorker, 0)) + exit(printf("pthread_create failed: %d\n", errno)); + } + for (int i = 0; i < 4; i++) { + if (pthread_join(th[i], 0)) + exit(printf("pthread_join failed: %d\n", errno)); + } return 0; } void *Worker(void *arg) { (void)arg; pthread_t th[4]; - for (int i = 0; i < 4; i++) - pthread_create(&th[i], 0, Worker1, 0); - for (int i = 0; i < 4; i++) - pthread_join(th[i], 0); + for (int i = 0; i < 4; i++) { + if (pthread_create(&th[i], 0, Worker1, 0)) + exit(printf("pthread_create failed: %d\n", errno)); + } + for (int i = 0; i < 4; i++) { + if (pthread_join(th[i], 0)) + exit(printf("pthread_join failed: %d\n", errno)); + } return 0; } int main() { pthread_t th[4]; - for (int i = 0; i < 4; i++) - pthread_create(&th[i], 0, Worker, 0); - for (int i = 0; i < 4; i++) - pthread_join(th[i], 0); + for (int i = 0; i < 4; i++) { + if (pthread_create(&th[i], 0, Worker, 0)) + exit(printf("pthread_create failed: %d\n", errno)); + } + for (int i = 0; i < 4; i++) { + if (pthread_join(th[i], 0)) + exit(printf("pthread_join failed: %d\n", errno)); + } fprintf(stderr, "DONE\n"); } diff --git a/test/ubsan/TestCases/Integer/suppressions.cpp b/test/ubsan/TestCases/Integer/suppressions.cpp index e2f632d0725c..e6ae626db3d7 100644 --- a/test/ubsan/TestCases/Integer/suppressions.cpp +++ b/test/ubsan/TestCases/Integer/suppressions.cpp @@ -1,31 +1,23 @@ -// XFAIL: win32 -// On Windows, %t starts with c:\. lit's ShLexer helpfully strips the -// quotes in the suppressions="%t..." lines below, so the UBSAN_OPTIONS -// env var that ubsan effectively sees is halt_on_error=1:suppressions=c:\... -// without any quotes. Since : is ubsan's UBSAN_OPTIONS separator, this -// confuses sanitizer_flag_parser. -// FIXME: Figure out how to make this test go on Windows. - // RUN: %clangxx -fsanitize=integer -g0 %s -o %t // Fails without any suppression. // RUN: %env_ubsan_opts=halt_on_error=1 not %run %t 2>&1 | FileCheck %s // RUN: echo "signed-integer-overflow:%t" > %t.wrong-supp -// RUN: %env_ubsan_opts=halt_on_error=1:suppressions="%t.wrong-supp" not %run %t 2>&1 | FileCheck %s +// RUN: %env_ubsan_opts=halt_on_error=1:suppressions='"%t.wrong-supp"' not %run %t 2>&1 | FileCheck %s // RUN: echo "unsigned-integer-overflow:do_overflow" > %t.func-supp -// RUN: %env_ubsan_opts=halt_on_error=1:suppressions="%t.func-supp" %run %t +// RUN: %env_ubsan_opts=halt_on_error=1:suppressions='"%t.func-supp"' %run %t // RUN: echo "unsigned-integer-overflow:%t" > %t.module-supp -// RUN: %env_ubsan_opts=halt_on_error=1:suppressions="%t.module-supp" %run %t +// RUN: %env_ubsan_opts=halt_on_error=1:suppressions='"%t.module-supp"' %run %t // Note: file-level suppressions should work even without debug info. // RUN: echo "unsigned-integer-overflow:%s" > %t.file-supp -// RUN: %env_ubsan_opts=halt_on_error=1:suppressions="%t.file-supp" %run %t +// RUN: %env_ubsan_opts=halt_on_error=1:suppressions='"%t.file-supp"' %run %t // Suppressions don't work for unrecoverable kinds. // RUN: %clangxx -fsanitize=integer -fno-sanitize-recover=integer %s -o %t-norecover -// RUN: %env_ubsan_opts=halt_on_error=1:suppressions="%t.module-supp" not %run %t-norecover 2>&1 | FileCheck %s +// RUN: %env_ubsan_opts=halt_on_error=1:suppressions='"%t.module-supp"' not %run %t-norecover 2>&1 | FileCheck %s #include <stdint.h> |