summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-09 21:23:31 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-09 21:23:31 +0000
commit3bce7d2fca357e6a1db9eff4a1c58545a3020f1b (patch)
tree20e806d15042e772e93336ab9b7c68c6d2e76f06 /lib
parent91d212a4a6c2c87a6e09bc8a5e665b011022aaaf (diff)
downloadsrc-test2-3bce7d2fca357e6a1db9eff4a1c58545a3020f1b.tar.gz
src-test2-3bce7d2fca357e6a1db9eff4a1c58545a3020f1b.zip
Notes
Diffstat (limited to 'lib')
-rw-r--r--lib/asan/CMakeLists.txt5
-rw-r--r--lib/asan/asan_report.cc2
-rw-r--r--lib/asan/asan_rtl.cc1
-rwxr-xr-xlib/asan/scripts/asan_symbolize.py77
-rw-r--r--lib/asan/tests/CMakeLists.txt5
-rw-r--r--lib/asan/weak_symbols.txt3
-rw-r--r--lib/builtins/arm/aeabi_fcmp.S4
-rw-r--r--lib/builtins/arm/comparesf2.S126
-rw-r--r--lib/lsan/CMakeLists.txt3
-rw-r--r--lib/lsan/lsan_allocator.cc13
-rw-r--r--lib/lsan/lsan_common.cc5
-rw-r--r--lib/sanitizer_common/sanitizer_common.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_common.h30
-rw-r--r--lib/sanitizer_common/sanitizer_flags.inc3
-rw-r--r--lib/sanitizer_common/sanitizer_internal_defs.h2
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc3
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc30
-rw-r--r--lib/sanitizer_common/sanitizer_printf.cc28
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace_printer.cc17
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace_printer.h3
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.h8
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_internal.h4
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc50
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc2
-rw-r--r--lib/sanitizer_common/tests/CMakeLists.txt3
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc9
-rw-r--r--lib/sanitizer_common/weak_symbols.txt6
-rw-r--r--lib/stats/CMakeLists.txt8
-rw-r--r--lib/tsan/CMakeLists.txt5
-rw-r--r--lib/tsan/rtl/tsan.syms.extra1
-rw-r--r--lib/tsan/rtl/tsan_interface.cc4
-rw-r--r--lib/tsan/rtl/tsan_interface.h2
-rw-r--r--lib/tsan/rtl/tsan_report.cc2
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc2
-rw-r--r--lib/tsan/tests/CMakeLists.txt8
-rw-r--r--lib/ubsan/CMakeLists.txt4
-rw-r--r--lib/ubsan/ubsan_diag.cc2
-rw-r--r--lib/ubsan/weak_symbols.txt1
40 files changed, 408 insertions, 83 deletions
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
index 1258ef6165b4..4bebb0a45a64 100644
--- a/lib/asan/CMakeLists.txt
+++ b/lib/asan/CMakeLists.txt
@@ -106,6 +106,10 @@ endif()
add_compiler_rt_component(asan)
if(APPLE)
+ add_weak_symbols("asan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
+
add_compiler_rt_runtime(clang_rt.asan
SHARED
OS ${SANITIZER_COMMON_SUPPORTED_OS}
@@ -117,6 +121,7 @@ if(APPLE)
RTLSanCommon
RTUbsan
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+ LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
DEFS ${ASAN_DYNAMIC_DEFINITIONS}
PARENT_TARGET asan)
else()
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 937ba4077d43..3ad48fa88b6f 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -179,6 +179,8 @@ class ScopedInErrorReport {
if (common_flags()->print_cmdline)
PrintCmdline();
+ if (common_flags()->print_module_map == 2) PrintModuleMap();
+
// Copy the message buffer so that we could start logging without holding a
// lock that gets aquired during printing.
InternalScopedBuffer<char> buffer_copy(kErrorMessageBufferSize);
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index fee7b8a2dbaf..d9d7d7e4f13d 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -46,6 +46,7 @@ static void AsanDie() {
// Don't die twice - run a busy loop.
while (1) { }
}
+ if (common_flags()->print_module_map >= 1) PrintModuleMap();
if (flags()->sleep_before_dying) {
Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
SleepForSeconds(flags()->sleep_before_dying);
diff --git a/lib/asan/scripts/asan_symbolize.py b/lib/asan/scripts/asan_symbolize.py
index 8e6fb61f7bf7..d82c6773e306 100755
--- a/lib/asan/scripts/asan_symbolize.py
+++ b/lib/asan/scripts/asan_symbolize.py
@@ -24,6 +24,7 @@ binary_name_filter = None
fix_filename_patterns = None
logfile = sys.stdin
allow_system_symbolizer = True
+force_system_symbolizer = False
# FIXME: merge the code that calls fix_filename().
def fix_filename(file_name):
@@ -37,6 +38,10 @@ def fix_filename(file_name):
def sysroot_path_filter(binary_name):
return sysroot_path + binary_name
+def is_valid_arch(s):
+ return s in ["i386", "x86_64", "x86_64h", "arm", "armv6", "armv7", "armv7s",
+ "armv7k", "arm64", "powerpc64", "powerpc64le", "s390x", "s390"]
+
def guess_arch(addr):
# Guess which arch we're running. 10 = len('0x') + 8 hex digits.
if len(addr) > 10:
@@ -206,10 +211,10 @@ class UnbufferedLineConverter(object):
class DarwinSymbolizer(Symbolizer):
- def __init__(self, addr, binary):
+ def __init__(self, addr, binary, arch):
super(DarwinSymbolizer, self).__init__()
self.binary = binary
- self.arch = guess_arch(addr)
+ self.arch = arch
self.open_atos()
def open_atos(self):
@@ -268,9 +273,9 @@ def BreakpadSymbolizerFactory(binary):
return None
-def SystemSymbolizerFactory(system, addr, binary):
+def SystemSymbolizerFactory(system, addr, binary, arch):
if system == 'Darwin':
- return DarwinSymbolizer(addr, binary)
+ return DarwinSymbolizer(addr, binary, arch)
elif system == 'Linux' or system == 'FreeBSD':
return Addr2LineSymbolizer(binary)
@@ -369,7 +374,7 @@ class SymbolizationLoop(object):
self.frame_no = 0
self.process_line = self.process_line_posix
- def symbolize_address(self, addr, binary, offset):
+ def symbolize_address(self, addr, binary, offset, arch):
# On non-Darwin (i.e. on platforms without .dSYM debug info) always use
# a single symbolizer binary.
# On Darwin, if the dsym hint producer is present:
@@ -381,31 +386,35 @@ class SymbolizationLoop(object):
# if so, reuse |last_llvm_symbolizer| which has the full set of hints;
# 3. otherwise create a new symbolizer and pass all currently known
# .dSYM hints to it.
- if not binary in self.llvm_symbolizers:
- use_new_symbolizer = True
- if self.system == 'Darwin' and self.dsym_hint_producer:
- dsym_hints_for_binary = set(self.dsym_hint_producer(binary))
- use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)
- self.dsym_hints |= dsym_hints_for_binary
- if self.last_llvm_symbolizer and not use_new_symbolizer:
+ result = None
+ if not force_system_symbolizer:
+ if not binary in self.llvm_symbolizers:
+ use_new_symbolizer = True
+ if self.system == 'Darwin' and self.dsym_hint_producer:
+ dsym_hints_for_binary = set(self.dsym_hint_producer(binary))
+ use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)
+ self.dsym_hints |= dsym_hints_for_binary
+ if self.last_llvm_symbolizer and not use_new_symbolizer:
+ self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
+ else:
+ self.last_llvm_symbolizer = LLVMSymbolizerFactory(
+ self.system, arch, self.dsym_hints)
self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
- else:
- self.last_llvm_symbolizer = LLVMSymbolizerFactory(
- self.system, guess_arch(addr), self.dsym_hints)
- self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
- # Use the chain of symbolizers:
- # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
- # (fall back to next symbolizer if the previous one fails).
- if not binary in symbolizers:
- symbolizers[binary] = ChainSymbolizer(
- [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
- result = symbolizers[binary].symbolize(addr, binary, offset)
+ # Use the chain of symbolizers:
+ # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
+ # (fall back to next symbolizer if the previous one fails).
+ if not binary in symbolizers:
+ symbolizers[binary] = ChainSymbolizer(
+ [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
+ result = symbolizers[binary].symbolize(addr, binary, offset)
+ else:
+ symbolizers[binary] = ChainSymbolizer([])
if result is None:
if not allow_system_symbolizer:
raise Exception('Failed to launch or use llvm-symbolizer.')
# Initialize system symbolizer only if other symbolizers failed.
symbolizers[binary].append_symbolizer(
- SystemSymbolizerFactory(self.system, addr, binary))
+ SystemSymbolizerFactory(self.system, addr, binary, arch))
result = symbolizers[binary].symbolize(addr, binary, offset)
# The system symbolizer must produce some result.
assert result
@@ -441,16 +450,26 @@ class SymbolizationLoop(object):
if DEBUG:
print line
_, frameno_str, addr, binary, offset = match.groups()
+ arch = ""
+ # Arch can be embedded in the filename, e.g.: "libabc.dylib:x86_64h"
+ colon_pos = binary.rfind(":")
+ if colon_pos != -1:
+ maybe_arch = binary[colon_pos+1:]
+ if is_valid_arch(maybe_arch):
+ arch = maybe_arch
+ binary = binary[0:colon_pos]
+ if arch == "":
+ arch = guess_arch(addr)
if frameno_str == '0':
# Assume that frame #0 is the first frame of new stack trace.
self.frame_no = 0
original_binary = binary
if self.binary_name_filter:
binary = self.binary_name_filter(binary)
- symbolized_line = self.symbolize_address(addr, binary, offset)
+ symbolized_line = self.symbolize_address(addr, binary, offset, arch)
if not symbolized_line:
if original_binary != binary:
- symbolized_line = self.symbolize_address(addr, binary, offset)
+ symbolized_line = self.symbolize_address(addr, binary, offset, arch)
return self.get_symbolized_lines(symbolized_line)
@@ -472,6 +491,8 @@ if __name__ == '__main__':
parser.add_argument('-l','--logfile', default=sys.stdin,
type=argparse.FileType('r'),
help='set log file name to parse, default is stdin')
+ parser.add_argument('--force-system-symbolizer', action='store_true',
+ help='don\'t use llvm-symbolizer')
args = parser.parse_args()
if args.path_to_cut:
fix_filename_patterns = args.path_to_cut
@@ -486,5 +507,9 @@ if __name__ == '__main__':
logfile = args.logfile
else:
logfile = sys.stdin
+ if args.force_system_symbolizer:
+ force_system_symbolizer = True
+ if force_system_symbolizer:
+ assert(allow_system_symbolizer)
loop = SymbolizationLoop(binary_name_filter)
loop.process_logfile()
diff --git a/lib/asan/tests/CMakeLists.txt b/lib/asan/tests/CMakeLists.txt
index 3e56763a8041..22fa61dd1cf2 100644
--- a/lib/asan/tests/CMakeLists.txt
+++ b/lib/asan/tests/CMakeLists.txt
@@ -59,6 +59,11 @@ list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
if(APPLE)
list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS})
+
+ add_weak_symbols("asan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
+ list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS})
endif()
if(MSVC)
diff --git a/lib/asan/weak_symbols.txt b/lib/asan/weak_symbols.txt
new file mode 100644
index 000000000000..ba7b0272c2b1
--- /dev/null
+++ b/lib/asan/weak_symbols.txt
@@ -0,0 +1,3 @@
+___asan_default_options
+___asan_default_suppressions
+___asan_on_error
diff --git a/lib/builtins/arm/aeabi_fcmp.S b/lib/builtins/arm/aeabi_fcmp.S
index 0a1d92a60b68..8e7774b58974 100644
--- a/lib/builtins/arm/aeabi_fcmp.S
+++ b/lib/builtins/arm/aeabi_fcmp.S
@@ -26,10 +26,10 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \
- mov r0, #0 SEPARATOR \
+ movs r0, #0 SEPARATOR \
pop { r4, pc } SEPARATOR \
1: SEPARATOR \
- mov r0, #1 SEPARATOR \
+ movs r0, #1 SEPARATOR \
pop { r4, pc } SEPARATOR \
END_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond)
diff --git a/lib/builtins/arm/comparesf2.S b/lib/builtins/arm/comparesf2.S
index 6d7019545475..b8ac81ffac09 100644
--- a/lib/builtins/arm/comparesf2.S
+++ b/lib/builtins/arm/comparesf2.S
@@ -47,27 +47,50 @@
DEFINE_COMPILERRT_FUNCTION(__eqsf2)
// Make copies of a and b with the sign bit shifted off the top. These will
// be used to detect zeros and NaNs.
+#if __ARM_ARCH_ISA_THUMB == 1
+ push {r6, lr}
+ lsls r2, r0, #1
+ lsls r3, r1, #1
+#else
mov r2, r0, lsl #1
mov r3, r1, lsl #1
+#endif
// We do the comparison in three stages (ignoring NaN values for the time
// being). First, we orr the absolute values of a and b; this sets the Z
// flag if both a and b are zero (of either sign). The shift of r3 doesn't
// effect this at all, but it *does* make sure that the C flag is clear for
// the subsequent operations.
+#if __ARM_ARCH_ISA_THUMB == 1
+ lsrs r6, r3, #1
+ orrs r6, r2, r6
+#else
orrs r12, r2, r3, lsr #1
-
+#endif
// Next, we check if a and b have the same or different signs. If they have
// opposite signs, this eor will set the N flag.
+#if __ARM_ARCH_ISA_THUMB == 1
+ beq 1f
+ movs r6, r0
+ eors r6, r1
+1:
+#else
it ne
eorsne r12, r0, r1
+#endif
// If a and b are equal (either both zeros or bit identical; again, we're
// ignoring NaNs for now), this subtract will zero out r0. If they have the
// same sign, the flags are updated as they would be for a comparison of the
// absolute values of a and b.
+#if __ARM_ARCH_ISA_THUMB == 1
+ bmi 1f
+ subs r0, r2, r3
+1:
+#else
it pl
subspl r0, r2, r3
+#endif
// If a is smaller in magnitude than b and both have the same sign, place
// the negation of the sign of b in r0. Thus, if both are negative and
@@ -79,30 +102,69 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2)
// still clear from the shift argument in orrs; if a is positive and b
// negative, this places 0 in r0; if a is negative and b positive, -1 is
// placed in r0.
+#if __ARM_ARCH_ISA_THUMB == 1
+ bhs 1f
+ // Here if a and b have the same sign and absA < absB, the result is thus
+ // b < 0 ? 1 : -1. Same if a and b have the opposite sign (ignoring Nan).
+ movs r0, #1
+ lsrs r1, #31
+ bne LOCAL_LABEL(CHECK_NAN)
+ negs r0, r0
+ b LOCAL_LABEL(CHECK_NAN)
+1:
+#else
it lo
mvnlo r0, r1, asr #31
+#endif
// If a is greater in magnitude than b and both have the same sign, place
// the sign of b in r0. Thus, if both are negative and a < b, -1 is placed
// in r0, which is the desired result. Conversely, if both are positive
// and a > b, zero is placed in r0.
+#if __ARM_ARCH_ISA_THUMB == 1
+ bls 1f
+ // Here both have the same sign and absA > absB.
+ movs r0, #1
+ lsrs r1, #31
+ beq LOCAL_LABEL(CHECK_NAN)
+ negs r0, r0
+1:
+#else
it hi
movhi r0, r1, asr #31
+#endif
// If you've been keeping track, at this point r0 contains -1 if a < b and
// 0 if a >= b. All that remains to be done is to set it to 1 if a > b.
// If a == b, then the Z flag is set, so we can get the correct final value
// into r0 by simply or'ing with 1 if Z is clear.
+ // For Thumb-1, r0 contains -1 if a < b, 0 if a > b and 0 if a == b.
+#if __ARM_ARCH_ISA_THUMB != 1
it ne
orrne r0, r0, #1
+#endif
// Finally, we need to deal with NaNs. If either argument is NaN, replace
// the value in r0 with 1.
+#if __ARM_ARCH_ISA_THUMB == 1
+LOCAL_LABEL(CHECK_NAN):
+ movs r6, #0xff
+ lsls r6, #24
+ cmp r2, r6
+ bhi 1f
+ cmp r3, r6
+1:
+ bls 2f
+ movs r0, #1
+2:
+ pop {r6, pc}
+#else
cmp r2, #0xff000000
ite ls
cmpls r3, #0xff000000
movhi r0, #1
JMP(lr)
+#endif
END_COMPILERRT_FUNCTION(__eqsf2)
DEFINE_COMPILERRT_FUNCTION_ALIAS(__lesf2, __eqsf2)
DEFINE_COMPILERRT_FUNCTION_ALIAS(__ltsf2, __eqsf2)
@@ -111,11 +173,48 @@ DEFINE_COMPILERRT_FUNCTION_ALIAS(__nesf2, __eqsf2)
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__gtsf2)
// Identical to the preceding except in that we return -1 for NaN values.
- // Given that the two paths share so much code, one might be tempted to
+ // Given that the two paths share so much code, one might be tempted to
// unify them; however, the extra code needed to do so makes the code size
// to performance tradeoff very hard to justify for such small functions.
- mov r2, r0, lsl #1
- mov r3, r1, lsl #1
+#if __ARM_ARCH_ISA_THUMB == 1
+ push {r6, lr}
+ lsls r2, r0, #1
+ lsls r3, r1, #1
+ lsrs r6, r3, #1
+ orrs r6, r2, r6
+ beq 1f
+ movs r6, r0
+ eors r6, r1
+1:
+ bmi 2f
+ subs r0, r2, r3
+2:
+ bhs 3f
+ movs r0, #1
+ lsrs r1, #31
+ bne LOCAL_LABEL(CHECK_NAN_2)
+ negs r0, r0
+ b LOCAL_LABEL(CHECK_NAN_2)
+3:
+ bls 4f
+ movs r0, #1
+ lsrs r1, #31
+ beq LOCAL_LABEL(CHECK_NAN_2)
+ negs r0, r0
+4:
+LOCAL_LABEL(CHECK_NAN_2):
+ movs r6, #0xff
+ lsls r6, #24
+ cmp r2, r6
+ bhi 5f
+ cmp r3, r6
+5:
+ bls 6f
+ movs r0, #1
+ negs r0, r0
+6:
+ pop {r6, pc}
+#else
orrs r12, r2, r3, lsr #1
it ne
eorsne r12, r0, r1
@@ -132,19 +231,32 @@ DEFINE_COMPILERRT_FUNCTION(__gtsf2)
cmpls r3, #0xff000000
movhi r0, #-1
JMP(lr)
+#endif
END_COMPILERRT_FUNCTION(__gtsf2)
DEFINE_COMPILERRT_FUNCTION_ALIAS(__gesf2, __gtsf2)
.p2align 2
DEFINE_COMPILERRT_FUNCTION(__unordsf2)
// Return 1 for NaN values, 0 otherwise.
- mov r2, r0, lsl #1
- mov r3, r1, lsl #1
- mov r0, #0
+ lsls r2, r0, #1
+ lsls r3, r1, #1
+ movs r0, #0
+#if __ARM_ARCH_ISA_THUMB == 1
+ movs r1, #0xff
+ lsls r1, #24
+ cmp r2, r1
+ bhi 1f
+ cmp r3, r1
+1:
+ bls 2f
+ movs r0, #1
+2:
+#else
cmp r2, #0xff000000
ite ls
cmpls r3, #0xff000000
movhi r0, #1
+#endif
JMP(lr)
END_COMPILERRT_FUNCTION(__unordsf2)
diff --git a/lib/lsan/CMakeLists.txt b/lib/lsan/CMakeLists.txt
index 73e475d2fdba..b782f2421dc2 100644
--- a/lib/lsan/CMakeLists.txt
+++ b/lib/lsan/CMakeLists.txt
@@ -23,9 +23,8 @@ add_compiler_rt_object_libraries(RTLSanCommon
CFLAGS ${LSAN_CFLAGS})
if(COMPILER_RT_HAS_LSAN)
+ add_compiler_rt_component(lsan)
foreach(arch ${LSAN_SUPPORTED_ARCH})
- add_compiler_rt_component(lsan)
-
add_compiler_rt_runtime(clang_rt.lsan
STATIC
ARCHS ${arch}
diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cc
index 1f6efc0f8d93..c805a39e1cc5 100644
--- a/lib/lsan/lsan_allocator.cc
+++ b/lib/lsan/lsan_allocator.cc
@@ -258,4 +258,17 @@ SANITIZER_INTERFACE_ATTRIBUTE
uptr __sanitizer_get_allocated_size(const void *p) {
return GetMallocUsableSize(p);
}
+
+#if !SANITIZER_SUPPORTS_WEAK_HOOKS
+// Provide default (no-op) implementation of malloc hooks.
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void __sanitizer_malloc_hook(void *ptr, uptr size) {
+ (void)ptr;
+ (void)size;
+}
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+void __sanitizer_free_hook(void *ptr) {
+ (void)ptr;
+}
+#endif
} // extern "C"
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index b20941ef23f6..f0554526b76f 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -758,5 +758,10 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
int __lsan_is_turned_off() {
return 0;
}
+
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+const char *__lsan_default_suppressions() {
+ return "";
+}
#endif
} // extern "C"
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc
index 89c5c4511dea..9824a5198b52 100644
--- a/lib/sanitizer_common/sanitizer_common.cc
+++ b/lib/sanitizer_common/sanitizer_common.cc
@@ -270,6 +270,8 @@ void LoadedModule::set(const char *module_name, uptr base_address,
void LoadedModule::clear() {
InternalFree(full_name_);
+ base_address_ = 0;
+ max_executable_address_ = 0;
full_name_ = nullptr;
arch_ = kModuleArchUnknown;
internal_memset(uuid_, 0, kModuleUUIDSize);
@@ -285,6 +287,8 @@ void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable) {
void *mem = InternalAlloc(sizeof(AddressRange));
AddressRange *r = new(mem) AddressRange(beg, end, executable);
ranges_.push_back(r);
+ if (executable && end > max_executable_address_)
+ max_executable_address_ = end;
}
bool LoadedModule::containsAddress(uptr address) const {
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index fee642f3e82e..fc44ecd5b871 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -283,6 +283,7 @@ void UpdateProcessName();
void CacheBinaryName();
void DisableCoreDumperIfNecessary();
void DumpProcessMap();
+void PrintModuleMap();
bool FileExists(const char *filename);
const char *GetEnv(const char *name);
bool SetEnv(const char *name, const char *value);
@@ -665,6 +666,32 @@ enum ModuleArch {
kModuleArchARM64
};
+// When adding a new architecture, don't forget to also update
+// script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cc.
+inline const char *ModuleArchToString(ModuleArch arch) {
+ switch (arch) {
+ case kModuleArchUnknown:
+ return "";
+ case kModuleArchI386:
+ return "i386";
+ case kModuleArchX86_64:
+ return "x86_64";
+ case kModuleArchX86_64H:
+ return "x86_64h";
+ case kModuleArchARMV6:
+ return "armv6";
+ case kModuleArchARMV7:
+ return "armv7";
+ case kModuleArchARMV7S:
+ return "armv7s";
+ case kModuleArchARMV7K:
+ return "armv7k";
+ case kModuleArchARM64:
+ return "arm64";
+ }
+ CHECK(0 && "Invalid module arch");
+}
+
const uptr kModuleUUIDSize = 16;
// Represents a binary loaded into virtual memory (e.g. this can be an
@@ -674,6 +701,7 @@ class LoadedModule {
LoadedModule()
: full_name_(nullptr),
base_address_(0),
+ max_executable_address_(0),
arch_(kModuleArchUnknown),
instrumented_(false) {
internal_memset(uuid_, 0, kModuleUUIDSize);
@@ -688,6 +716,7 @@ class LoadedModule {
const char *full_name() const { return full_name_; }
uptr base_address() const { return base_address_; }
+ uptr max_executable_address() const { return max_executable_address_; }
ModuleArch arch() const { return arch_; }
const u8 *uuid() const { return uuid_; }
bool instrumented() const { return instrumented_; }
@@ -707,6 +736,7 @@ class LoadedModule {
private:
char *full_name_; // Owned.
uptr base_address_;
+ uptr max_executable_address_;
ModuleArch arch_;
u8 uuid_[kModuleUUIDSize];
bool instrumented_;
diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc
index 43900f87b330..d7fa34a58081 100644
--- a/lib/sanitizer_common/sanitizer_flags.inc
+++ b/lib/sanitizer_common/sanitizer_flags.inc
@@ -74,6 +74,9 @@ COMMON_FLAG(bool, allocator_may_return_null, false,
COMMON_FLAG(bool, print_summary, true,
"If false, disable printing error summaries in addition to error "
"reports.")
+COMMON_FLAG(int, print_module_map, 0,
+ "OS X only. 0 = don't print, 1 = print only once before process "
+ "exits, 2 = print after each report.")
COMMON_FLAG(bool, check_printf, true, "Check printf arguments.")
COMMON_FLAG(bool, handle_segv, true,
"If set, registers the tool's custom SIGSEGV/SIGBUS handler.")
diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h
index 8ebe91a6b3ab..5338f79423cc 100644
--- a/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -32,7 +32,7 @@
# define SANITIZER_WEAK_ATTRIBUTE __attribute__((weak))
#endif
-#if (SANITIZER_LINUX || SANITIZER_WINDOWS) && !SANITIZER_GO
+#if (SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_WINDOWS) && !SANITIZER_GO
# define SANITIZER_SUPPORTS_WEAK_HOOKS 1
#else
# define SANITIZER_SUPPORTS_WEAK_HOOKS 0
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 76cdc72a0f0c..7328a5c0ac18 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -1393,6 +1393,8 @@ void MaybeReexec() {
// No need to re-exec on Linux.
}
+void PrintModuleMap() { }
+
uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding) {
UNREACHABLE("FindAvailableMemoryRange is not available");
return 0;
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index eb14c970a7fb..f99f0b5948de 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -26,10 +26,7 @@
#include "sanitizer_procmaps.h"
#include "sanitizer_stacktrace.h"
-#if SANITIZER_ANDROID || SANITIZER_FREEBSD
#include <dlfcn.h> // for dlsym()
-#endif
-
#include <link.h>
#include <pthread.h>
#include <signal.h>
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 73e018c857e8..b4f8ab5e3a9e 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -854,6 +854,36 @@ void SignalContext::DumpAllRegisters(void *context) {
# undef DUMPREG
}
+static inline bool CompareBaseAddress(const LoadedModule &a,
+ const LoadedModule &b) {
+ return a.base_address() < b.base_address();
+}
+
+void FormatUUID(char *out, uptr size, const u8 *uuid) {
+ internal_snprintf(out, size,
+ "<%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-"
+ "%02X%02X%02X%02X%02X%02X>",
+ uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5],
+ uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11],
+ uuid[12], uuid[13], uuid[14], uuid[15]);
+}
+
+void PrintModuleMap() {
+ Printf("Process module map:\n");
+ MemoryMappingLayout memory_mapping(false);
+ InternalMmapVector<LoadedModule> modules(/*initial_capacity*/ 128);
+ memory_mapping.DumpListOfModules(&modules);
+ InternalSort(&modules, modules.size(), CompareBaseAddress);
+ for (uptr i = 0; i < modules.size(); ++i) {
+ char uuid_str[128];
+ FormatUUID(uuid_str, sizeof(uuid_str), modules[i].uuid());
+ Printf("0x%zx-0x%zx %s (%s) %s\n", modules[i].base_address(),
+ modules[i].max_executable_address(), modules[i].full_name(),
+ ModuleArchToString(modules[i].arch()), uuid_str);
+ }
+ Printf("End of module map.\n");
+}
+
} // namespace __sanitizer
#endif // SANITIZER_MAC
diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cc
index f394e75b05e6..c8317be6043f 100644
--- a/lib/sanitizer_common/sanitizer_printf.cc
+++ b/lib/sanitizer_common/sanitizer_printf.cc
@@ -43,7 +43,7 @@ static int AppendChar(char **buff, const char *buff_end, char c) {
// on the value of |pad_with_zero|.
static int AppendNumber(char **buff, const char *buff_end, u64 absolute_value,
u8 base, u8 minimal_num_length, bool pad_with_zero,
- bool negative) {
+ bool negative, bool uppercase) {
uptr const kMaxLen = 30;
RAW_CHECK(base == 10 || base == 16);
RAW_CHECK(base == 10 || !negative);
@@ -76,23 +76,25 @@ static int AppendNumber(char **buff, const char *buff_end, u64 absolute_value,
if (negative && !pad_with_zero) result += AppendChar(buff, buff_end, '-');
for (; pos >= 0; pos--) {
char digit = static_cast<char>(num_buffer[pos]);
- result += AppendChar(buff, buff_end, (digit < 10) ? '0' + digit
- : 'a' + digit - 10);
+ digit = (digit < 10) ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10;
+ result += AppendChar(buff, buff_end, digit);
}
return result;
}
static int AppendUnsigned(char **buff, const char *buff_end, u64 num, u8 base,
- u8 minimal_num_length, bool pad_with_zero) {
+ u8 minimal_num_length, bool pad_with_zero,
+ bool uppercase) {
return AppendNumber(buff, buff_end, num, base, minimal_num_length,
- pad_with_zero, false /* negative */);
+ pad_with_zero, false /* negative */, uppercase);
}
static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num,
u8 minimal_num_length, bool pad_with_zero) {
bool negative = (num < 0);
return AppendNumber(buff, buff_end, (u64)(negative ? -num : num), 10,
- minimal_num_length, pad_with_zero, negative);
+ minimal_num_length, pad_with_zero, negative,
+ false /* uppercase */);
}
static int AppendString(char **buff, const char *buff_end, int precision,
@@ -112,14 +114,16 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) {
int result = 0;
result += AppendString(buff, buff_end, -1, "0x");
result += AppendUnsigned(buff, buff_end, ptr_value, 16,
- SANITIZER_POINTER_FORMAT_LENGTH, true);
+ SANITIZER_POINTER_FORMAT_LENGTH,
+ true /* pad_with_zero */, false /* uppercase */);
return result;
}
int VSNPrintf(char *buff, int buff_length,
const char *format, va_list args) {
static const char *kPrintfFormatsHelp =
- "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x}; %p; %(\\.\\*)?s; %c\n";
+ "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; %(\\.\\*)?s; "
+ "%c\n";
RAW_CHECK(format);
RAW_CHECK(buff_length > 0);
const char *buff_end = &buff[buff_length - 1];
@@ -164,12 +168,14 @@ int VSNPrintf(char *buff, int buff_length,
break;
}
case 'u':
- case 'x': {
+ case 'x':
+ case 'X': {
uval = have_ll ? va_arg(args, u64)
: have_z ? va_arg(args, uptr)
: va_arg(args, unsigned);
- result += AppendUnsigned(&buff, buff_end, uval,
- (*cur == 'u') ? 10 : 16, width, pad_with_zero);
+ bool uppercase = (*cur == 'X');
+ result += AppendUnsigned(&buff, buff_end, uval, (*cur == 'u') ? 10 : 16,
+ width, pad_with_zero, uppercase);
break;
}
case 'p': {
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
index 6fba581bd964..377f1ce755be 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
+++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.cc
@@ -93,7 +93,7 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
vs_style, strip_path_prefix);
} else if (info.module) {
RenderModuleLocation(buffer, info.module, info.module_offset,
- strip_path_prefix);
+ info.module_arch, strip_path_prefix);
} else {
buffer->append("(<unknown module>)");
}
@@ -103,8 +103,9 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
if (info.address & kExternalPCBit)
{} // There PCs are not meaningful.
else if (info.module)
- buffer->append("(%s+%p)", StripModuleName(info.module),
- (void *)info.module_offset);
+ // Always strip the module name for %M.
+ RenderModuleLocation(buffer, StripModuleName(info.module),
+ info.module_offset, info.module_arch, "");
else
buffer->append("(%p)", (void *)info.address);
break;
@@ -165,9 +166,13 @@ void RenderSourceLocation(InternalScopedString *buffer, const char *file,
}
void RenderModuleLocation(InternalScopedString *buffer, const char *module,
- uptr offset, const char *strip_path_prefix) {
- buffer->append("(%s+0x%zx)", StripPathPrefix(module, strip_path_prefix),
- offset);
+ uptr offset, ModuleArch arch,
+ const char *strip_path_prefix) {
+ buffer->append("(%s", StripPathPrefix(module, strip_path_prefix));
+ if (arch != kModuleArchUnknown) {
+ buffer->append(":%s", ModuleArchToString(arch));
+ }
+ buffer->append("+0x%zx)", offset);
}
} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.h b/lib/sanitizer_common/sanitizer_stacktrace_printer.h
index 7be1d1977dce..ce85bd7f23fa 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace_printer.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.h
@@ -57,7 +57,8 @@ void RenderSourceLocation(InternalScopedString *buffer, const char *file,
const char *strip_path_prefix);
void RenderModuleLocation(InternalScopedString *buffer, const char *module,
- uptr offset, const char *strip_path_prefix);
+ uptr offset, ModuleArch arch,
+ const char *strip_path_prefix);
// Same as RenderFrame, but for data section (global variables).
// Accepts %s, %l from above.
diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cc
index 534e55f57f3a..1cd5b6ee24c0 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer.cc
@@ -33,9 +33,11 @@ void AddressInfo::Clear() {
function_offset = kUnknown;
}
-void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset) {
+void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset,
+ ModuleArch mod_arch) {
module = internal_strdup(mod_name);
module_offset = mod_offset;
+ module_arch = mod_arch;
}
SymbolizedStack::SymbolizedStack() : next(nullptr), info() {}
diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h
index 572f1dd752d7..4fc7742a21e3 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer.h
+++ b/lib/sanitizer_common/sanitizer_symbolizer.h
@@ -31,6 +31,7 @@ struct AddressInfo {
char *module;
uptr module_offset;
+ ModuleArch module_arch;
static const uptr kUnknown = ~(uptr)0;
char *function;
@@ -43,7 +44,7 @@ struct AddressInfo {
AddressInfo();
// Deletes all strings and resets all fields.
void Clear();
- void FillModuleInfo(const char *mod_name, uptr mod_offset);
+ void FillModuleInfo(const char *mod_name, uptr mod_offset, ModuleArch arch);
};
// Linked list of symbolized frames (each frame is described by AddressInfo).
@@ -65,6 +66,8 @@ struct DataInfo {
// (de)allocated using sanitizer internal allocator.
char *module;
uptr module_offset;
+ ModuleArch module_arch;
+
char *file;
uptr line;
char *name;
@@ -143,7 +146,8 @@ class Symbolizer final {
static Symbolizer *PlatformInit();
bool FindModuleNameAndOffsetForAddress(uptr address, const char **module_name,
- uptr *module_offset);
+ uptr *module_offset,
+ ModuleArch *module_arch);
ListOfModules modules_;
// If stale, need to reload the modules before looking up addresses.
bool modules_fresh_;
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_internal.h b/lib/sanitizer_common/sanitizer_symbolizer_internal.h
index ada059cd725d..2ae42b33868b 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_internal.h
+++ b/lib/sanitizer_common/sanitizer_symbolizer_internal.h
@@ -124,8 +124,8 @@ class LLVMSymbolizer : public SymbolizerTool {
bool SymbolizeData(uptr addr, DataInfo *info) override;
private:
- const char *SendCommand(bool is_data, const char *module_name,
- uptr module_offset);
+ const char *FormatAndSendCommand(bool is_data, const char *module_name,
+ uptr module_offset, ModuleArch arch);
LLVMSymbolizerProcess *symbolizer_process_;
static const uptr kBufferSize = 16 * 1024;
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc
index 31506fe5c834..7c377a729638 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc
@@ -64,11 +64,13 @@ SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) {
BlockingMutexLock l(&mu_);
const char *module_name;
uptr module_offset;
+ ModuleArch arch;
SymbolizedStack *res = SymbolizedStack::New(addr);
- if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))
+ if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset,
+ &arch))
return res;
// Always fill data about module name and offset.
- res->info.FillModuleInfo(module_name, module_offset);
+ res->info.FillModuleInfo(module_name, module_offset, arch);
for (auto &tool : tools_) {
SymbolizerScope sym_scope(this);
if (tool.SymbolizePC(addr, res)) {
@@ -82,11 +84,14 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
BlockingMutexLock l(&mu_);
const char *module_name;
uptr module_offset;
- if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset))
+ ModuleArch arch;
+ if (!FindModuleNameAndOffsetForAddress(addr, &module_name, &module_offset,
+ &arch))
return false;
info->Clear();
info->module = internal_strdup(module_name);
info->module_offset = module_offset;
+ info->module_arch = arch;
for (auto &tool : tools_) {
SymbolizerScope sym_scope(this);
if (tool.SymbolizeData(addr, info)) {
@@ -100,8 +105,9 @@ bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
uptr *module_address) {
BlockingMutexLock l(&mu_);
const char *internal_module_name = nullptr;
+ ModuleArch arch;
if (!FindModuleNameAndOffsetForAddress(pc, &internal_module_name,
- module_address))
+ module_address, &arch))
return false;
if (module_name)
@@ -134,12 +140,14 @@ void Symbolizer::PrepareForSandboxing() {
bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address,
const char **module_name,
- uptr *module_offset) {
+ uptr *module_offset,
+ ModuleArch *module_arch) {
const LoadedModule *module = FindModuleForAddress(address);
if (module == nullptr)
return false;
*module_name = module->full_name();
*module_offset = address - module->base_address();
+ *module_arch = module->arch();
return true;
}
@@ -197,6 +205,8 @@ class LLVMSymbolizerProcess : public SymbolizerProcess {
buffer[length - 2] == '\n';
}
+ // When adding a new architecture, don't forget to also update
+ // script/asan_symbolize.py and sanitizer_common.h.
void GetArgV(const char *path_to_binary,
const char *(&argv)[kArgVMax]) const override {
#if defined(__x86_64h__)
@@ -284,7 +294,8 @@ void ParseSymbolizePCOutput(const char *str, SymbolizedStack *res) {
top_frame = false;
} else {
cur = SymbolizedStack::New(res->info.address);
- cur->info.FillModuleInfo(res->info.module, res->info.module_offset);
+ cur->info.FillModuleInfo(res->info.module, res->info.module_offset,
+ res->info.module_arch);
last->next = cur;
last = cur;
}
@@ -317,8 +328,10 @@ void ParseSymbolizeDataOutput(const char *str, DataInfo *info) {
}
bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
- if (const char *buf = SendCommand(/*is_data*/ false, stack->info.module,
- stack->info.module_offset)) {
+ AddressInfo *info = &stack->info;
+ const char *buf = FormatAndSendCommand(
+ /*is_data*/ false, info->module, info->module_offset, info->module_arch);
+ if (buf) {
ParseSymbolizePCOutput(buf, stack);
return true;
}
@@ -326,8 +339,9 @@ bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
}
bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
- if (const char *buf =
- SendCommand(/*is_data*/ true, info->module, info->module_offset)) {
+ const char *buf = FormatAndSendCommand(
+ /*is_data*/ true, info->module, info->module_offset, info->module_arch);
+ if (buf) {
ParseSymbolizeDataOutput(buf, info);
info->start += (addr - info->module_offset); // Add the base address.
return true;
@@ -335,11 +349,19 @@ bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
return false;
}
-const char *LLVMSymbolizer::SendCommand(bool is_data, const char *module_name,
- uptr module_offset) {
+const char *LLVMSymbolizer::FormatAndSendCommand(bool is_data,
+ const char *module_name,
+ uptr module_offset,
+ ModuleArch arch) {
CHECK(module_name);
- internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n",
- is_data ? "DATA " : "", module_name, module_offset);
+ const char *is_data_str = is_data ? "DATA " : "";
+ if (arch == kModuleArchUnknown) {
+ internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data_str,
+ module_name, module_offset);
+ } else {
+ internal_snprintf(buffer_, kBufferSize, "%s\"%s:%s\" 0x%zx\n", is_data_str,
+ module_name, ModuleArchToString(arch), module_offset);
+ }
return symbolizer_process_->SendCommand(buffer_);
}
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index 6efd33021bfe..9682d2921420 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -388,6 +388,8 @@ void DumpProcessMap() {
}
#endif
+void PrintModuleMap() { }
+
void DisableCoreDumperIfNecessary() {
// Do nothing.
}
diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt
index b66f7563b01e..841acb315435 100644
--- a/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/lib/sanitizer_common/tests/CMakeLists.txt
@@ -81,6 +81,9 @@ endif()
if(APPLE)
list(APPEND SANITIZER_TEST_CFLAGS_COMMON ${DARWIN_osx_CFLAGS})
list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${DARWIN_osx_LINKFLAGS})
+
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
+ list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${WEAK_SYMBOL_LINKFLAGS})
endif()
# MSVC linker is allocating 1M for the stack by default, which is not
diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
index 05796fcbff77..405f8d86ea3c 100644
--- a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
@@ -52,13 +52,18 @@ TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
InternalScopedString str(128);
- RenderModuleLocation(&str, "/dir/exe", 0x123, "");
+ RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "");
EXPECT_STREQ("(/dir/exe+0x123)", str.data());
// Check that we strip file prefix if necessary.
str.clear();
- RenderModuleLocation(&str, "/dir/exe", 0x123, "/dir/");
+ RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "/dir/");
EXPECT_STREQ("(exe+0x123)", str.data());
+
+ // Check that we render the arch.
+ str.clear();
+ RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H, "/dir/");
+ EXPECT_STREQ("(exe:x86_64h+0x123)", str.data());
}
TEST(SanitizerStacktracePrinter, RenderFrame) {
diff --git a/lib/sanitizer_common/weak_symbols.txt b/lib/sanitizer_common/weak_symbols.txt
new file mode 100644
index 000000000000..8a1e32b8041b
--- /dev/null
+++ b/lib/sanitizer_common/weak_symbols.txt
@@ -0,0 +1,6 @@
+___sanitizer_free_hook
+___sanitizer_malloc_hook
+___sanitizer_symbolize_code
+___sanitizer_symbolize_data
+___sanitizer_symbolize_demangle
+___sanitizer_symbolize_flush
diff --git a/lib/stats/CMakeLists.txt b/lib/stats/CMakeLists.txt
index 33ab1aea685d..ec75262d46fc 100644
--- a/lib/stats/CMakeLists.txt
+++ b/lib/stats/CMakeLists.txt
@@ -5,8 +5,14 @@ set_target_properties(stats PROPERTIES FOLDER "Compiler-RT Misc")
if(APPLE)
set(STATS_LIB_FLAVOR SHARED)
+
+ add_weak_symbols("asan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
else()
set(STATS_LIB_FLAVOR STATIC)
+
+ set(WEAK_SYMBOL_LINKFLAGS)
endif()
add_compiler_rt_runtime(clang_rt.stats
@@ -17,6 +23,7 @@ add_compiler_rt_runtime(clang_rt.stats
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
CFLAGS ${SANITIZER_COMMON_CFLAGS}
+ LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
PARENT_TARGET stats)
add_compiler_rt_runtime(clang_rt.stats_client
@@ -25,4 +32,5 @@ add_compiler_rt_runtime(clang_rt.stats_client
OS ${SANITIZER_COMMON_SUPPORTED_OS}
SOURCES stats_client.cc
CFLAGS ${SANITIZER_COMMON_CFLAGS}
+ LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
PARENT_TARGET stats)
diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt
index b26a884b1a4c..75d26349ae30 100644
--- a/lib/tsan/CMakeLists.txt
+++ b/lib/tsan/CMakeLists.txt
@@ -107,6 +107,10 @@ if(APPLE)
# Pass ASM file directly to the C++ compiler.
set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES LANGUAGE C)
endif()
+
+ add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
+
add_compiler_rt_runtime(clang_rt.tsan
SHARED
OS ${TSAN_SUPPORTED_OS}
@@ -117,6 +121,7 @@ if(APPLE)
RTSanitizerCommonLibc
RTUbsan
CFLAGS ${TSAN_RTL_CFLAGS}
+ LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
PARENT_TARGET tsan)
add_compiler_rt_object_libraries(RTTsan_dynamic
OS ${TSAN_SUPPORTED_OS}
diff --git a/lib/tsan/rtl/tsan.syms.extra b/lib/tsan/rtl/tsan.syms.extra
index 1bc1d93298d3..22dfde914136 100644
--- a/lib/tsan/rtl/tsan.syms.extra
+++ b/lib/tsan/rtl/tsan.syms.extra
@@ -1,4 +1,5 @@
__tsan_init
+__tsan_flush_memory
__tsan_read*
__tsan_write*
__tsan_vptr*
diff --git a/lib/tsan/rtl/tsan_interface.cc b/lib/tsan/rtl/tsan_interface.cc
index 809d2abeb0be..ad9b1fe9a585 100644
--- a/lib/tsan/rtl/tsan_interface.cc
+++ b/lib/tsan/rtl/tsan_interface.cc
@@ -28,6 +28,10 @@ void __tsan_init() {
Initialize(cur_thread());
}
+void __tsan_flush_memory() {
+ FlushShadowMemory();
+}
+
void __tsan_read16(void *addr) {
MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog8);
MemoryRead(cur_thread(), CALLERPC, (uptr)addr + 8, kSizeLog8);
diff --git a/lib/tsan/rtl/tsan_interface.h b/lib/tsan/rtl/tsan_interface.h
index bae01bd707d7..4e342a58a066 100644
--- a/lib/tsan/rtl/tsan_interface.h
+++ b/lib/tsan/rtl/tsan_interface.h
@@ -32,6 +32,8 @@ extern "C" {
// before any instrumented code is executed and before any call to malloc.
SANITIZER_INTERFACE_ATTRIBUTE void __tsan_init();
+SANITIZER_INTERFACE_ATTRIBUTE void __tsan_flush_memory();
+
SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read1(void *addr);
SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read2(void *addr);
SANITIZER_INTERFACE_ATTRIBUTE void __tsan_read4(void *addr);
diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc
index 156876e5c22a..07fd41208eb7 100644
--- a/lib/tsan/rtl/tsan_report.cc
+++ b/lib/tsan/rtl/tsan_report.cc
@@ -358,6 +358,8 @@ void PrintReport(const ReportDesc *rep) {
ReportErrorSummary(rep_typ_str, frame->info);
}
+ if (common_flags()->print_module_map == 2) PrintModuleMap();
+
Printf("==================\n");
}
diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc
index 804f3cf64ee8..bfb835889c7a 100644
--- a/lib/tsan/rtl/tsan_rtl.cc
+++ b/lib/tsan/rtl/tsan_rtl.cc
@@ -404,6 +404,8 @@ void Initialize(ThreadState *thr) {
int Finalize(ThreadState *thr) {
bool failed = false;
+ if (common_flags()->print_module_map == 1) PrintModuleMap();
+
if (flags()->atexit_sleep_ms > 0 && ThreadCount(thr) > 1)
SleepForMillis(flags()->atexit_sleep_ms);
diff --git a/lib/tsan/tests/CMakeLists.txt b/lib/tsan/tests/CMakeLists.txt
index 4587e47ba904..ac7412940cf0 100644
--- a/lib/tsan/tests/CMakeLists.txt
+++ b/lib/tsan/tests/CMakeLists.txt
@@ -76,14 +76,18 @@ macro(add_tsan_unittest testname)
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
list(APPEND TEST_OBJECTS lib${TSAN_TEST_RUNTIME}.a)
list(APPEND TEST_DEPS ${TSAN_TEST_RUNTIME})
+
+ add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
+
# Intentionally do *not* link with `-fsanitize=thread`. We already link
# against a static version of the runtime, and we don't want the dynamic
# one.
add_compiler_rt_test(TsanUnitTests "${testname}-${arch}-Test"
OBJECTS ${TEST_OBJECTS}
DEPS ${TEST_DEPS}
- LINK_FLAGS ${TARGET_LINK_FLAGS} ${DARWIN_osx_LINKFLAGS}
- -lc++)
+ LINK_FLAGS ${TARGET_LINK_FLAGS} ${DARWIN_osx_LINK_FLAGS}
+ ${WEAK_SYMBOL_LINKFLAGS} -lc++)
endif()
endforeach()
endif()
diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt
index 036c65a097f0..ebff36019d45 100644
--- a/lib/ubsan/CMakeLists.txt
+++ b/lib/ubsan/CMakeLists.txt
@@ -56,6 +56,9 @@ if(APPLE)
SOURCES ${UBSAN_STANDALONE_SOURCES}
CFLAGS ${UBSAN_STANDALONE_CFLAGS})
+ add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
+ add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
+
add_compiler_rt_runtime(clang_rt.ubsan
SHARED
OS ${SANITIZER_COMMON_SUPPORTED_OS}
@@ -64,6 +67,7 @@ if(APPLE)
RTUbsan_standalone
RTSanitizerCommon
RTSanitizerCommonLibc
+ LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
PARENT_TARGET ubsan)
endif()
diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc
index d842694aa80f..c531c5f7757d 100644
--- a/lib/ubsan/ubsan_diag.cc
+++ b/lib/ubsan/ubsan_diag.cc
@@ -157,7 +157,7 @@ static void RenderLocation(InternalScopedString *Buffer, Location Loc) {
common_flags()->strip_path_prefix);
else if (Info.module)
RenderModuleLocation(Buffer, Info.module, Info.module_offset,
- common_flags()->strip_path_prefix);
+ Info.module_arch, common_flags()->strip_path_prefix);
else
Buffer->append("%p", Info.address);
return;
diff --git a/lib/ubsan/weak_symbols.txt b/lib/ubsan/weak_symbols.txt
new file mode 100644
index 000000000000..69e1bc1857ed
--- /dev/null
+++ b/lib/ubsan/weak_symbols.txt
@@ -0,0 +1 @@
+___ubsan_default_options