Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewReader.cpp
35295 views
1
//===-- LVCodeViewReader.cpp ----------------------------------------------===//
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 implements the LVCodeViewReader class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h"
14
#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
15
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
16
#include "llvm/DebugInfo/CodeView/EnumTables.h"
17
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
18
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
19
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
20
#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
21
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
22
#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
23
#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
24
#include "llvm/DebugInfo/PDB/GenericError.h"
25
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
26
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
27
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
28
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
29
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
30
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
31
#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
32
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
33
#include "llvm/Demangle/Demangle.h"
34
#include "llvm/Object/COFF.h"
35
#include "llvm/Support/Errc.h"
36
#include "llvm/Support/Error.h"
37
#include "llvm/Support/FormatAdapters.h"
38
#include "llvm/Support/FormatVariadic.h"
39
#include "llvm/Support/WithColor.h"
40
41
using namespace llvm;
42
using namespace llvm::codeview;
43
using namespace llvm::logicalview;
44
using namespace llvm::msf;
45
using namespace llvm::object;
46
using namespace llvm::pdb;
47
48
#define DEBUG_TYPE "CodeViewReader"
49
50
StringRef LVCodeViewReader::getSymbolKindName(SymbolKind Kind) {
51
switch (Kind) {
52
#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
53
case EnumName: \
54
return #EnumName;
55
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
56
default:
57
return "UnknownSym";
58
}
59
llvm_unreachable("Unknown SymbolKind::Kind");
60
}
61
62
std::string LVCodeViewReader::formatRegisterId(RegisterId Register,
63
CPUType CPU) {
64
#define RETURN_CASE(Enum, X, Ret) \
65
case Enum::X: \
66
return Ret;
67
68
if (CPU == CPUType::ARMNT) {
69
switch (Register) {
70
#define CV_REGISTERS_ARM
71
#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
72
#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
73
#undef CV_REGISTER
74
#undef CV_REGISTERS_ARM
75
76
default:
77
break;
78
}
79
} else if (CPU == CPUType::ARM64) {
80
switch (Register) {
81
#define CV_REGISTERS_ARM64
82
#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
83
#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
84
#undef CV_REGISTER
85
#undef CV_REGISTERS_ARM64
86
87
default:
88
break;
89
}
90
} else {
91
switch (Register) {
92
#define CV_REGISTERS_X86
93
#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
94
#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
95
#undef CV_REGISTER
96
#undef CV_REGISTERS_X86
97
98
default:
99
break;
100
}
101
}
102
return "formatUnknownEnum(Id)";
103
}
104
105
void LVCodeViewReader::printRelocatedField(StringRef Label,
106
const coff_section *CoffSection,
107
uint32_t RelocOffset,
108
uint32_t Offset,
109
StringRef *RelocSym) {
110
StringRef SymStorage;
111
StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;
112
if (!resolveSymbolName(CoffSection, RelocOffset, Symbol))
113
W.printSymbolOffset(Label, Symbol, Offset);
114
else
115
W.printHex(Label, RelocOffset);
116
}
117
118
void LVCodeViewReader::getLinkageName(const coff_section *CoffSection,
119
uint32_t RelocOffset, uint32_t Offset,
120
StringRef *RelocSym) {
121
StringRef SymStorage;
122
StringRef &Symbol = RelocSym ? *RelocSym : SymStorage;
123
if (resolveSymbolName(CoffSection, RelocOffset, Symbol))
124
Symbol = "";
125
}
126
127
Expected<StringRef>
128
LVCodeViewReader::getFileNameForFileOffset(uint32_t FileOffset,
129
const SymbolGroup *SG) {
130
if (SG) {
131
Expected<StringRef> Filename = SG->getNameFromChecksums(FileOffset);
132
if (!Filename) {
133
consumeError(Filename.takeError());
134
return StringRef("");
135
}
136
return *Filename;
137
}
138
139
// The file checksum subsection should precede all references to it.
140
if (!CVFileChecksumTable.valid() || !CVStringTable.valid())
141
return createStringError(object_error::parse_failed, getFileName());
142
143
VarStreamArray<FileChecksumEntry>::Iterator Iter =
144
CVFileChecksumTable.getArray().at(FileOffset);
145
146
// Check if the file checksum table offset is valid.
147
if (Iter == CVFileChecksumTable.end())
148
return createStringError(object_error::parse_failed, getFileName());
149
150
Expected<StringRef> NameOrErr = CVStringTable.getString(Iter->FileNameOffset);
151
if (!NameOrErr)
152
return createStringError(object_error::parse_failed, getFileName());
153
return *NameOrErr;
154
}
155
156
Error LVCodeViewReader::printFileNameForOffset(StringRef Label,
157
uint32_t FileOffset,
158
const SymbolGroup *SG) {
159
Expected<StringRef> NameOrErr = getFileNameForFileOffset(FileOffset, SG);
160
if (!NameOrErr)
161
return NameOrErr.takeError();
162
W.printHex(Label, *NameOrErr, FileOffset);
163
return Error::success();
164
}
165
166
void LVCodeViewReader::cacheRelocations() {
167
for (const SectionRef &Section : getObj().sections()) {
168
const coff_section *CoffSection = getObj().getCOFFSection(Section);
169
170
for (const RelocationRef &Relocacion : Section.relocations())
171
RelocMap[CoffSection].push_back(Relocacion);
172
173
// Sort relocations by address.
174
llvm::sort(RelocMap[CoffSection], [](RelocationRef L, RelocationRef R) {
175
return L.getOffset() < R.getOffset();
176
});
177
}
178
}
179
180
// Given a section and an offset into this section the function returns the
181
// symbol used for the relocation at the offset.
182
Error LVCodeViewReader::resolveSymbol(const coff_section *CoffSection,
183
uint64_t Offset, SymbolRef &Sym) {
184
const auto &Relocations = RelocMap[CoffSection];
185
basic_symbol_iterator SymI = getObj().symbol_end();
186
for (const RelocationRef &Relocation : Relocations) {
187
uint64_t RelocationOffset = Relocation.getOffset();
188
189
if (RelocationOffset == Offset) {
190
SymI = Relocation.getSymbol();
191
break;
192
}
193
}
194
if (SymI == getObj().symbol_end())
195
return make_error<StringError>("Unknown Symbol", inconvertibleErrorCode());
196
Sym = *SymI;
197
return ErrorSuccess();
198
}
199
200
// Given a section and an offset into this section the function returns the
201
// name of the symbol used for the relocation at the offset.
202
Error LVCodeViewReader::resolveSymbolName(const coff_section *CoffSection,
203
uint64_t Offset, StringRef &Name) {
204
SymbolRef Symbol;
205
if (Error E = resolveSymbol(CoffSection, Offset, Symbol))
206
return E;
207
Expected<StringRef> NameOrErr = Symbol.getName();
208
if (!NameOrErr)
209
return NameOrErr.takeError();
210
Name = *NameOrErr;
211
return ErrorSuccess();
212
}
213
214
// CodeView and DWARF can have references to compiler generated elements,
215
// used for initialization. The MSVC includes in the PDBs, internal compile
216
// units, associated with the MS runtime support. We mark them as 'system'
217
// and they are printed only if the command line option 'internal=system'.
218
bool LVCodeViewReader::isSystemEntry(LVElement *Element, StringRef Name) const {
219
Name = Name.empty() ? Element->getName() : Name;
220
auto Find = [=](const char *String) -> bool { return Name.contains(String); };
221
auto Starts = [=](const char *Pattern) -> bool {
222
return Name.starts_with(Pattern);
223
};
224
auto CheckExclude = [&]() -> bool {
225
if (Starts("__") || Starts("_PMD") || Starts("_PMFN"))
226
return true;
227
if (Find("_s__"))
228
return true;
229
if (Find("_CatchableType") || Find("_TypeDescriptor"))
230
return true;
231
if (Find("Intermediate\\vctools"))
232
return true;
233
if (Find("$initializer$") || Find("dynamic initializer"))
234
return true;
235
if (Find("`vftable'") || Find("_GLOBAL__sub"))
236
return true;
237
return false;
238
};
239
bool Excluded = CheckExclude();
240
if (Excluded)
241
Element->setIsSystem();
242
243
return Excluded;
244
}
245
246
Error LVCodeViewReader::collectInlineeInfo(
247
DebugInlineeLinesSubsectionRef &Lines, const llvm::pdb::SymbolGroup *SG) {
248
for (const InlineeSourceLine &Line : Lines) {
249
TypeIndex TIInlinee = Line.Header->Inlinee;
250
uint32_t LineNumber = Line.Header->SourceLineNum;
251
uint32_t FileOffset = Line.Header->FileID;
252
LLVM_DEBUG({
253
DictScope S(W, "InlineeSourceLine");
254
LogicalVisitor.printTypeIndex("Inlinee", TIInlinee, StreamTPI);
255
if (Error Err = printFileNameForOffset("FileID", FileOffset, SG))
256
return Err;
257
W.printNumber("SourceLineNum", LineNumber);
258
259
if (Lines.hasExtraFiles()) {
260
W.printNumber("ExtraFileCount", Line.ExtraFiles.size());
261
ListScope ExtraFiles(W, "ExtraFiles");
262
for (const ulittle32_t &FID : Line.ExtraFiles)
263
if (Error Err = printFileNameForOffset("FileID", FID, SG))
264
return Err;
265
}
266
});
267
Expected<StringRef> NameOrErr = getFileNameForFileOffset(FileOffset, SG);
268
if (!NameOrErr)
269
return NameOrErr.takeError();
270
LogicalVisitor.addInlineeInfo(TIInlinee, LineNumber, *NameOrErr);
271
}
272
273
return Error::success();
274
}
275
276
Error LVCodeViewReader::traverseInlineeLines(StringRef Subsection) {
277
BinaryStreamReader SR(Subsection, llvm::endianness::little);
278
DebugInlineeLinesSubsectionRef Lines;
279
if (Error E = Lines.initialize(SR))
280
return createStringError(errorToErrorCode(std::move(E)), getFileName());
281
282
return collectInlineeInfo(Lines);
283
}
284
285
Error LVCodeViewReader::createLines(
286
const FixedStreamArray<LineNumberEntry> &LineNumbers, LVAddress Addendum,
287
uint32_t Segment, uint32_t Begin, uint32_t Size, uint32_t NameIndex,
288
const SymbolGroup *SG) {
289
LLVM_DEBUG({
290
uint32_t End = Begin + Size;
291
W.getOStream() << formatv("{0:x-4}:{1:x-8}-{2:x-8}\n", Segment, Begin, End);
292
});
293
294
for (const LineNumberEntry &Line : LineNumbers) {
295
if (Line.Offset >= Size)
296
return createStringError(object_error::parse_failed, getFileName());
297
298
LineInfo LI(Line.Flags);
299
300
LLVM_DEBUG({
301
W.getOStream() << formatv(
302
"{0} {1:x-8}\n", utostr(LI.getStartLine()),
303
fmt_align(Begin + Line.Offset, AlignStyle::Right, 8, '0'));
304
});
305
306
// The 'processLines()' function will move each created logical line
307
// to its enclosing logical scope, using the debug ranges information
308
// and they will be released when its scope parent is deleted.
309
LVLineDebug *LineDebug = createLineDebug();
310
CULines.push_back(LineDebug);
311
LVAddress Address = linearAddress(Segment, Begin + Line.Offset);
312
LineDebug->setAddress(Address + Addendum);
313
314
if (LI.isAlwaysStepInto())
315
LineDebug->setIsAlwaysStepInto();
316
else if (LI.isNeverStepInto())
317
LineDebug->setIsNeverStepInto();
318
else
319
LineDebug->setLineNumber(LI.getStartLine());
320
321
if (LI.isStatement())
322
LineDebug->setIsNewStatement();
323
324
Expected<StringRef> NameOrErr = getFileNameForFileOffset(NameIndex, SG);
325
if (!NameOrErr)
326
return NameOrErr.takeError();
327
LineDebug->setFilename(*NameOrErr);
328
}
329
330
return Error::success();
331
}
332
333
Error LVCodeViewReader::initializeFileAndStringTables(
334
BinaryStreamReader &Reader) {
335
while (Reader.bytesRemaining() > 0 &&
336
(!CVFileChecksumTable.valid() || !CVStringTable.valid())) {
337
// The section consists of a number of subsection in the following format:
338
// |SubSectionType|SubSectionSize|Contents...|
339
uint32_t SubType, SubSectionSize;
340
341
if (Error E = Reader.readInteger(SubType))
342
return createStringError(errorToErrorCode(std::move(E)), getFileName());
343
if (Error E = Reader.readInteger(SubSectionSize))
344
return createStringError(errorToErrorCode(std::move(E)), getFileName());
345
346
StringRef Contents;
347
if (Error E = Reader.readFixedString(Contents, SubSectionSize))
348
return createStringError(errorToErrorCode(std::move(E)), getFileName());
349
350
BinaryStreamRef ST(Contents, llvm::endianness::little);
351
switch (DebugSubsectionKind(SubType)) {
352
case DebugSubsectionKind::FileChecksums:
353
if (Error E = CVFileChecksumTable.initialize(ST))
354
return createStringError(errorToErrorCode(std::move(E)), getFileName());
355
break;
356
case DebugSubsectionKind::StringTable:
357
if (Error E = CVStringTable.initialize(ST))
358
return createStringError(errorToErrorCode(std::move(E)), getFileName());
359
break;
360
default:
361
break;
362
}
363
364
uint32_t PaddedSize = alignTo(SubSectionSize, 4);
365
if (Error E = Reader.skip(PaddedSize - SubSectionSize))
366
return createStringError(errorToErrorCode(std::move(E)), getFileName());
367
}
368
369
return Error::success();
370
}
371
372
Error LVCodeViewReader::loadTypeServer(TypeServer2Record &TS) {
373
LLVM_DEBUG({
374
W.printString("Guid", formatv("{0}", TS.getGuid()).str());
375
W.printNumber("Age", TS.getAge());
376
W.printString("Name", TS.getName());
377
});
378
379
SmallString<128> ServerName(TS.getName());
380
BuffOrErr = MemoryBuffer::getFile(ServerName);
381
if (BuffOrErr.getError()) {
382
// The server name does not exist. Try in the same directory as the
383
// input file.
384
ServerName = createAlternativePath(ServerName);
385
BuffOrErr = MemoryBuffer::getFile(ServerName);
386
if (BuffOrErr.getError()) {
387
// For the error message, use the original type server name.
388
return createStringError(errc::bad_file_descriptor,
389
"File '%s' does not exist.",
390
TS.getName().str().c_str());
391
}
392
}
393
MemBuffer = std::move(BuffOrErr.get());
394
395
// Check if the buffer corresponds to a PDB file.
396
assert(identify_magic((*MemBuffer).getBuffer()) == file_magic::pdb &&
397
"Invalid PDB file.");
398
399
if (Error Err = loadDataForPDB(PDB_ReaderType::Native, ServerName, Session))
400
return createStringError(errorToErrorCode(std::move(Err)), "%s",
401
ServerName.c_str());
402
403
PdbSession.reset(static_cast<NativeSession *>(Session.release()));
404
PDBFile &Pdb = PdbSession->getPDBFile();
405
406
// Just because a file with a matching name was found and it was an actual
407
// PDB file doesn't mean it matches. For it to match the InfoStream's GUID
408
// must match the GUID specified in the TypeServer2 record.
409
Expected<InfoStream &> expectedInfo = Pdb.getPDBInfoStream();
410
if (!expectedInfo || expectedInfo->getGuid() != TS.getGuid())
411
return createStringError(errc::invalid_argument, "signature_out_of_date");
412
413
// The reader needs to switch to a type server, to process the types from
414
// the server. We need to keep the original input source, as reading other
415
// sections will require the input associated with the loaded object file.
416
TypeServer = std::make_shared<InputFile>(&Pdb);
417
LogicalVisitor.setInput(TypeServer);
418
419
LazyRandomTypeCollection &Types = types();
420
LazyRandomTypeCollection &Ids = ids();
421
if (Error Err = traverseTypes(Pdb, Types, Ids))
422
return Err;
423
424
return Error::success();
425
}
426
427
Error LVCodeViewReader::loadPrecompiledObject(PrecompRecord &Precomp,
428
CVTypeArray &CVTypesObj) {
429
LLVM_DEBUG({
430
W.printHex("Count", Precomp.getTypesCount());
431
W.printHex("Signature", Precomp.getSignature());
432
W.printString("PrecompFile", Precomp.getPrecompFilePath());
433
});
434
435
SmallString<128> ServerName(Precomp.getPrecompFilePath());
436
BuffOrErr = MemoryBuffer::getFile(ServerName);
437
if (BuffOrErr.getError()) {
438
// The server name does not exist. Try in the directory as the input file.
439
ServerName = createAlternativePath(ServerName);
440
if (BuffOrErr.getError()) {
441
// For the error message, use the original type server name.
442
return createStringError(errc::bad_file_descriptor,
443
"File '%s' does not exist.",
444
Precomp.getPrecompFilePath().str().c_str());
445
}
446
}
447
MemBuffer = std::move(BuffOrErr.get());
448
449
Expected<std::unique_ptr<Binary>> BinOrErr = createBinary(*MemBuffer);
450
if (errorToErrorCode(BinOrErr.takeError()))
451
return createStringError(errc::not_supported,
452
"Binary object format in '%s' is not supported.",
453
ServerName.c_str());
454
455
Binary &BinaryObj = *BinOrErr.get();
456
if (!BinaryObj.isCOFF())
457
return createStringError(errc::not_supported, "'%s' is not a COFF object.",
458
ServerName.c_str());
459
460
Builder = std::make_unique<AppendingTypeTableBuilder>(BuilderAllocator);
461
462
// The MSVC precompiled header object file, should contain just a single
463
// ".debug$P" section.
464
COFFObjectFile &Obj = *cast<COFFObjectFile>(&BinaryObj);
465
for (const SectionRef &Section : Obj.sections()) {
466
Expected<StringRef> SectionNameOrErr = Section.getName();
467
if (!SectionNameOrErr)
468
return SectionNameOrErr.takeError();
469
if (*SectionNameOrErr == ".debug$P") {
470
Expected<StringRef> DataOrErr = Section.getContents();
471
if (!DataOrErr)
472
return DataOrErr.takeError();
473
uint32_t Magic;
474
if (Error Err = consume(*DataOrErr, Magic))
475
return Err;
476
if (Magic != COFF::DEBUG_SECTION_MAGIC)
477
return errorCodeToError(object_error::parse_failed);
478
479
ReaderPrecomp = std::make_unique<BinaryStreamReader>(
480
*DataOrErr, llvm::endianness::little);
481
cantFail(
482
ReaderPrecomp->readArray(CVTypesPrecomp, ReaderPrecomp->getLength()));
483
484
// Append all the type records up to the LF_ENDPRECOMP marker and
485
// check if the signatures match.
486
for (const CVType &Type : CVTypesPrecomp) {
487
ArrayRef<uint8_t> TypeData = Type.data();
488
if (Type.kind() == LF_ENDPRECOMP) {
489
EndPrecompRecord EndPrecomp = cantFail(
490
TypeDeserializer::deserializeAs<EndPrecompRecord>(TypeData));
491
if (Precomp.getSignature() != EndPrecomp.getSignature())
492
return createStringError(errc::invalid_argument, "no matching pch");
493
break;
494
}
495
Builder->insertRecordBytes(TypeData);
496
}
497
// Done processing .debug$P, break out of section loop.
498
break;
499
}
500
}
501
502
// Append all the type records, skipping the first record which is the
503
// reference to the precompiled header object information.
504
for (const CVType &Type : CVTypesObj) {
505
ArrayRef<uint8_t> TypeData = Type.data();
506
if (Type.kind() != LF_PRECOMP)
507
Builder->insertRecordBytes(TypeData);
508
}
509
510
// Set up a type stream that refers to the added type records.
511
Builder->ForEachRecord(
512
[&](TypeIndex TI, const CVType &Type) { TypeArray.push_back(Type); });
513
514
ItemStream =
515
std::make_unique<BinaryItemStream<CVType>>(llvm::endianness::little);
516
ItemStream->setItems(TypeArray);
517
TypeStream.setUnderlyingStream(*ItemStream);
518
519
PrecompHeader =
520
std::make_shared<LazyRandomTypeCollection>(TypeStream, TypeArray.size());
521
522
// Change the original input source to use the collected type records.
523
LogicalVisitor.setInput(PrecompHeader);
524
525
LazyRandomTypeCollection &Types = types();
526
LazyRandomTypeCollection &Ids = ids();
527
LVTypeVisitor TDV(W, &LogicalVisitor, Types, Ids, StreamTPI,
528
LogicalVisitor.getShared());
529
return visitTypeStream(Types, TDV);
530
}
531
532
Error LVCodeViewReader::traverseTypeSection(StringRef SectionName,
533
const SectionRef &Section) {
534
LLVM_DEBUG({
535
ListScope D(W, "CodeViewTypes");
536
W.printNumber("Section", SectionName, getObj().getSectionID(Section));
537
});
538
539
Expected<StringRef> DataOrErr = Section.getContents();
540
if (!DataOrErr)
541
return DataOrErr.takeError();
542
uint32_t Magic;
543
if (Error Err = consume(*DataOrErr, Magic))
544
return Err;
545
if (Magic != COFF::DEBUG_SECTION_MAGIC)
546
return errorCodeToError(object_error::parse_failed);
547
548
// Get the first type record. It will indicate if this object uses a type
549
// server (/Zi) or a PCH file (/Yu).
550
CVTypeArray CVTypes;
551
BinaryStreamReader Reader(*DataOrErr, llvm::endianness::little);
552
cantFail(Reader.readArray(CVTypes, Reader.getLength()));
553
CVTypeArray::Iterator FirstType = CVTypes.begin();
554
555
// The object was compiled with /Zi. It uses types from a type server PDB.
556
if (FirstType->kind() == LF_TYPESERVER2) {
557
TypeServer2Record TS = cantFail(
558
TypeDeserializer::deserializeAs<TypeServer2Record>(FirstType->data()));
559
return loadTypeServer(TS);
560
}
561
562
// The object was compiled with /Yc or /Yu. It uses types from another
563
// object file with a matching signature.
564
if (FirstType->kind() == LF_PRECOMP) {
565
PrecompRecord Precomp = cantFail(
566
TypeDeserializer::deserializeAs<PrecompRecord>(FirstType->data()));
567
return loadPrecompiledObject(Precomp, CVTypes);
568
}
569
570
LazyRandomTypeCollection &Types = types();
571
LazyRandomTypeCollection &Ids = ids();
572
Types.reset(*DataOrErr, 100);
573
LVTypeVisitor TDV(W, &LogicalVisitor, Types, Ids, StreamTPI,
574
LogicalVisitor.getShared());
575
return visitTypeStream(Types, TDV);
576
}
577
578
Error LVCodeViewReader::traverseTypes(PDBFile &Pdb,
579
LazyRandomTypeCollection &Types,
580
LazyRandomTypeCollection &Ids) {
581
// Traverse types (TPI and IPI).
582
auto VisitTypes = [&](LazyRandomTypeCollection &Types,
583
LazyRandomTypeCollection &Ids,
584
SpecialStream StreamIdx) -> Error {
585
LVTypeVisitor TDV(W, &LogicalVisitor, Types, Ids, StreamIdx,
586
LogicalVisitor.getShared());
587
return visitTypeStream(Types, TDV);
588
};
589
590
Expected<TpiStream &> StreamTpiOrErr = Pdb.getPDBTpiStream();
591
if (!StreamTpiOrErr)
592
return StreamTpiOrErr.takeError();
593
TpiStream &StreamTpi = *StreamTpiOrErr;
594
StreamTpi.buildHashMap();
595
LLVM_DEBUG({
596
W.getOStream() << formatv("Showing {0:N} TPI records\n",
597
StreamTpi.getNumTypeRecords());
598
});
599
if (Error Err = VisitTypes(Types, Ids, StreamTPI))
600
return Err;
601
602
Expected<TpiStream &> StreamIpiOrErr = Pdb.getPDBIpiStream();
603
if (!StreamIpiOrErr)
604
return StreamIpiOrErr.takeError();
605
TpiStream &StreamIpi = *StreamIpiOrErr;
606
StreamIpi.buildHashMap();
607
LLVM_DEBUG({
608
W.getOStream() << formatv("Showing {0:N} IPI records\n",
609
StreamIpi.getNumTypeRecords());
610
});
611
return VisitTypes(Ids, Ids, StreamIPI);
612
}
613
614
Error LVCodeViewReader::traverseSymbolsSubsection(StringRef Subsection,
615
const SectionRef &Section,
616
StringRef SectionContents) {
617
ArrayRef<uint8_t> BinaryData(Subsection.bytes_begin(),
618
Subsection.bytes_end());
619
LVSymbolVisitorDelegate VisitorDelegate(this, Section, &getObj(),
620
SectionContents);
621
CVSymbolArray Symbols;
622
BinaryStreamReader Reader(BinaryData, llvm::endianness::little);
623
if (Error E = Reader.readArray(Symbols, Reader.getLength()))
624
return createStringError(errorToErrorCode(std::move(E)), getFileName());
625
626
LazyRandomTypeCollection &Types = types();
627
LazyRandomTypeCollection &Ids = ids();
628
SymbolVisitorCallbackPipeline Pipeline;
629
SymbolDeserializer Deserializer(&VisitorDelegate,
630
CodeViewContainer::ObjectFile);
631
// As we are processing a COFF format, use TPI as IPI, so the generic code
632
// to process the CodeView format does not contain any additional checks.
633
LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids,
634
&VisitorDelegate, LogicalVisitor.getShared());
635
636
Pipeline.addCallbackToPipeline(Deserializer);
637
Pipeline.addCallbackToPipeline(Traverser);
638
CVSymbolVisitor Visitor(Pipeline);
639
return Visitor.visitSymbolStream(Symbols);
640
}
641
642
Error LVCodeViewReader::traverseSymbolSection(StringRef SectionName,
643
const SectionRef &Section) {
644
LLVM_DEBUG({
645
ListScope D(W, "CodeViewDebugInfo");
646
W.printNumber("Section", SectionName, getObj().getSectionID(Section));
647
});
648
649
Expected<StringRef> SectionOrErr = Section.getContents();
650
if (!SectionOrErr)
651
return SectionOrErr.takeError();
652
StringRef SectionContents = *SectionOrErr;
653
StringRef Data = SectionContents;
654
655
SmallVector<StringRef, 10> SymbolNames;
656
StringMap<StringRef> FunctionLineTables;
657
658
uint32_t Magic;
659
if (Error E = consume(Data, Magic))
660
return createStringError(errorToErrorCode(std::move(E)), getFileName());
661
662
if (Magic != COFF::DEBUG_SECTION_MAGIC)
663
return createStringError(object_error::parse_failed, getFileName());
664
665
BinaryStreamReader FSReader(Data, llvm::endianness::little);
666
if (Error Err = initializeFileAndStringTables(FSReader))
667
return Err;
668
669
while (!Data.empty()) {
670
// The section consists of a number of subsection in the following format:
671
// |SubSectionType|SubSectionSize|Contents...|
672
uint32_t SubType, SubSectionSize;
673
if (Error E = consume(Data, SubType))
674
return createStringError(errorToErrorCode(std::move(E)), getFileName());
675
if (Error E = consume(Data, SubSectionSize))
676
return createStringError(errorToErrorCode(std::move(E)), getFileName());
677
678
// Process the subsection as normal even if the ignore bit is set.
679
SubType &= ~SubsectionIgnoreFlag;
680
681
// Get the contents of the subsection.
682
if (SubSectionSize > Data.size())
683
return createStringError(object_error::parse_failed, getFileName());
684
StringRef Contents = Data.substr(0, SubSectionSize);
685
686
// Add SubSectionSize to the current offset and align that offset
687
// to find the next subsection.
688
size_t SectionOffset = Data.data() - SectionContents.data();
689
size_t NextOffset = SectionOffset + SubSectionSize;
690
NextOffset = alignTo(NextOffset, 4);
691
if (NextOffset > SectionContents.size())
692
return createStringError(object_error::parse_failed, getFileName());
693
Data = SectionContents.drop_front(NextOffset);
694
695
switch (DebugSubsectionKind(SubType)) {
696
case DebugSubsectionKind::Symbols:
697
if (Error Err =
698
traverseSymbolsSubsection(Contents, Section, SectionContents))
699
return Err;
700
break;
701
702
case DebugSubsectionKind::InlineeLines:
703
if (Error Err = traverseInlineeLines(Contents))
704
return Err;
705
break;
706
707
case DebugSubsectionKind::Lines:
708
// Holds a PC to file:line table. Some data to parse this subsection
709
// is stored in the other subsections, so just check sanity and store
710
// the pointers for deferred processing.
711
712
// Collect function and ranges only if we need to print logical lines.
713
if (options().getGeneralCollectRanges()) {
714
715
if (SubSectionSize < 12) {
716
// There should be at least three words to store two function
717
// relocations and size of the code.
718
return createStringError(object_error::parse_failed, getFileName());
719
}
720
721
StringRef SymbolName;
722
if (Error Err = resolveSymbolName(getObj().getCOFFSection(Section),
723
SectionOffset, SymbolName))
724
return createStringError(errorToErrorCode(std::move(Err)),
725
getFileName());
726
727
LLVM_DEBUG({ W.printString("Symbol Name", SymbolName); });
728
if (FunctionLineTables.count(SymbolName) != 0) {
729
// Saw debug info for this function already?
730
return createStringError(object_error::parse_failed, getFileName());
731
}
732
733
FunctionLineTables[SymbolName] = Contents;
734
SymbolNames.push_back(SymbolName);
735
}
736
break;
737
738
// Do nothing for unrecognized subsections.
739
default:
740
break;
741
}
742
W.flush();
743
}
744
745
// Traverse the line tables now that we've read all the subsections and
746
// know all the required information.
747
for (StringRef SymbolName : SymbolNames) {
748
LLVM_DEBUG({
749
ListScope S(W, "FunctionLineTable");
750
W.printString("Symbol Name", SymbolName);
751
});
752
753
BinaryStreamReader Reader(FunctionLineTables[SymbolName],
754
llvm::endianness::little);
755
756
DebugLinesSubsectionRef Lines;
757
if (Error E = Lines.initialize(Reader))
758
return createStringError(errorToErrorCode(std::move(E)), getFileName());
759
760
// Find the associated symbol table information.
761
LVSymbolTableEntry SymbolTableEntry = getSymbolTableEntry(SymbolName);
762
LVScope *Function = SymbolTableEntry.Scope;
763
if (!Function)
764
continue;
765
766
LVAddress Addendum = SymbolTableEntry.Address;
767
LVSectionIndex SectionIndex = SymbolTableEntry.SectionIndex;
768
769
// The given scope represents the function that contains the line numbers.
770
// Collect all generated debug lines associated with the function.
771
CULines.clear();
772
773
// For the given scope, collect all scopes ranges.
774
LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
775
ScopesWithRanges->clear();
776
Function->getRanges(*ScopesWithRanges);
777
ScopesWithRanges->sort();
778
779
uint16_t Segment = Lines.header()->RelocSegment;
780
uint32_t Begin = Lines.header()->RelocOffset;
781
uint32_t Size = Lines.header()->CodeSize;
782
for (const LineColumnEntry &Block : Lines)
783
if (Error Err = createLines(Block.LineNumbers, Addendum, Segment, Begin,
784
Size, Block.NameIndex))
785
return Err;
786
787
// Include lines from any inlined functions within the current function.
788
includeInlineeLines(SectionIndex, Function);
789
790
if (Error Err = createInstructions(Function, SectionIndex))
791
return Err;
792
793
processLines(&CULines, SectionIndex, Function);
794
}
795
796
return Error::success();
797
}
798
799
void LVCodeViewReader::sortScopes() { Root->sort(); }
800
801
void LVCodeViewReader::print(raw_ostream &OS) const {
802
LLVM_DEBUG(dbgs() << "CreateReaders\n");
803
}
804
805
void LVCodeViewReader::mapRangeAddress(const ObjectFile &Obj,
806
const SectionRef &Section,
807
bool IsComdat) {
808
if (!Obj.isCOFF())
809
return;
810
811
const COFFObjectFile *Object = cast<COFFObjectFile>(&Obj);
812
813
for (const SymbolRef &Sym : Object->symbols()) {
814
if (!Section.containsSymbol(Sym))
815
continue;
816
817
COFFSymbolRef Symbol = Object->getCOFFSymbol(Sym);
818
if (Symbol.getComplexType() != llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION)
819
continue;
820
821
StringRef SymbolName;
822
Expected<StringRef> SymNameOrErr = Object->getSymbolName(Symbol);
823
if (!SymNameOrErr) {
824
W.startLine() << "Invalid symbol name: " << Symbol.getSectionNumber()
825
<< "\n";
826
consumeError(SymNameOrErr.takeError());
827
continue;
828
}
829
SymbolName = *SymNameOrErr;
830
831
LLVM_DEBUG({
832
Expected<const coff_section *> SectionOrErr =
833
Object->getSection(Symbol.getSectionNumber());
834
if (!SectionOrErr) {
835
W.startLine() << "Invalid section number: " << Symbol.getSectionNumber()
836
<< "\n";
837
consumeError(SectionOrErr.takeError());
838
return;
839
}
840
W.printNumber("Section #", Symbol.getSectionNumber());
841
W.printString("Name", SymbolName);
842
W.printHex("Value", Symbol.getValue());
843
});
844
845
// Record the symbol name (linkage) and its loading address.
846
addToSymbolTable(SymbolName, Symbol.getValue(), Symbol.getSectionNumber(),
847
IsComdat);
848
}
849
}
850
851
Error LVCodeViewReader::createScopes(COFFObjectFile &Obj) {
852
if (Error Err = loadTargetInfo(Obj))
853
return Err;
854
855
// Initialization required when processing a COFF file:
856
// Cache the symbols relocations.
857
// Create a mapping for virtual addresses.
858
// Get the functions entry points.
859
cacheRelocations();
860
mapVirtualAddress(Obj);
861
862
for (const SectionRef &Section : Obj.sections()) {
863
Expected<StringRef> SectionNameOrErr = Section.getName();
864
if (!SectionNameOrErr)
865
return SectionNameOrErr.takeError();
866
// .debug$T is a standard CodeView type section, while .debug$P is the
867
// same format but used for MSVC precompiled header object files.
868
if (*SectionNameOrErr == ".debug$T" || *SectionNameOrErr == ".debug$P")
869
if (Error Err = traverseTypeSection(*SectionNameOrErr, Section))
870
return Err;
871
}
872
873
// Process collected namespaces.
874
LogicalVisitor.processNamespaces();
875
876
for (const SectionRef &Section : Obj.sections()) {
877
Expected<StringRef> SectionNameOrErr = Section.getName();
878
if (!SectionNameOrErr)
879
return SectionNameOrErr.takeError();
880
if (*SectionNameOrErr == ".debug$S")
881
if (Error Err = traverseSymbolSection(*SectionNameOrErr, Section))
882
return Err;
883
}
884
885
// Check if we have to close the Compile Unit scope.
886
LogicalVisitor.closeScope();
887
888
// Traverse the strings recorded and transform them into filenames.
889
LogicalVisitor.processFiles();
890
891
// Process collected element lines.
892
LogicalVisitor.processLines();
893
894
// Translate composite names into a single component.
895
Root->transformScopedName();
896
return Error::success();
897
}
898
899
Error LVCodeViewReader::createScopes(PDBFile &Pdb) {
900
if (Error Err = loadTargetInfo(Pdb))
901
return Err;
902
903
if (!Pdb.hasPDBTpiStream() || !Pdb.hasPDBDbiStream())
904
return Error::success();
905
906
// Open the executable associated with the PDB file and get the section
907
// addresses used to calculate linear addresses for CodeView Symbols.
908
if (!ExePath.empty()) {
909
ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
910
MemoryBuffer::getFileOrSTDIN(ExePath);
911
if (BuffOrErr.getError()) {
912
return createStringError(errc::bad_file_descriptor,
913
"File '%s' does not exist.", ExePath.c_str());
914
}
915
BinaryBuffer = std::move(BuffOrErr.get());
916
917
// Check if the buffer corresponds to a PECOFF executable.
918
assert(identify_magic(BinaryBuffer->getBuffer()) ==
919
file_magic::pecoff_executable &&
920
"Invalid PECOFF executable file.");
921
922
Expected<std::unique_ptr<Binary>> BinOrErr =
923
createBinary(BinaryBuffer->getMemBufferRef());
924
if (errorToErrorCode(BinOrErr.takeError())) {
925
return createStringError(errc::not_supported,
926
"Binary object format in '%s' is not supported.",
927
ExePath.c_str());
928
}
929
BinaryExecutable = std::move(*BinOrErr);
930
if (COFFObjectFile *COFFObject =
931
dyn_cast<COFFObjectFile>(BinaryExecutable.get()))
932
mapVirtualAddress(*COFFObject);
933
}
934
935
// In order to generate a full logical view, we have to traverse both
936
// streams TPI and IPI if they are present. The following table gives
937
// the stream where a specified type is located. If the IPI stream is
938
// not present, all the types are located in the TPI stream.
939
//
940
// TPI Stream:
941
// LF_POINTER LF_MODIFIER LF_PROCEDURE LF_MFUNCTION
942
// LF_LABEL LF_ARGLIST LF_FIELDLIST LF_ARRAY
943
// LF_CLASS LF_STRUCTURE LF_INTERFACE LF_UNION
944
// LF_ENUM LF_TYPESERVER2 LF_VFTABLE LF_VTSHAPE
945
// LF_BITFIELD LF_METHODLIST LF_PRECOMP LF_ENDPRECOMP
946
//
947
// IPI stream:
948
// LF_FUNC_ID LF_MFUNC_ID LF_BUILDINFO
949
// LF_SUBSTR_LIST LF_STRING_ID LF_UDT_SRC_LINE
950
// LF_UDT_MOD_SRC_LINE
951
952
LazyRandomTypeCollection &Types = types();
953
LazyRandomTypeCollection &Ids = ids();
954
if (Error Err = traverseTypes(Pdb, Types, Ids))
955
return Err;
956
957
// Process collected namespaces.
958
LogicalVisitor.processNamespaces();
959
960
LLVM_DEBUG({ W.getOStream() << "Traversing inlined lines\n"; });
961
962
auto VisitInlineeLines = [&](int32_t Modi, const SymbolGroup &SG,
963
DebugInlineeLinesSubsectionRef &Lines) -> Error {
964
return collectInlineeInfo(Lines, &SG);
965
};
966
967
FilterOptions Filters = {};
968
LinePrinter Printer(/*Indent=*/2, false, nulls(), Filters);
969
const PrintScope HeaderScope(Printer, /*IndentLevel=*/2);
970
if (Error Err = iterateModuleSubsections<DebugInlineeLinesSubsectionRef>(
971
Input, HeaderScope, VisitInlineeLines))
972
return Err;
973
974
// Traverse global symbols.
975
LLVM_DEBUG({ W.getOStream() << "Traversing global symbols\n"; });
976
if (Pdb.hasPDBGlobalsStream()) {
977
Expected<GlobalsStream &> GlobalsOrErr = Pdb.getPDBGlobalsStream();
978
if (!GlobalsOrErr)
979
return GlobalsOrErr.takeError();
980
GlobalsStream &Globals = *GlobalsOrErr;
981
const GSIHashTable &Table = Globals.getGlobalsTable();
982
Expected<SymbolStream &> ExpectedSyms = Pdb.getPDBSymbolStream();
983
if (ExpectedSyms) {
984
985
SymbolVisitorCallbackPipeline Pipeline;
986
SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
987
LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids, nullptr,
988
LogicalVisitor.getShared());
989
990
// As the global symbols do not have an associated Compile Unit, create
991
// one, as the container for all global symbols.
992
RecordPrefix Prefix(SymbolKind::S_COMPILE3);
993
CVSymbol Symbol(&Prefix, sizeof(Prefix));
994
uint32_t Offset = 0;
995
if (Error Err = Traverser.visitSymbolBegin(Symbol, Offset))
996
consumeError(std::move(Err));
997
else {
998
// The CodeView compile unit containing the global symbols does not
999
// have a name; generate one using its parent name (object filename)
1000
// follow by the '_global' string.
1001
std::string Name(CompileUnit->getParentScope()->getName());
1002
CompileUnit->setName(Name.append("_global"));
1003
1004
Pipeline.addCallbackToPipeline(Deserializer);
1005
Pipeline.addCallbackToPipeline(Traverser);
1006
CVSymbolVisitor Visitor(Pipeline);
1007
1008
BinaryStreamRef SymStream =
1009
ExpectedSyms->getSymbolArray().getUnderlyingStream();
1010
for (uint32_t PubSymOff : Table) {
1011
Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, PubSymOff);
1012
if (Sym) {
1013
if (Error Err = Visitor.visitSymbolRecord(*Sym, PubSymOff))
1014
return createStringError(errorToErrorCode(std::move(Err)),
1015
getFileName());
1016
} else {
1017
consumeError(Sym.takeError());
1018
}
1019
}
1020
}
1021
1022
LogicalVisitor.closeScope();
1023
} else {
1024
consumeError(ExpectedSyms.takeError());
1025
}
1026
}
1027
1028
// Traverse symbols (DBI).
1029
LLVM_DEBUG({ W.getOStream() << "Traversing symbol groups\n"; });
1030
1031
auto VisitSymbolGroup = [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
1032
Expected<ModuleDebugStreamRef> ExpectedModS =
1033
getModuleDebugStream(Pdb, Modi);
1034
if (ExpectedModS) {
1035
ModuleDebugStreamRef &ModS = *ExpectedModS;
1036
1037
LLVM_DEBUG({
1038
W.getOStream() << formatv("Traversing Group: Mod {0:4}\n", Modi);
1039
});
1040
1041
SymbolVisitorCallbackPipeline Pipeline;
1042
SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
1043
LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids, nullptr,
1044
LogicalVisitor.getShared());
1045
1046
Pipeline.addCallbackToPipeline(Deserializer);
1047
Pipeline.addCallbackToPipeline(Traverser);
1048
CVSymbolVisitor Visitor(Pipeline);
1049
BinarySubstreamRef SS = ModS.getSymbolsSubstream();
1050
if (Error Err =
1051
Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset))
1052
return createStringError(errorToErrorCode(std::move(Err)),
1053
getFileName());
1054
} else {
1055
// If the module stream does not exist, it is not an error condition.
1056
consumeError(ExpectedModS.takeError());
1057
}
1058
1059
return Error::success();
1060
};
1061
1062
if (Error Err = iterateSymbolGroups(Input, HeaderScope, VisitSymbolGroup))
1063
return Err;
1064
1065
// At this stage, the logical view contains all scopes, symbols and types.
1066
// For PDBs we can use the module id, to access its specific compile unit.
1067
// The line record addresses has been already resolved, so we can apply the
1068
// flow as when processing DWARF.
1069
1070
LLVM_DEBUG({ W.getOStream() << "Traversing lines\n"; });
1071
1072
// Record all line records for a Compile Unit.
1073
CULines.clear();
1074
1075
auto VisitDebugLines = [this](int32_t Modi, const SymbolGroup &SG,
1076
DebugLinesSubsectionRef &Lines) -> Error {
1077
if (!options().getPrintLines())
1078
return Error::success();
1079
1080
uint16_t Segment = Lines.header()->RelocSegment;
1081
uint32_t Begin = Lines.header()->RelocOffset;
1082
uint32_t Size = Lines.header()->CodeSize;
1083
1084
LLVM_DEBUG({ W.getOStream() << formatv("Modi = {0}\n", Modi); });
1085
1086
// We have line information for a new module; finish processing the
1087
// collected information for the current module. Once it is done, start
1088
// recording the line information for the new module.
1089
if (CurrentModule != Modi) {
1090
if (Error Err = processModule())
1091
return Err;
1092
CULines.clear();
1093
CurrentModule = Modi;
1094
}
1095
1096
for (const LineColumnEntry &Block : Lines)
1097
if (Error Err = createLines(Block.LineNumbers, /*Addendum=*/0, Segment,
1098
Begin, Size, Block.NameIndex, &SG))
1099
return Err;
1100
1101
return Error::success();
1102
};
1103
1104
if (Error Err = iterateModuleSubsections<DebugLinesSubsectionRef>(
1105
Input, HeaderScope, VisitDebugLines))
1106
return Err;
1107
1108
// Check if we have to close the Compile Unit scope.
1109
LogicalVisitor.closeScope();
1110
1111
// Process collected element lines.
1112
LogicalVisitor.processLines();
1113
1114
// Translate composite names into a single component.
1115
Root->transformScopedName();
1116
return Error::success();
1117
}
1118
1119
Error LVCodeViewReader::processModule() {
1120
if (LVScope *Scope = getScopeForModule(CurrentModule)) {
1121
CompileUnit = static_cast<LVScopeCompileUnit *>(Scope);
1122
1123
LLVM_DEBUG({ dbgs() << "Processing Scope: " << Scope->getName() << "\n"; });
1124
1125
// For the given compile unit, collect all scopes ranges.
1126
// For a complete ranges and lines mapping, the logical view support
1127
// needs for the compile unit to have a low and high pc values. We
1128
// can traverse the 'Modules' section and get the information for the
1129
// specific module. Another option, is from all the ranges collected
1130
// to take the first and last values.
1131
LVSectionIndex SectionIndex = DotTextSectionIndex;
1132
LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
1133
ScopesWithRanges->clear();
1134
CompileUnit->getRanges(*ScopesWithRanges);
1135
if (!ScopesWithRanges->empty())
1136
CompileUnit->addObject(ScopesWithRanges->getLower(),
1137
ScopesWithRanges->getUpper());
1138
ScopesWithRanges->sort();
1139
1140
if (Error Err = createInstructions())
1141
return Err;
1142
1143
// Include lines from any inlined functions within the current function.
1144
includeInlineeLines(SectionIndex, Scope);
1145
1146
processLines(&CULines, SectionIndex, nullptr);
1147
}
1148
1149
return Error::success();
1150
}
1151
1152
// In order to create the scopes, the CodeView Reader will:
1153
// = Traverse the TPI/IPI stream (Type visitor):
1154
// Collect forward references, scoped names, type indexes that will represent
1155
// a logical element, strings, line records, linkage names.
1156
// = Traverse the symbols section (Symbol visitor):
1157
// Create the scopes tree and creates the required logical elements, by
1158
// using the collected indexes from the type visitor.
1159
Error LVCodeViewReader::createScopes() {
1160
LLVM_DEBUG({
1161
W.startLine() << "\n";
1162
W.printString("File", getFileName().str());
1163
W.printString("Exe", ExePath);
1164
W.printString("Format", FileFormatName);
1165
});
1166
1167
if (Error Err = LVReader::createScopes())
1168
return Err;
1169
1170
LogicalVisitor.setRoot(Root);
1171
1172
if (isObj()) {
1173
if (Error Err = createScopes(getObj()))
1174
return Err;
1175
} else {
1176
if (Error Err = createScopes(getPdb()))
1177
return Err;
1178
}
1179
1180
return Error::success();
1181
}
1182
1183
Error LVCodeViewReader::loadTargetInfo(const ObjectFile &Obj) {
1184
// Detect the architecture from the object file. We usually don't need OS
1185
// info to lookup a target and create register info.
1186
Triple TT;
1187
TT.setArch(Triple::ArchType(Obj.getArch()));
1188
TT.setVendor(Triple::UnknownVendor);
1189
TT.setOS(Triple::UnknownOS);
1190
1191
// Features to be passed to target/subtarget
1192
Expected<SubtargetFeatures> Features = Obj.getFeatures();
1193
SubtargetFeatures FeaturesValue;
1194
if (!Features) {
1195
consumeError(Features.takeError());
1196
FeaturesValue = SubtargetFeatures();
1197
}
1198
FeaturesValue = *Features;
1199
return loadGenericTargetInfo(TT.str(), FeaturesValue.getString());
1200
}
1201
1202
Error LVCodeViewReader::loadTargetInfo(const PDBFile &Pdb) {
1203
Triple TT;
1204
TT.setArch(Triple::ArchType::x86_64);
1205
TT.setVendor(Triple::UnknownVendor);
1206
TT.setOS(Triple::Win32);
1207
1208
StringRef TheFeature = "";
1209
1210
return loadGenericTargetInfo(TT.str(), TheFeature);
1211
}
1212
1213
std::string LVCodeViewReader::getRegisterName(LVSmall Opcode,
1214
ArrayRef<uint64_t> Operands) {
1215
// Get Compilation Unit CPU Type.
1216
CPUType CPU = getCompileUnitCPUType();
1217
// For CodeView the register always is in Operands[0];
1218
RegisterId Register = (RegisterId(Operands[0]));
1219
return formatRegisterId(Register, CPU);
1220
}
1221
1222