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