1 //===-- sanitizer_symbolizer_fuchsia.cc -----------------------------------===// 2 // 3 // This file is distributed under the University of Illinois Open Source 4 // License. See LICENSE.TXT for details. 5 // 6 //===----------------------------------------------------------------------===// 7 // 8 // This file is shared between various sanitizers' runtime libraries. 9 // 10 // Implementation of Fuchsia-specific symbolizer. 11 //===----------------------------------------------------------------------===// 12 13 #include "sanitizer_platform.h" 14 #if SANITIZER_FUCHSIA 15 16 #include "sanitizer_fuchsia.h" 17 #include "sanitizer_symbolizer.h" 18 19 namespace __sanitizer { 20 21 // For Fuchsia we don't do any actual symbolization per se. 22 // Instead, we emit text containing raw addresses and raw linkage 23 // symbol names, embedded in Fuchsia's symbolization markup format. 24 // Fuchsia's logging infrastructure emits enough information about 25 // process memory layout that a post-processing filter can do the 26 // symbolization and pretty-print the markup. See the spec at: 27 // https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md 28 29 // This is used by UBSan for type names, and by ASan for global variable names. 30 constexpr const char *kFormatDemangle = "{{{symbol:%s}}}"; 31 constexpr uptr kFormatDemangleMax = 1024; // Arbitrary. 32 33 // Function name or equivalent from PC location. 34 constexpr const char *kFormatFunction = "{{{pc:%p}}}"; 35 constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex. 36 37 // Global variable name or equivalent from data memory address. 38 constexpr const char *kFormatData = "{{{data:%p}}}"; 39 40 // One frame in a backtrace (printed on a line by itself). 41 constexpr const char *kFormatFrame = "{{{bt:%u:%p}}}"; 42 43 // This is used by UBSan for type names, and by ASan for global variable names. 44 // It's expected to return a static buffer that will be reused on each call. 45 const char *Symbolizer::Demangle(const char *name) { 46 static char buffer[kFormatDemangleMax]; 47 internal_snprintf(buffer, sizeof(buffer), kFormatDemangle, name); 48 return buffer; 49 } 50 51 // This is used mostly for suppression matching. Making it work 52 // would enable "interceptor_via_lib" suppressions. It's also used 53 // once in UBSan to say "in module ..." in a message that also 54 // includes an address in the module, so post-processing can already 55 // pretty-print that so as to indicate the module. 56 bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, 57 uptr *module_address) { 58 return false; 59 } 60 61 // This is used in some places for suppression checking, which we 62 // don't really support for Fuchsia. It's also used in UBSan to 63 // identify a PC location to a function name, so we always fill in 64 // the function member with a string containing markup around the PC 65 // value. 66 // TODO(mcgrathr): Under SANITIZER_GO, it's currently used by TSan 67 // to render stack frames, but that should be changed to use 68 // RenderStackFrame. 69 SymbolizedStack *Symbolizer::SymbolizePC(uptr addr) { 70 SymbolizedStack *s = SymbolizedStack::New(addr); 71 char buffer[kFormatFunctionMax]; 72 internal_snprintf(buffer, sizeof(buffer), kFormatFunction, addr); 73 s->info.function = internal_strdup(buffer); 74 return s; 75 } 76 77 // Always claim we succeeded, so that RenderDataInfo will be called. 78 bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { 79 info->Clear(); 80 info->start = addr; 81 return true; 82 } 83 84 // We ignore the format argument to __sanitizer_symbolize_global. 85 void RenderData(InternalScopedString *buffer, const char *format, 86 const DataInfo *DI, const char *strip_path_prefix) { 87 buffer->append(kFormatData, DI->start); 88 } 89 90 // We don't support the stack_trace_format flag at all. 91 void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, 92 const AddressInfo &info, bool vs_style, 93 const char *strip_path_prefix, const char *strip_func_prefix) { 94 buffer->append(kFormatFrame, frame_no, info.address); 95 } 96 97 Symbolizer *Symbolizer::PlatformInit() { 98 return new (symbolizer_allocator_) Symbolizer({}); 99 } 100 101 void Symbolizer::LateInitialize() { Symbolizer::GetOrInit(); } 102 103 } // namespace __sanitizer 104 105 #endif // SANITIZER_FUCHSIA 106