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
41using namespace llvm;
42using namespace llvm::codeview;
43using namespace llvm::logicalview;
44using namespace llvm::msf;
45using namespace llvm::object;
46using namespace llvm::pdb;
47
48#define DEBUG_TYPE "CodeViewReader"
49
50StringRef 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
62std::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
105void 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, Offset: RelocOffset, Name&: Symbol))
113 W.printSymbolOffset(Label, Symbol, Value: Offset);
114 else
115 W.printHex(Label, Value: RelocOffset);
116}
117
118void 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, Offset: RelocOffset, Name&: Symbol))
124 Symbol = "";
125}
126
127Expected<StringRef>
128LVCodeViewReader::getFileNameForFileOffset(uint32_t FileOffset,
129 const SymbolGroup *SG) {
130 if (SG) {
131 Expected<StringRef> Filename = SG->getNameFromChecksums(Offset: FileOffset);
132 if (!Filename) {
133 consumeError(Err: 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(EC: object_error::parse_failed, S: getFileName());
142
143 VarStreamArray<FileChecksumEntry>::Iterator Iter =
144 CVFileChecksumTable.getArray().at(Offset: FileOffset);
145
146 // Check if the file checksum table offset is valid.
147 if (Iter == CVFileChecksumTable.end())
148 return createStringError(EC: object_error::parse_failed, S: getFileName());
149
150 Expected<StringRef> NameOrErr = CVStringTable.getString(Offset: Iter->FileNameOffset);
151 if (!NameOrErr)
152 return createStringError(EC: object_error::parse_failed, S: getFileName());
153 return *NameOrErr;
154}
155
156Error 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, Str: *NameOrErr, Value: FileOffset);
163 return Error::success();
164}
165
166void 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(x: Relocacion);
172
173 // Sort relocations by address.
174 llvm::sort(C&: RelocMap[CoffSection], Comp: [](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.
182Error 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>(Args: "Unknown Symbol", Args: 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.
202Error LVCodeViewReader::resolveSymbolName(const coff_section *CoffSection,
203 uint64_t Offset, StringRef &Name) {
204 SymbolRef Symbol;
205 if (Error E = resolveSymbol(CoffSection, Offset, Sym&: 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'.
218bool LVCodeViewReader::isSystemEntry(LVElement *Element, StringRef Name) const {
219 Name = Name.empty() ? Element->getName() : Name;
220 auto Find = [=](const char *String) -> bool { return Name.contains(Other: String); };
221 auto Starts = [=](const char *Pattern) -> bool {
222 return Name.starts_with(Prefix: 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
246Error 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(TI: TIInlinee, LineNumber, Filename: *NameOrErr);
271 }
272
273 return Error::success();
274}
275
276Error LVCodeViewReader::traverseInlineeLines(StringRef Subsection) {
277 BinaryStreamReader SR(Subsection, llvm::endianness::little);
278 DebugInlineeLinesSubsectionRef Lines;
279 if (Error E = Lines.initialize(Reader: SR))
280 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
281
282 return collectInlineeInfo(Lines);
283}
284
285Error 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(EC: object_error::parse_failed, S: 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(Elt: LineDebug);
311 LVAddress Address = linearAddress(Segment, Offset: 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(FileOffset: NameIndex, SG);
325 if (!NameOrErr)
326 return NameOrErr.takeError();
327 LineDebug->setFilename(*NameOrErr);
328 }
329
330 return Error::success();
331}
332
333Error 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(Dest&: SubType))
342 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
343 if (Error E = Reader.readInteger(Dest&: SubSectionSize))
344 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
345
346 StringRef Contents;
347 if (Error E = Reader.readFixedString(Dest&: Contents, Length: SubSectionSize))
348 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
349
350 BinaryStreamRef ST(Contents, llvm::endianness::little);
351 switch (DebugSubsectionKind(SubType)) {
352 case DebugSubsectionKind::FileChecksums:
353 if (Error E = CVFileChecksumTable.initialize(Stream: ST))
354 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
355 break;
356 case DebugSubsectionKind::StringTable:
357 if (Error E = CVStringTable.initialize(Contents: ST))
358 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
359 break;
360 default:
361 break;
362 }
363
364 uint32_t PaddedSize = alignTo(Value: SubSectionSize, Align: 4);
365 if (Error E = Reader.skip(Amount: PaddedSize - SubSectionSize))
366 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
367 }
368
369 return Error::success();
370}
371
372Error 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(Filename: 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(From: ServerName);
385 BuffOrErr = MemoryBuffer::getFile(Filename: ServerName);
386 if (BuffOrErr.getError()) {
387 // For the error message, use the original type server name.
388 return createStringError(EC: errc::bad_file_descriptor,
389 Fmt: "File '%s' does not exist.",
390 Vals: 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(Type: PDB_ReaderType::Native, Path: ServerName, Session))
400 return createStringError(EC: errorToErrorCode(Err: std::move(Err)), Fmt: "%s",
401 Vals: ServerName.c_str());
402
403 PdbSession.reset(p: 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(EC: errc::invalid_argument, S: "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>(args: &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
427Error 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(Filename: ServerName);
437 if (BuffOrErr.getError()) {
438 // The server name does not exist. Try in the directory as the input file.
439 ServerName = createAlternativePath(From: ServerName);
440 if (BuffOrErr.getError()) {
441 // For the error message, use the original type server name.
442 return createStringError(EC: errc::bad_file_descriptor,
443 Fmt: "File '%s' does not exist.",
444 Vals: Precomp.getPrecompFilePath().str().c_str());
445 }
446 }
447 MemBuffer = std::move(BuffOrErr.get());
448
449 Expected<std::unique_ptr<Binary>> BinOrErr = createBinary(Source: *MemBuffer);
450 if (errorToErrorCode(Err: BinOrErr.takeError()))
451 return createStringError(EC: errc::not_supported,
452 Fmt: "Binary object format in '%s' is not supported.",
453 Vals: ServerName.c_str());
454
455 Binary &BinaryObj = *BinOrErr.get();
456 if (!BinaryObj.isCOFF())
457 return createStringError(EC: errc::not_supported, Fmt: "'%s' is not a COFF object.",
458 Vals: ServerName.c_str());
459
460 Builder = std::make_unique<AppendingTypeTableBuilder>(args&: BuilderAllocator);
461
462 // The MSVC precompiled header object file, should contain just a single
463 // ".debug$P" section.
464 COFFObjectFile &Obj = *cast<COFFObjectFile>(Val: &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(Data&: *DataOrErr, Item&: Magic))
475 return Err;
476 if (Magic != COFF::DEBUG_SECTION_MAGIC)
477 return errorCodeToError(EC: object_error::parse_failed);
478
479 ReaderPrecomp = std::make_unique<BinaryStreamReader>(
480 args&: *DataOrErr, args: llvm::endianness::little);
481 cantFail(
482 Err: ReaderPrecomp->readArray(Array&: CVTypesPrecomp, Size: 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 ValOrErr: TypeDeserializer::deserializeAs<EndPrecompRecord>(Data: TypeData));
491 if (Precomp.getSignature() != EndPrecomp.getSignature())
492 return createStringError(EC: errc::invalid_argument, S: "no matching pch");
493 break;
494 }
495 Builder->insertRecordBytes(Record&: 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(Record&: TypeData);
508 }
509
510 // Set up a type stream that refers to the added type records.
511 Builder->ForEachRecord(
512 Func: [&](TypeIndex TI, const CVType &Type) { TypeArray.push_back(x: Type); });
513
514 ItemStream =
515 std::make_unique<BinaryItemStream<CVType>>(args: llvm::endianness::little);
516 ItemStream->setItems(TypeArray);
517 TypeStream.setUnderlyingStream(NewStream: *ItemStream);
518
519 PrecompHeader =
520 std::make_shared<LazyRandomTypeCollection>(args&: TypeStream, args: 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, Callbacks&: TDV);
530}
531
532Error 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(Data&: *DataOrErr, Item&: Magic))
544 return Err;
545 if (Magic != COFF::DEBUG_SECTION_MAGIC)
546 return errorCodeToError(EC: 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(Err: Reader.readArray(Array&: CVTypes, Size: 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 ValOrErr: TypeDeserializer::deserializeAs<TypeServer2Record>(Data: 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 ValOrErr: TypeDeserializer::deserializeAs<PrecompRecord>(Data: FirstType->data()));
567 return loadPrecompiledObject(Precomp, CVTypesObj&: CVTypes);
568 }
569
570 LazyRandomTypeCollection &Types = types();
571 LazyRandomTypeCollection &Ids = ids();
572 Types.reset(Data: *DataOrErr, RecordCountHint: 100);
573 LVTypeVisitor TDV(W, &LogicalVisitor, Types, Ids, StreamTPI,
574 LogicalVisitor.getShared());
575 return visitTypeStream(Types, Callbacks&: TDV);
576}
577
578Error 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, Callbacks&: 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
614Error 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(Array&: Symbols, Size: Reader.getLength()))
624 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: 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(Callbacks&: Deserializer);
637 Pipeline.addCallbackToPipeline(Callbacks&: Traverser);
638 CVSymbolVisitor Visitor(Pipeline);
639 return Visitor.visitSymbolStream(Symbols);
640}
641
642Error 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, Item&: Magic))
660 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
661
662 if (Magic != COFF::DEBUG_SECTION_MAGIC)
663 return createStringError(EC: object_error::parse_failed, S: getFileName());
664
665 BinaryStreamReader FSReader(Data, llvm::endianness::little);
666 if (Error Err = initializeFileAndStringTables(Reader&: 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, Item&: SubType))
674 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
675 if (Error E = consume(Data, Item&: SubSectionSize))
676 return createStringError(EC: errorToErrorCode(Err: std::move(E)), S: 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(EC: object_error::parse_failed, S: getFileName());
684 StringRef Contents = Data.substr(Start: 0, N: 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(Value: NextOffset, Align: 4);
691 if (NextOffset > SectionContents.size())
692 return createStringError(EC: object_error::parse_failed, S: getFileName());
693 Data = SectionContents.drop_front(N: NextOffset);
694
695 switch (DebugSubsectionKind(SubType)) {
696 case DebugSubsectionKind::Symbols:
697 if (Error Err =
698 traverseSymbolsSubsection(Subsection: Contents, Section, SectionContents))
699 return Err;
700 break;
701
702 case DebugSubsectionKind::InlineeLines:
703 if (Error Err = traverseInlineeLines(Subsection: 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(EC: object_error::parse_failed, S: getFileName());
719 }
720
721 StringRef SymbolName;
722 if (Error Err = resolveSymbolName(CoffSection: getObj().getCOFFSection(Section),
723 Offset: SectionOffset, Name&: SymbolName))
724 return createStringError(EC: errorToErrorCode(Err: std::move(Err)),
725 S: getFileName());
726
727 LLVM_DEBUG({ W.printString("Symbol Name", SymbolName); });
728 if (FunctionLineTables.count(Key: SymbolName) != 0) {
729 // Saw debug info for this function already?
730 return createStringError(EC: object_error::parse_failed, S: getFileName());
731 }
732
733 FunctionLineTables[SymbolName] = Contents;
734 SymbolNames.push_back(Elt: 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(EC: errorToErrorCode(Err: std::move(E)), S: getFileName());
759
760 // Find the associated symbol table information.
761 LVSymbolTableEntry SymbolTableEntry = getSymbolTableEntry(Name: 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(RangeList&: *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(LineNumbers: Block.LineNumbers, Addendum, Segment, Begin,
784 Size, NameIndex: 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(DebugLines: &CULines, SectionIndex, Function);
794 }
795
796 return Error::success();
797}
798
799void LVCodeViewReader::sortScopes() { Root->sort(); }
800
801void LVCodeViewReader::print(raw_ostream &OS) const {
802 LLVM_DEBUG(dbgs() << "CreateReaders\n");
803}
804
805void 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>(Val: &Obj);
812
813 for (const SymbolRef &Sym : Object->symbols()) {
814 if (!Section.containsSymbol(S: Sym))
815 continue;
816
817 COFFSymbolRef Symbol = Object->getCOFFSymbol(Symbol: 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(Err: 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(Name: SymbolName, Address: Symbol.getValue(), SectionIndex: Symbol.getSectionNumber(),
847 IsComdat);
848 }
849}
850
851Error 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(COFFObj: 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(SectionName: *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(SectionName: *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
899Error 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(Filename: ExePath);
911 if (BuffOrErr.getError()) {
912 return createStringError(EC: errc::bad_file_descriptor,
913 Fmt: "File '%s' does not exist.", Vals: 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(Source: BinaryBuffer->getMemBufferRef());
924 if (errorToErrorCode(Err: BinOrErr.takeError())) {
925 return createStringError(EC: errc::not_supported,
926 Fmt: "Binary object format in '%s' is not supported.",
927 Vals: ExePath.c_str());
928 }
929 BinaryExecutable = std::move(*BinOrErr);
930 if (COFFObjectFile *COFFObject =
931 dyn_cast<COFFObjectFile>(Val: BinaryExecutable.get()))
932 mapVirtualAddress(COFFObj: *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: &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 File&: Input, HeaderScope, Callback: 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(Record&: Symbol, Offset))
996 consumeError(Err: 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(s: "_global"));
1003
1004 Pipeline.addCallbackToPipeline(Callbacks&: Deserializer);
1005 Pipeline.addCallbackToPipeline(Callbacks&: Traverser);
1006 CVSymbolVisitor Visitor(Pipeline);
1007
1008 BinaryStreamRef SymStream =
1009 ExpectedSyms->getSymbolArray().getUnderlyingStream();
1010 for (uint32_t PubSymOff : Table) {
1011 Expected<CVSymbol> Sym = readSymbolFromStream(Stream: SymStream, Offset: PubSymOff);
1012 if (Sym) {
1013 if (Error Err = Visitor.visitSymbolRecord(Record&: *Sym, Offset: PubSymOff))
1014 return createStringError(EC: errorToErrorCode(Err: std::move(Err)),
1015 S: getFileName());
1016 } else {
1017 consumeError(Err: Sym.takeError());
1018 }
1019 }
1020 }
1021
1022 LogicalVisitor.closeScope();
1023 } else {
1024 consumeError(Err: 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(File&: Pdb, Index: 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(Callbacks&: Deserializer);
1047 Pipeline.addCallbackToPipeline(Callbacks&: Traverser);
1048 CVSymbolVisitor Visitor(Pipeline);
1049 BinarySubstreamRef SS = ModS.getSymbolsSubstream();
1050 if (Error Err =
1051 Visitor.visitSymbolStream(Symbols: ModS.getSymbolArray(), InitialOffset: SS.Offset))
1052 return createStringError(EC: errorToErrorCode(Err: std::move(Err)),
1053 S: getFileName());
1054 } else {
1055 // If the module stream does not exist, it is not an error condition.
1056 consumeError(Err: ExpectedModS.takeError());
1057 }
1058
1059 return Error::success();
1060 };
1061
1062 if (Error Err = iterateSymbolGroups(Input, HeaderScope, Callback: 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(LineNumbers: Block.LineNumbers, /*Addendum=*/0, Segment,
1098 Begin, Size, NameIndex: Block.NameIndex, SG: &SG))
1099 return Err;
1100
1101 return Error::success();
1102 };
1103
1104 if (Error Err = iterateModuleSubsections<DebugLinesSubsectionRef>(
1105 File&: Input, HeaderScope, Callback: 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
1119Error LVCodeViewReader::processModule() {
1120 if (LVScope *Scope = getScopeForModule(Modi: 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(RangeList&: *ScopesWithRanges);
1135 if (!ScopesWithRanges->empty())
1136 CompileUnit->addObject(LowerAddress: ScopesWithRanges->getLower(),
1137 UpperAddress: 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, Function: Scope);
1145
1146 processLines(DebugLines: &CULines, SectionIndex, Function: 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.
1159Error 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(Obj&: getObj()))
1174 return Err;
1175 } else {
1176 if (Error Err = createScopes(Pdb&: getPdb()))
1177 return Err;
1178 }
1179
1180 return Error::success();
1181}
1182
1183Error 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(Kind: 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(Err: Features.takeError());
1196 FeaturesValue = SubtargetFeatures();
1197 }
1198 FeaturesValue = *Features;
1199 return loadGenericTargetInfo(TheTriple: TT.str(), TheFeatures: FeaturesValue.getString());
1200}
1201
1202Error LVCodeViewReader::loadTargetInfo(const PDBFile &Pdb) {
1203 Triple TT;
1204 TT.setArch(Kind: Triple::ArchType::x86_64);
1205 TT.setVendor(Triple::UnknownVendor);
1206 TT.setOS(Triple::Win32);
1207
1208 StringRef TheFeature = "";
1209
1210 return loadGenericTargetInfo(TheTriple: TT.str(), TheFeatures: TheFeature);
1211}
1212
1213std::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