Update aosp/master compiler-rt for rebase to r222486.
Change-Id: I38047809dbac0425193c82e810315998adbb380d
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt
index 4d69a25..90d9fac 100644
--- a/lib/msan/CMakeLists.txt
+++ b/lib/msan/CMakeLists.txt
@@ -14,16 +14,15 @@
set(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
append_no_rtti_flag(MSAN_RTL_CFLAGS)
-append_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)
+append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)
# Prevent clang from generating libc calls.
-append_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding MSAN_RTL_CFLAGS)
+append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding MSAN_RTL_CFLAGS)
set(MSAN_RUNTIME_LIBRARIES)
# Static runtime library.
add_custom_target(msan)
-set(arch "x86_64")
-if(CAN_TARGET_${arch})
+foreach(arch ${MSAN_SUPPORTED_ARCH})
add_compiler_rt_runtime(clang_rt.msan-${arch} ${arch} STATIC
SOURCES ${MSAN_RTL_SOURCES}
$<TARGET_OBJECTS:RTInterception.${arch}>
@@ -36,7 +35,7 @@
add_sanitizer_rt_symbols(clang_rt.msan-${arch} msan.syms.extra)
add_dependencies(msan clang_rt.msan-${arch}-symbols)
endif()
-endif()
+endforeach()
add_compiler_rt_resource_file(msan_blacklist msan_blacklist.txt)
add_dependencies(msan msan_blacklist)
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index fd7fdbb..09622c4 100644
--- a/lib/msan/msan.cc
+++ b/lib/msan/msan.cc
@@ -34,27 +34,25 @@
static THREADLOCAL int msan_expect_umr = 0;
static THREADLOCAL int msan_expected_umr_found = 0;
-static bool msan_running_under_dr;
-
// Function argument shadow. Each argument starts at the next available 8-byte
// aligned address.
SANITIZER_INTERFACE_ATTRIBUTE
-THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSizeInWords];
+THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)];
// Function argument origin. Each argument starts at the same offset as the
// corresponding shadow in (__msan_param_tls). Slightly weird, but changing this
// would break compatibility with older prebuilt binaries.
SANITIZER_INTERFACE_ATTRIBUTE
-THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSizeInWords];
+THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)];
SANITIZER_INTERFACE_ATTRIBUTE
-THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSizeInWords];
+THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)];
SANITIZER_INTERFACE_ATTRIBUTE
THREADLOCAL u32 __msan_retval_origin_tls;
SANITIZER_INTERFACE_ATTRIBUTE
-THREADLOCAL u64 __msan_va_arg_tls[kMsanParamTlsSizeInWords];
+THREADLOCAL u64 __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)];
SANITIZER_INTERFACE_ATTRIBUTE
THREADLOCAL u64 __msan_va_arg_overflow_size_tls;
@@ -63,7 +61,6 @@
THREADLOCAL u32 __msan_origin_tls;
static THREADLOCAL int is_in_symbolizer;
-static THREADLOCAL int is_in_loader;
extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins;
@@ -79,14 +76,6 @@
void ExitSymbolizer() { --is_in_symbolizer; }
bool IsInSymbolizer() { return is_in_symbolizer; }
-void EnterLoader() { ++is_in_loader; }
-void ExitLoader() { --is_in_loader; }
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-bool __msan_is_in_loader() { return is_in_loader; }
-}
-
static Flags msan_flags;
Flags *flags() {
@@ -187,7 +176,7 @@
ParseFlagsFromString(f, options);
}
-void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
+void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
bool request_fast_unwind) {
MsanThread *t = GetCurrentThread();
if (!t || !StackTrace::WillUseFastUnwind(request_fast_unwind)) {
@@ -280,16 +269,19 @@
}
}
- StackDepotHandle h = StackDepotPut_WithHandle(stack->trace, stack->size);
+ StackDepotHandle h = StackDepotPut_WithHandle(*stack);
if (!h.valid()) return id;
- int use_count = h.use_count();
- if (use_count > flags()->origin_history_per_stack_limit)
- return id;
+
+ if (flags()->origin_history_per_stack_limit > 0) {
+ int use_count = h.use_count();
+ if (use_count > flags()->origin_history_per_stack_limit) return id;
+ }
u32 chained_id;
bool inserted = ChainedOriginDepotPut(h.id(), o.id(), &chained_id);
- if (inserted) h.inc_use_count_unsafe();
+ if (inserted && flags()->origin_history_per_stack_limit > 0)
+ h.inc_use_count_unsafe();
return Origin(chained_id, depth).raw_id();
}
@@ -377,6 +369,7 @@
if (MSAN_REPLACE_OPERATORS_NEW_AND_DELETE)
ReplaceOperatorsNewAndDelete();
+ DisableCoreDumperIfNecessary();
if (StackSizeIsUnlimited()) {
VPrintf(1, "Unlimited stack, doing reexec\n");
// A reasonably large stack size. It is bigger than the usual 8Mb, because,
@@ -390,7 +383,7 @@
__msan_clear_on_return();
if (__msan_get_track_origins())
VPrintf(1, "msan_track_origins\n");
- if (!InitShadow(/* prot1 */ !msan_running_under_dr, /* prot2 */ true,
+ if (!InitShadow(/* prot1 */ true, /* prot2 */ true,
/* map_shadow */ true, __msan_get_track_origins())) {
Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n");
Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
@@ -401,8 +394,7 @@
Die();
}
- Symbolizer::Init(common_flags()->external_symbolizer_path);
- Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer);
+ Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);
MsanTSDInit(MsanTSDDtor);
@@ -482,7 +474,7 @@
(void)sp;
ReportUMRInsideAddressRange(__func__, x, size, offset);
__msan::PrintWarningWithOrigin(pc, bp,
- __msan_get_origin(((char *)x) + offset));
+ __msan_get_origin(((const char *)x) + offset));
if (__msan::flags()->halt_on_error) {
Printf("Exiting\n");
Die();
@@ -495,40 +487,13 @@
return old;
}
-int __msan_has_dynamic_component() {
- return msan_running_under_dr;
-}
+int __msan_has_dynamic_component() { return false; }
NOINLINE
void __msan_clear_on_return() {
__msan_param_tls[0] = 0;
}
-static void* get_tls_base() {
- u64 p;
- asm("mov %%fs:0, %0"
- : "=r"(p) ::);
- return (void*)p;
-}
-
-int __msan_get_retval_tls_offset() {
- // volatile here is needed to avoid UB, because the compiler thinks that we
- // are doing address arithmetics on unrelated pointers, and takes some
- // shortcuts
- volatile sptr retval_tls_p = (sptr)&__msan_retval_tls;
- volatile sptr tls_base_p = (sptr)get_tls_base();
- return retval_tls_p - tls_base_p;
-}
-
-int __msan_get_param_tls_offset() {
- // volatile here is needed to avoid UB, because the compiler thinks that we
- // are doing address arithmetics on unrelated pointers, and takes some
- // shortcuts
- volatile sptr param_tls_p = (sptr)&__msan_param_tls;
- volatile sptr tls_base_p = (sptr)get_tls_base();
- return param_tls_p - tls_base_p;
-}
-
void __msan_partial_poison(const void* data, void* shadow, uptr size) {
internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size);
}
@@ -562,11 +527,11 @@
// 'descr' is created at compile time and contains '----' in the beginning.
// When we see descr for the first time we replace '----' with a uniq id
// and set the origin to (id | (31-th bit)).
-void __msan_set_alloca_origin(void *a, uptr size, const char *descr) {
+void __msan_set_alloca_origin(void *a, uptr size, char *descr) {
__msan_set_alloca_origin4(a, size, descr, 0);
}
-void __msan_set_alloca_origin4(void *a, uptr size, const char *descr, uptr pc) {
+void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) {
static const u32 dash = '-';
static const u32 first_timer =
dash + (dash << 8) + (dash << 16) + (dash << 24);
@@ -654,18 +619,6 @@
death_callback = callback;
}
-void *__msan_wrap_indirect_call(void *target) {
- return IndirectExternCall(target);
-}
-
-void __msan_dr_is_initialized() {
- msan_running_under_dr = true;
-}
-
-void __msan_set_indirect_call_wrapper(uptr wrapper) {
- SetIndirectCallWrapper(wrapper);
-}
-
#if !SANITIZER_SUPPORTS_WEAK_HOOKS
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
diff --git a/lib/msan/msan.h b/lib/msan/msan.h
index 05a8c47..aed8738 100644
--- a/lib/msan/msan.h
+++ b/lib/msan/msan.h
@@ -25,15 +25,25 @@
# define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1
#endif
+#if defined(__mips64)
+#define MEM_TO_SHADOW(mem) (((uptr)mem) & ~0x4000000000ULL)
+#define SHADOW_TO_ORIGIN(shadow) (((uptr)shadow) + 0x2000000000ULL)
+#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW(mem)))
+#define MEM_IS_APP(mem) ((uptr)mem >= 0xe000000000ULL)
+#define MEM_IS_SHADOW(mem) \
+ ((uptr)mem >= 0xa000000000ULL && (uptr)mem <= 0xc000000000ULL)
+#elif defined(__x86_64__)
#define MEM_TO_SHADOW(mem) (((uptr)mem) & ~0x400000000000ULL)
#define SHADOW_TO_ORIGIN(shadow) (((uptr)shadow) + 0x200000000000ULL)
#define MEM_TO_ORIGIN(mem) (SHADOW_TO_ORIGIN(MEM_TO_SHADOW(mem)))
#define MEM_IS_APP(mem) ((uptr)mem >= 0x600000000000ULL)
#define MEM_IS_SHADOW(mem) \
((uptr)mem >= 0x200000000000ULL && (uptr)mem <= 0x400000000000ULL)
+#endif
-const int kMsanParamTlsSizeInWords = 100;
-const int kMsanRetvalTlsSizeInWords = 100;
+// These constants must be kept in sync with the ones in MemorySanitizer.cc.
+const int kMsanParamTlsSize = 800;
+const int kMsanRetvalTlsSize = 800;
namespace __msan {
extern int msan_inited;
@@ -64,14 +74,11 @@
~SymbolizerScope() { ExitSymbolizer(); }
};
-void EnterLoader();
-void ExitLoader();
-
void MsanDie();
void PrintWarning(uptr pc, uptr bp);
void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin);
-void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
+void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp,
bool request_fast_unwind);
void ReportUMR(StackTrace *stack, u32 origin);
@@ -96,27 +103,24 @@
// the previous origin id.
u32 ChainOrigin(u32 id, StackTrace *stack);
-#define GET_MALLOC_STACK_TRACE \
- StackTrace stack; \
- stack.size = 0; \
- if (__msan_get_track_origins() && msan_inited) \
- GetStackTrace(&stack, common_flags()->malloc_context_size, \
- StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
- common_flags()->fast_unwind_on_malloc)
-
-#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
- StackTrace stack; \
- stack.size = 0; \
- if (__msan_get_track_origins() > 1 && msan_inited) \
- GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
+#define GET_MALLOC_STACK_TRACE \
+ BufferedStackTrace stack; \
+ if (__msan_get_track_origins() && msan_inited) \
+ GetStackTrace(&stack, common_flags()->malloc_context_size, \
+ StackTrace::GetCurrentPc(), GET_CURRENT_FRAME(), \
common_flags()->fast_unwind_on_malloc)
-#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
- StackTrace stack; \
- stack.size = 0; \
- if (msan_inited) \
- GetStackTrace(&stack, kStackTraceMax, pc, bp, \
- common_flags()->fast_unwind_on_fatal)
+#define GET_STORE_STACK_TRACE_PC_BP(pc, bp) \
+ BufferedStackTrace stack; \
+ if (__msan_get_track_origins() > 1 && msan_inited) \
+ GetStackTrace(&stack, flags()->store_context_size, pc, bp, \
+ common_flags()->fast_unwind_on_malloc)
+
+#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \
+ BufferedStackTrace stack; \
+ if (msan_inited) \
+ GetStackTrace(&stack, kStackTraceMax, pc, bp, \
+ common_flags()->fast_unwind_on_fatal)
#define GET_STORE_STACK_TRACE \
GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME())
@@ -141,10 +145,8 @@
} // namespace __msan
#define MSAN_MALLOC_HOOK(ptr, size) \
- if (&__msan_malloc_hook) __msan_malloc_hook(ptr, size); \
if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
#define MSAN_FREE_HOOK(ptr) \
- if (&__msan_free_hook) __msan_free_hook(ptr); \
if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
#endif // MSAN_H
diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc
index fb1788f..aa1ea1d 100644
--- a/lib/msan/msan_allocator.cc
+++ b/lib/msan/msan_allocator.cc
@@ -40,14 +40,26 @@
}
};
-static const uptr kAllocatorSpace = 0x600000000000ULL;
-static const uptr kAllocatorSize = 0x80000000000; // 8T.
-static const uptr kMetadataSize = sizeof(Metadata);
-static const uptr kMaxAllowedMallocSize = 8UL << 30;
+#if defined(__mips64)
+ static const uptr kMaxAllowedMallocSize = 2UL << 30;
+ static const uptr kRegionSizeLog = 20;
+ static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
+ typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
+ typedef CompactSizeClassMap SizeClassMap;
-typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,
+ typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, sizeof(Metadata),
+ SizeClassMap, kRegionSizeLog, ByteMap,
+ MsanMapUnmapCallback> PrimaryAllocator;
+#elif defined(__x86_64__)
+ static const uptr kAllocatorSpace = 0x600000000000ULL;
+ static const uptr kAllocatorSize = 0x80000000000; // 8T.
+ static const uptr kMetadataSize = sizeof(Metadata);
+ static const uptr kMaxAllowedMallocSize = 8UL << 30;
+
+ typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,
DefaultSizeClassMap,
MsanMapUnmapCallback> PrimaryAllocator;
+#endif
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
@@ -102,7 +114,7 @@
} else if (flags()->poison_in_malloc) {
__msan_poison(allocated, size);
if (__msan_get_track_origins()) {
- u32 stack_id = StackDepotPut(stack->trace, stack->size);
+ u32 stack_id = StackDepotPut(*stack);
CHECK(stack_id);
u32 id;
ChainedOriginDepotPut(stack_id, Origin::kHeapRoot, &id);
@@ -125,7 +137,7 @@
if (flags()->poison_in_free) {
__msan_poison(p, size);
if (__msan_get_track_origins()) {
- u32 stack_id = StackDepotPut(stack->trace, stack->size);
+ u32 stack_id = StackDepotPut(*stack);
CHECK(stack_id);
u32 id;
ChainedOriginDepotPut(stack_id, Origin::kHeapRoot, &id);
@@ -188,40 +200,19 @@
allocator.GetStats(stats);
return stats[AllocatorStatAllocated];
}
-uptr __msan_get_current_allocated_bytes() {
- return __sanitizer_get_current_allocated_bytes();
-}
uptr __sanitizer_get_heap_size() {
uptr stats[AllocatorStatCount];
allocator.GetStats(stats);
return stats[AllocatorStatMapped];
}
-uptr __msan_get_heap_size() {
- return __sanitizer_get_heap_size();
-}
uptr __sanitizer_get_free_bytes() { return 1; }
-uptr __msan_get_free_bytes() {
- return __sanitizer_get_free_bytes();
-}
uptr __sanitizer_get_unmapped_bytes() { return 1; }
-uptr __msan_get_unmapped_bytes() {
- return __sanitizer_get_unmapped_bytes();
-}
uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; }
-uptr __msan_get_estimated_allocated_size(uptr size) {
- return __sanitizer_get_estimated_allocated_size(size);
-}
int __sanitizer_get_ownership(const void *p) { return AllocationSize(p) != 0; }
-int __msan_get_ownership(const void *p) {
- return __sanitizer_get_ownership(p);
-}
uptr __sanitizer_get_allocated_size(const void *p) { return AllocationSize(p); }
-uptr __msan_get_allocated_size(const void *p) {
- return __sanitizer_get_allocated_size(p);
-}
diff --git a/lib/msan/msan_chained_origin_depot.cc b/lib/msan/msan_chained_origin_depot.cc
index faf0461..f3fb3c8 100644
--- a/lib/msan/msan_chained_origin_depot.cc
+++ b/lib/msan/msan_chained_origin_depot.cc
@@ -19,31 +19,6 @@
struct ChainedOriginDepotDesc {
u32 here_id;
u32 prev_id;
- u32 hash() const {
- const u32 m = 0x5bd1e995;
- const u32 seed = 0x9747b28c;
- const u32 r = 24;
- u32 h = seed;
- u32 k = here_id;
- k *= m;
- k ^= k >> r;
- k *= m;
- h *= m;
- h ^= k;
-
- k = prev_id;
- k *= m;
- k ^= k >> r;
- k *= m;
- h *= m;
- h ^= k;
-
- h ^= h >> 13;
- h *= m;
- h ^= h >> 15;
- return h;
- }
- bool is_valid() { return true; }
};
struct ChainedOriginDepotNode {
@@ -59,6 +34,44 @@
static uptr storage_size(const args_type &args) {
return sizeof(ChainedOriginDepotNode);
}
+ /* This is murmur2 hash for the 64->32 bit case.
+ It does not behave all that well because the keys have a very biased
+ distribution (I've seen 7-element buckets with the table only 14% full).
+
+ here_id is built of
+ * (1 bits) Reserved, zero.
+ * (8 bits) Part id = bits 13..20 of the hash value of here_id's key.
+ * (23 bits) Sequential number (each part has each own sequence).
+
+ prev_id has either the same distribution as here_id (but with 3:8:21)
+ split, or one of two reserved values (-1) or (-2). Either case can
+ dominate depending on the workload.
+ */
+ static u32 hash(const args_type &args) {
+ const u32 m = 0x5bd1e995;
+ const u32 seed = 0x9747b28c;
+ const u32 r = 24;
+ u32 h = seed;
+ u32 k = args.here_id;
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+ h *= m;
+ h ^= k;
+
+ k = args.prev_id;
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+ h *= m;
+ h ^= k;
+
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+ return h;
+ }
+ static bool is_valid(const args_type &args) { return true; }
void store(const args_type &args, u32 other_hash) {
here_id = args.here_id;
prev_id = args.prev_id;
@@ -103,4 +116,12 @@
return desc.here_id;
}
+void ChainedOriginDepotLockAll() {
+ chainedOriginDepot.LockAll();
+}
+
+void ChainedOriginDepotUnlockAll() {
+ chainedOriginDepot.UnlockAll();
+}
+
} // namespace __msan
diff --git a/lib/msan/msan_chained_origin_depot.h b/lib/msan/msan_chained_origin_depot.h
index db427b0..f7a71ce 100644
--- a/lib/msan/msan_chained_origin_depot.h
+++ b/lib/msan/msan_chained_origin_depot.h
@@ -21,6 +21,9 @@
// Retrieves a stored stack trace by the id.
u32 ChainedOriginDepotGet(u32 id, u32 *other);
+void ChainedOriginDepotLockAll();
+void ChainedOriginDepotUnlockAll();
+
} // namespace __msan
#endif // MSAN_CHAINED_ORIGIN_DEPOT_H
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 3394690..aa6b1ff 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -15,6 +15,7 @@
// sanitizer_common/sanitizer_common_interceptors.h
//===----------------------------------------------------------------------===//
+#include "interception/interception.h"
#include "msan.h"
#include "msan_chained_origin_depot.h"
#include "msan_origin.h"
@@ -25,7 +26,6 @@
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_interception.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_linux.h"
@@ -64,21 +64,22 @@
} while (0)
// Check that [x, x+n) range is unpoisoned.
-#define CHECK_UNPOISONED_0(x, n) \
- do { \
- sptr offset = __msan_test_shadow(x, n); \
- if (__msan::IsInSymbolizer()) break; \
- if (offset >= 0 && __msan::flags()->report_umrs) { \
- GET_CALLER_PC_BP_SP; \
- (void) sp; \
- ReportUMRInsideAddressRange(__func__, x, n, offset); \
- __msan::PrintWarningWithOrigin(pc, bp, \
- __msan_get_origin((char *)x + offset)); \
- if (__msan::flags()->halt_on_error) { \
- Printf("Exiting\n"); \
- Die(); \
- } \
- } \
+#define CHECK_UNPOISONED_0(x, n) \
+ do { \
+ sptr offset = __msan_test_shadow(x, n); \
+ if (__msan::IsInSymbolizer()) \
+ break; \
+ if (offset >= 0 && __msan::flags()->report_umrs) { \
+ GET_CALLER_PC_BP_SP; \
+ (void) sp; \
+ ReportUMRInsideAddressRange(__func__, x, n, offset); \
+ __msan::PrintWarningWithOrigin( \
+ pc, bp, __msan_get_origin((const char *)x + offset)); \
+ if (__msan::flags()->halt_on_error) { \
+ Printf("Exiting\n"); \
+ Die(); \
+ } \
+ } \
} while (0)
// Check that [x, x+n) range is unpoisoned unless we are in a nested
@@ -88,9 +89,6 @@
if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
} while (0);
-static void *fast_memset(void *ptr, int c, SIZE_T n);
-static void *fast_memcpy(void *dst, const void *src, SIZE_T n);
-
INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
ENSURE_MSAN_INITED();
SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
@@ -263,6 +261,7 @@
copy_size++; // trailing \0
char *res = REAL(strncpy)(dest, src, n); // NOLINT
CopyPoison(dest, src, copy_size, &stack);
+ __msan_unpoison(dest + copy_size, n - copy_size);
return res;
}
@@ -316,11 +315,8 @@
INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
ENSURE_MSAN_INITED();
char *res = REAL(gcvt)(number, ndigit, buf);
- // DynamoRio tool will take care of unpoisoning gcvt result for us.
- if (!__msan_has_dynamic_component()) {
- SIZE_T n = REAL(strlen)(buf);
- __msan_unpoison(buf, n + 1);
- }
+ SIZE_T n = REAL(strlen)(buf);
+ __msan_unpoison(buf, n + 1);
return res;
}
@@ -350,9 +346,7 @@
#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
ENSURE_MSAN_INITED(); \
ret_type res = REAL(func)(__VA_ARGS__); \
- if (!__msan_has_dynamic_component()) { \
- __msan_unpoison(endptr, sizeof(*endptr)); \
- } \
+ __msan_unpoison(endptr, sizeof(*endptr)); \
return res;
#define INTERCEPTOR_STRTO(ret_type, func) \
@@ -409,7 +403,7 @@
INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
ENSURE_MSAN_INITED();
int res = REAL(vswprintf)(str, size, format, ap);
- if (res >= 0 && !__msan_has_dynamic_component()) {
+ if (res >= 0) {
__msan_unpoison(str, 4 * (res + 1));
}
return res;
@@ -537,7 +531,7 @@
INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
CHECK(MEM_IS_APP(s));
ENSURE_MSAN_INITED();
- wchar_t *res = (wchar_t *)fast_memset(s, c, n * sizeof(wchar_t));
+ wchar_t *res = (wchar_t *)REAL(memset)(s, c, n * sizeof(wchar_t));
__msan_unpoison(s, n * sizeof(wchar_t));
return res;
}
@@ -576,20 +570,16 @@
INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
ENSURE_MSAN_INITED();
char *res = REAL(fcvt)(x, a, b, c);
- if (!__msan_has_dynamic_component()) {
- __msan_unpoison(b, sizeof(*b));
- __msan_unpoison(c, sizeof(*c));
- }
+ __msan_unpoison(b, sizeof(*b));
+ __msan_unpoison(c, sizeof(*c));
+ if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
INTERCEPTOR(char *, getenv, char *name) {
ENSURE_MSAN_INITED();
char *res = REAL(getenv)(name);
- if (!__msan_has_dynamic_component()) {
- if (res)
- __msan_unpoison(res, REAL(strlen)(res) + 1);
- }
+ if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
@@ -843,7 +833,7 @@
if (flags()->poison_in_malloc)
__msan_poison(data, size);
if (__msan_get_track_origins()) {
- u32 stack_id = StackDepotPut(stack.trace, stack.size);
+ u32 stack_id = StackDepotPut(stack);
u32 id;
ChainedOriginDepotPut(stack_id, Origin::kHeapRoot, &id);
__msan_set_origin(data, size, Origin(id, 1).raw_id());
@@ -927,17 +917,15 @@
}
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
UnpoisonParam(3);
- return IndirectExternCall(cbdata->callback)(info, size, cbdata->data);
+ return cbdata->callback(info, size, cbdata->data);
}
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
ENSURE_MSAN_INITED();
- EnterLoader();
dl_iterate_phdr_data cbdata;
cbdata.callback = callback;
cbdata.data = data;
int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
- ExitLoader();
return res;
}
@@ -977,7 +965,7 @@
typedef void (*signal_cb)(int x);
signal_cb cb =
(signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
- IndirectExternCall(cb)(signo);
+ cb(signo);
}
static void SignalAction(int signo, void *si, void *uc) {
@@ -990,7 +978,7 @@
typedef void (*sigaction_cb)(int, void *, void *);
sigaction_cb cb =
(sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
- IndirectExternCall(cb)(signo, si, uc);
+ cb(signo, si, uc);
}
INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
@@ -1006,7 +994,7 @@
__sanitizer_sigaction new_act;
__sanitizer_sigaction *pnew_act = act ? &new_act : 0;
if (act) {
- internal_memcpy(pnew_act, act, sizeof(__sanitizer_sigaction));
+ REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));
uptr cb = (uptr)pnew_act->sigaction;
uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
? (uptr)SignalAction
@@ -1118,7 +1106,7 @@
void MSanAtExitWrapper(void *arg) {
UnpoisonParam(1);
MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
- IndirectExternCall(r->func)(r->arg);
+ r->func(r->arg);
InternalFree(r);
}
@@ -1149,34 +1137,22 @@
return p;
}
-// Linux kernel has a bug that leads to kernel deadlock if a process
-// maps TBs of memory and then calls mlock().
-static void MlockIsUnsupported() {
- static atomic_uint8_t printed;
- if (atomic_exchange(&printed, 1, memory_order_relaxed))
- return;
- VPrintf(1,
- "INFO: MemorySanitizer ignores mlock/mlockall/munlock/munlockall\n");
+static void BeforeFork() {
+ StackDepotLockAll();
+ ChainedOriginDepotLockAll();
}
-INTERCEPTOR(int, mlock, const void *addr, uptr len) {
- MlockIsUnsupported();
- return 0;
+static void AfterFork() {
+ ChainedOriginDepotUnlockAll();
+ StackDepotUnlockAll();
}
-INTERCEPTOR(int, munlock, const void *addr, uptr len) {
- MlockIsUnsupported();
- return 0;
-}
-
-INTERCEPTOR(int, mlockall, int flags) {
- MlockIsUnsupported();
- return 0;
-}
-
-INTERCEPTOR(int, munlockall, void) {
- MlockIsUnsupported();
- return 0;
+INTERCEPTOR(int, fork, void) {
+ ENSURE_MSAN_INITED();
+ BeforeFork();
+ int pid = REAL(fork)();
+ AfterFork();
+ return pid;
}
struct MSanInterceptorContext {
@@ -1240,12 +1216,8 @@
} while (false) // FIXME
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
-#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) \
- if (!__msan_has_dynamic_component() && map) { \
- /* If msandr didn't clear the shadow before the initializers ran, we do */ \
- /* it ourselves afterwards. */ \
- ForEachMappedRegion((link_map *)map, __msan_unpoison); \
- }
+#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) \
+ if (map) ForEachMappedRegion((link_map *)map, __msan_unpoison);
#include "sanitizer_common/sanitizer_common_interceptors.inc"
@@ -1259,59 +1231,25 @@
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
#include "sanitizer_common/sanitizer_common_syscalls.inc"
-// static
-void *fast_memset(void *ptr, int c, SIZE_T n) {
- // hack until we have a really fast internal_memset
- if (sizeof(uptr) == 8 &&
- (n % 8) == 0 &&
- ((uptr)ptr % 8) == 0) {
- uptr c8 = (unsigned)c & 0xFF;
- c8 = (c8 << 8) | c8;
- c8 = (c8 << 16) | c8;
- c8 = (c8 << 32) | c8;
- uptr *p = (uptr*)ptr;
- for (SIZE_T i = 0; i < n / 8; i++)
- p[i] = c8;
- return ptr;
- }
- return internal_memset(ptr, c, n);
-}
-
-// static
-void *fast_memcpy(void *dst, const void *src, SIZE_T n) {
- // Same hack as in fast_memset above.
- if (sizeof(uptr) == 8 &&
- (n % 8) == 0 &&
- ((uptr)dst % 8) == 0 &&
- ((uptr)src % 8) == 0) {
- uptr *d = (uptr*)dst;
- uptr *s = (uptr*)src;
- for (SIZE_T i = 0; i < n / 8; i++)
- d[i] = s[i];
- return dst;
- }
- return internal_memcpy(dst, src, n);
-}
-
static void PoisonShadow(uptr ptr, uptr size, u8 value) {
uptr PageSize = GetPageSizeCached();
uptr shadow_beg = MEM_TO_SHADOW(ptr);
uptr shadow_end = MEM_TO_SHADOW(ptr + size);
if (value ||
shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
- fast_memset((void*)shadow_beg, value, shadow_end - shadow_beg);
+ REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
} else {
uptr page_beg = RoundUpTo(shadow_beg, PageSize);
uptr page_end = RoundDownTo(shadow_end, PageSize);
if (page_beg >= page_end) {
- fast_memset((void *)shadow_beg, 0, shadow_end - shadow_beg);
+ REAL(memset)((void *)shadow_beg, 0, shadow_end - shadow_beg);
} else {
if (page_beg != shadow_beg) {
- fast_memset((void *)shadow_beg, 0, page_beg - shadow_beg);
+ REAL(memset)((void *)shadow_beg, 0, page_beg - shadow_beg);
}
if (page_end != shadow_end) {
- fast_memset((void *)page_end, 0, shadow_end - page_end);
+ REAL(memset)((void *)page_end, 0, shadow_end - page_end);
}
MmapFixedNoReserve(page_beg, page_end - page_beg);
}
@@ -1319,7 +1257,7 @@
}
// These interface functions reside here so that they can use
-// fast_memset, etc.
+// REAL(memset), etc.
void __msan_unpoison(const void *a, uptr size) {
if (!MEM_IS_APP(a)) return;
PoisonShadow((uptr)a, size, 0);
@@ -1338,7 +1276,7 @@
}
void __msan_clear_and_unpoison(void *a, uptr size) {
- fast_memset(a, 0, size);
+ REAL(memset)(a, 0, size);
PoisonShadow((uptr)a, size, 0);
}
@@ -1347,7 +1285,7 @@
if (msan_init_is_running) return REAL(memcpy)(dest, src, n);
ENSURE_MSAN_INITED();
GET_STORE_STACK_TRACE;
- void *res = fast_memcpy(dest, src, n);
+ void *res = REAL(memcpy)(dest, src, n);
CopyPoison(dest, src, n, &stack);
return res;
}
@@ -1356,7 +1294,7 @@
if (!msan_inited) return internal_memset(s, c, n);
if (msan_init_is_running) return REAL(memset)(s, c, n);
ENSURE_MSAN_INITED();
- void *res = fast_memset(s, c, n);
+ void *res = REAL(memset)(s, c, n);
__msan_unpoison(s, n);
return res;
}
@@ -1445,7 +1383,7 @@
*dst = dst_o;
}
} else {
- fast_memcpy((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
+ REAL(memcpy)((void *)MEM_TO_ORIGIN(beg), (void *)MEM_TO_ORIGIN(s),
end - beg);
}
}
@@ -1455,15 +1393,15 @@
if (!MEM_IS_APP(dst)) return;
if (!MEM_IS_APP(src)) return;
if (src == dst) return;
- internal_memmove((void *)MEM_TO_SHADOW((uptr)dst),
- (void *)MEM_TO_SHADOW((uptr)src), size);
+ REAL(memmove)((void *)MEM_TO_SHADOW((uptr)dst),
+ (void *)MEM_TO_SHADOW((uptr)src), size);
CopyOrigin(dst, src, size, stack);
}
void CopyPoison(void *dst, const void *src, uptr size, StackTrace *stack) {
if (!MEM_IS_APP(dst)) return;
if (!MEM_IS_APP(src)) return;
- fast_memcpy((void *)MEM_TO_SHADOW((uptr)dst),
+ REAL(memcpy)((void *)MEM_TO_SHADOW((uptr)dst),
(void *)MEM_TO_SHADOW((uptr)src), size);
CopyOrigin(dst, src, size, stack);
}
@@ -1597,6 +1535,7 @@
INTERCEPT_FUNCTION(tzset);
INTERCEPT_FUNCTION(__cxa_atexit);
INTERCEPT_FUNCTION(shmat);
+ INTERCEPT_FUNCTION(fork);
inited = 1;
}
diff --git a/lib/msan/msan_interface_internal.h b/lib/msan/msan_interface_internal.h
index 47b47dc..8641f81 100644
--- a/lib/msan/msan_interface_internal.h
+++ b/lib/msan/msan_interface_internal.h
@@ -88,9 +88,9 @@
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_set_origin(const void *a, uptr size, u32 origin);
SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_set_alloca_origin(void *a, uptr size, const char *descr);
+void __msan_set_alloca_origin(void *a, uptr size, char *descr);
SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_set_alloca_origin4(void *a, uptr size, const char *descr, uptr pc);
+void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc);
SANITIZER_INTERFACE_ATTRIBUTE
u32 __msan_chain_origin(u32 id);
SANITIZER_INTERFACE_ATTRIBUTE
@@ -122,16 +122,6 @@
SANITIZER_INTERFACE_ATTRIBUTE
int __msan_has_dynamic_component();
-// Returns x such that %fs:x is the first byte of __msan_retval_tls.
-SANITIZER_INTERFACE_ATTRIBUTE
-int __msan_get_retval_tls_offset();
-SANITIZER_INTERFACE_ATTRIBUTE
-int __msan_get_param_tls_offset();
-
-// For intercepting mmap from ld.so in msandr.
-SANITIZER_INTERFACE_ATTRIBUTE
-bool __msan_is_in_loader();
-
// For testing.
SANITIZER_INTERFACE_ATTRIBUTE
u32 __msan_get_umr_origin();
@@ -161,37 +151,6 @@
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_unaligned_store64(uu64 *p, u64 x);
-// ---------------------------
-// FIXME: Replace these functions with __sanitizer equivalent.
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __msan_get_estimated_allocated_size(uptr size);
-SANITIZER_INTERFACE_ATTRIBUTE
-int __msan_get_ownership(const void *p);
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __msan_get_allocated_size(const void *p);
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __msan_get_current_allocated_bytes();
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __msan_get_heap_size();
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __msan_get_free_bytes();
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __msan_get_unmapped_bytes();
-SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
-/* OPTIONAL */ void __msan_malloc_hook(void *ptr, uptr size);
-SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
-/* OPTIONAL */ void __msan_free_hook(void *ptr);
-// ---------------------------
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_dr_is_initialized();
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__msan_wrap_indirect_call(void *target);
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_set_indirect_call_wrapper(uptr wrapper);
-
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_set_death_callback(void (*callback)(void));
} // extern "C"
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc
index a8fbabb..2a970c0 100644
--- a/lib/msan/msan_linux.cc
+++ b/lib/msan/msan_linux.cc
@@ -35,8 +35,14 @@
namespace __msan {
+#if defined(__mips64)
+static const uptr kMemBeg = 0xe000000000;
+static const uptr kMemEnd = 0xffffffffff;
+#elif defined(__x86_64__)
static const uptr kMemBeg = 0x600000000000;
static const uptr kMemEnd = 0x7fffffffffff;
+#endif
+
static const uptr kShadowBeg = MEM_TO_SHADOW(kMemBeg);
static const uptr kShadowEnd = MEM_TO_SHADOW(kMemEnd);
static const uptr kBad1Beg = 0;
diff --git a/lib/msan/msan_new_delete.cc b/lib/msan/msan_new_delete.cc
index 3bae49c..9a8e56e 100644
--- a/lib/msan/msan_new_delete.cc
+++ b/lib/msan/msan_new_delete.cc
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "msan.h"
-#include "sanitizer_common/sanitizer_interception.h"
+#include "interception/interception.h"
#if MSAN_REPLACE_OPERATORS_NEW_AND_DELETE
diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cc
index 85e61e2..f4978c7 100644
--- a/lib/msan/msan_report.cc
+++ b/lib/msan/msan_report.cc
@@ -46,15 +46,15 @@
Printf(
" %sUninitialized value was created by an allocation of '%s%s%s'"
" in the stack frame of function '%s%s%s'%s\n",
- d.Origin(), d.Name(), s, d.Origin(), d.Name(),
- Symbolizer::Get()->Demangle(sep + 1), d.Origin(), d.End());
+ d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, d.Origin(),
+ d.End());
InternalFree(s);
if (pc) {
// For some reason function address in LLVM IR is 1 less then the address
// of the first instruction.
- pc += 1;
- StackTrace::PrintStack(&pc, 1);
+ pc = StackTrace::GetNextInstructionPc(pc);
+ StackTrace(&pc, 1).Print();
}
}
@@ -77,20 +77,16 @@
DescribeStackOrigin(so, pc);
break;
} else if (prev_o.isHeapRoot()) {
- uptr size = 0;
- const uptr *trace = StackDepotGet(stack_id, &size);
Printf(" %sUninitialized value was created by a heap allocation%s\n",
d.Origin(), d.End());
- StackTrace::PrintStack(trace, size);
+ StackDepotGet(stack_id).Print();
break;
} else {
// chained origin
- uptr size = 0;
- const uptr *trace = StackDepotGet(stack_id, &size);
// FIXME: copied? modified? passed through? observed?
Printf(" %sUninitialized value was stored to memory at%s\n", d.Origin(),
d.End());
- StackTrace::PrintStack(trace, size);
+ StackDepotGet(stack_id).Print();
id = prev_id;
}
}
diff --git a/lib/msan/msan_thread.cc b/lib/msan/msan_thread.cc
index 5fe99f6..2a1e05a 100644
--- a/lib/msan/msan_thread.cc
+++ b/lib/msan/msan_thread.cc
@@ -73,7 +73,7 @@
return 0;
}
- thread_return_t res = IndirectExternCall(start_routine_)(arg_);
+ thread_return_t res = start_routine_(arg_);
return res;
}
diff --git a/lib/msan/tests/CMakeLists.txt b/lib/msan/tests/CMakeLists.txt
index c654615..f3c11ba 100644
--- a/lib/msan/tests/CMakeLists.txt
+++ b/lib/msan/tests/CMakeLists.txt
@@ -48,7 +48,7 @@
-lstdc++
)
-append_if(COMPILER_RT_HAS_LIBDL -ldl MSAN_UNITTEST_LINK_FLAGS)
+append_list_if(COMPILER_RT_HAS_LIBDL -ldl MSAN_UNITTEST_LINK_FLAGS)
set(MSAN_LOADABLE_LINK_FLAGS
-fsanitize=memory
-shared
diff --git a/lib/msan/tests/msan_loadable.cc b/lib/msan/tests/msan_loadable.cc
index db3bf48..06e880f 100644
--- a/lib/msan/tests/msan_loadable.cc
+++ b/lib/msan/tests/msan_loadable.cc
@@ -20,24 +20,6 @@
// No name mangling.
extern "C" {
-__attribute__((constructor))
-void loadable_module_init(void) {
- if (!__msan_has_dynamic_component())
- return;
- // The real test is that this compare should not make an uninit.
- if (dso_global == NULL)
- dso_global = malloc(4);
-}
-
-__attribute__((destructor))
-void loadable_module_fini(void) {
- if (!__msan_has_dynamic_component())
- return;
- free(dso_global);
- // *Don't* overwrite it with NULL! That would unpoison it, but our test
- // relies on reloading at the same address and keeping the poison.
-}
-
void **get_dso_global() {
return &dso_global;
}
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index f7268d6..12012a0 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -251,7 +251,6 @@
TEST(MemorySanitizer, CallAndRet) {
- if (!__msan_has_dynamic_component()) return;
ReturnPoisoned<S1>();
ReturnPoisoned<S2>();
ReturnPoisoned<S4>();
@@ -494,14 +493,12 @@
static char *DynRetTestStr;
TEST(MemorySanitizer, DynRet) {
- if (!__msan_has_dynamic_component()) return;
ReturnPoisoned<S8>();
EXPECT_NOT_POISONED(clearenv());
}
TEST(MemorySanitizer, DynRet1) {
- if (!__msan_has_dynamic_component()) return;
ReturnPoisoned<S8>();
}
@@ -570,7 +567,7 @@
EXPECT_NOT_POISONED(x[16]);
EXPECT_NOT_POISONED(x[31]);
fclose(f);
- delete x;
+ delete[] x;
}
TEST(MemorySanitizer, read) {
@@ -583,7 +580,7 @@
EXPECT_NOT_POISONED(x[16]);
EXPECT_NOT_POISONED(x[31]);
close(fd);
- delete x;
+ delete[] x;
}
TEST(MemorySanitizer, pread) {
@@ -596,7 +593,7 @@
EXPECT_NOT_POISONED(x[16]);
EXPECT_NOT_POISONED(x[31]);
close(fd);
- delete x;
+ delete[] x;
}
TEST(MemorySanitizer, readv) {
@@ -1452,13 +1449,8 @@
x[2] = 0;
memmove(x, x + 1, (size - 1) * sizeof(T));
EXPECT_NOT_POISONED(x[1]);
- if (!__msan_has_dynamic_component()) {
- // FIXME: under DR we will lose this information
- // because accesses in memmove will unpoisin the shadow.
- // We need to use our own memove implementation instead of libc's.
- EXPECT_POISONED(x[0]);
- EXPECT_POISONED(x[2]);
- }
+ EXPECT_POISONED(x[0]);
+ EXPECT_POISONED(x[2]);
delete [] x;
}
@@ -1483,14 +1475,16 @@
TEST(MemorySanitizer, strncpy) { // NOLINT
char* x = new char[3];
- char* y = new char[3];
+ char* y = new char[5];
x[0] = 'a';
x[1] = *GetPoisoned<char>(1, 1);
- x[2] = 0;
- strncpy(y, x, 2); // NOLINT
+ x[2] = '\0';
+ strncpy(y, x, 4); // NOLINT
EXPECT_NOT_POISONED(y[0]);
EXPECT_POISONED(y[1]);
- EXPECT_POISONED(y[2]);
+ EXPECT_NOT_POISONED(y[2]);
+ EXPECT_NOT_POISONED(y[3]);
+ EXPECT_POISONED(y[4]);
}
TEST(MemorySanitizer, stpcpy) { // NOLINT
@@ -2062,8 +2056,26 @@
char *str = fcvt(12345.6789, 10, &a, &b);
EXPECT_NOT_POISONED(a);
EXPECT_NOT_POISONED(b);
+ ASSERT_NE(nullptr, str);
+ EXPECT_NOT_POISONED(str[0]);
+ ASSERT_NE(0U, strlen(str));
}
+TEST(MemorySanitizer, fcvt_long) {
+ int a, b;
+ break_optimization(&a);
+ break_optimization(&b);
+ EXPECT_POISONED(a);
+ EXPECT_POISONED(b);
+ char *str = fcvt(111111112345.6789, 10, &a, &b);
+ EXPECT_NOT_POISONED(a);
+ EXPECT_NOT_POISONED(b);
+ ASSERT_NE(nullptr, str);
+ EXPECT_NOT_POISONED(str[0]);
+ ASSERT_NE(0U, strlen(str));
+}
+
+
TEST(MemorySanitizer, memchr) {
char x[10];
break_optimization(x);
@@ -2787,7 +2799,7 @@
EXPECT_NOT_POISONED(s[4]);
EXPECT_NOT_POISONED(s[5]);
EXPECT_POISONED(s[6]);
- delete s;
+ delete[] s;
delete d;
}
@@ -3712,56 +3724,6 @@
}
#endif // defined(__clang__)
-TEST(MemorySanitizerDr, StoreInDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- char* s = new char[10];
- dso_memfill(s, 9);
- EXPECT_NOT_POISONED(s[5]);
- EXPECT_POISONED(s[9]);
-}
-
-int return_poisoned_int() {
- return ReturnPoisoned<U8>();
-}
-
-TEST(MemorySanitizerDr, ReturnFromDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- EXPECT_NOT_POISONED(dso_callfn(return_poisoned_int));
-}
-
-NOINLINE int TrashParamTLS(long long x, long long y, long long z) { //NOLINT
- EXPECT_POISONED(x);
- EXPECT_POISONED(y);
- EXPECT_POISONED(z);
- return 0;
-}
-
-static int CheckParamTLS(long long x, long long y, long long z) { //NOLINT
- EXPECT_NOT_POISONED(x);
- EXPECT_NOT_POISONED(y);
- EXPECT_NOT_POISONED(z);
- return 0;
-}
-
-TEST(MemorySanitizerDr, CallFromDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- S8* x = GetPoisoned<S8>();
- S8* y = GetPoisoned<S8>();
- S8* z = GetPoisoned<S8>();
- EXPECT_NOT_POISONED(TrashParamTLS(*x, *y, *z));
- EXPECT_NOT_POISONED(dso_callfn1(CheckParamTLS));
-}
-
-static void StackStoreInDSOFn(int* x, int* y) {
- EXPECT_NOT_POISONED(*x);
- EXPECT_NOT_POISONED(*y);
-}
-
-TEST(MemorySanitizerDr, StackStoreInDSOTest) {
- if (!__msan_has_dynamic_component()) return;
- dso_stack_store(StackStoreInDSOFn, 1);
-}
-
TEST(MemorySanitizerOrigins, SetGet) {
EXPECT_EQ(TrackingOrigins(), __msan_get_track_origins());
if (!TrackingOrigins()) return;