LLVM 20.0.0git
LVCodeViewReader.h
Go to the documentation of this file.
1//===-- LVCodeViewReader.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// This file defines the LVCodeViewReader class, which is used to describe a
10// debug information (COFF) reader.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWREADER_H
15#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWREADER_H
16
29
30namespace llvm {
31template <> struct BinaryItemTraits<codeview::CVType> {
32 static size_t length(const codeview::CVType &Item) { return Item.length(); }
34 return Item.data();
35 }
36};
37
38namespace codeview {
39class LazyRandomTypeCollection;
40}
41namespace object {
42struct coff_section;
43}
44namespace pdb {
45class SymbolGroup;
46}
47namespace logicalview {
48
49class LVElement;
50class LVLine;
51class LVScope;
52class LVScopeCompileUnit;
53class LVSymbol;
54class LVType;
55class LVTypeVisitor;
56class LVSymbolVisitor;
57class LVSymbolVisitorDelegate;
58
60
61// The DWARF reader uses the DWARF constants to create the logical elements.
62// The DW_TAG_* and DW_AT_* are used to select the logical object and to
63// set specific attributes, such as name, type, etc.
64// As the CodeView constants are different to the DWARF constants, the
65// CodeView reader will map them to the DWARF ones.
66
67class LVCodeViewReader final : public LVBinaryReader {
68 friend class LVTypeVisitor;
69 friend class LVSymbolVisitor;
71
72 using LVModules = std::vector<LVScope *>;
73 LVModules Modules;
74
75 // Encapsulates access to the input file and any dependent type server,
76 // including any precompiled header object.
78 std::shared_ptr<llvm::pdb::InputFile> TypeServer;
79 std::shared_ptr<LazyRandomTypeCollection> PrecompHeader;
80
81 // Persistance data when loading a type server.
82 ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = nullptr;
83 std::unique_ptr<MemoryBuffer> MemBuffer;
84 std::unique_ptr<llvm::pdb::IPDBSession> Session;
85 std::unique_ptr<llvm::pdb::NativeSession> PdbSession;
86
87 // Persistance data when loading a precompiled header.
88 BumpPtrAllocator BuilderAllocator;
89 std::unique_ptr<AppendingTypeTableBuilder> Builder;
90 std::unique_ptr<BinaryItemStream<CVType>> ItemStream;
91 std::unique_ptr<BinaryStreamReader> ReaderPrecomp;
92 std::vector<CVType> TypeArray;
93 CVTypeArray TypeStream;
94 CVTypeArray CVTypesPrecomp;
95
96 // Persistance data when loading an executable file.
97 std::unique_ptr<MemoryBuffer> BinaryBuffer;
98 std::unique_ptr<llvm::object::Binary> BinaryExecutable;
99
100 Error loadTargetInfo(const object::ObjectFile &Obj);
101 Error loadTargetInfo(const llvm::pdb::PDBFile &Pdb);
102
103 void mapRangeAddress(const object::ObjectFile &Obj,
104 const object::SectionRef &Section,
105 bool IsComdat) override;
106
107 llvm::object::COFFObjectFile &getObj() { return Input.obj(); }
108 llvm::pdb::PDBFile &getPdb() { return Input.pdb(); }
109 bool isObj() const { return Input.isObj(); }
110 bool isPdb() const { return Input.isPdb(); }
111 StringRef getFileName() { return Input.getFilePath(); }
112
113 // Pathname to executable image.
114 std::string ExePath;
115
116 LVOffset CurrentOffset = 0;
117 int32_t CurrentModule = -1;
118
119 using RelocMapTy = DenseMap<const llvm::object::coff_section *,
120 std::vector<llvm::object::RelocationRef>>;
121 RelocMapTy RelocMap;
122
123 // Object files have only one type stream that contains both types and ids.
124 // Precompiled header objects don't contain an IPI stream. Use the TPI.
125 LazyRandomTypeCollection &types() {
126 return TypeServer ? TypeServer->types()
127 : (PrecompHeader ? *PrecompHeader : Input.types());
128 }
129 LazyRandomTypeCollection &ids() {
130 return TypeServer ? TypeServer->ids()
131 : (PrecompHeader ? *PrecompHeader : Input.ids());
132 }
133
134 LVLogicalVisitor LogicalVisitor;
135
136 Expected<StringRef>
137 getFileNameForFileOffset(uint32_t FileOffset,
138 const llvm::pdb::SymbolGroup *SG = nullptr);
139 void printRelocatedField(StringRef Label,
140 const llvm::object::coff_section *CoffSection,
141 uint32_t RelocOffset, uint32_t Offset,
142 StringRef *RelocSym);
143
144 Error printFileNameForOffset(StringRef Label, uint32_t FileOffset,
145 const llvm::pdb::SymbolGroup *SG = nullptr);
146
147 Error loadPrecompiledObject(PrecompRecord &Precomp, CVTypeArray &CVTypesObj);
148 Error loadTypeServer(TypeServer2Record &TS);
149 Error traverseTypes(llvm::pdb::PDBFile &Pdb, LazyRandomTypeCollection &Types,
150 LazyRandomTypeCollection &Ids);
151
152 Error collectInlineeInfo(DebugInlineeLinesSubsectionRef &Lines,
153 const llvm::pdb::SymbolGroup *SG = nullptr);
154
155 void cacheRelocations();
156 Error resolveSymbol(const llvm::object::coff_section *CoffSection,
158 Error resolveSymbolName(const llvm::object::coff_section *CoffSection,
159 uint64_t Offset, StringRef &Name);
160 Error traverseTypeSection(StringRef SectionName,
161 const llvm::object::SectionRef &Section);
162 Error traverseSymbolSection(StringRef SectionName,
163 const llvm::object::SectionRef &Section);
164 Error traverseInlineeLines(StringRef Subsection);
165
166 DebugChecksumsSubsectionRef CVFileChecksumTable;
167 DebugStringTableSubsectionRef CVStringTable;
168
169 Error traverseSymbolsSubsection(StringRef Subsection,
170 const llvm::object::SectionRef &Section,
171 StringRef SectionContents);
172
173 /// Given a .debug$S section, find the string table and file checksum table.
174 /// This function taken from (COFFDumper.cpp).
175 /// TODO: It can be moved to the COFF library.
176 Error initializeFileAndStringTables(BinaryStreamReader &Reader);
177
178 Error createLines(const FixedStreamArray<LineNumberEntry> &LineNumbers,
179 LVAddress Addendum, uint32_t Segment, uint32_t Begin,
180 uint32_t Size, uint32_t NameIndex,
181 const llvm::pdb::SymbolGroup *SG = nullptr);
184 Error processModule();
185
186protected:
187 Error createScopes() override;
188 void sortScopes() override;
189
190public:
194 StringRef ExePath)
196 Input(&Obj), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
200 Input(&Pdb), ExePath(ExePath), LogicalVisitor(this, W, Input) {}
203 ~LVCodeViewReader() = default;
204
205 void getLinkageName(const llvm::object::coff_section *CoffSection,
206 uint32_t RelocOffset, uint32_t Offset,
207 StringRef *RelocSym);
208
209 void addModule(LVScope *Scope) { Modules.push_back(Scope); }
211 return Modi >= Modules.size() ? nullptr : Modules[Modi];
212 }
213
214 // Get the string representation for the CodeView symbols.
216 static std::string formatRegisterId(RegisterId Register, CPUType CPU);
217
218 std::string getRegisterName(LVSmall Opcode,
220
221 bool isSystemEntry(LVElement *Element, StringRef Name) const override;
222
223 void print(raw_ostream &OS) const;
224 void printRecords(raw_ostream &OS) const override {
225 LogicalVisitor.printRecords(OS);
226 };
227
228#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
229 void dump() const { print(dbgs()); }
230#endif
231};
232
233} // end namespace logicalview
234} // end namespace llvm
235
236#endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWREADER_H
Lightweight arrays that are backed by an arbitrary BinaryStream.
static Expected< StringRef > getFileName(const DebugStringTableSubsectionRef &Strings, const DebugChecksumsSubsectionRef &Checksums, uint32_t FileID)
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
DenseMap< uint64_t, uint64_t > RelocMap
mir Rename Register Operands
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Represents either an error or a value T.
Definition: ErrorOr.h:56
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
ArrayRef< uint8_t > data() const
Definition: CVRecord.h:49
uint32_t length() const
Definition: CVRecord.h:40
void getLinkageName(const llvm::object::coff_section *CoffSection, uint32_t RelocOffset, uint32_t Offset, StringRef *RelocSym)
void print(raw_ostream &OS) const
void printRecords(raw_ostream &OS) const override
static std::string formatRegisterId(RegisterId Register, CPUType CPU)
std::string getRegisterName(LVSmall Opcode, ArrayRef< uint64_t > Operands) override
LVCodeViewReader(StringRef Filename, StringRef FileFormatName, llvm::object::COFFObjectFile &Obj, ScopedPrinter &W, StringRef ExePath)
LVCodeViewReader & operator=(const LVCodeViewReader &)=delete
LVScope * getScopeForModule(uint32_t Modi)
static StringRef getSymbolKindName(SymbolKind Kind)
LVCodeViewReader(StringRef Filename, StringRef FileFormatName, llvm::pdb::PDBFile &Pdb, ScopedPrinter &W, StringRef ExePath)
LVCodeViewReader(const LVCodeViewReader &)=delete
bool isSystemEntry(LVElement *Element, StringRef Name) const override
std::string FileFormatName
Definition: LVReader.h:127
This class is the base class for all object file types.
Definition: ObjectFile.h:229
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:168
StringRef getFilePath() const
Definition: InputFile.cpp:379
codeview::LazyRandomTypeCollection & types()
Definition: InputFile.cpp:457
codeview::LazyRandomTypeCollection & ids()
Definition: InputFile.cpp:461
object::COFFObjectFile & obj()
Definition: InputFile.cpp:359
bool isObj() const
Definition: InputFile.cpp:408
bool isPdb() const
Definition: InputFile.cpp:406
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition: CodeView.h:76
VarStreamArray< CVType > CVTypeArray
Definition: CVRecord.h:127
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:48
uint64_t LVOffset
Definition: LVObject.h:39
uint64_t LVAddress
Definition: LVObject.h:36
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
static size_t length(const codeview::CVType &Item)
static ArrayRef< uint8_t > bytes(const codeview::CVType &Item)