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