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