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 #include <string> 15 16 #include "llvm/DebugInfo/Symbolize/DIPrinter.h" 17 #include "llvm/DebugInfo/Symbolize/Symbolize.h" 18 19 static llvm::symbolize::LLVMSymbolizer *getDefaultSymbolizer() { 20 static llvm::symbolize::LLVMSymbolizer *DefaultSymbolizer = 21 new llvm::symbolize::LLVMSymbolizer(); 22 return DefaultSymbolizer; 23 } 24 25 namespace __sanitizer { 26 int internal_snprintf(char *buffer, unsigned long length, const char *format, 27 ...); 28 } // namespace __sanitizer 29 30 extern "C" { 31 32 typedef uint64_t u64; 33 34 bool __sanitizer_symbolize_code(const char *ModuleName, uint64_t ModuleOffset, 35 char *Buffer, int MaxLength) { 36 std::string Result; 37 { 38 llvm::raw_string_ostream OS(Result); 39 llvm::symbolize::DIPrinter Printer(OS); 40 // TODO: it is neccessary to set proper SectionIndex here. 41 // object::SectionedAddress::UndefSection works for only absolute addresses. 42 auto ResOrErr = getDefaultSymbolizer()->symbolizeInlinedCode( 43 ModuleName, 44 {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); 45 Printer << (ResOrErr ? ResOrErr.get() : llvm::DIInliningInfo()); 46 } 47 return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", 48 Result.c_str()) < MaxLength; 49 } 50 51 bool __sanitizer_symbolize_data(const char *ModuleName, uint64_t ModuleOffset, 52 char *Buffer, int MaxLength) { 53 std::string Result; 54 { 55 llvm::raw_string_ostream OS(Result); 56 llvm::symbolize::DIPrinter Printer(OS); 57 // TODO: it is neccessary to set proper SectionIndex here. 58 // object::SectionedAddress::UndefSection works for only absolute addresses. 59 auto ResOrErr = getDefaultSymbolizer()->symbolizeData( 60 ModuleName, 61 {ModuleOffset, llvm::object::SectionedAddress::UndefSection}); 62 Printer << (ResOrErr ? ResOrErr.get() : llvm::DIGlobal()); 63 } 64 return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", 65 Result.c_str()) < MaxLength; 66 } 67 68 void __sanitizer_symbolize_flush() { getDefaultSymbolizer()->flush(); } 69 70 int __sanitizer_symbolize_demangle(const char *Name, char *Buffer, 71 int MaxLength) { 72 std::string Result = 73 llvm::symbolize::LLVMSymbolizer::DemangleName(Name, nullptr); 74 return __sanitizer::internal_snprintf(Buffer, MaxLength, "%s", 75 Result.c_str()) < MaxLength 76 ? static_cast<int>(Result.size() + 1) 77 : 0; 78 } 79 80 } // extern "C" 81