aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/Modules/CompilerRTDarwinUtils.cmake3
-rw-r--r--cmake/config-ix.cmake159
-rw-r--r--include/sanitizer/common_interface_defs.h6
-rw-r--r--lib/asan/asan_report.cc3
-rw-r--r--lib/builtins/CMakeLists.txt3
-rw-r--r--lib/builtins/int_types.h3
-rw-r--r--lib/cfi/cfi.cc6
-rw-r--r--lib/profile/CMakeLists.txt10
-rw-r--r--lib/profile/InstrProfData.inc67
-rw-r--r--lib/profile/InstrProfiling.c5
-rw-r--r--lib/profile/InstrProfilingFile.c9
-rw-r--r--lib/profile/InstrProfilingPort.h6
-rw-r--r--lib/profile/InstrProfilingValue.c2
-rw-r--r--lib/sanitizer_common/sanitizer_common.h4
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc34
-rw-r--r--lib/sanitizer_common/sanitizer_common_libcdep.cc3
-rw-r--r--lib/sanitizer_common/sanitizer_common_nolibc.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc9
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc10
-rw-r--r--lib/sanitizer_common/sanitizer_mac.h6
-rw-r--r--lib/sanitizer_common/sanitizer_printf.cc7
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc6
-rw-r--r--test/cfi/CMakeLists.txt4
-rw-r--r--test/msan/insertvalue_origin.cc1
-rw-r--r--test/profile/Linux/instrprof-basic.c31
-rw-r--r--test/profile/Linux/instrprof-dlopen.test34
-rw-r--r--test/profile/Linux/instrprof-dynamic-one-shared.test23
-rw-r--r--test/profile/Linux/instrprof-dynamic-two-shared.test24
-rw-r--r--test/profile/Linux/lit.local.cfg37
-rw-r--r--test/profile/instrprof-shared.test2
-rw-r--r--test/profile/instrprof-value-prof.c164
-rw-r--r--test/profile/instrprof-version-mismatch.c11
-rw-r--r--test/safestack/overflow.c4
-rw-r--r--test/sanitizer_common/TestCases/Linux/closedir.c5
-rw-r--r--test/tsan/mmap_stress.cc41
-rw-r--r--test/ubsan/TestCases/Integer/suppressions.cpp18
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>