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