1 //===-- sanitizer_symbolize.cpp ---------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Implementation of weak hooks from sanitizer_symbolizer_posix_libcdep.cpp. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include <stdio.h> 14 15 #include <string> 16 17 #include "llvm/DebugInfo/Symbolize/DIPrinter.h" 18 #include "llvm/DebugInfo/Symbolize/Symbolize.h" 19 20 static llvm::symbolize::LLVMSymbolizer *getDefaultSymbolizer() { 21 static llvm::symbolize::LLVMSymbolizer *DefaultSymbolizer = 22 new llvm::symbolize::LLVMSymbolizer(); 23 return DefaultSymbolizer; 24 } 25 26 namespace __sanitizer { 27 int internal_snprintf(char *buffer, unsigned long length, const char *format, 28 ...); 29 } // namespace __sanitizer 30 31 extern "C" { 32 33 typedef uint64_t u64; 34 35 bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset, 36 char *Buffer, int MaxLength, 37 bool SymbolizeInlineFrames) { 38 std::string Result; 39 { 40 llvm::raw_string_ostream OS(Result); 41 llvm::symbolize::DIPrinter Printer(OS); 42 // TODO: it is neccessary to set proper SectionIndex here. 43 // object::SectionedAddress::UndefSection works for only absolute addresses. 44 if (SymbolizeInlineFrames) { 45 auto ResOrErr = getDefaultSymbolizer()->symbolizeInlinedCode( 46 ModuleName, 47 {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); 48 Printer << (ResOrErr ? ResOrErr.get() : llvm::DIInliningInfo()); 49 } else { 50 auto ResOrErr = getDefaultSymbolizer()->symbolizeCode( 51 ModuleName, 52 {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); 53 Printer << (ResOrErr ? ResOrErr.get() : llvm::DILineInfo()); 54 } 55 } 56 return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", 57 Result.c_str()) < MaxLength; 58 } 59 60 bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset, 61 char *Buffer, int MaxLength) { 62 std::string Result; 63 { 64 llvm::raw_string_ostream OS(Result); 65 llvm::symbolize::DIPrinter Printer(OS); 66 // TODO: it is neccessary to set proper SectionIndex here. 67 // object::SectionedAddress::UndefSection works for only absolute addresses. 68 auto ResOrErr = getDefaultSymbolizer()->symbolizeData( 69 ModuleName, 70 {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); 71 Printer << (ResOrErr ? ResOrErr.get() : llvm::DIGlobal()); 72 } 73 return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", 74 Result.c_str()) < MaxLength; 75 } 76 77 void __sanitizer_symbolize_flush() { getDefaultSymbolizer()->flush(); } 78 79 int __sanitizer_symbolize_demangle(const char *Name, char *Buffer, 80 int MaxLength) { 81 std::string Result = 82 llvm::symbolize::LLVMSymbolizer::DemangleName(Name, nullptr); 83 return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", 84 Result.c_str()) < MaxLength 85 ? static_cast<int>(Result.size() + 1) 86 : 0; 87 } 88 89 } // extern "C" 90