LLVM 20.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 for (const RelocationRef &Relocacion : Section.relocations())
166 RelocMap[CoffSection].push_back(Relocacion);
167
168 // Sort relocations by address.
169 llvm::sort(RelocMap[CoffSection], [](RelocationRef L, RelocationRef R) {
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.count(SymbolName) != 0) {
724 // Saw debug info for this function already?
725 return createStringError(object_error::parse_failed, getFileName());
726 }
727
728 FunctionLineTables[SymbolName] = Contents;
729 SymbolNames.push_back(SymbolName);
730 }
731 break;
732
733 // Do nothing for unrecognized subsections.
734 default:
735 break;
736 }
737 W.flush();
738 }
739
740 // Traverse the line tables now that we've read all the subsections and
741 // know all the required information.
742 for (StringRef SymbolName : SymbolNames) {
743 LLVM_DEBUG({
744 ListScope S(W, "FunctionLineTable");
745 W.printString("Symbol Name", SymbolName);
746 });
747
748 BinaryStreamReader Reader(FunctionLineTables[SymbolName],
750
752 if (Error E = Lines.initialize(Reader))
753 return createStringError(errorToErrorCode(std::move(E)), getFileName());
754
755 // Find the associated symbol table information.
758 if (!Function)
759 continue;
760
761 LVAddress Addendum = SymbolTableEntry.Address;
762 LVSectionIndex SectionIndex = SymbolTableEntry.SectionIndex;
763
764 // The given scope represents the function that contains the line numbers.
765 // Collect all generated debug lines associated with the function.
766 CULines.clear();
767
768 // For the given scope, collect all scopes ranges.
769 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
770 ScopesWithRanges->clear();
771 Function->getRanges(*ScopesWithRanges);
772 ScopesWithRanges->sort();
773
774 uint16_t Segment = Lines.header()->RelocSegment;
775 uint32_t Begin = Lines.header()->RelocOffset;
776 uint32_t Size = Lines.header()->CodeSize;
777 for (const LineColumnEntry &Block : Lines)
778 if (Error Err = createLines(Block.LineNumbers, Addendum, Segment, Begin,
779 Size, Block.NameIndex))
780 return Err;
781
782 // Include lines from any inlined functions within the current function.
783 includeInlineeLines(SectionIndex, Function);
784
785 if (Error Err = createInstructions(Function, SectionIndex))
786 return Err;
787
788 processLines(&CULines, SectionIndex, Function);
789 }
790
791 return Error::success();
792}
793
795
797 LLVM_DEBUG(dbgs() << "CreateReaders\n");
798}
799
800void LVCodeViewReader::mapRangeAddress(const ObjectFile &Obj,
801 const SectionRef &Section,
802 bool IsComdat) {
803 if (!Obj.isCOFF())
804 return;
805
806 const COFFObjectFile *Object = cast<COFFObjectFile>(&Obj);
807
808 for (const SymbolRef &Sym : Object->symbols()) {
809 if (!Section.containsSymbol(Sym))
810 continue;
811
812 COFFSymbolRef Symbol = Object->getCOFFSymbol(Sym);
813 if (Symbol.getComplexType() != llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION)
814 continue;
815
816 StringRef SymbolName;
817 Expected<StringRef> SymNameOrErr = Object->getSymbolName(Symbol);
818 if (!SymNameOrErr) {
819 W.startLine() << "Invalid symbol name: " << Symbol.getSectionNumber()
820 << "\n";
821 consumeError(SymNameOrErr.takeError());
822 continue;
823 }
824 SymbolName = *SymNameOrErr;
825
826 LLVM_DEBUG({
827 Expected<const coff_section *> SectionOrErr =
828 Object->getSection(Symbol.getSectionNumber());
829 if (!SectionOrErr) {
830 W.startLine() << "Invalid section number: " << Symbol.getSectionNumber()
831 << "\n";
832 consumeError(SectionOrErr.takeError());
833 return;
834 }
835 W.printNumber("Section #", Symbol.getSectionNumber());
836 W.printString("Name", SymbolName);
837 W.printHex("Value", Symbol.getValue());
838 });
839
840 // Record the symbol name (linkage) and its loading address.
841 addToSymbolTable(SymbolName, Symbol.getValue(), Symbol.getSectionNumber(),
842 IsComdat);
843 }
844}
845
847 if (Error Err = loadTargetInfo(Obj))
848 return Err;
849
850 // Initialization required when processing a COFF file:
851 // Cache the symbols relocations.
852 // Create a mapping for virtual addresses.
853 // Get the functions entry points.
854 cacheRelocations();
856
857 for (const SectionRef &Section : Obj.sections()) {
858 Expected<StringRef> SectionNameOrErr = Section.getName();
859 if (!SectionNameOrErr)
860 return SectionNameOrErr.takeError();
861 // .debug$T is a standard CodeView type section, while .debug$P is the
862 // same format but used for MSVC precompiled header object files.
863 if (*SectionNameOrErr == ".debug$T" || *SectionNameOrErr == ".debug$P")
864 if (Error Err = traverseTypeSection(*SectionNameOrErr, Section))
865 return Err;
866 }
867
868 // Process collected namespaces.
869 LogicalVisitor.processNamespaces();
870
871 for (const SectionRef &Section : Obj.sections()) {
872 Expected<StringRef> SectionNameOrErr = Section.getName();
873 if (!SectionNameOrErr)
874 return SectionNameOrErr.takeError();
875 if (*SectionNameOrErr == ".debug$S")
876 if (Error Err = traverseSymbolSection(*SectionNameOrErr, Section))
877 return Err;
878 }
879
880 // Check if we have to close the Compile Unit scope.
881 LogicalVisitor.closeScope();
882
883 // Traverse the strings recorded and transform them into filenames.
884 LogicalVisitor.processFiles();
885
886 // Process collected element lines.
887 LogicalVisitor.processLines();
888
889 // Translate composite names into a single component.
891 return Error::success();
892}
893
895 if (Error Err = loadTargetInfo(Pdb))
896 return Err;
897
898 if (!Pdb.hasPDBTpiStream() || !Pdb.hasPDBDbiStream())
899 return Error::success();
900
901 // Open the executable associated with the PDB file and get the section
902 // addresses used to calculate linear addresses for CodeView Symbols.
903 if (!ExePath.empty()) {
906 if (BuffOrErr.getError()) {
908 "File '%s' does not exist.", ExePath.c_str());
909 }
910 BinaryBuffer = std::move(BuffOrErr.get());
911
912 // Check if the buffer corresponds to a PECOFF executable.
913 assert(identify_magic(BinaryBuffer->getBuffer()) ==
915 "Invalid PECOFF executable file.");
916
918 createBinary(BinaryBuffer->getMemBufferRef());
919 if (errorToErrorCode(BinOrErr.takeError())) {
921 "Binary object format in '%s' is not supported.",
922 ExePath.c_str());
923 }
924 BinaryExecutable = std::move(*BinOrErr);
925 if (COFFObjectFile *COFFObject =
926 dyn_cast<COFFObjectFile>(BinaryExecutable.get()))
927 mapVirtualAddress(*COFFObject);
928 }
929
930 // In order to generate a full logical view, we have to traverse both
931 // streams TPI and IPI if they are present. The following table gives
932 // the stream where a specified type is located. If the IPI stream is
933 // not present, all the types are located in the TPI stream.
934 //
935 // TPI Stream:
936 // LF_POINTER LF_MODIFIER LF_PROCEDURE LF_MFUNCTION
937 // LF_LABEL LF_ARGLIST LF_FIELDLIST LF_ARRAY
938 // LF_CLASS LF_STRUCTURE LF_INTERFACE LF_UNION
939 // LF_ENUM LF_TYPESERVER2 LF_VFTABLE LF_VTSHAPE
940 // LF_BITFIELD LF_METHODLIST LF_PRECOMP LF_ENDPRECOMP
941 //
942 // IPI stream:
943 // LF_FUNC_ID LF_MFUNC_ID LF_BUILDINFO
944 // LF_SUBSTR_LIST LF_STRING_ID LF_UDT_SRC_LINE
945 // LF_UDT_MOD_SRC_LINE
946
948 LazyRandomTypeCollection &Ids = ids();
949 if (Error Err = traverseTypes(Pdb, Types, Ids))
950 return Err;
951
952 // Process collected namespaces.
953 LogicalVisitor.processNamespaces();
954
955 LLVM_DEBUG({ W.getOStream() << "Traversing inlined lines\n"; });
956
957 auto VisitInlineeLines = [&](int32_t Modi, const SymbolGroup &SG,
959 return collectInlineeInfo(Lines, &SG);
960 };
961
962 FilterOptions Filters = {};
963 LinePrinter Printer(/*Indent=*/2, false, nulls(), Filters);
964 const PrintScope HeaderScope(Printer, /*IndentLevel=*/2);
965 if (Error Err = iterateModuleSubsections<DebugInlineeLinesSubsectionRef>(
966 Input, HeaderScope, VisitInlineeLines))
967 return Err;
968
969 // Traverse global symbols.
970 LLVM_DEBUG({ W.getOStream() << "Traversing global symbols\n"; });
971 if (Pdb.hasPDBGlobalsStream()) {
972 Expected<GlobalsStream &> GlobalsOrErr = Pdb.getPDBGlobalsStream();
973 if (!GlobalsOrErr)
974 return GlobalsOrErr.takeError();
975 GlobalsStream &Globals = *GlobalsOrErr;
976 const GSIHashTable &Table = Globals.getGlobalsTable();
977 Expected<SymbolStream &> ExpectedSyms = Pdb.getPDBSymbolStream();
978 if (ExpectedSyms) {
979
981 SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
982 LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids, nullptr,
983 LogicalVisitor.getShared());
984
985 // As the global symbols do not have an associated Compile Unit, create
986 // one, as the container for all global symbols.
987 RecordPrefix Prefix(SymbolKind::S_COMPILE3);
988 CVSymbol Symbol(&Prefix, sizeof(Prefix));
989 uint32_t Offset = 0;
990 if (Error Err = Traverser.visitSymbolBegin(Symbol, Offset))
991 consumeError(std::move(Err));
992 else {
993 // The CodeView compile unit containing the global symbols does not
994 // have a name; generate one using its parent name (object filename)
995 // follow by the '_global' string.
996 std::string Name(CompileUnit->getParentScope()->getName());
997 CompileUnit->setName(Name.append("_global"));
998
999 Pipeline.addCallbackToPipeline(Deserializer);
1000 Pipeline.addCallbackToPipeline(Traverser);
1001 CVSymbolVisitor Visitor(Pipeline);
1002
1003 BinaryStreamRef SymStream =
1004 ExpectedSyms->getSymbolArray().getUnderlyingStream();
1005 for (uint32_t PubSymOff : Table) {
1006 Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, PubSymOff);
1007 if (Sym) {
1008 if (Error Err = Visitor.visitSymbolRecord(*Sym, PubSymOff))
1009 return createStringError(errorToErrorCode(std::move(Err)),
1010 getFileName());
1011 } else {
1012 consumeError(Sym.takeError());
1013 }
1014 }
1015 }
1016
1017 LogicalVisitor.closeScope();
1018 } else {
1019 consumeError(ExpectedSyms.takeError());
1020 }
1021 }
1022
1023 // Traverse symbols (DBI).
1024 LLVM_DEBUG({ W.getOStream() << "Traversing symbol groups\n"; });
1025
1026 auto VisitSymbolGroup = [&](uint32_t Modi, const SymbolGroup &SG) -> Error {
1027 Expected<ModuleDebugStreamRef> ExpectedModS =
1029 if (ExpectedModS) {
1030 ModuleDebugStreamRef &ModS = *ExpectedModS;
1031
1032 LLVM_DEBUG({
1033 W.getOStream() << formatv("Traversing Group: Mod {0:4}\n", Modi);
1034 });
1035
1037 SymbolDeserializer Deserializer(nullptr, CodeViewContainer::Pdb);
1038 LVSymbolVisitor Traverser(this, W, &LogicalVisitor, Types, Ids, nullptr,
1039 LogicalVisitor.getShared());
1040
1041 Pipeline.addCallbackToPipeline(Deserializer);
1042 Pipeline.addCallbackToPipeline(Traverser);
1043 CVSymbolVisitor Visitor(Pipeline);
1045 if (Error Err =
1046 Visitor.visitSymbolStream(ModS.getSymbolArray(), SS.Offset))
1047 return createStringError(errorToErrorCode(std::move(Err)),
1048 getFileName());
1049 } else {
1050 // If the module stream does not exist, it is not an error condition.
1051 consumeError(ExpectedModS.takeError());
1052 }
1053
1054 return Error::success();
1055 };
1056
1057 if (Error Err = iterateSymbolGroups(Input, HeaderScope, VisitSymbolGroup))
1058 return Err;
1059
1060 // At this stage, the logical view contains all scopes, symbols and types.
1061 // For PDBs we can use the module id, to access its specific compile unit.
1062 // The line record addresses has been already resolved, so we can apply the
1063 // flow as when processing DWARF.
1064
1065 LLVM_DEBUG({ W.getOStream() << "Traversing lines\n"; });
1066
1067 // Record all line records for a Compile Unit.
1068 CULines.clear();
1069
1070 auto VisitDebugLines = [this](int32_t Modi, const SymbolGroup &SG,
1072 if (!options().getPrintLines())
1073 return Error::success();
1074
1075 uint16_t Segment = Lines.header()->RelocSegment;
1076 uint32_t Begin = Lines.header()->RelocOffset;
1077 uint32_t Size = Lines.header()->CodeSize;
1078
1079 LLVM_DEBUG({ W.getOStream() << formatv("Modi = {0}\n", Modi); });
1080
1081 // We have line information for a new module; finish processing the
1082 // collected information for the current module. Once it is done, start
1083 // recording the line information for the new module.
1084 if (CurrentModule != Modi) {
1085 if (Error Err = processModule())
1086 return Err;
1087 CULines.clear();
1088 CurrentModule = Modi;
1089 }
1090
1091 for (const LineColumnEntry &Block : Lines)
1092 if (Error Err = createLines(Block.LineNumbers, /*Addendum=*/0, Segment,
1093 Begin, Size, Block.NameIndex, &SG))
1094 return Err;
1095
1096 return Error::success();
1097 };
1098
1099 if (Error Err = iterateModuleSubsections<DebugLinesSubsectionRef>(
1100 Input, HeaderScope, VisitDebugLines))
1101 return Err;
1102
1103 // Check if we have to close the Compile Unit scope.
1104 LogicalVisitor.closeScope();
1105
1106 // Process collected element lines.
1107 LogicalVisitor.processLines();
1108
1109 // Translate composite names into a single component.
1111 return Error::success();
1112}
1113
1114Error LVCodeViewReader::processModule() {
1115 if (LVScope *Scope = getScopeForModule(CurrentModule)) {
1116 CompileUnit = static_cast<LVScopeCompileUnit *>(Scope);
1117
1118 LLVM_DEBUG({ dbgs() << "Processing Scope: " << Scope->getName() << "\n"; });
1119
1120 // For the given compile unit, collect all scopes ranges.
1121 // For a complete ranges and lines mapping, the logical view support
1122 // needs for the compile unit to have a low and high pc values. We
1123 // can traverse the 'Modules' section and get the information for the
1124 // specific module. Another option, is from all the ranges collected
1125 // to take the first and last values.
1126 LVSectionIndex SectionIndex = DotTextSectionIndex;
1127 LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);
1128 ScopesWithRanges->clear();
1129 CompileUnit->getRanges(*ScopesWithRanges);
1130 if (!ScopesWithRanges->empty())
1131 CompileUnit->addObject(ScopesWithRanges->getLower(),
1132 ScopesWithRanges->getUpper());
1133 ScopesWithRanges->sort();
1134
1135 if (Error Err = createInstructions())
1136 return Err;
1137
1138 // Include lines from any inlined functions within the current function.
1139 includeInlineeLines(SectionIndex, Scope);
1140
1141 processLines(&CULines, SectionIndex, nullptr);
1142 }
1143
1144 return Error::success();
1145}
1146
1147// In order to create the scopes, the CodeView Reader will:
1148// = Traverse the TPI/IPI stream (Type visitor):
1149// Collect forward references, scoped names, type indexes that will represent
1150// a logical element, strings, line records, linkage names.
1151// = Traverse the symbols section (Symbol visitor):
1152// Create the scopes tree and creates the required logical elements, by
1153// using the collected indexes from the type visitor.
1155 LLVM_DEBUG({
1156 W.startLine() << "\n";
1157 W.printString("File", getFileName().str());
1158 W.printString("Exe", ExePath);
1159 W.printString("Format", FileFormatName);
1160 });
1161
1162 if (Error Err = LVReader::createScopes())
1163 return Err;
1164
1165 LogicalVisitor.setRoot(Root);
1166
1167 if (isObj()) {
1168 if (Error Err = createScopes(getObj()))
1169 return Err;
1170 } else {
1171 if (Error Err = createScopes(getPdb()))
1172 return Err;
1173 }
1174
1175 return Error::success();
1176}
1177
1178Error LVCodeViewReader::loadTargetInfo(const ObjectFile &Obj) {
1179 // Detect the architecture from the object file. We usually don't need OS
1180 // info to lookup a target and create register info.
1181 Triple TT;
1182 TT.setArch(Triple::ArchType(Obj.getArch()));
1183 TT.setVendor(Triple::UnknownVendor);
1184 TT.setOS(Triple::UnknownOS);
1185
1186 // Features to be passed to target/subtarget
1188 SubtargetFeatures FeaturesValue;
1189 if (!Features) {
1190 consumeError(Features.takeError());
1191 FeaturesValue = SubtargetFeatures();
1192 }
1193 FeaturesValue = *Features;
1194 return loadGenericTargetInfo(TT.str(), FeaturesValue.getString());
1195}
1196
1197Error LVCodeViewReader::loadTargetInfo(const PDBFile &Pdb) {
1198 Triple TT;
1199 TT.setArch(Triple::ArchType::x86_64);
1200 TT.setVendor(Triple::UnknownVendor);
1201 TT.setOS(Triple::Win32);
1202
1203 StringRef TheFeature = "";
1204
1205 return loadGenericTargetInfo(TT.str(), TheFeature);
1206}
1207
1210 // Get Compilation Unit CPU Type.
1212 // For CodeView the register always is in Operands[0];
1214 return formatRegisterId(Register, CPU);
1215}
bbsections Prepares for basic block sections
dxil pretty DXIL Metadata Pretty Printer
#define LLVM_DEBUG(...)
Definition: Debug.h:106
uint64_t Size
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)
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.
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:335
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
reference get()
Returns a reference to the stored T value.
Definition: Error.h:578
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:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:276
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
const unsigned char * bytes_end() const
Definition: StringRef.h:131
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:609
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:144
const unsigned char * bytes_begin() const
Definition: StringRef.h:128
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:181
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: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:96
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)
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:329
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:128
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:821
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:275
@ SS
Definition: X86.h:212
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition: CodeView.h:76
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:48
@ D
The DMD compiler emits 'D' for the CV source language.
Definition: CodeView.h:173
Expected< CVSymbol > readSymbolFromStream(BinaryStreamRef Stream, uint32_t Offset)
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
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:98
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1291
@ bad_file_descriptor
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1664
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:756
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=' ')
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:111
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:1069
@ pdb
Windows PDB debug info file.
Definition: Magic.h:54
@ pecoff_executable
PECOFF executable file.
Definition: Magic.h:49