diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h --- a/compiler-rt/include/sanitizer/common_interface_defs.h +++ b/compiler-rt/include/sanitizer/common_interface_defs.h @@ -211,6 +211,15 @@ // Same as __sanitizer_symbolize_pc, but for data section (i.e. globals). void __sanitizer_symbolize_global(void *data_ptr, const char *fmt, char *out_buf, size_t out_buf_size); +// Determine the return address. +#if !defined(_MSC_VER) || defined(__clang__) +#define __sanitizer_return_address() \ + __builtin_extract_return_addr(__builtin_return_address(0)) +#else +extern "C" void *_ReturnAddress(void); +#pragma intrinsic(_ReturnAddress) +#define __sanitizer_return_address() _ReturnAddress() +#endif /// Sets the callback to be called immediately before death on error. /// diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -3,7 +3,7 @@ clang_compiler_add_cxx_check() # FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here -filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64) +filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el riscv64 sparcv9 sparc) if(APPLE) darwin_filter_host_archs(SANITIZER_UNITTEST_SUPPORTED_ARCH SANITIZER_UNITTEST_SUPPORTED_ARCH) endif() diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp @@ -9,33 +9,47 @@ void SymbolizeSmallBuffer() { char data[] = "abcdef"; - __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", data, 0); + __sanitizer_symbolize_pc(__sanitizer_return_address(), "%p %F %L", data, 0); printf("UNCHANGED '%s'\n", data); - __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", data, 1); + __sanitizer_symbolize_pc(__sanitizer_return_address(), "%p %F %L", data, 1); printf("EMPTY '%s'\n", data); - __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", data, + __sanitizer_symbolize_pc(__sanitizer_return_address(), "%p %F %L", data, sizeof(data)); printf("PARTIAL '%s'\n", data); } void SymbolizeCaller() { char data[100]; - __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", data, + __sanitizer_symbolize_pc(__sanitizer_return_address(), "%p %F %L", data, sizeof(data)); printf("FIRST_FORMAT %s\n", data); - __sanitizer_symbolize_pc(__builtin_return_address(0), + __sanitizer_symbolize_pc(__sanitizer_return_address(), "FUNC:%f LINE:%l FILE:%s", data, sizeof(data)); printf("SECOND_FORMAT %s\n", data); - __sanitizer_symbolize_pc(__builtin_return_address(0), - "LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" - "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" - "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" - "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" - "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG" - "FUNC:%f LINE:%l FILE:%s", data, sizeof(data)); + __sanitizer_symbolize_pc(__sanitizer_return_address(), + "LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" + "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" + "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" + "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" + "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG" + "FUNC:%f LINE:%l FILE:%s", + data, sizeof(data)); printf("LONG_FORMAT %s\n", data); } +struct s { + int i; +}; + +struct s SymbolizeSRet() { + char data[100]; + __sanitizer_symbolize_pc(__sanitizer_return_address(), + "FUNC:%f LINE:%l FILE:%s", data, sizeof(data)); + printf("SRET: %s\n", data); + struct s s = {1}; + return s; +} + void SymbolizeData() { char data[100]; __sanitizer_symbolize_global(&GLOBAL_VAR_ABC, "%g %s:%l", data, sizeof(data)); @@ -52,6 +66,10 @@ // CHECK: SECOND_FORMAT FUNC:main LINE:[[@LINE+1]] FILE:symbolize_pc.cpp SymbolizeCaller(); + struct s s; + // CHECK: SRET: FUNC:main LINE:[[@LINE+1]] FILE:symbolize_pc.cpp + s = SymbolizeSRet(); + // CHECK: GLOBAL: GLOBAL_VAR_ABC SymbolizeData(); } diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp @@ -12,7 +12,7 @@ char buffer[10000]; __attribute__((noinline)) static void Symbolize() { - __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", buffer, + __sanitizer_symbolize_pc(__sanitizer_return_address(), "%p %F %L", buffer, sizeof(buffer)); for (char *p = buffer; strlen(p); p += strlen(p) + 1) printf("%s\n", p); diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp @@ -12,7 +12,7 @@ char buffer[10000]; __attribute__((noinline)) static void Symbolize() { - __sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", buffer, + __sanitizer_symbolize_pc(__sanitizer_return_address(), "%p %F %L", buffer, sizeof(buffer)); for (char *p = buffer; strlen(p); p += strlen(p) + 1) printf("%s\n", p);