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