summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-08-22 13:31:37 +0000
committerAlexey Samsonov <samsonov@google.com>2012-08-22 13:31:37 +0000
commita85b6b8154f57043af388d7626502fbcc93150ed (patch)
tree793ee040c1d0daa71bf153b6dc64a699bcee30f6
parent9e10605d6b4b508c38234524fe69e6fca62cf217 (diff)
downloadbcm5719-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.h10
-rw-r--r--compiler-rt/lib/asan/asan_internal.h5
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc4
-rw-r--r--compiler-rt/lib/asan/asan_stack.cc41
-rw-r--r--compiler-rt/lib/asan/asan_win.cc2
-rw-r--r--compiler-rt/lib/asan/lit_tests/interface_symbols.c5
-rw-r--r--compiler-rt/lib/asan/lit_tests/symbolize_callback.cc21
-rwxr-xr-xcompiler-rt/lib/asan/output_tests/test_output.sh2
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
OpenPOWER on IntegriCloud