diff options
| author | Alexey Samsonov <samsonov@google.com> | 2012-08-22 13:31:37 +0000 |
|---|---|---|
| committer | Alexey Samsonov <samsonov@google.com> | 2012-08-22 13:31:37 +0000 |
| commit | a85b6b8154f57043af388d7626502fbcc93150ed (patch) | |
| tree | 793ee040c1d0daa71bf153b6dc64a699bcee30f6 | |
| parent | 9e10605d6b4b508c38234524fe69e6fca62cf217 (diff) | |
| download | bcm5719-llvm-a85b6b8154f57043af388d7626502fbcc93150ed.tar.gz bcm5719-llvm-a85b6b8154f57043af388d7626502fbcc93150ed.zip | |
[ASan] get rid of ASAN_USE_EXTERNAL_SYMBOLIZER compiler def in favor of __asan_set_symbolize_callback interface function. Now the user doesn't have to recompile ASan runtime to provide its own symbolizer
llvm-svn: 162358
| -rw-r--r-- | compiler-rt/lib/asan/asan_interface.h | 10 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_internal.h | 5 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_rtl.cc | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_stack.cc | 41 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_win.cc | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/lit_tests/interface_symbols.c | 5 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/lit_tests/symbolize_callback.cc | 21 | ||||
| -rwxr-xr-x | compiler-rt/lib/asan/output_tests/test_output.sh | 2 |
8 files changed, 62 insertions, 28 deletions
diff --git a/compiler-rt/lib/asan/asan_interface.h b/compiler-rt/lib/asan/asan_interface.h index 5a23329925b..54a0312f2f5 100644 --- a/compiler-rt/lib/asan/asan_interface.h +++ b/compiler-rt/lib/asan/asan_interface.h @@ -134,6 +134,16 @@ extern "C" { void __asan_set_on_error_callback(void (*callback)(void)) SANITIZER_INTERFACE_ATTRIBUTE; + // User may register its own symbolization function. It should print + // the description of instruction at address "pc" to "out_buffer". + // Description should be at most "out_size" bytes long. + // User-specified function should return true if symbolization was + // successful. + typedef bool (*__asan_symbolize_callback)(const void *pc, char *out_buffer, + int out_size); + void __asan_set_symbolize_callback(__asan_symbolize_callback callback) + SANITIZER_INTERFACE_ATTRIBUTE; + // Returns the estimated number of bytes that will be reserved by allocator // for request of "size" bytes. If ASan allocator can't allocate that much // memory, returns the maximal possible allocation size, otherwise returns diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index d9f88667a3f..4ed138c87e6 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -156,10 +156,7 @@ enum LinkerInitialized { LINKER_INITIALIZED = 0 }; #endif #ifdef _WIN32 -# ifndef ASAN_USE_EXTERNAL_SYMBOLIZER -# define ASAN_USE_EXTERNAL_SYMBOLIZER __asan_WinSymbolize -bool __asan_WinSymbolize(const void *addr, char *out_buffer, int buffer_size); -# endif +bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size); #endif // _WIN32 // These magic values are written to shadow for better error reporting. diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 2e83067ac6f..3943620a1a3 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -252,6 +252,7 @@ static NOINLINE void force_interface_symbols() { case 33: __asan_after_dynamic_init(); break; case 34: __asan_malloc_hook(0, 0); break; case 35: __asan_free_hook(0); break; + case 36: __asan_set_symbolize_callback(0); break; } } @@ -359,6 +360,9 @@ void __asan_init() { } InstallSignalHandlers(); +#ifdef _WIN32 + __asan_set_symbolize_callback(WinSymbolize); +#endif // _WIN32 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited // should be set to 1 prior to initializing the threads. diff --git a/compiler-rt/lib/asan/asan_stack.cc b/compiler-rt/lib/asan/asan_stack.cc index 1099f32fa13..42ef88c6bb7 100644 --- a/compiler-rt/lib/asan/asan_stack.cc +++ b/compiler-rt/lib/asan/asan_stack.cc @@ -12,6 +12,7 @@ // Code for ASan stack trace. //===----------------------------------------------------------------------===// #include "asan_interceptors.h" +#include "asan_interface.h" #include "asan_lock.h" #include "asan_stack.h" #include "asan_thread.h" @@ -19,13 +20,10 @@ #include "sanitizer_common/sanitizer_procmaps.h" #include "sanitizer_common/sanitizer_symbolizer.h" -#ifdef ASAN_USE_EXTERNAL_SYMBOLIZER -extern bool -ASAN_USE_EXTERNAL_SYMBOLIZER(const void *pc, char *out, int out_size); -#endif - namespace __asan { +static __asan_symbolize_callback symbolize_callback; + static const char *StripPathPrefix(const char *filepath) { const char *path_prefix = flags()->strip_path_prefix; if (filepath == internal_strstr(filepath, path_prefix)) @@ -45,25 +43,21 @@ static uptr patch_pc(uptr pc) { return pc - 1; } -#if defined(ASAN_USE_EXTERNAL_SYMBOLIZER) -void AsanStackTrace::PrintStack(uptr *addr, uptr size) { - for (uptr i = 0; i < size && addr[i]; i++) { - uptr pc = patch_pc(addr[i]); - char buff[4096]; - ASAN_USE_EXTERNAL_SYMBOLIZER((void*)pc, buff, sizeof(buff)); - // We can't know anything about the string returned by external - // symbolizer, but if it starts with filename, try to strip path prefix - // from it. - AsanPrintf(" #%zu 0x%zx %s\n", i, pc, StripPathPrefix(buff)); - } -} - -#else // ASAN_USE_EXTERNAL_SYMBOLIZER void AsanStackTrace::PrintStack(uptr *addr, uptr size) { ProcessMaps proc_maps; uptr frame_num = 0; for (uptr i = 0; i < size && addr[i]; i++) { uptr pc = patch_pc(addr[i]); + if (symbolize_callback) { + char buff[4096]; + symbolize_callback((void*)pc, buff, sizeof(buff)); + // We can't know anything about the string returned by external + // symbolizer, but if it starts with filename, try to strip path prefix + // from it. + AsanPrintf(" #%zu 0x%zx %s\n", frame_num, pc, StripPathPrefix(buff)); + frame_num++; + continue; + } AddressInfo addr_frames[64]; uptr addr_frames_num = 0; if (flags()->symbolize) { @@ -102,7 +96,6 @@ void AsanStackTrace::PrintStack(uptr *addr, uptr size) { } } } -#endif // ASAN_USE_EXTERNAL_SYMBOLIZER uptr AsanStackTrace::GetCurrentPc() { return GET_CALLER_PC(); @@ -240,3 +233,11 @@ void AsanStackTrace::UncompressStack(AsanStackTrace *stack, } } // namespace __asan + +// ------------------ Interface -------------- {{{1 +using namespace __asan; // NOLINT + +void NOINLINE __asan_set_symbolize_callback( + __asan_symbolize_callback callback) { + symbolize_callback = callback; +} diff --git a/compiler-rt/lib/asan/asan_win.cc b/compiler-rt/lib/asan/asan_win.cc index 9e899d5865f..d50ee143c7f 100644 --- a/compiler-rt/lib/asan/asan_win.cc +++ b/compiler-rt/lib/asan/asan_win.cc @@ -55,7 +55,7 @@ void AsanStackTrace::GetStackTrace(uptr max_s, uptr pc, uptr bp) { trace[i] = (uptr)tmp[i + offset]; } -bool __asan_WinSymbolize(const void *addr, char *out_buffer, int buffer_size) { +bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size) { ScopedLock lock(&dbghelp_lock); if (!dbghelp_initialized) { SymSetOptions(SYMOPT_DEFERRED_LOADS | diff --git a/compiler-rt/lib/asan/lit_tests/interface_symbols.c b/compiler-rt/lib/asan/lit_tests/interface_symbols.c index ebc283ae58d..8b92695c975 100644 --- a/compiler-rt/lib/asan/lit_tests/interface_symbols.c +++ b/compiler-rt/lib/asan/lit_tests/interface_symbols.c @@ -3,8 +3,9 @@ // RUN: %clang -faddress-sanitizer -dead_strip -O2 %s -o %t.exe // RUN: nm %t.exe | egrep " [TW] " | sed "s/.* T //" | sed "s/.* W //" \ // RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" > %t.symbols -// RUN: cat %p/../asan_interface.h | sed "s/\/\/.*//" | grep "__asan_.*(" \ -// RUN: | sed "s/.* __asan_/__asan_/;s/(.*//" > %t.interface +// RUN: cat %p/../asan_interface.h | sed "s/\/\/.*//" | sed "s/typedef.*//" \ +// RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ +// RUN: > %t.interface // RUN: echo __asan_report_load1 >> %t.interface // RUN: echo __asan_report_load2 >> %t.interface // RUN: echo __asan_report_load4 >> %t.interface diff --git a/compiler-rt/lib/asan/lit_tests/symbolize_callback.cc b/compiler-rt/lib/asan/lit_tests/symbolize_callback.cc new file mode 100644 index 00000000000..08ed9644d3e --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/symbolize_callback.cc @@ -0,0 +1,21 @@ +// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <stdlib.h> + +bool MySymbolizer(const void *pc, char *out_buffer, int out_size) { + snprintf(out_buffer, out_size, "MySymbolizer"); + return true; +} + +typedef bool (*asan_symbolize_callback)(const void*, char*, int); +extern "C" +void __asan_set_symbolize_callback(asan_symbolize_callback); + +int main() { + __asan_set_symbolize_callback(MySymbolizer); + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return x[5]; + // CHECK: MySymbolizer +} diff --git a/compiler-rt/lib/asan/output_tests/test_output.sh b/compiler-rt/lib/asan/output_tests/test_output.sh index 5dd4e9b4c2d..fb2d74cbf88 100755 --- a/compiler-rt/lib/asan/output_tests/test_output.sh +++ b/compiler-rt/lib/asan/output_tests/test_output.sh @@ -50,7 +50,7 @@ rm ./a.out echo "Checking the presense of interface symbols in compiled file" $CC -g -faddress-sanitizer -dead_strip -O2 $C_TEST.c nm ./a.out | egrep " [TW] " | sed "s/.* T //" | sed "s/.* W //" | grep "__asan_" | sed "s/___asan_/__asan_/" > symbols.txt -cat $ASAN_INTERFACE_H | sed "s/\/\/.*//" | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" > interface.txt +cat $ASAN_INTERFACE_H | sed "s/\/\/.*//" | sed "s/typedef.*//" | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" > interface.txt for i in __asan_report_{load,store}{1,2,4,8,16} do echo $i >> interface.txt |

