summaryrefslogtreecommitdiffstats
path: root/lld/COFF/PDB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/COFF/PDB.cpp')
-rw-r--r--lld/COFF/PDB.cpp148
1 files changed, 136 insertions, 12 deletions
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index bf1438e7407..b69eac8aac6 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -109,6 +109,9 @@ public:
/// Link CodeView from each object file in the symbol table into the PDB.
void addObjectsToPDB();
+ /// Link info for each import file in the symbol table into the PDB.
+ void addImportFilesToPDB(ArrayRef<OutputSection *> OutputSections);
+
/// Link CodeView from a single object file into the target (output) PDB.
/// When a precompiled headers object is linked, its TPI map might be provided
/// externally.
@@ -878,7 +881,7 @@ static void scopeStackOpen(SmallVectorImpl<SymbolScope> &Stack,
}
static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,
- uint32_t CurOffset, ObjFile *File) {
+ uint32_t CurOffset, InputFile *File) {
if (Stack.empty()) {
warn("symbol scopes are not balanced in " + File->getName());
return;
@@ -1104,7 +1107,6 @@ static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) {
SC.DataCrc = CRC.getCRC();
} else {
SC.Characteristics = OS ? OS->Header.Characteristics : 0;
- // FIXME: When we start creating DBI for import libraries, use those here.
SC.Imod = Modi;
}
SC.RelocCrc = 0; // FIXME
@@ -1454,16 +1456,7 @@ static std::string quote(ArrayRef<StringRef> Args) {
return R;
}
-static void addCommonLinkerModuleSymbols(StringRef Path,
- pdb::DbiModuleDescriptorBuilder &Mod,
- BumpPtrAllocator &Allocator) {
- ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
- Compile3Sym CS(SymbolRecordKind::Compile3Sym);
- EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym);
-
- ONS.Name = "* Linker *";
- ONS.Signature = 0;
-
+static void fillLinkerVerRecord(Compile3Sym &CS) {
CS.Machine = toCodeViewMachine(Config->Machine);
// Interestingly, if we set the string to 0.0.0.0, then when trying to view
// local variables WinDbg emits an error that private symbols are not present.
@@ -1487,6 +1480,18 @@ static void addCommonLinkerModuleSymbols(StringRef Path,
CS.VersionFrontendQFE = 0;
CS.Version = "LLVM Linker";
CS.setLanguage(SourceLanguage::Link);
+}
+
+static void addCommonLinkerModuleSymbols(StringRef Path,
+ pdb::DbiModuleDescriptorBuilder &Mod,
+ BumpPtrAllocator &Allocator) {
+ ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
+ EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym);
+ Compile3Sym CS(SymbolRecordKind::Compile3Sym);
+ fillLinkerVerRecord(CS);
+
+ ONS.Name = "* Linker *";
+ ONS.Signature = 0;
ArrayRef<StringRef> Args = makeArrayRef(Config->Argv).drop_front();
std::string ArgStr = quote(Args);
@@ -1513,6 +1518,33 @@ static void addCommonLinkerModuleSymbols(StringRef Path,
EBS, Allocator, CodeViewContainer::Pdb));
}
+static void addLinkerModuleCoffGroup(PartialSection *Sec,
+ pdb::DbiModuleDescriptorBuilder &Mod,
+ OutputSection &OS,
+ BumpPtrAllocator &Allocator) {
+ // If there's a section, there's at least one chunk
+ assert(!Sec->Chunks.empty());
+ const Chunk *firstChunk = *Sec->Chunks.begin();
+ const Chunk *lastChunk = *Sec->Chunks.rbegin();
+
+ // Emit COFF group
+ CoffGroupSym CGS(SymbolRecordKind::CoffGroupSym);
+ CGS.Name = Sec->Name;
+ CGS.Segment = OS.SectionIndex;
+ CGS.Offset = firstChunk->getRVA() - OS.getRVA();
+ CGS.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA();
+ CGS.Characteristics = Sec->Characteristics;
+
+ // Somehow .idata sections & sections groups in the debug symbol stream have
+ // the "write" flag set. However the section header for the corresponding
+ // .idata section doesn't have it.
+ if (CGS.Name.startswith(".idata"))
+ CGS.Characteristics |= llvm::COFF::IMAGE_SCN_MEM_WRITE;
+
+ Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
+ CGS, Allocator, CodeViewContainer::Pdb));
+}
+
static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
OutputSection &OS,
BumpPtrAllocator &Allocator) {
@@ -1525,6 +1557,97 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
Sym.SectionNumber = OS.SectionIndex;
Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
Sym, Allocator, CodeViewContainer::Pdb));
+
+ // Skip COFF groups in MinGW because it adds a significant footprint to the
+ // PDB, due to each function being in its own section
+ if (Config->MinGW)
+ return;
+
+ // Output COFF groups for individual chunks of this section.
+ for (PartialSection *Sec : OS.ContribSections) {
+ addLinkerModuleCoffGroup(Sec, Mod, OS, Allocator);
+ }
+}
+
+// Add all import files as modules to the PDB.
+void PDBLinker::addImportFilesToPDB(ArrayRef<OutputSection *> OutputSections) {
+ if (ImportFile::Instances.empty())
+ return;
+
+ std::map<std::string, llvm::pdb::DbiModuleDescriptorBuilder *> DllToModuleDbi;
+
+ for (ImportFile *File : ImportFile::Instances) {
+ if (!File->Live)
+ continue;
+
+ if (!File->ThunkSym)
+ continue;
+
+ std::string DLL = StringRef(File->DLLName).lower();
+ llvm::pdb::DbiModuleDescriptorBuilder *&Mod = DllToModuleDbi[DLL];
+ if (!Mod) {
+ pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
+ SmallString<128> LibPath = File->ParentName;
+ pdbMakeAbsolute(LibPath);
+ sys::path::native(LibPath);
+
+ // Name modules similar to MSVC's link.exe.
+ // The first module is the simple dll filename
+ llvm::pdb::DbiModuleDescriptorBuilder &FirstMod =
+ ExitOnErr(DbiBuilder.addModuleInfo(File->DLLName));
+ FirstMod.setObjFileName(LibPath);
+ pdb::SectionContrib SC =
+ createSectionContrib(nullptr, llvm::pdb::kInvalidStreamIndex);
+ FirstMod.setFirstSectionContrib(SC);
+
+ // The second module is where the import stream goes.
+ Mod = &ExitOnErr(DbiBuilder.addModuleInfo("Import:" + File->DLLName));
+ Mod->setObjFileName(LibPath);
+ }
+
+ DefinedImportThunk *Thunk = cast<DefinedImportThunk>(File->ThunkSym);
+
+ ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
+ Compile3Sym CS(SymbolRecordKind::Compile3Sym);
+ Thunk32Sym TS(SymbolRecordKind::Thunk32Sym);
+ ScopeEndSym ES(SymbolRecordKind::ScopeEndSym);
+
+ ONS.Name = File->DLLName;
+ ONS.Signature = 0;
+
+ fillLinkerVerRecord(CS);
+
+ TS.Name = Thunk->getName();
+ TS.Parent = 0;
+ TS.End = 0;
+ TS.Next = 0;
+ TS.Thunk = ThunkOrdinal::Standard;
+ TS.Length = Thunk->getChunk()->getSize();
+ TS.Segment = Thunk->getChunk()->getOutputSection()->SectionIndex;
+ TS.Offset = Thunk->getChunk()->OutputSectionOff;
+
+ Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
+ ONS, Alloc, CodeViewContainer::Pdb));
+ Mod->addSymbol(codeview::SymbolSerializer::writeOneSymbol(
+ CS, Alloc, CodeViewContainer::Pdb));
+
+ SmallVector<SymbolScope, 4> Scopes;
+ CVSymbol NewSym = codeview::SymbolSerializer::writeOneSymbol(
+ TS, Alloc, CodeViewContainer::Pdb);
+ scopeStackOpen(Scopes, Mod->getNextSymbolOffset(), NewSym);
+
+ Mod->addSymbol(NewSym);
+
+ NewSym = codeview::SymbolSerializer::writeOneSymbol(ES, Alloc,
+ CodeViewContainer::Pdb);
+ scopeStackClose(Scopes, Mod->getNextSymbolOffset(), File);
+
+ Mod->addSymbol(NewSym);
+
+ pdb::SectionContrib SC =
+ createSectionContrib(Thunk->getChunk(), Mod->getModuleIndex());
+ Mod->setFirstSectionContrib(SC);
+ }
}
// Creates a PDB file.
@@ -1537,6 +1660,7 @@ void coff::createPDB(SymbolTable *Symtab,
PDB.initialize(BuildId);
PDB.addObjectsToPDB();
+ PDB.addImportFilesToPDB(OutputSections);
PDB.addSections(OutputSections, SectionTable);
PDB.addNatvisFiles();
OpenPOWER on IntegriCloud