[Sanitizer] Add skeleton for InternalSymbolizer that can be used by providing callbac...
authorAlexey Samsonov <samsonov@google.com>
Thu, 24 Jan 2013 13:42:45 +0000 (13:42 +0000)
committerAlexey Samsonov <samsonov@google.com>
Thu, 24 Jan 2013 13:42:45 +0000 (13:42 +0000)
llvm-svn: 173344

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cc

index a1d95ae..40d8d7d 100644 (file)
@@ -176,6 +176,47 @@ class ExternalSymbolizer {
 
 static LowLevelAllocator symbolizer_allocator;  // Linker initialized.
 
+#if SANITIZER_SUPPORTS_WEAK_HOOKS
+extern "C" {
+SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
+bool __sanitizer_symbolize_code(const char *ModuleName, u64 ModuleOffset,
+                                char *Buffer, int MaxLength);
+SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
+bool __sanitizer_symbolize_data(const char *ModuleName, u64 ModuleOffset,
+                                char *Buffer, int MaxLength);
+}  // extern "C"
+#endif  // SANITIZER_SUPPORTS_WEAK_HOOKS
+
+class InternalSymbolizer {
+ public:
+  typedef bool (*SanitizerSymbolizeFn)(const char*, u64, char*, int);
+  static InternalSymbolizer *get() {
+#if SANITIZER_SUPPORTS_WEAK_HOOKS
+    if (__sanitizer_symbolize_code != 0 &&
+        __sanitizer_symbolize_data != 0) {
+      void *mem = symbolizer_allocator.Allocate(sizeof(InternalSymbolizer));
+      return new(mem) InternalSymbolizer();
+    }
+#endif  // SANITIZER_SUPPORTS_WEAK_HOOKS
+    return 0;
+  }
+  char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
+#if SANITIZER_SUPPORTS_WEAK_HOOKS
+    SanitizerSymbolizeFn symbolize_fn = is_data ? __sanitizer_symbolize_data
+                                                : __sanitizer_symbolize_code;
+    if (symbolize_fn(module_name, module_offset, buffer_, kBufferSize))
+      return buffer_;
+#endif  // SANITIZER_SUPPORTS_WEAK_HOOKS
+    return 0;
+  }
+
+ private:
+  InternalSymbolizer() { }
+
+  static const int kBufferSize = 16 * 1024;
+  char buffer_[kBufferSize];
+};
+
 class Symbolizer {
  public:
   uptr SymbolizeCode(uptr addr, AddressInfo *frames, uptr max_frames) {
@@ -270,6 +311,15 @@ class Symbolizer {
 
  private:
   char *SendCommand(bool is_data, const char *module_name, uptr module_offset) {
+    // First, try to use internal symbolizer.
+    if (internal_symbolizer_ == 0) {
+      internal_symbolizer_ = InternalSymbolizer::get();
+    }
+    if (internal_symbolizer_) {
+      return internal_symbolizer_->SendCommand(is_data, module_name,
+                                               module_offset);
+    }
+    // Otherwise, fall back to external symbolizer.
     if (external_symbolizer_ == 0) {
       ReportExternalSymbolizerError(
           "WARNING: Trying to symbolize code, but external "
@@ -324,6 +374,7 @@ class Symbolizer {
   uptr n_modules_;
 
   ExternalSymbolizer *external_symbolizer_;  // Leaked.
+  InternalSymbolizer *internal_symbolizer_;  // Leaked.
 };
 
 static Symbolizer symbolizer;  // Linker initialized.