1 //===- Symbolize.h ----------------------------------------------*- 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 // Header for LLVM symbolization library. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H 14 #define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H 15 16 #include "llvm/DebugInfo/Symbolize/DIFetcher.h" 17 #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h" 18 #include "llvm/Object/Binary.h" 19 #include "llvm/Object/ELFObjectFile.h" 20 #include "llvm/Object/ObjectFile.h" 21 #include "llvm/Support/Error.h" 22 #include <algorithm> 23 #include <cstdint> 24 #include <map> 25 #include <memory> 26 #include <string> 27 #include <utility> 28 #include <vector> 29 30 namespace llvm { 31 namespace symbolize { 32 33 using namespace object; 34 35 using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; 36 using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind; 37 38 class LLVMSymbolizer { 39 public: 40 struct Options { 41 FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName; 42 FileLineInfoKind PathStyle = FileLineInfoKind::AbsoluteFilePath; 43 bool UseSymbolTable = true; 44 bool Demangle = true; 45 bool RelativeAddresses = false; 46 bool UntagAddresses = false; 47 bool UseDIA = false; 48 std::string DefaultArch; 49 std::vector<std::string> DsymHints; 50 std::string FallbackDebugPath; 51 std::string DWPName; 52 std::vector<std::string> DebugFileDirectory; 53 }; 54 55 LLVMSymbolizer() = default; 56 LLVMSymbolizer(const Options &Opts) : Opts(Opts) {} 57 58 ~LLVMSymbolizer() { flush(); } 59 60 // Overloads accepting ObjectFile does not support COFF currently 61 Expected<DILineInfo> symbolizeCode(const ObjectFile &Obj, 62 object::SectionedAddress ModuleOffset); 63 Expected<DILineInfo> symbolizeCode(const std::string &ModuleName, 64 object::SectionedAddress ModuleOffset); 65 Expected<DIInliningInfo> 66 symbolizeInlinedCode(const ObjectFile &Obj, 67 object::SectionedAddress ModuleOffset); 68 Expected<DIInliningInfo> 69 symbolizeInlinedCode(const std::string &ModuleName, 70 object::SectionedAddress ModuleOffset); 71 72 Expected<DIGlobal> symbolizeData(const ObjectFile &Obj, 73 object::SectionedAddress ModuleOffset); 74 Expected<DIGlobal> symbolizeData(const std::string &ModuleName, 75 object::SectionedAddress ModuleOffset); 76 Expected<std::vector<DILocal>> 77 symbolizeFrame(const ObjectFile &Obj, object::SectionedAddress ModuleOffset); 78 Expected<std::vector<DILocal>> 79 symbolizeFrame(const std::string &ModuleName, 80 object::SectionedAddress ModuleOffset); 81 void flush(); 82 83 static std::string 84 DemangleName(const std::string &Name, 85 const SymbolizableModule *DbiModuleDescriptor); 86 87 void addDIFetcher(std::unique_ptr<DIFetcher> Fetcher) { 88 DIFetchers.push_back(std::move(Fetcher)); 89 } 90 91 private: 92 // Bundles together object file with code/data and object file with 93 // corresponding debug info. These objects can be the same. 94 using ObjectPair = std::pair<const ObjectFile *, const ObjectFile *>; 95 96 template <typename T> 97 Expected<DILineInfo> 98 symbolizeCodeCommon(const T &ModuleSpecifier, 99 object::SectionedAddress ModuleOffset); 100 template <typename T> 101 Expected<DIInliningInfo> 102 symbolizeInlinedCodeCommon(const T &ModuleSpecifier, 103 object::SectionedAddress ModuleOffset); 104 template <typename T> 105 Expected<DIGlobal> symbolizeDataCommon(const T &ModuleSpecifier, 106 object::SectionedAddress ModuleOffset); 107 template <typename T> 108 Expected<std::vector<DILocal>> 109 symbolizeFrameCommon(const T &ModuleSpecifier, 110 object::SectionedAddress ModuleOffset); 111 112 /// Returns a SymbolizableModule or an error if loading debug info failed. 113 /// Only one attempt is made to load a module, and errors during loading are 114 /// only reported once. Subsequent calls to get module info for a module that 115 /// failed to load will return nullptr. 116 Expected<SymbolizableModule *> 117 getOrCreateModuleInfo(const std::string &ModuleName); 118 Expected<SymbolizableModule *> getOrCreateModuleInfo(const ObjectFile &Obj); 119 120 Expected<SymbolizableModule *> 121 createModuleInfo(const ObjectFile *Obj, std::unique_ptr<DIContext> Context, 122 StringRef ModuleName); 123 124 ObjectFile *lookUpDsymFile(const std::string &Path, 125 const MachOObjectFile *ExeObj, 126 const std::string &ArchName); 127 ObjectFile *lookUpDebuglinkObject(const std::string &Path, 128 const ObjectFile *Obj, 129 const std::string &ArchName); 130 ObjectFile *lookUpBuildIDObject(const std::string &Path, 131 const ELFObjectFileBase *Obj, 132 const std::string &ArchName); 133 134 bool findDebugBinary(const std::string &OrigPath, 135 const std::string &DebuglinkName, uint32_t CRCHash, 136 std::string &Result); 137 138 bool findDebugBinary(const ArrayRef<uint8_t> BuildID, std::string &Result); 139 140 /// Returns pair of pointers to object and debug object. 141 Expected<ObjectPair> getOrCreateObjectPair(const std::string &Path, 142 const std::string &ArchName); 143 144 /// Return a pointer to object file at specified path, for a specified 145 /// architecture (e.g. if path refers to a Mach-O universal binary, only one 146 /// object file from it will be returned). 147 Expected<ObjectFile *> getOrCreateObject(const std::string &Path, 148 const std::string &ArchName); 149 150 std::map<std::string, std::unique_ptr<SymbolizableModule>, std::less<>> 151 Modules; 152 153 /// Contains cached results of getOrCreateObjectPair(). 154 std::map<std::pair<std::string, std::string>, ObjectPair> 155 ObjectPairForPathArch; 156 157 /// Contains parsed binary for each path, or parsing error. 158 std::map<std::string, OwningBinary<Binary>> BinaryForPath; 159 160 /// Parsed object file for path/architecture pair, where "path" refers 161 /// to Mach-O universal binary. 162 std::map<std::pair<std::string, std::string>, std::unique_ptr<ObjectFile>> 163 ObjectForUBPathAndArch; 164 165 Options Opts; 166 167 SmallVector<std::unique_ptr<DIFetcher>> DIFetchers; 168 }; 169 170 } // end namespace symbolize 171 } // end namespace llvm 172 173 #endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H 174