File indexing completed on 2026-05-10 08:43:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWREADER_H
0015 #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWREADER_H
0016
0017 #include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
0018 #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
0019 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
0020 #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
0021 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
0022 #include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h"
0023 #include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h"
0024 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
0025 #include "llvm/DebugInfo/PDB/PDB.h"
0026 #include "llvm/Support/BinaryByteStream.h"
0027 #include "llvm/Support/BinaryItemStream.h"
0028 #include "llvm/Support/BinaryStreamArray.h"
0029
0030 namespace llvm {
0031 template <> struct BinaryItemTraits<codeview::CVType> {
0032 static size_t length(const codeview::CVType &Item) { return Item.length(); }
0033 static ArrayRef<uint8_t> bytes(const codeview::CVType &Item) {
0034 return Item.data();
0035 }
0036 };
0037
0038 namespace codeview {
0039 class LazyRandomTypeCollection;
0040 }
0041 namespace object {
0042 struct coff_section;
0043 }
0044 namespace pdb {
0045 class SymbolGroup;
0046 }
0047 namespace logicalview {
0048
0049 class LVElement;
0050 class LVLine;
0051 class LVScope;
0052 class LVScopeCompileUnit;
0053 class LVSymbol;
0054 class LVType;
0055 class LVTypeVisitor;
0056 class LVSymbolVisitor;
0057 class LVSymbolVisitorDelegate;
0058
0059 using LVNames = SmallVector<StringRef, 16>;
0060
0061
0062
0063
0064
0065
0066
0067 class LVCodeViewReader final : public LVBinaryReader {
0068 friend class LVTypeVisitor;
0069 friend class LVSymbolVisitor;
0070 friend class LVSymbolVisitorDelegate;
0071
0072 using LVModules = std::vector<LVScope *>;
0073 LVModules Modules;
0074
0075
0076
0077 llvm::pdb::InputFile Input;
0078 std::shared_ptr<llvm::pdb::InputFile> TypeServer;
0079 std::shared_ptr<LazyRandomTypeCollection> PrecompHeader;
0080
0081
0082 ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = nullptr;
0083 std::unique_ptr<MemoryBuffer> MemBuffer;
0084 std::unique_ptr<llvm::pdb::IPDBSession> Session;
0085 std::unique_ptr<llvm::pdb::NativeSession> PdbSession;
0086
0087
0088 BumpPtrAllocator BuilderAllocator;
0089 std::unique_ptr<AppendingTypeTableBuilder> Builder;
0090 std::unique_ptr<BinaryItemStream<CVType>> ItemStream;
0091 std::unique_ptr<BinaryStreamReader> ReaderPrecomp;
0092 std::vector<CVType> TypeArray;
0093 CVTypeArray TypeStream;
0094 CVTypeArray CVTypesPrecomp;
0095
0096
0097 std::unique_ptr<MemoryBuffer> BinaryBuffer;
0098 std::unique_ptr<llvm::object::Binary> BinaryExecutable;
0099
0100 Error loadTargetInfo(const object::ObjectFile &Obj);
0101 Error loadTargetInfo(const llvm::pdb::PDBFile &Pdb);
0102
0103 void mapRangeAddress(const object::ObjectFile &Obj,
0104 const object::SectionRef &Section,
0105 bool IsComdat) override;
0106
0107 llvm::object::COFFObjectFile &getObj() { return Input.obj(); }
0108 llvm::pdb::PDBFile &getPdb() { return Input.pdb(); }
0109 bool isObj() const { return Input.isObj(); }
0110 bool isPdb() const { return Input.isPdb(); }
0111 StringRef getFileName() { return Input.getFilePath(); }
0112
0113
0114 std::string ExePath;
0115
0116 LVOffset CurrentOffset = 0;
0117 int32_t CurrentModule = -1;
0118
0119 using RelocMapTy = DenseMap<const llvm::object::coff_section *,
0120 std::vector<llvm::object::RelocationRef>>;
0121 RelocMapTy RelocMap;
0122
0123
0124
0125 LazyRandomTypeCollection &types() {
0126 return TypeServer ? TypeServer->types()
0127 : (PrecompHeader ? *PrecompHeader : Input.types());
0128 }
0129 LazyRandomTypeCollection &ids() {
0130 return TypeServer ? TypeServer->ids()
0131 : (PrecompHeader ? *PrecompHeader : Input.ids());
0132 }
0133
0134 LVLogicalVisitor LogicalVisitor;
0135
0136 Expected<StringRef>
0137 getFileNameForFileOffset(uint32_t FileOffset,
0138 const llvm::pdb::SymbolGroup *SG = nullptr);
0139 void printRelocatedField(StringRef Label,
0140 const llvm::object::coff_section *CoffSection,
0141 uint32_t RelocOffset, uint32_t Offset,
0142 StringRef *RelocSym);
0143
0144 Error printFileNameForOffset(StringRef Label, uint32_t FileOffset,
0145 const llvm::pdb::SymbolGroup *SG = nullptr);
0146
0147 Error loadPrecompiledObject(PrecompRecord &Precomp, CVTypeArray &CVTypesObj);
0148 Error loadTypeServer(TypeServer2Record &TS);
0149 Error traverseTypes(llvm::pdb::PDBFile &Pdb, LazyRandomTypeCollection &Types,
0150 LazyRandomTypeCollection &Ids);
0151
0152 Error collectInlineeInfo(DebugInlineeLinesSubsectionRef &Lines,
0153 const llvm::pdb::SymbolGroup *SG = nullptr);
0154
0155 void cacheRelocations();
0156 Error resolveSymbol(const llvm::object::coff_section *CoffSection,
0157 uint64_t Offset, llvm::object::SymbolRef &Sym);
0158 Error resolveSymbolName(const llvm::object::coff_section *CoffSection,
0159 uint64_t Offset, StringRef &Name);
0160 Error traverseTypeSection(StringRef SectionName,
0161 const llvm::object::SectionRef &Section);
0162 Error traverseSymbolSection(StringRef SectionName,
0163 const llvm::object::SectionRef &Section);
0164 Error traverseInlineeLines(StringRef Subsection);
0165
0166 DebugChecksumsSubsectionRef CVFileChecksumTable;
0167 DebugStringTableSubsectionRef CVStringTable;
0168
0169 Error traverseSymbolsSubsection(StringRef Subsection,
0170 const llvm::object::SectionRef &Section,
0171 StringRef SectionContents);
0172
0173
0174
0175
0176 Error initializeFileAndStringTables(BinaryStreamReader &Reader);
0177
0178 Error createLines(const FixedStreamArray<LineNumberEntry> &LineNumbers,
0179 LVAddress Addendum, uint32_t Segment, uint32_t Begin,
0180 uint32_t Size, uint32_t NameIndex,
0181 const llvm::pdb::SymbolGroup *SG = nullptr);
0182 Error createScopes(llvm::object::COFFObjectFile &Obj);
0183 Error createScopes(llvm::pdb::PDBFile &Pdb);
0184 Error processModule();
0185
0186 protected:
0187 Error createScopes() override;
0188 void sortScopes() override;
0189
0190 public:
0191 LVCodeViewReader() = delete;
0192 LVCodeViewReader(StringRef Filename, StringRef FileFormatName,
0193 llvm::object::COFFObjectFile &Obj, ScopedPrinter &W,
0194 StringRef ExePath)
0195 : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::COFF),
0196 Input(&Obj), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
0197 LVCodeViewReader(StringRef Filename, StringRef FileFormatName,
0198 llvm::pdb::PDBFile &Pdb, ScopedPrinter &W, StringRef ExePath)
0199 : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::COFF),
0200 Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
0201 LVCodeViewReader(const LVCodeViewReader &) = delete;
0202 LVCodeViewReader &operator=(const LVCodeViewReader &) = delete;
0203 ~LVCodeViewReader() = default;
0204
0205 void getLinkageName(const llvm::object::coff_section *CoffSection,
0206 uint32_t RelocOffset, uint32_t Offset,
0207 StringRef *RelocSym);
0208
0209 void addModule(LVScope *Scope) { Modules.push_back(Scope); }
0210 LVScope *getScopeForModule(uint32_t Modi) {
0211 return Modi >= Modules.size() ? nullptr : Modules[Modi];
0212 }
0213
0214
0215 static StringRef getSymbolKindName(SymbolKind Kind);
0216 static std::string formatRegisterId(RegisterId Register, CPUType CPU);
0217
0218 std::string getRegisterName(LVSmall Opcode,
0219 ArrayRef<uint64_t> Operands) override;
0220
0221 bool isSystemEntry(LVElement *Element, StringRef Name) const override;
0222
0223 void print(raw_ostream &OS) const;
0224 void printRecords(raw_ostream &OS) const override {
0225 LogicalVisitor.printRecords(OS);
0226 };
0227
0228 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0229 void dump() const { print(dbgs()); }
0230 #endif
0231 };
0232
0233 }
0234 }
0235
0236 #endif