From: Mike Aizatsky Date: Mon, 5 Dec 2016 21:45:14 +0000 (+0000) Subject: [sanitizers] __sanitizer_get_module_and_offset_for_pc interface function X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0d98da7c1f7a41f4d84e1232c1f53989a09f229e;p=platform%2Fupstream%2Fllvm.git [sanitizers] __sanitizer_get_module_and_offset_for_pc interface function Summary: The function computes full module name and coverts pc into offset. Reviewers: kcc Subscribers: kubabrecka Differential Revision: https://reviews.llvm.org/D26820 llvm-svn: 288711 --- diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h index 130f0f2..f9f9302 100644 --- a/compiler-rt/include/sanitizer/common_interface_defs.h +++ b/compiler-rt/include/sanitizer/common_interface_defs.h @@ -182,6 +182,13 @@ extern "C" { void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old); + + // Get full module name and calculate pc offset within it. + // Returns 1 if pc belongs to some module, 0 if module was not found. + int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path, + size_t module_path_len, + void **pc_offset); + #ifdef __cplusplus } // extern "C" #endif diff --git a/compiler-rt/lib/asan/asan_win_dll_thunk.cc b/compiler-rt/lib/asan/asan_win_dll_thunk.cc index 668b93d..0f62928 100644 --- a/compiler-rt/lib/asan/asan_win_dll_thunk.cc +++ b/compiler-rt/lib/asan/asan_win_dll_thunk.cc @@ -366,6 +366,7 @@ INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container) INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks) INTERFACE_FUNCTION(__sanitizer_start_switch_fiber) INTERFACE_FUNCTION(__sanitizer_finish_switch_fiber) +INTERFACE_FUNCTION(__sanitizer_get_module_and_offset_for_pc) // TODO(timurrrr): Add more interface functions on the as-needed basis. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc index ddf537a..36c98d05 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc @@ -82,6 +82,21 @@ void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context, } } +static int GetModuleAndOffsetForPc(uptr pc, char *module_name, + uptr module_name_len, uptr *pc_offset) { + const char *found_module_name = nullptr; + bool ok = Symbolizer::GetOrInit()->GetModuleNameAndOffsetForPC( + pc, &found_module_name, pc_offset); + + if (!ok) return false; + + if (module_name && module_name_len) { + internal_strncpy(module_name, found_module_name, module_name_len); + module_name[module_name_len - 1] = '\x00'; + } + return true; +} + } // namespace __sanitizer using namespace __sanitizer; @@ -117,4 +132,11 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt, internal_strncpy(out_buf, data_desc.data(), out_buf_size); out_buf[out_buf_size - 1] = 0; } + +SANITIZER_INTERFACE_ATTRIBUTE +int __sanitizer_get_module_and_offset_for_pc( // NOLINT + uptr pc, char *module_name, uptr module_name_len, uptr *pc_offset) { + return __sanitizer::GetModuleAndOffsetForPc(pc, module_name, module_name_len, + pc_offset); +} } // extern "C" diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc index dce73ed..f50d8b1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -55,7 +55,7 @@ const char *DemangleCXXABI(const char *name) { // own demangler (libc++abi's implementation could be adapted so that // it does not allocate). For now, we just call it anyway, and we leak // the returned value. - if (__cxxabiv1::__cxa_demangle) + if (&__cxxabiv1::__cxa_demangle) if (const char *demangled_name = __cxxabiv1::__cxa_demangle(name, 0, 0, 0)) return demangled_name; diff --git a/compiler-rt/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc b/compiler-rt/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc new file mode 100644 index 0000000..c95946e --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/get_module_and_offset_for_pc.cc @@ -0,0 +1,63 @@ +// RUN: %clangxx -DSHARED %s -shared -o %T/get_module_and_offset_for_pc.so -fPIC +// RUN: %clangxx -DSO_DIR=\"%T\" -O0 %s -ldl -o %t +// RUN: %run %t 2>&1 | FileCheck %s +// UNSUPPORTED: i386-darwin +// +// Tests __sanitizer_get_module_and_offset_for_pc. + +#include +#include +#include +#include + +#ifdef SHARED +extern "C" { +int foo() { return 1; } +} +#else + +void Test(void *pc, const char *name) { + char module_name[1024]; + void *offset; + int ok = __sanitizer_get_module_and_offset_for_pc( + pc, module_name, sizeof(module_name), &offset); + if (!ok) { + printf("NOT FOUND %s: %p\n", name, pc); + } else { + printf("FOUND %s: %s %p\n", name, module_name, offset); + } +} + +void TestCallerPc() { Test(__builtin_return_address(0), "callerpc"); } + +void TestDlsym() { + void *handle = dlopen(SO_DIR "/get_module_and_offset_for_pc.so", RTLD_LAZY); + assert(handle); + void *foo = dlsym(handle, "foo"); + assert(foo); + Test(foo, "foo"); + dlclose(handle); +} + +// Call __sanitizer_get_module_and_offset_for_pc lots of times +// to make sure it is not too slow. +void TestLoop() { + void *pc = __builtin_return_address(0); + char module_name[1024]; + void *offset; + for (int i = 0; i < 1000000; ++i) { + __sanitizer_get_module_and_offset_for_pc(pc, module_name, + sizeof(module_name), &offset); + } +} + +int main() { + Test(0, "null"); + TestCallerPc(); + TestDlsym(); + TestLoop(); +} +#endif +// CHECK: NOT FOUND null: (nil) +// CHECK-NEXT: FOUND callerpc: {{.*}}/get_module_and_offset_for_pc.cc.tmp {{.*}} +// CHECK-NEXT: FOUND foo: {{.*}}/get_module_and_offset_for_pc.so {{.*}}