llvm-project
1865 строк · 69.8 Кб
1//===- PDB.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#include "PDB.h"10#include "COFFLinkerContext.h"11#include "Chunks.h"12#include "Config.h"13#include "DebugTypes.h"14#include "Driver.h"15#include "SymbolTable.h"16#include "Symbols.h"17#include "TypeMerger.h"18#include "Writer.h"19#include "lld/Common/Timer.h"20#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"21#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"22#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"23#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"24#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"25#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"26#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"27#include "llvm/DebugInfo/CodeView/RecordName.h"28#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"29#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"30#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"31#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"32#include "llvm/DebugInfo/MSF/MSFBuilder.h"33#include "llvm/DebugInfo/MSF/MSFCommon.h"34#include "llvm/DebugInfo/MSF/MSFError.h"35#include "llvm/DebugInfo/PDB/GenericError.h"36#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"37#include "llvm/DebugInfo/PDB/Native/DbiStream.h"38#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"39#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"40#include "llvm/DebugInfo/PDB/Native/InfoStream.h"41#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"42#include "llvm/DebugInfo/PDB/Native/NativeSession.h"43#include "llvm/DebugInfo/PDB/Native/PDBFile.h"44#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"45#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"46#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"47#include "llvm/DebugInfo/PDB/Native/TpiStream.h"48#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"49#include "llvm/DebugInfo/PDB/PDB.h"50#include "llvm/Object/COFF.h"51#include "llvm/Object/CVDebugRecord.h"52#include "llvm/Support/BinaryByteStream.h"53#include "llvm/Support/CRC.h"54#include "llvm/Support/Endian.h"55#include "llvm/Support/Errc.h"56#include "llvm/Support/FormatAdapters.h"57#include "llvm/Support/FormatVariadic.h"58#include "llvm/Support/Path.h"59#include "llvm/Support/ScopedPrinter.h"60#include "llvm/Support/TimeProfiler.h"61#include <memory>62#include <optional>63
64using namespace llvm;65using namespace llvm::codeview;66using namespace lld;67using namespace lld::coff;68
69using llvm::object::coff_section;70using llvm::pdb::StringTableFixup;71
72namespace {73class DebugSHandler;74
75class PDBLinker {76friend DebugSHandler;77
78public:79PDBLinker(COFFLinkerContext &ctx)80: builder(bAlloc()), tMerger(ctx, bAlloc()), ctx(ctx) {81// This isn't strictly necessary, but link.exe usually puts an empty string82// as the first "valid" string in the string table, so we do the same in83// order to maintain as much byte-for-byte compatibility as possible.84pdbStrTab.insert("");85}86
87/// Emit the basic PDB structure: initial streams, headers, etc.88void initialize(llvm::codeview::DebugInfo *buildId);89
90/// Add natvis files specified on the command line.91void addNatvisFiles();92
93/// Add named streams specified on the command line.94void addNamedStreams();95
96/// Link CodeView from each object file in the symbol table into the PDB.97void addObjectsToPDB();98
99/// Add every live, defined public symbol to the PDB.100void addPublicsToPDB();101
102/// Link info for each import file in the symbol table into the PDB.103void addImportFilesToPDB();104
105void createModuleDBI(ObjFile *file);106
107/// Link CodeView from a single object file into the target (output) PDB.108/// When a precompiled headers object is linked, its TPI map might be provided109/// externally.110void addDebug(TpiSource *source);111
112void addDebugSymbols(TpiSource *source);113
114// Analyze the symbol records to separate module symbols from global symbols,115// find string references, and calculate how large the symbol stream will be116// in the PDB.117void analyzeSymbolSubsection(SectionChunk *debugChunk,118uint32_t &moduleSymOffset,119uint32_t &nextRelocIndex,120std::vector<StringTableFixup> &stringTableFixups,121BinaryStreamRef symData);122
123// Write all module symbols from all live debug symbol subsections of the124// given object file into the given stream writer.125Error writeAllModuleSymbolRecords(ObjFile *file, BinaryStreamWriter &writer);126
127// Callback to copy and relocate debug symbols during PDB file writing.128static Error commitSymbolsForObject(void *ctx, void *obj,129BinaryStreamWriter &writer);130
131// Copy the symbol record, relocate it, and fix the alignment if necessary.132// Rewrite type indices in the record. Replace unrecognized symbol records133// with S_SKIP records.134void writeSymbolRecord(SectionChunk *debugChunk,135ArrayRef<uint8_t> sectionContents, CVSymbol sym,136size_t alignedSize, uint32_t &nextRelocIndex,137std::vector<uint8_t> &storage);138
139/// Add the section map and section contributions to the PDB.140void addSections(ArrayRef<uint8_t> sectionTable);141
142/// Write the PDB to disk and store the Guid generated for it in *Guid.143void commit(codeview::GUID *guid);144
145// Print statistics regarding the final PDB146void printStats();147
148private:149void pdbMakeAbsolute(SmallVectorImpl<char> &fileName);150void translateIdSymbols(MutableArrayRef<uint8_t> &recordData,151TpiSource *source);152void addCommonLinkerModuleSymbols(StringRef path,153pdb::DbiModuleDescriptorBuilder &mod);154
155pdb::PDBFileBuilder builder;156
157TypeMerger tMerger;158
159COFFLinkerContext &ctx;160
161/// PDBs use a single global string table for filenames in the file checksum162/// table.163DebugStringTableSubsection pdbStrTab;164
165llvm::SmallString<128> nativePath;166
167// For statistics168uint64_t globalSymbols = 0;169uint64_t moduleSymbols = 0;170uint64_t publicSymbols = 0;171uint64_t nbTypeRecords = 0;172uint64_t nbTypeRecordsBytes = 0;173};174
175/// Represents an unrelocated DEBUG_S_FRAMEDATA subsection.
176struct UnrelocatedFpoData {177SectionChunk *debugChunk = nullptr;178ArrayRef<uint8_t> subsecData;179uint32_t relocIndex = 0;180};181
182/// The size of the magic bytes at the beginning of a symbol section or stream.
183enum : uint32_t { kSymbolStreamMagicSize = 4 };184
185class DebugSHandler {186PDBLinker &linker;187
188/// The object file whose .debug$S sections we're processing.189ObjFile &file;190
191/// The DEBUG_S_STRINGTABLE subsection. These strings are referred to by192/// index from other records in the .debug$S section. All of these strings193/// need to be added to the global PDB string table, and all references to194/// these strings need to have their indices re-written to refer to the195/// global PDB string table.196DebugStringTableSubsectionRef cvStrTab;197
198/// The DEBUG_S_FILECHKSMS subsection. As above, these are referred to199/// by other records in the .debug$S section and need to be merged into the200/// PDB.201DebugChecksumsSubsectionRef checksums;202
203/// The DEBUG_S_FRAMEDATA subsection(s). There can be more than one of204/// these and they need not appear in any specific order. However, they205/// contain string table references which need to be re-written, so we206/// collect them all here and re-write them after all subsections have been207/// discovered and processed.208std::vector<UnrelocatedFpoData> frameDataSubsecs;209
210/// List of string table references in symbol records. Later they will be211/// applied to the symbols during PDB writing.212std::vector<StringTableFixup> stringTableFixups;213
214/// Sum of the size of all module symbol records across all .debug$S sections.215/// Includes record realignment and the size of the symbol stream magic216/// prefix.217uint32_t moduleStreamSize = kSymbolStreamMagicSize;218
219/// Next relocation index in the current .debug$S section. Resets every220/// handleDebugS call.221uint32_t nextRelocIndex = 0;222
223void advanceRelocIndex(SectionChunk *debugChunk, ArrayRef<uint8_t> subsec);224
225void addUnrelocatedSubsection(SectionChunk *debugChunk,226const DebugSubsectionRecord &ss);227
228void addFrameDataSubsection(SectionChunk *debugChunk,229const DebugSubsectionRecord &ss);230
231public:232DebugSHandler(PDBLinker &linker, ObjFile &file)233: linker(linker), file(file) {}234
235void handleDebugS(SectionChunk *debugChunk);236
237void finish();238};239}
240
241// Visual Studio's debugger requires absolute paths in various places in the
242// PDB to work without additional configuration:
243// https://docs.microsoft.com/en-us/visualstudio/debugger/debug-source-files-common-properties-solution-property-pages-dialog-box
244void PDBLinker::pdbMakeAbsolute(SmallVectorImpl<char> &fileName) {245// The default behavior is to produce paths that are valid within the context246// of the machine that you perform the link on. If the linker is running on247// a POSIX system, we will output absolute POSIX paths. If the linker is248// running on a Windows system, we will output absolute Windows paths. If the249// user desires any other kind of behavior, they should explicitly pass250// /pdbsourcepath, in which case we will treat the exact string the user251// passed in as the gospel and not normalize, canonicalize it.252if (sys::path::is_absolute(fileName, sys::path::Style::windows) ||253sys::path::is_absolute(fileName, sys::path::Style::posix))254return;255
256// It's not absolute in any path syntax. Relative paths necessarily refer to257// the local file system, so we can make it native without ending up with a258// nonsensical path.259if (ctx.config.pdbSourcePath.empty()) {260sys::path::native(fileName);261sys::fs::make_absolute(fileName);262sys::path::remove_dots(fileName, true);263return;264}265
266// Try to guess whether /PDBSOURCEPATH is a unix path or a windows path.267// Since PDB's are more of a Windows thing, we make this conservative and only268// decide that it's a unix path if we're fairly certain. Specifically, if269// it starts with a forward slash.270SmallString<128> absoluteFileName = ctx.config.pdbSourcePath;271sys::path::Style guessedStyle = absoluteFileName.starts_with("/")272? sys::path::Style::posix273: sys::path::Style::windows;274sys::path::append(absoluteFileName, guessedStyle, fileName);275sys::path::native(absoluteFileName, guessedStyle);276sys::path::remove_dots(absoluteFileName, true, guessedStyle);277
278fileName = std::move(absoluteFileName);279}
280
281static void addTypeInfo(pdb::TpiStreamBuilder &tpiBuilder,282TypeCollection &typeTable) {283// Start the TPI or IPI stream header.284tpiBuilder.setVersionHeader(pdb::PdbTpiV80);285
286// Flatten the in memory type table and hash each type.287typeTable.ForEachRecord([&](TypeIndex ti, const CVType &type) {288auto hash = pdb::hashTypeRecord(type);289if (auto e = hash.takeError())290fatal("type hashing error");291tpiBuilder.addTypeRecord(type.RecordData, *hash);292});293}
294
295static void addGHashTypeInfo(COFFLinkerContext &ctx,296pdb::PDBFileBuilder &builder) {297// Start the TPI or IPI stream header.298builder.getTpiBuilder().setVersionHeader(pdb::PdbTpiV80);299builder.getIpiBuilder().setVersionHeader(pdb::PdbTpiV80);300for (TpiSource *source : ctx.tpiSourceList) {301builder.getTpiBuilder().addTypeRecords(source->mergedTpi.recs,302source->mergedTpi.recSizes,303source->mergedTpi.recHashes);304builder.getIpiBuilder().addTypeRecords(source->mergedIpi.recs,305source->mergedIpi.recSizes,306source->mergedIpi.recHashes);307}308}
309
310static void311recordStringTableReferences(CVSymbol sym, uint32_t symOffset,312std::vector<StringTableFixup> &stringTableFixups) {313// For now we only handle S_FILESTATIC, but we may need the same logic for314// S_DEFRANGE and S_DEFRANGE_SUBFIELD. However, I cannot seem to generate any315// PDBs that contain these types of records, so because of the uncertainty316// they are omitted here until we can prove that it's necessary.317switch (sym.kind()) {318case SymbolKind::S_FILESTATIC: {319// FileStaticSym::ModFileOffset320uint32_t ref = *reinterpret_cast<const ulittle32_t *>(&sym.data()[8]);321stringTableFixups.push_back({ref, symOffset + 8});322break;323}324case SymbolKind::S_DEFRANGE:325case SymbolKind::S_DEFRANGE_SUBFIELD:326log("Not fixing up string table reference in S_DEFRANGE / "327"S_DEFRANGE_SUBFIELD record");328break;329default:330break;331}332}
333
334static SymbolKind symbolKind(ArrayRef<uint8_t> recordData) {335const RecordPrefix *prefix =336reinterpret_cast<const RecordPrefix *>(recordData.data());337return static_cast<SymbolKind>(uint16_t(prefix->RecordKind));338}
339
340/// MSVC translates S_PROC_ID_END to S_END, and S_[LG]PROC32_ID to S_[LG]PROC32
341void PDBLinker::translateIdSymbols(MutableArrayRef<uint8_t> &recordData,342TpiSource *source) {343RecordPrefix *prefix = reinterpret_cast<RecordPrefix *>(recordData.data());344
345SymbolKind kind = symbolKind(recordData);346
347if (kind == SymbolKind::S_PROC_ID_END) {348prefix->RecordKind = SymbolKind::S_END;349return;350}351
352// In an object file, GPROC32_ID has an embedded reference which refers to the353// single object file type index namespace. This has already been translated354// to the PDB file's ID stream index space, but we need to convert this to a355// symbol that refers to the type stream index space. So we remap again from356// ID index space to type index space.357if (kind == SymbolKind::S_GPROC32_ID || kind == SymbolKind::S_LPROC32_ID) {358SmallVector<TiReference, 1> refs;359auto content = recordData.drop_front(sizeof(RecordPrefix));360CVSymbol sym(recordData);361discoverTypeIndicesInSymbol(sym, refs);362assert(refs.size() == 1);363assert(refs.front().Count == 1);364
365TypeIndex *ti =366reinterpret_cast<TypeIndex *>(content.data() + refs[0].Offset);367// `ti` is the index of a FuncIdRecord or MemberFuncIdRecord which lives in368// the IPI stream, whose `FunctionType` member refers to the TPI stream.369// Note that LF_FUNC_ID and LF_MFUNC_ID have the same record layout, and370// in both cases we just need the second type index.371if (!ti->isSimple() && !ti->isNoneType()) {372TypeIndex newType = TypeIndex(SimpleTypeKind::NotTranslated);373if (ctx.config.debugGHashes) {374auto idToType = tMerger.funcIdToType.find(*ti);375if (idToType != tMerger.funcIdToType.end())376newType = idToType->second;377} else {378if (tMerger.getIDTable().contains(*ti)) {379CVType funcIdData = tMerger.getIDTable().getType(*ti);380if (funcIdData.length() >= 8 && (funcIdData.kind() == LF_FUNC_ID ||381funcIdData.kind() == LF_MFUNC_ID)) {382newType = *reinterpret_cast<const TypeIndex *>(&funcIdData.data()[8]);383}384}385}386if (newType == TypeIndex(SimpleTypeKind::NotTranslated)) {387warn(formatv("procedure symbol record for `{0}` in {1} refers to PDB "388"item index {2:X} which is not a valid function ID record",389getSymbolName(CVSymbol(recordData)),390source->file->getName(), ti->getIndex()));391}392*ti = newType;393}394
395kind = (kind == SymbolKind::S_GPROC32_ID) ? SymbolKind::S_GPROC32396: SymbolKind::S_LPROC32;397prefix->RecordKind = uint16_t(kind);398}399}
400
401namespace {402struct ScopeRecord {403ulittle32_t ptrParent;404ulittle32_t ptrEnd;405};406} // namespace407
408/// Given a pointer to a symbol record that opens a scope, return a pointer to
409/// the scope fields.
410static ScopeRecord *getSymbolScopeFields(void *sym) {411return reinterpret_cast<ScopeRecord *>(reinterpret_cast<char *>(sym) +412sizeof(RecordPrefix));413}
414
415// To open a scope, push the offset of the current symbol record onto the
416// stack.
417static void scopeStackOpen(SmallVectorImpl<uint32_t> &stack,418std::vector<uint8_t> &storage) {419stack.push_back(storage.size());420}
421
422// To close a scope, update the record that opened the scope.
423static void scopeStackClose(SmallVectorImpl<uint32_t> &stack,424std::vector<uint8_t> &storage,425uint32_t storageBaseOffset, ObjFile *file) {426if (stack.empty()) {427warn("symbol scopes are not balanced in " + file->getName());428return;429}430
431// Update ptrEnd of the record that opened the scope to point to the432// current record, if we are writing into the module symbol stream.433uint32_t offOpen = stack.pop_back_val();434uint32_t offEnd = storageBaseOffset + storage.size();435uint32_t offParent = stack.empty() ? 0 : (stack.back() + storageBaseOffset);436ScopeRecord *scopeRec = getSymbolScopeFields(&(storage)[offOpen]);437scopeRec->ptrParent = offParent;438scopeRec->ptrEnd = offEnd;439}
440
441static bool symbolGoesInModuleStream(const CVSymbol &sym,442unsigned symbolScopeDepth) {443switch (sym.kind()) {444case SymbolKind::S_GDATA32:445case SymbolKind::S_GTHREAD32:446// We really should not be seeing S_PROCREF and S_LPROCREF in the first place447// since they are synthesized by the linker in response to S_GPROC32 and448// S_LPROC32, but if we do see them, don't put them in the module stream I449// guess.450case SymbolKind::S_PROCREF:451case SymbolKind::S_LPROCREF:452return false;453// S_UDT and S_CONSTANT records go in the module stream if it is not a global record.454case SymbolKind::S_UDT:455case SymbolKind::S_CONSTANT:456return symbolScopeDepth > 0;457// S_GDATA32 does not go in the module stream, but S_LDATA32 does.458case SymbolKind::S_LDATA32:459case SymbolKind::S_LTHREAD32:460default:461return true;462}463}
464
465static bool symbolGoesInGlobalsStream(const CVSymbol &sym,466unsigned symbolScopeDepth) {467switch (sym.kind()) {468case SymbolKind::S_GDATA32:469case SymbolKind::S_GTHREAD32:470case SymbolKind::S_GPROC32:471case SymbolKind::S_LPROC32:472case SymbolKind::S_GPROC32_ID:473case SymbolKind::S_LPROC32_ID:474// We really should not be seeing S_PROCREF and S_LPROCREF in the first place475// since they are synthesized by the linker in response to S_GPROC32 and476// S_LPROC32, but if we do see them, copy them straight through.477case SymbolKind::S_PROCREF:478case SymbolKind::S_LPROCREF:479return true;480// Records that go in the globals stream, unless they are function-local.481case SymbolKind::S_UDT:482case SymbolKind::S_LDATA32:483case SymbolKind::S_LTHREAD32:484case SymbolKind::S_CONSTANT:485return symbolScopeDepth == 0;486default:487return false;488}489}
490
491static void addGlobalSymbol(pdb::GSIStreamBuilder &builder, uint16_t modIndex,492unsigned symOffset,493std::vector<uint8_t> &symStorage) {494CVSymbol sym{ArrayRef(symStorage)};495switch (sym.kind()) {496case SymbolKind::S_CONSTANT:497case SymbolKind::S_UDT:498case SymbolKind::S_GDATA32:499case SymbolKind::S_GTHREAD32:500case SymbolKind::S_LTHREAD32:501case SymbolKind::S_LDATA32:502case SymbolKind::S_PROCREF:503case SymbolKind::S_LPROCREF: {504// sym is a temporary object, so we have to copy and reallocate the record505// to stabilize it.506uint8_t *mem = bAlloc().Allocate<uint8_t>(sym.length());507memcpy(mem, sym.data().data(), sym.length());508builder.addGlobalSymbol(CVSymbol(ArrayRef(mem, sym.length())));509break;510}511case SymbolKind::S_GPROC32:512case SymbolKind::S_LPROC32: {513SymbolRecordKind k = SymbolRecordKind::ProcRefSym;514if (sym.kind() == SymbolKind::S_LPROC32)515k = SymbolRecordKind::LocalProcRef;516ProcRefSym ps(k);517ps.Module = modIndex;518// For some reason, MSVC seems to add one to this value.519++ps.Module;520ps.Name = getSymbolName(sym);521ps.SumName = 0;522ps.SymOffset = symOffset;523builder.addGlobalSymbol(ps);524break;525}526default:527llvm_unreachable("Invalid symbol kind!");528}529}
530
531// Check if the given symbol record was padded for alignment. If so, zero out
532// the padding bytes and update the record prefix with the new size.
533static void fixRecordAlignment(MutableArrayRef<uint8_t> recordBytes,534size_t oldSize) {535size_t alignedSize = recordBytes.size();536if (oldSize == alignedSize)537return;538reinterpret_cast<RecordPrefix *>(recordBytes.data())->RecordLen =539alignedSize - 2;540memset(recordBytes.data() + oldSize, 0, alignedSize - oldSize);541}
542
543// Replace any record with a skip record of the same size. This is useful when
544// we have reserved size for a symbol record, but type index remapping fails.
545static void replaceWithSkipRecord(MutableArrayRef<uint8_t> recordBytes) {546memset(recordBytes.data(), 0, recordBytes.size());547auto *prefix = reinterpret_cast<RecordPrefix *>(recordBytes.data());548prefix->RecordKind = SymbolKind::S_SKIP;549prefix->RecordLen = recordBytes.size() - 2;550}
551
552// Copy the symbol record, relocate it, and fix the alignment if necessary.
553// Rewrite type indices in the record. Replace unrecognized symbol records with
554// S_SKIP records.
555void PDBLinker::writeSymbolRecord(SectionChunk *debugChunk,556ArrayRef<uint8_t> sectionContents,557CVSymbol sym, size_t alignedSize,558uint32_t &nextRelocIndex,559std::vector<uint8_t> &storage) {560// Allocate space for the new record at the end of the storage.561storage.resize(storage.size() + alignedSize);562auto recordBytes = MutableArrayRef<uint8_t>(storage).take_back(alignedSize);563
564// Copy the symbol record and relocate it.565debugChunk->writeAndRelocateSubsection(sectionContents, sym.data(),566nextRelocIndex, recordBytes.data());567fixRecordAlignment(recordBytes, sym.length());568
569// Re-map all the type index references.570TpiSource *source = debugChunk->file->debugTypesObj;571if (!source->remapTypesInSymbolRecord(recordBytes)) {572log("ignoring unknown symbol record with kind 0x" + utohexstr(sym.kind()));573replaceWithSkipRecord(recordBytes);574}575
576// An object file may have S_xxx_ID symbols, but these get converted to577// "real" symbols in a PDB.578translateIdSymbols(recordBytes, source);579}
580
581void PDBLinker::analyzeSymbolSubsection(582SectionChunk *debugChunk, uint32_t &moduleSymOffset,583uint32_t &nextRelocIndex, std::vector<StringTableFixup> &stringTableFixups,584BinaryStreamRef symData) {585ObjFile *file = debugChunk->file;586uint32_t moduleSymStart = moduleSymOffset;587
588uint32_t scopeLevel = 0;589std::vector<uint8_t> storage;590ArrayRef<uint8_t> sectionContents = debugChunk->getContents();591
592ArrayRef<uint8_t> symsBuffer;593cantFail(symData.readBytes(0, symData.getLength(), symsBuffer));594
595if (symsBuffer.empty())596warn("empty symbols subsection in " + file->getName());597
598Error ec = forEachCodeViewRecord<CVSymbol>(599symsBuffer, [&](CVSymbol sym) -> llvm::Error {600// Track the current scope.601if (symbolOpensScope(sym.kind()))602++scopeLevel;603else if (symbolEndsScope(sym.kind()))604--scopeLevel;605
606uint32_t alignedSize =607alignTo(sym.length(), alignOf(CodeViewContainer::Pdb));608
609// Copy global records. Some global records (mainly procedures)610// reference the current offset into the module stream.611if (symbolGoesInGlobalsStream(sym, scopeLevel)) {612storage.clear();613writeSymbolRecord(debugChunk, sectionContents, sym, alignedSize,614nextRelocIndex, storage);615addGlobalSymbol(builder.getGsiBuilder(),616file->moduleDBI->getModuleIndex(), moduleSymOffset,617storage);618++globalSymbols;619}620
621// Update the module stream offset and record any string table index622// references. There are very few of these and they will be rewritten623// later during PDB writing.624if (symbolGoesInModuleStream(sym, scopeLevel)) {625recordStringTableReferences(sym, moduleSymOffset, stringTableFixups);626moduleSymOffset += alignedSize;627++moduleSymbols;628}629
630return Error::success();631});632
633// If we encountered corrupt records, ignore the whole subsection. If we wrote634// any partial records, undo that. For globals, we just keep what we have and635// continue.636if (ec) {637warn("corrupt symbol records in " + file->getName());638moduleSymOffset = moduleSymStart;639consumeError(std::move(ec));640}641}
642
643Error PDBLinker::writeAllModuleSymbolRecords(ObjFile *file,644BinaryStreamWriter &writer) {645ExitOnError exitOnErr;646std::vector<uint8_t> storage;647SmallVector<uint32_t, 4> scopes;648
649// Visit all live .debug$S sections a second time, and write them to the PDB.650for (SectionChunk *debugChunk : file->getDebugChunks()) {651if (!debugChunk->live || debugChunk->getSize() == 0 ||652debugChunk->getSectionName() != ".debug$S")653continue;654
655ArrayRef<uint8_t> sectionContents = debugChunk->getContents();656auto contents =657SectionChunk::consumeDebugMagic(sectionContents, ".debug$S");658DebugSubsectionArray subsections;659BinaryStreamReader reader(contents, llvm::endianness::little);660exitOnErr(reader.readArray(subsections, contents.size()));661
662uint32_t nextRelocIndex = 0;663for (const DebugSubsectionRecord &ss : subsections) {664if (ss.kind() != DebugSubsectionKind::Symbols)665continue;666
667uint32_t moduleSymStart = writer.getOffset();668scopes.clear();669storage.clear();670ArrayRef<uint8_t> symsBuffer;671BinaryStreamRef sr = ss.getRecordData();672cantFail(sr.readBytes(0, sr.getLength(), symsBuffer));673auto ec = forEachCodeViewRecord<CVSymbol>(674symsBuffer, [&](CVSymbol sym) -> llvm::Error {675// Track the current scope. Only update records in the postmerge676// pass.677if (symbolOpensScope(sym.kind()))678scopeStackOpen(scopes, storage);679else if (symbolEndsScope(sym.kind()))680scopeStackClose(scopes, storage, moduleSymStart, file);681
682// Copy, relocate, and rewrite each module symbol.683if (symbolGoesInModuleStream(sym, scopes.size())) {684uint32_t alignedSize =685alignTo(sym.length(), alignOf(CodeViewContainer::Pdb));686writeSymbolRecord(debugChunk, sectionContents, sym, alignedSize,687nextRelocIndex, storage);688}689return Error::success();690});691
692// If we encounter corrupt records in the second pass, ignore them. We693// already warned about them in the first analysis pass.694if (ec) {695consumeError(std::move(ec));696storage.clear();697}698
699// Writing bytes has a very high overhead, so write the entire subsection700// at once.701// TODO: Consider buffering symbols for the entire object file to reduce702// overhead even further.703if (Error e = writer.writeBytes(storage))704return e;705}706}707
708return Error::success();709}
710
711Error PDBLinker::commitSymbolsForObject(void *ctx, void *obj,712BinaryStreamWriter &writer) {713return static_cast<PDBLinker *>(ctx)->writeAllModuleSymbolRecords(714static_cast<ObjFile *>(obj), writer);715}
716
717static pdb::SectionContrib createSectionContrib(COFFLinkerContext &ctx,718const Chunk *c, uint32_t modi) {719OutputSection *os = c ? ctx.getOutputSection(c) : nullptr;720pdb::SectionContrib sc;721memset(&sc, 0, sizeof(sc));722sc.ISect = os ? os->sectionIndex : llvm::pdb::kInvalidStreamIndex;723sc.Off = c && os ? c->getRVA() - os->getRVA() : 0;724sc.Size = c ? c->getSize() : -1;725if (auto *secChunk = dyn_cast_or_null<SectionChunk>(c)) {726sc.Characteristics = secChunk->header->Characteristics;727sc.Imod = secChunk->file->moduleDBI->getModuleIndex();728ArrayRef<uint8_t> contents = secChunk->getContents();729JamCRC crc(0);730crc.update(contents);731sc.DataCrc = crc.getCRC();732} else {733sc.Characteristics = os ? os->header.Characteristics : 0;734sc.Imod = modi;735}736sc.RelocCrc = 0; // FIXME737
738return sc;739}
740
741static uint32_t742translateStringTableIndex(uint32_t objIndex,743const DebugStringTableSubsectionRef &objStrTable,744DebugStringTableSubsection &pdbStrTable) {745auto expectedString = objStrTable.getString(objIndex);746if (!expectedString) {747warn("Invalid string table reference");748consumeError(expectedString.takeError());749return 0;750}751
752return pdbStrTable.insert(*expectedString);753}
754
755void DebugSHandler::handleDebugS(SectionChunk *debugChunk) {756// Note that we are processing the *unrelocated* section contents. They will757// be relocated later during PDB writing.758ArrayRef<uint8_t> contents = debugChunk->getContents();759contents = SectionChunk::consumeDebugMagic(contents, ".debug$S");760DebugSubsectionArray subsections;761BinaryStreamReader reader(contents, llvm::endianness::little);762ExitOnError exitOnErr;763exitOnErr(reader.readArray(subsections, contents.size()));764debugChunk->sortRelocations();765
766// Reset the relocation index, since this is a new section.767nextRelocIndex = 0;768
769for (const DebugSubsectionRecord &ss : subsections) {770// Ignore subsections with the 'ignore' bit. Some versions of the Visual C++771// runtime have subsections with this bit set.772if (uint32_t(ss.kind()) & codeview::SubsectionIgnoreFlag)773continue;774
775switch (ss.kind()) {776case DebugSubsectionKind::StringTable: {777assert(!cvStrTab.valid() &&778"Encountered multiple string table subsections!");779exitOnErr(cvStrTab.initialize(ss.getRecordData()));780break;781}782case DebugSubsectionKind::FileChecksums:783assert(!checksums.valid() &&784"Encountered multiple checksum subsections!");785exitOnErr(checksums.initialize(ss.getRecordData()));786break;787case DebugSubsectionKind::Lines:788case DebugSubsectionKind::InlineeLines:789addUnrelocatedSubsection(debugChunk, ss);790break;791case DebugSubsectionKind::FrameData:792addFrameDataSubsection(debugChunk, ss);793break;794case DebugSubsectionKind::Symbols:795linker.analyzeSymbolSubsection(debugChunk, moduleStreamSize,796nextRelocIndex, stringTableFixups,797ss.getRecordData());798break;799
800case DebugSubsectionKind::CrossScopeImports:801case DebugSubsectionKind::CrossScopeExports:802// These appear to relate to cross-module optimization, so we might use803// these for ThinLTO.804break;805
806case DebugSubsectionKind::ILLines:807case DebugSubsectionKind::FuncMDTokenMap:808case DebugSubsectionKind::TypeMDTokenMap:809case DebugSubsectionKind::MergedAssemblyInput:810// These appear to relate to .Net assembly info.811break;812
813case DebugSubsectionKind::CoffSymbolRVA:814// Unclear what this is for.815break;816
817case DebugSubsectionKind::XfgHashType:818case DebugSubsectionKind::XfgHashVirtual:819break;820
821default:822warn("ignoring unknown debug$S subsection kind 0x" +823utohexstr(uint32_t(ss.kind())) + " in file " + toString(&file));824break;825}826}827}
828
829void DebugSHandler::advanceRelocIndex(SectionChunk *sc,830ArrayRef<uint8_t> subsec) {831ptrdiff_t vaBegin = subsec.data() - sc->getContents().data();832assert(vaBegin > 0);833auto relocs = sc->getRelocs();834for (; nextRelocIndex < relocs.size(); ++nextRelocIndex) {835if (relocs[nextRelocIndex].VirtualAddress >= (uint32_t)vaBegin)836break;837}838}
839
840namespace {841/// Wrapper class for unrelocated line and inlinee line subsections, which
842/// require only relocation and type index remapping to add to the PDB.
843class UnrelocatedDebugSubsection : public DebugSubsection {844public:845UnrelocatedDebugSubsection(DebugSubsectionKind k, SectionChunk *debugChunk,846ArrayRef<uint8_t> subsec, uint32_t relocIndex)847: DebugSubsection(k), debugChunk(debugChunk), subsec(subsec),848relocIndex(relocIndex) {}849
850Error commit(BinaryStreamWriter &writer) const override;851uint32_t calculateSerializedSize() const override { return subsec.size(); }852
853SectionChunk *debugChunk;854ArrayRef<uint8_t> subsec;855uint32_t relocIndex;856};857} // namespace858
859Error UnrelocatedDebugSubsection::commit(BinaryStreamWriter &writer) const {860std::vector<uint8_t> relocatedBytes(subsec.size());861uint32_t tmpRelocIndex = relocIndex;862debugChunk->writeAndRelocateSubsection(debugChunk->getContents(), subsec,863tmpRelocIndex, relocatedBytes.data());864
865// Remap type indices in inlinee line records in place. Skip the remapping if866// there is no type source info.867if (kind() == DebugSubsectionKind::InlineeLines &&868debugChunk->file->debugTypesObj) {869TpiSource *source = debugChunk->file->debugTypesObj;870DebugInlineeLinesSubsectionRef inlineeLines;871BinaryStreamReader storageReader(relocatedBytes, llvm::endianness::little);872ExitOnError exitOnErr;873exitOnErr(inlineeLines.initialize(storageReader));874for (const InlineeSourceLine &line : inlineeLines) {875TypeIndex &inlinee = *const_cast<TypeIndex *>(&line.Header->Inlinee);876if (!source->remapTypeIndex(inlinee, TiRefKind::IndexRef)) {877log("bad inlinee line record in " + debugChunk->file->getName() +878" with bad inlinee index 0x" + utohexstr(inlinee.getIndex()));879}880}881}882
883return writer.writeBytes(relocatedBytes);884}
885
886void DebugSHandler::addUnrelocatedSubsection(SectionChunk *debugChunk,887const DebugSubsectionRecord &ss) {888ArrayRef<uint8_t> subsec;889BinaryStreamRef sr = ss.getRecordData();890cantFail(sr.readBytes(0, sr.getLength(), subsec));891advanceRelocIndex(debugChunk, subsec);892file.moduleDBI->addDebugSubsection(893std::make_shared<UnrelocatedDebugSubsection>(ss.kind(), debugChunk,894subsec, nextRelocIndex));895}
896
897void DebugSHandler::addFrameDataSubsection(SectionChunk *debugChunk,898const DebugSubsectionRecord &ss) {899// We need to re-write string table indices here, so save off all900// frame data subsections until we've processed the entire list of901// subsections so that we can be sure we have the string table.902ArrayRef<uint8_t> subsec;903BinaryStreamRef sr = ss.getRecordData();904cantFail(sr.readBytes(0, sr.getLength(), subsec));905advanceRelocIndex(debugChunk, subsec);906frameDataSubsecs.push_back({debugChunk, subsec, nextRelocIndex});907}
908
909static Expected<StringRef>910getFileName(const DebugStringTableSubsectionRef &strings,911const DebugChecksumsSubsectionRef &checksums, uint32_t fileID) {912auto iter = checksums.getArray().at(fileID);913if (iter == checksums.getArray().end())914return make_error<CodeViewError>(cv_error_code::no_records);915uint32_t offset = iter->FileNameOffset;916return strings.getString(offset);917}
918
919void DebugSHandler::finish() {920pdb::DbiStreamBuilder &dbiBuilder = linker.builder.getDbiBuilder();921
922// If we found any symbol records for the module symbol stream, defer them.923if (moduleStreamSize > kSymbolStreamMagicSize)924file.moduleDBI->addUnmergedSymbols(&file, moduleStreamSize -925kSymbolStreamMagicSize);926
927// We should have seen all debug subsections across the entire object file now928// which means that if a StringTable subsection and Checksums subsection were929// present, now is the time to handle them.930if (!cvStrTab.valid()) {931if (checksums.valid())932fatal(".debug$S sections with a checksums subsection must also contain a "933"string table subsection");934
935if (!stringTableFixups.empty())936warn("No StringTable subsection was encountered, but there are string "937"table references");938return;939}940
941ExitOnError exitOnErr;942
943// Handle FPO data. Each subsection begins with a single image base944// relocation, which is then added to the RvaStart of each frame data record945// when it is added to the PDB. The string table indices for the FPO program946// must also be rewritten to use the PDB string table.947for (const UnrelocatedFpoData &subsec : frameDataSubsecs) {948// Relocate the first four bytes of the subection and reinterpret them as a949// 32 bit little-endian integer.950SectionChunk *debugChunk = subsec.debugChunk;951ArrayRef<uint8_t> subsecData = subsec.subsecData;952uint32_t relocIndex = subsec.relocIndex;953auto unrelocatedRvaStart = subsecData.take_front(sizeof(uint32_t));954uint8_t relocatedRvaStart[sizeof(uint32_t)];955debugChunk->writeAndRelocateSubsection(debugChunk->getContents(),956unrelocatedRvaStart, relocIndex,957&relocatedRvaStart[0]);958// Use of memcpy here avoids violating type-based aliasing rules.959support::ulittle32_t rvaStart;960memcpy(&rvaStart, &relocatedRvaStart[0], sizeof(support::ulittle32_t));961
962// Copy each frame data record, add in rvaStart, translate string table963// indices, and add the record to the PDB.964DebugFrameDataSubsectionRef fds;965BinaryStreamReader reader(subsecData, llvm::endianness::little);966exitOnErr(fds.initialize(reader));967for (codeview::FrameData fd : fds) {968fd.RvaStart += rvaStart;969fd.FrameFunc =970translateStringTableIndex(fd.FrameFunc, cvStrTab, linker.pdbStrTab);971dbiBuilder.addNewFpoData(fd);972}973}974
975// Translate the fixups and pass them off to the module builder so they will976// be applied during writing.977for (StringTableFixup &ref : stringTableFixups) {978ref.StrTabOffset =979translateStringTableIndex(ref.StrTabOffset, cvStrTab, linker.pdbStrTab);980}981file.moduleDBI->setStringTableFixups(std::move(stringTableFixups));982
983// Make a new file checksum table that refers to offsets in the PDB-wide984// string table. Generally the string table subsection appears after the985// checksum table, so we have to do this after looping over all the986// subsections. The new checksum table must have the exact same layout and987// size as the original. Otherwise, the file references in the line and988// inlinee line tables will be incorrect.989auto newChecksums = std::make_unique<DebugChecksumsSubsection>(linker.pdbStrTab);990for (const FileChecksumEntry &fc : checksums) {991SmallString<128> filename =992exitOnErr(cvStrTab.getString(fc.FileNameOffset));993linker.pdbMakeAbsolute(filename);994exitOnErr(dbiBuilder.addModuleSourceFile(*file.moduleDBI, filename));995newChecksums->addChecksum(filename, fc.Kind, fc.Checksum);996}997assert(checksums.getArray().getUnderlyingStream().getLength() ==998newChecksums->calculateSerializedSize() &&999"file checksum table must have same layout");1000
1001file.moduleDBI->addDebugSubsection(std::move(newChecksums));1002}
1003
1004static void warnUnusable(InputFile *f, Error e, bool shouldWarn) {1005if (!shouldWarn) {1006consumeError(std::move(e));1007return;1008}1009auto msg = "Cannot use debug info for '" + toString(f) + "' [LNK4099]";1010if (e)1011warn(msg + "\n>>> failed to load reference " + toString(std::move(e)));1012else1013warn(msg);1014}
1015
1016// Allocate memory for a .debug$S / .debug$F section and relocate it.
1017static ArrayRef<uint8_t> relocateDebugChunk(SectionChunk &debugChunk) {1018uint8_t *buffer = bAlloc().Allocate<uint8_t>(debugChunk.getSize());1019assert(debugChunk.getOutputSectionIdx() == 0 &&1020"debug sections should not be in output sections");1021debugChunk.writeTo(buffer);1022return ArrayRef(buffer, debugChunk.getSize());1023}
1024
1025void PDBLinker::addDebugSymbols(TpiSource *source) {1026// If this TpiSource doesn't have an object file, it must be from a type1027// server PDB. Type server PDBs do not contain symbols, so stop here.1028if (!source->file)1029return;1030
1031llvm::TimeTraceScope timeScope("Merge symbols");1032ScopedTimer t(ctx.symbolMergingTimer);1033ExitOnError exitOnErr;1034pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();1035DebugSHandler dsh(*this, *source->file);1036// Now do all live .debug$S and .debug$F sections.1037for (SectionChunk *debugChunk : source->file->getDebugChunks()) {1038if (!debugChunk->live || debugChunk->getSize() == 0)1039continue;1040
1041bool isDebugS = debugChunk->getSectionName() == ".debug$S";1042bool isDebugF = debugChunk->getSectionName() == ".debug$F";1043if (!isDebugS && !isDebugF)1044continue;1045
1046if (isDebugS) {1047dsh.handleDebugS(debugChunk);1048} else if (isDebugF) {1049// Handle old FPO data .debug$F sections. These are relatively rare.1050ArrayRef<uint8_t> relocatedDebugContents =1051relocateDebugChunk(*debugChunk);1052FixedStreamArray<object::FpoData> fpoRecords;1053BinaryStreamReader reader(relocatedDebugContents,1054llvm::endianness::little);1055uint32_t count = relocatedDebugContents.size() / sizeof(object::FpoData);1056exitOnErr(reader.readArray(fpoRecords, count));1057
1058// These are already relocated and don't refer to the string table, so we1059// can just copy it.1060for (const object::FpoData &fd : fpoRecords)1061dbiBuilder.addOldFpoData(fd);1062}1063}1064
1065// Do any post-processing now that all .debug$S sections have been processed.1066dsh.finish();1067}
1068
1069// Add a module descriptor for every object file. We need to put an absolute
1070// path to the object into the PDB. If this is a plain object, we make its
1071// path absolute. If it's an object in an archive, we make the archive path
1072// absolute.
1073void PDBLinker::createModuleDBI(ObjFile *file) {1074pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();1075SmallString<128> objName;1076ExitOnError exitOnErr;1077
1078bool inArchive = !file->parentName.empty();1079objName = inArchive ? file->parentName : file->getName();1080pdbMakeAbsolute(objName);1081StringRef modName = inArchive ? file->getName() : objName.str();1082
1083file->moduleDBI = &exitOnErr(dbiBuilder.addModuleInfo(modName));1084file->moduleDBI->setObjFileName(objName);1085file->moduleDBI->setMergeSymbolsCallback(this, &commitSymbolsForObject);1086
1087ArrayRef<Chunk *> chunks = file->getChunks();1088uint32_t modi = file->moduleDBI->getModuleIndex();1089
1090for (Chunk *c : chunks) {1091auto *secChunk = dyn_cast<SectionChunk>(c);1092if (!secChunk || !secChunk->live)1093continue;1094pdb::SectionContrib sc = createSectionContrib(ctx, secChunk, modi);1095file->moduleDBI->setFirstSectionContrib(sc);1096break;1097}1098}
1099
1100void PDBLinker::addDebug(TpiSource *source) {1101// Before we can process symbol substreams from .debug$S, we need to process1102// type information, file checksums, and the string table. Add type info to1103// the PDB first, so that we can get the map from object file type and item1104// indices to PDB type and item indices. If we are using ghashes, types have1105// already been merged.1106if (!ctx.config.debugGHashes) {1107llvm::TimeTraceScope timeScope("Merge types (Non-GHASH)");1108ScopedTimer t(ctx.typeMergingTimer);1109if (Error e = source->mergeDebugT(&tMerger)) {1110// If type merging failed, ignore the symbols.1111warnUnusable(source->file, std::move(e),1112ctx.config.warnDebugInfoUnusable);1113return;1114}1115}1116
1117// If type merging failed, ignore the symbols.1118Error typeError = std::move(source->typeMergingError);1119if (typeError) {1120warnUnusable(source->file, std::move(typeError),1121ctx.config.warnDebugInfoUnusable);1122return;1123}1124
1125addDebugSymbols(source);1126}
1127
1128static pdb::BulkPublic createPublic(COFFLinkerContext &ctx, Defined *def) {1129pdb::BulkPublic pub;1130pub.Name = def->getName().data();1131pub.NameLen = def->getName().size();1132
1133PublicSymFlags flags = PublicSymFlags::None;1134if (auto *d = dyn_cast<DefinedCOFF>(def)) {1135if (d->getCOFFSymbol().isFunctionDefinition())1136flags = PublicSymFlags::Function;1137} else if (isa<DefinedImportThunk>(def)) {1138flags = PublicSymFlags::Function;1139}1140pub.setFlags(flags);1141
1142OutputSection *os = ctx.getOutputSection(def->getChunk());1143assert(os && "all publics should be in final image");1144pub.Offset = def->getRVA() - os->getRVA();1145pub.Segment = os->sectionIndex;1146return pub;1147}
1148
1149// Add all object files to the PDB. Merge .debug$T sections into IpiData and
1150// TpiData.
1151void PDBLinker::addObjectsToPDB() {1152{1153llvm::TimeTraceScope timeScope("Add objects to PDB");1154ScopedTimer t1(ctx.addObjectsTimer);1155
1156// Create module descriptors1157for (ObjFile *obj : ctx.objFileInstances)1158createModuleDBI(obj);1159
1160// Reorder dependency type sources to come first.1161tMerger.sortDependencies();1162
1163// Merge type information from input files using global type hashing.1164if (ctx.config.debugGHashes)1165tMerger.mergeTypesWithGHash();1166
1167// Merge dependencies and then regular objects.1168{1169llvm::TimeTraceScope timeScope("Merge debug info (dependencies)");1170for (TpiSource *source : tMerger.dependencySources)1171addDebug(source);1172}1173{1174llvm::TimeTraceScope timeScope("Merge debug info (objects)");1175for (TpiSource *source : tMerger.objectSources)1176addDebug(source);1177}1178
1179builder.getStringTableBuilder().setStrings(pdbStrTab);1180}1181
1182// Construct TPI and IPI stream contents.1183{1184llvm::TimeTraceScope timeScope("TPI/IPI stream layout");1185ScopedTimer t2(ctx.tpiStreamLayoutTimer);1186
1187// Collect all the merged types.1188if (ctx.config.debugGHashes) {1189addGHashTypeInfo(ctx, builder);1190} else {1191addTypeInfo(builder.getTpiBuilder(), tMerger.getTypeTable());1192addTypeInfo(builder.getIpiBuilder(), tMerger.getIDTable());1193}1194}1195
1196if (ctx.config.showSummary) {1197for (TpiSource *source : ctx.tpiSourceList) {1198nbTypeRecords += source->nbTypeRecords;1199nbTypeRecordsBytes += source->nbTypeRecordsBytes;1200}1201}1202}
1203
1204void PDBLinker::addPublicsToPDB() {1205llvm::TimeTraceScope timeScope("Publics layout");1206ScopedTimer t3(ctx.publicsLayoutTimer);1207// Compute the public symbols.1208auto &gsiBuilder = builder.getGsiBuilder();1209std::vector<pdb::BulkPublic> publics;1210ctx.symtab.forEachSymbol([&publics, this](Symbol *s) {1211// Only emit external, defined, live symbols that have a chunk. Static,1212// non-external symbols do not appear in the symbol table.1213auto *def = dyn_cast<Defined>(s);1214if (def && def->isLive() && def->getChunk()) {1215// Don't emit a public symbol for coverage data symbols. LLVM code1216// coverage (and PGO) create a __profd_ and __profc_ symbol for every1217// function. C++ mangled names are long, and tend to dominate symbol size.1218// Including these names triples the size of the public stream, which1219// results in bloated PDB files. These symbols generally are not helpful1220// for debugging, so suppress them.1221StringRef name = def->getName();1222if (name.data()[0] == '_' && name.data()[1] == '_') {1223// Drop the '_' prefix for x86.1224if (ctx.config.machine == I386)1225name = name.drop_front(1);1226if (name.starts_with("__profd_") || name.starts_with("__profc_") ||1227name.starts_with("__covrec_")) {1228return;1229}1230}1231publics.push_back(createPublic(ctx, def));1232}1233});1234
1235if (!publics.empty()) {1236publicSymbols = publics.size();1237gsiBuilder.addPublicSymbols(std::move(publics));1238}1239}
1240
1241void PDBLinker::printStats() {1242if (!ctx.config.showSummary)1243return;1244
1245SmallString<256> buffer;1246raw_svector_ostream stream(buffer);1247
1248stream << center_justify("Summary", 80) << '\n'1249<< std::string(80, '-') << '\n';1250
1251auto print = [&](uint64_t v, StringRef s) {1252stream << format_decimal(v, 15) << " " << s << '\n';1253};1254
1255print(ctx.objFileInstances.size(),1256"Input OBJ files (expanded from all cmd-line inputs)");1257print(ctx.typeServerSourceMappings.size(), "PDB type server dependencies");1258print(ctx.precompSourceMappings.size(), "Precomp OBJ dependencies");1259print(nbTypeRecords, "Input type records");1260print(nbTypeRecordsBytes, "Input type records bytes");1261print(builder.getTpiBuilder().getRecordCount(), "Merged TPI records");1262print(builder.getIpiBuilder().getRecordCount(), "Merged IPI records");1263print(pdbStrTab.size(), "Output PDB strings");1264print(globalSymbols, "Global symbol records");1265print(moduleSymbols, "Module symbol records");1266print(publicSymbols, "Public symbol records");1267
1268auto printLargeInputTypeRecs = [&](StringRef name,1269ArrayRef<uint32_t> recCounts,1270TypeCollection &records) {1271// Figure out which type indices were responsible for the most duplicate1272// bytes in the input files. These should be frequently emitted LF_CLASS and1273// LF_FIELDLIST records.1274struct TypeSizeInfo {1275uint32_t typeSize;1276uint32_t dupCount;1277TypeIndex typeIndex;1278uint64_t totalInputSize() const { return uint64_t(dupCount) * typeSize; }1279bool operator<(const TypeSizeInfo &rhs) const {1280if (totalInputSize() == rhs.totalInputSize())1281return typeIndex < rhs.typeIndex;1282return totalInputSize() < rhs.totalInputSize();1283}1284};1285SmallVector<TypeSizeInfo, 0> tsis;1286for (auto e : enumerate(recCounts)) {1287TypeIndex typeIndex = TypeIndex::fromArrayIndex(e.index());1288uint32_t typeSize = records.getType(typeIndex).length();1289uint32_t dupCount = e.value();1290tsis.push_back({typeSize, dupCount, typeIndex});1291}1292
1293if (!tsis.empty()) {1294stream << "\nTop 10 types responsible for the most " << name1295<< " input:\n";1296stream << " index total bytes count size\n";1297llvm::sort(tsis);1298unsigned i = 0;1299for (const auto &tsi : reverse(tsis)) {1300stream << formatv(" {0,10:X}: {1,14:N} = {2,5:N} * {3,6:N}\n",1301tsi.typeIndex.getIndex(), tsi.totalInputSize(),1302tsi.dupCount, tsi.typeSize);1303if (++i >= 10)1304break;1305}1306stream
1307<< "Run llvm-pdbutil to print details about a particular record:\n";1308stream << formatv("llvm-pdbutil dump -{0}s -{0}-index {1:X} {2}\n",1309(name == "TPI" ? "type" : "id"),1310tsis.back().typeIndex.getIndex(), ctx.config.pdbPath);1311}1312};1313
1314if (!ctx.config.debugGHashes) {1315// FIXME: Reimplement for ghash.1316printLargeInputTypeRecs("TPI", tMerger.tpiCounts, tMerger.getTypeTable());1317printLargeInputTypeRecs("IPI", tMerger.ipiCounts, tMerger.getIDTable());1318}1319
1320message(buffer);1321}
1322
1323void PDBLinker::addNatvisFiles() {1324llvm::TimeTraceScope timeScope("Natvis files");1325for (StringRef file : ctx.config.natvisFiles) {1326ErrorOr<std::unique_ptr<MemoryBuffer>> dataOrErr =1327MemoryBuffer::getFile(file);1328if (!dataOrErr) {1329warn("Cannot open input file: " + file);1330continue;1331}1332std::unique_ptr<MemoryBuffer> data = std::move(*dataOrErr);1333
1334// Can't use takeBuffer() here since addInjectedSource() takes ownership.1335if (ctx.driver.tar)1336ctx.driver.tar->append(relativeToRoot(data->getBufferIdentifier()),1337data->getBuffer());1338
1339builder.addInjectedSource(file, std::move(data));1340}1341}
1342
1343void PDBLinker::addNamedStreams() {1344llvm::TimeTraceScope timeScope("Named streams");1345ExitOnError exitOnErr;1346for (const auto &streamFile : ctx.config.namedStreams) {1347const StringRef stream = streamFile.getKey(), file = streamFile.getValue();1348ErrorOr<std::unique_ptr<MemoryBuffer>> dataOrErr =1349MemoryBuffer::getFile(file);1350if (!dataOrErr) {1351warn("Cannot open input file: " + file);1352continue;1353}1354std::unique_ptr<MemoryBuffer> data = std::move(*dataOrErr);1355exitOnErr(builder.addNamedStream(stream, data->getBuffer()));1356ctx.driver.takeBuffer(std::move(data));1357}1358}
1359
1360static codeview::CPUType toCodeViewMachine(COFF::MachineTypes machine) {1361switch (machine) {1362case COFF::IMAGE_FILE_MACHINE_AMD64:1363return codeview::CPUType::X64;1364case COFF::IMAGE_FILE_MACHINE_ARM:1365return codeview::CPUType::ARM7;1366case COFF::IMAGE_FILE_MACHINE_ARM64:1367return codeview::CPUType::ARM64;1368case COFF::IMAGE_FILE_MACHINE_ARMNT:1369return codeview::CPUType::ARMNT;1370case COFF::IMAGE_FILE_MACHINE_I386:1371return codeview::CPUType::Intel80386;1372default:1373llvm_unreachable("Unsupported CPU Type");1374}1375}
1376
1377// Mimic MSVC which surrounds arguments containing whitespace with quotes.
1378// Double double-quotes are handled, so that the resulting string can be
1379// executed again on the cmd-line.
1380static std::string quote(ArrayRef<StringRef> args) {1381std::string r;1382r.reserve(256);1383for (StringRef a : args) {1384if (!r.empty())1385r.push_back(' ');1386bool hasWS = a.contains(' ');1387bool hasQ = a.contains('"');1388if (hasWS || hasQ)1389r.push_back('"');1390if (hasQ) {1391SmallVector<StringRef, 4> s;1392a.split(s, '"');1393r.append(join(s, "\"\""));1394} else {1395r.append(std::string(a));1396}1397if (hasWS || hasQ)1398r.push_back('"');1399}1400return r;1401}
1402
1403static void fillLinkerVerRecord(Compile3Sym &cs, MachineTypes machine) {1404cs.Machine = toCodeViewMachine(machine);1405// Interestingly, if we set the string to 0.0.0.0, then when trying to view1406// local variables WinDbg emits an error that private symbols are not present.1407// By setting this to a valid MSVC linker version string, local variables are1408// displayed properly. As such, even though it is not representative of1409// LLVM's version information, we need this for compatibility.1410cs.Flags = CompileSym3Flags::None;1411cs.VersionBackendBuild = 25019;1412cs.VersionBackendMajor = 14;1413cs.VersionBackendMinor = 10;1414cs.VersionBackendQFE = 0;1415
1416// MSVC also sets the frontend to 0.0.0.0 since this is specifically for the1417// linker module (which is by definition a backend), so we don't need to do1418// anything here. Also, it seems we can use "LLVM Linker" for the linker name1419// without any problems. Only the backend version has to be hardcoded to a1420// magic number.1421cs.VersionFrontendBuild = 0;1422cs.VersionFrontendMajor = 0;1423cs.VersionFrontendMinor = 0;1424cs.VersionFrontendQFE = 0;1425cs.Version = "LLVM Linker";1426cs.setLanguage(SourceLanguage::Link);1427}
1428
1429void PDBLinker::addCommonLinkerModuleSymbols(1430StringRef path, pdb::DbiModuleDescriptorBuilder &mod) {1431ObjNameSym ons(SymbolRecordKind::ObjNameSym);1432EnvBlockSym ebs(SymbolRecordKind::EnvBlockSym);1433Compile3Sym cs(SymbolRecordKind::Compile3Sym);1434fillLinkerVerRecord(cs, ctx.config.machine);1435
1436ons.Name = "* Linker *";1437ons.Signature = 0;1438
1439ArrayRef<StringRef> args = ArrayRef(ctx.config.argv).drop_front();1440std::string argStr = quote(args);1441ebs.Fields.push_back("cwd");1442SmallString<64> cwd;1443if (ctx.config.pdbSourcePath.empty())1444sys::fs::current_path(cwd);1445else1446cwd = ctx.config.pdbSourcePath;1447ebs.Fields.push_back(cwd);1448ebs.Fields.push_back("exe");1449SmallString<64> exe = ctx.config.argv[0];1450pdbMakeAbsolute(exe);1451ebs.Fields.push_back(exe);1452ebs.Fields.push_back("pdb");1453ebs.Fields.push_back(path);1454ebs.Fields.push_back("cmd");1455ebs.Fields.push_back(argStr);1456llvm::BumpPtrAllocator &bAlloc = lld::bAlloc();1457mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(1458ons, bAlloc, CodeViewContainer::Pdb));1459mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(1460cs, bAlloc, CodeViewContainer::Pdb));1461mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(1462ebs, bAlloc, CodeViewContainer::Pdb));1463}
1464
1465static void addLinkerModuleCoffGroup(PartialSection *sec,1466pdb::DbiModuleDescriptorBuilder &mod,1467OutputSection &os) {1468// If there's a section, there's at least one chunk1469assert(!sec->chunks.empty());1470const Chunk *firstChunk = *sec->chunks.begin();1471const Chunk *lastChunk = *sec->chunks.rbegin();1472
1473// Emit COFF group1474CoffGroupSym cgs(SymbolRecordKind::CoffGroupSym);1475cgs.Name = sec->name;1476cgs.Segment = os.sectionIndex;1477cgs.Offset = firstChunk->getRVA() - os.getRVA();1478cgs.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA();1479cgs.Characteristics = sec->characteristics;1480
1481// Somehow .idata sections & sections groups in the debug symbol stream have1482// the "write" flag set. However the section header for the corresponding1483// .idata section doesn't have it.1484if (cgs.Name.starts_with(".idata"))1485cgs.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE;1486
1487mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(1488cgs, bAlloc(), CodeViewContainer::Pdb));1489}
1490
1491static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &mod,1492OutputSection &os, bool isMinGW) {1493SectionSym sym(SymbolRecordKind::SectionSym);1494sym.Alignment = 12; // 2^12 = 4KB1495sym.Characteristics = os.header.Characteristics;1496sym.Length = os.getVirtualSize();1497sym.Name = os.name;1498sym.Rva = os.getRVA();1499sym.SectionNumber = os.sectionIndex;1500mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(1501sym, bAlloc(), CodeViewContainer::Pdb));1502
1503// Skip COFF groups in MinGW because it adds a significant footprint to the1504// PDB, due to each function being in its own section1505if (isMinGW)1506return;1507
1508// Output COFF groups for individual chunks of this section.1509for (PartialSection *sec : os.contribSections) {1510addLinkerModuleCoffGroup(sec, mod, os);1511}1512}
1513
1514// Add all import files as modules to the PDB.
1515void PDBLinker::addImportFilesToPDB() {1516if (ctx.importFileInstances.empty())1517return;1518
1519llvm::TimeTraceScope timeScope("Import files");1520ExitOnError exitOnErr;1521std::map<std::string, llvm::pdb::DbiModuleDescriptorBuilder *> dllToModuleDbi;1522
1523for (ImportFile *file : ctx.importFileInstances) {1524if (!file->live)1525continue;1526
1527if (!file->thunkSym)1528continue;1529
1530if (!file->thunkLive)1531continue;1532
1533std::string dll = StringRef(file->dllName).lower();1534llvm::pdb::DbiModuleDescriptorBuilder *&mod = dllToModuleDbi[dll];1535if (!mod) {1536pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();1537SmallString<128> libPath = file->parentName;1538pdbMakeAbsolute(libPath);1539sys::path::native(libPath);1540
1541// Name modules similar to MSVC's link.exe.1542// The first module is the simple dll filename1543llvm::pdb::DbiModuleDescriptorBuilder &firstMod =1544exitOnErr(dbiBuilder.addModuleInfo(file->dllName));1545firstMod.setObjFileName(libPath);1546pdb::SectionContrib sc =1547createSectionContrib(ctx, nullptr, llvm::pdb::kInvalidStreamIndex);1548firstMod.setFirstSectionContrib(sc);1549
1550// The second module is where the import stream goes.1551mod = &exitOnErr(dbiBuilder.addModuleInfo("Import:" + file->dllName));1552mod->setObjFileName(libPath);1553}1554
1555DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);1556Chunk *thunkChunk = thunk->getChunk();1557OutputSection *thunkOS = ctx.getOutputSection(thunkChunk);1558
1559ObjNameSym ons(SymbolRecordKind::ObjNameSym);1560Compile3Sym cs(SymbolRecordKind::Compile3Sym);1561Thunk32Sym ts(SymbolRecordKind::Thunk32Sym);1562ScopeEndSym es(SymbolRecordKind::ScopeEndSym);1563
1564ons.Name = file->dllName;1565ons.Signature = 0;1566
1567fillLinkerVerRecord(cs, ctx.config.machine);1568
1569ts.Name = thunk->getName();1570ts.Parent = 0;1571ts.End = 0;1572ts.Next = 0;1573ts.Thunk = ThunkOrdinal::Standard;1574ts.Length = thunkChunk->getSize();1575ts.Segment = thunkOS->sectionIndex;1576ts.Offset = thunkChunk->getRVA() - thunkOS->getRVA();1577
1578llvm::BumpPtrAllocator &bAlloc = lld::bAlloc();1579mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(1580ons, bAlloc, CodeViewContainer::Pdb));1581mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(1582cs, bAlloc, CodeViewContainer::Pdb));1583
1584CVSymbol newSym = codeview::SymbolSerializer::writeOneSymbol(1585ts, bAlloc, CodeViewContainer::Pdb);1586
1587// Write ptrEnd for the S_THUNK32.1588ScopeRecord *thunkSymScope =1589getSymbolScopeFields(const_cast<uint8_t *>(newSym.data().data()));1590
1591mod->addSymbol(newSym);1592
1593newSym = codeview::SymbolSerializer::writeOneSymbol(es, bAlloc,1594CodeViewContainer::Pdb);1595thunkSymScope->ptrEnd = mod->getNextSymbolOffset();1596
1597mod->addSymbol(newSym);1598
1599pdb::SectionContrib sc =1600createSectionContrib(ctx, thunk->getChunk(), mod->getModuleIndex());1601mod->setFirstSectionContrib(sc);1602}1603}
1604
1605// Creates a PDB file.
1606void lld::coff::createPDB(COFFLinkerContext &ctx,1607ArrayRef<uint8_t> sectionTable,1608llvm::codeview::DebugInfo *buildId) {1609llvm::TimeTraceScope timeScope("PDB file");1610ScopedTimer t1(ctx.totalPdbLinkTimer);1611{1612PDBLinker pdb(ctx);1613
1614pdb.initialize(buildId);1615pdb.addObjectsToPDB();1616pdb.addImportFilesToPDB();1617pdb.addSections(sectionTable);1618pdb.addNatvisFiles();1619pdb.addNamedStreams();1620pdb.addPublicsToPDB();1621
1622{1623llvm::TimeTraceScope timeScope("Commit PDB file to disk");1624ScopedTimer t2(ctx.diskCommitTimer);1625codeview::GUID guid;1626pdb.commit(&guid);1627memcpy(&buildId->PDB70.Signature, &guid, 16);1628}1629
1630t1.stop();1631pdb.printStats();1632
1633// Manually start this profile point to measure ~PDBLinker().1634if (getTimeTraceProfilerInstance() != nullptr)1635timeTraceProfilerBegin("PDBLinker destructor", StringRef(""));1636}1637// Manually end this profile point to measure ~PDBLinker().1638if (getTimeTraceProfilerInstance() != nullptr)1639timeTraceProfilerEnd();1640}
1641
1642void PDBLinker::initialize(llvm::codeview::DebugInfo *buildId) {1643ExitOnError exitOnErr;1644exitOnErr(builder.initialize(ctx.config.pdbPageSize));1645
1646buildId->Signature.CVSignature = OMF::Signature::PDB70;1647// Signature is set to a hash of the PDB contents when the PDB is done.1648memset(buildId->PDB70.Signature, 0, 16);1649buildId->PDB70.Age = 1;1650
1651// Create streams in MSF for predefined streams, namely1652// PDB, TPI, DBI and IPI.1653for (int i = 0; i < (int)pdb::kSpecialStreamCount; ++i)1654exitOnErr(builder.getMsfBuilder().addStream(0));1655
1656// Add an Info stream.1657auto &infoBuilder = builder.getInfoBuilder();1658infoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);1659infoBuilder.setHashPDBContentsToGUID(true);1660
1661// Add an empty DBI stream.1662pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();1663dbiBuilder.setAge(buildId->PDB70.Age);1664dbiBuilder.setVersionHeader(pdb::PdbDbiV70);1665dbiBuilder.setMachineType(ctx.config.machine);1666// Technically we are not link.exe 14.11, but there are known cases where1667// debugging tools on Windows expect Microsoft-specific version numbers or1668// they fail to work at all. Since we know we produce PDBs that are1669// compatible with LINK 14.11, we set that version number here.1670dbiBuilder.setBuildNumber(14, 11);1671}
1672
1673void PDBLinker::addSections(ArrayRef<uint8_t> sectionTable) {1674llvm::TimeTraceScope timeScope("PDB output sections");1675ExitOnError exitOnErr;1676// It's not entirely clear what this is, but the * Linker * module uses it.1677pdb::DbiStreamBuilder &dbiBuilder = builder.getDbiBuilder();1678nativePath = ctx.config.pdbPath;1679pdbMakeAbsolute(nativePath);1680uint32_t pdbFilePathNI = dbiBuilder.addECName(nativePath);1681auto &linkerModule = exitOnErr(dbiBuilder.addModuleInfo("* Linker *"));1682linkerModule.setPdbFilePathNI(pdbFilePathNI);1683addCommonLinkerModuleSymbols(nativePath, linkerModule);1684
1685// Add section contributions. They must be ordered by ascending RVA.1686for (OutputSection *os : ctx.outputSections) {1687addLinkerModuleSectionSymbol(linkerModule, *os, ctx.config.mingw);1688for (Chunk *c : os->chunks) {1689pdb::SectionContrib sc =1690createSectionContrib(ctx, c, linkerModule.getModuleIndex());1691builder.getDbiBuilder().addSectionContrib(sc);1692}1693}1694
1695// The * Linker * first section contrib is only used along with /INCREMENTAL,1696// to provide trampolines thunks for incremental function patching. Set this1697// as "unused" because LLD doesn't support /INCREMENTAL link.1698pdb::SectionContrib sc =1699createSectionContrib(ctx, nullptr, llvm::pdb::kInvalidStreamIndex);1700linkerModule.setFirstSectionContrib(sc);1701
1702// Add Section Map stream.1703ArrayRef<object::coff_section> sections = {1704(const object::coff_section *)sectionTable.data(),1705sectionTable.size() / sizeof(object::coff_section)};1706dbiBuilder.createSectionMap(sections);1707
1708// Add COFF section header stream.1709exitOnErr(1710dbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, sectionTable));1711}
1712
1713void PDBLinker::commit(codeview::GUID *guid) {1714// Print an error and continue if PDB writing fails. This is done mainly so1715// the user can see the output of /time and /summary, which is very helpful1716// when trying to figure out why a PDB file is too large.1717if (Error e = builder.commit(ctx.config.pdbPath, guid)) {1718e = handleErrors(std::move(e),1719[](const llvm::msf::MSFError &me) {1720error(me.message());1721if (me.isPageOverflow())1722error("try setting a larger /pdbpagesize");1723});1724checkError(std::move(e));1725error("failed to write PDB file " + Twine(ctx.config.pdbPath));1726}1727}
1728
1729static uint32_t getSecrelReloc(Triple::ArchType arch) {1730switch (arch) {1731case Triple::x86_64:1732return COFF::IMAGE_REL_AMD64_SECREL;1733case Triple::x86:1734return COFF::IMAGE_REL_I386_SECREL;1735case Triple::thumb:1736return COFF::IMAGE_REL_ARM_SECREL;1737case Triple::aarch64:1738return COFF::IMAGE_REL_ARM64_SECREL;1739default:1740llvm_unreachable("unknown machine type");1741}1742}
1743
1744// Try to find a line table for the given offset Addr into the given chunk C.
1745// If a line table was found, the line table, the string and checksum tables
1746// that are used to interpret the line table, and the offset of Addr in the line
1747// table are stored in the output arguments. Returns whether a line table was
1748// found.
1749static bool findLineTable(const SectionChunk *c, uint32_t addr,1750DebugStringTableSubsectionRef &cvStrTab,1751DebugChecksumsSubsectionRef &checksums,1752DebugLinesSubsectionRef &lines,1753uint32_t &offsetInLinetable) {1754ExitOnError exitOnErr;1755const uint32_t secrelReloc = getSecrelReloc(c->getArch());1756
1757for (SectionChunk *dbgC : c->file->getDebugChunks()) {1758if (dbgC->getSectionName() != ".debug$S")1759continue;1760
1761// Build a mapping of SECREL relocations in dbgC that refer to `c`.1762DenseMap<uint32_t, uint32_t> secrels;1763for (const coff_relocation &r : dbgC->getRelocs()) {1764if (r.Type != secrelReloc)1765continue;1766
1767if (auto *s = dyn_cast_or_null<DefinedRegular>(1768c->file->getSymbols()[r.SymbolTableIndex]))1769if (s->getChunk() == c)1770secrels[r.VirtualAddress] = s->getValue();1771}1772
1773ArrayRef<uint8_t> contents =1774SectionChunk::consumeDebugMagic(dbgC->getContents(), ".debug$S");1775DebugSubsectionArray subsections;1776BinaryStreamReader reader(contents, llvm::endianness::little);1777exitOnErr(reader.readArray(subsections, contents.size()));1778
1779for (const DebugSubsectionRecord &ss : subsections) {1780switch (ss.kind()) {1781case DebugSubsectionKind::StringTable: {1782assert(!cvStrTab.valid() &&1783"Encountered multiple string table subsections!");1784exitOnErr(cvStrTab.initialize(ss.getRecordData()));1785break;1786}1787case DebugSubsectionKind::FileChecksums:1788assert(!checksums.valid() &&1789"Encountered multiple checksum subsections!");1790exitOnErr(checksums.initialize(ss.getRecordData()));1791break;1792case DebugSubsectionKind::Lines: {1793ArrayRef<uint8_t> bytes;1794auto ref = ss.getRecordData();1795exitOnErr(ref.readLongestContiguousChunk(0, bytes));1796size_t offsetInDbgC = bytes.data() - dbgC->getContents().data();1797
1798// Check whether this line table refers to C.1799auto i = secrels.find(offsetInDbgC);1800if (i == secrels.end())1801break;1802
1803// Check whether this line table covers Addr in C.1804DebugLinesSubsectionRef linesTmp;1805exitOnErr(linesTmp.initialize(BinaryStreamReader(ref)));1806uint32_t offsetInC = i->second + linesTmp.header()->RelocOffset;1807if (addr < offsetInC || addr >= offsetInC + linesTmp.header()->CodeSize)1808break;1809
1810assert(!lines.header() &&1811"Encountered multiple line tables for function!");1812exitOnErr(lines.initialize(BinaryStreamReader(ref)));1813offsetInLinetable = addr - offsetInC;1814break;1815}1816default:1817break;1818}1819
1820if (cvStrTab.valid() && checksums.valid() && lines.header())1821return true;1822}1823}1824
1825return false;1826}
1827
1828// Use CodeView line tables to resolve a file and line number for the given
1829// offset into the given chunk and return them, or std::nullopt if a line table
1830// was not found.
1831std::optional<std::pair<StringRef, uint32_t>>1832lld::coff::getFileLineCodeView(const SectionChunk *c, uint32_t addr) {1833ExitOnError exitOnErr;1834
1835DebugStringTableSubsectionRef cvStrTab;1836DebugChecksumsSubsectionRef checksums;1837DebugLinesSubsectionRef lines;1838uint32_t offsetInLinetable;1839
1840if (!findLineTable(c, addr, cvStrTab, checksums, lines, offsetInLinetable))1841return std::nullopt;1842
1843std::optional<uint32_t> nameIndex;1844std::optional<uint32_t> lineNumber;1845for (const LineColumnEntry &entry : lines) {1846for (const LineNumberEntry &ln : entry.LineNumbers) {1847LineInfo li(ln.Flags);1848if (ln.Offset > offsetInLinetable) {1849if (!nameIndex) {1850nameIndex = entry.NameIndex;1851lineNumber = li.getStartLine();1852}1853StringRef filename =1854exitOnErr(getFileName(cvStrTab, checksums, *nameIndex));1855return std::make_pair(filename, *lineNumber);1856}1857nameIndex = entry.NameIndex;1858lineNumber = li.getStartLine();1859}1860}1861if (!nameIndex)1862return std::nullopt;1863StringRef filename = exitOnErr(getFileName(cvStrTab, checksums, *nameIndex));1864return std::make_pair(filename, *lineNumber);1865}
1866