diff options
Diffstat (limited to 'COFF/PDB.cpp')
| -rw-r--r-- | COFF/PDB.cpp | 109 |
1 files changed, 57 insertions, 52 deletions
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp index 923fc64c7734..e32bcd20a541 100644 --- a/COFF/PDB.cpp +++ b/COFF/PDB.cpp @@ -20,20 +20,23 @@ #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" -#include "llvm/DebugInfo/MSF/ByteStream.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" -#include "llvm/DebugInfo/PDB/Raw/DbiStream.h" -#include "llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h" -#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" -#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h" -#include "llvm/DebugInfo/PDB/Raw/PDBFile.h" -#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h" -#include "llvm/DebugInfo/PDB/Raw/TpiStream.h" -#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h" +#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h" +#include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h" #include "llvm/Object/COFF.h" +#include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/Endian.h" #include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include <memory> @@ -79,32 +82,49 @@ static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) { return Data.slice(4); } -// Merge .debug$T sections and returns it. -static std::vector<uint8_t> mergeDebugT(SymbolTable *Symtab) { - ScopedPrinter W(outs()); +static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, + codeview::TypeTableBuilder &TypeTable) { + // Start the TPI or IPI stream header. + TpiBuilder.setVersionHeader(pdb::PdbTpiV80); + + // Flatten the in memory type table. + TypeTable.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Rec) { + // FIXME: Hash types. + TpiBuilder.addTypeRecord(Rec, None); + }); +} +// Merge .debug$T sections into IpiData and TpiData. +static void mergeDebugT(SymbolTable *Symtab, pdb::PDBFileBuilder &Builder, + codeview::TypeTableBuilder &TypeTable, + codeview::TypeTableBuilder &IDTable) { // Visit all .debug$T sections to add them to Builder. - codeview::TypeTableBuilder Builder(BAlloc); for (ObjectFile *File : Symtab->ObjectFiles) { ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T"); if (Data.empty()) continue; - msf::ByteStream Stream(Data); + BinaryByteStream Stream(Data, support::little); codeview::CVTypeArray Types; - msf::StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); + // Follow type servers. If the same type server is encountered more than + // once for this instance of `PDBTypeServerHandler` (for example if many + // object files reference the same TypeServer), the types from the + // TypeServer will only be visited once. + pdb::PDBTypeServerHandler Handler; + Handler.addSearchPath(llvm::sys::path::parent_path(File->getName())); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); - if (!codeview::mergeTypeStreams(Builder, Types)) - fatal("codeview::mergeTypeStreams failed"); + if (auto Err = + codeview::mergeTypeStreams(IDTable, TypeTable, &Handler, Types)) + fatal(Err, "codeview::mergeTypeStreams failed"); } - // Construct section contents. - std::vector<uint8_t> V; - Builder.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Rec) { - V.insert(V.end(), Rec.begin(), Rec.end()); - }); - return V; + // Construct TPI stream contents. + addTypeInfo(Builder.getTpiBuilder(), TypeTable); + + // Construct IPI stream contents. + addTypeInfo(Builder.getIpiBuilder(), IDTable); } static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) { @@ -115,6 +135,8 @@ static void dumpDebugT(ScopedPrinter &W, ObjectFile *File) { TypeDatabase TDB; TypeDumpVisitor TDV(TDB, &W, false); + // Use a default implementation that does not follow type servers and instead + // just dumps the contents of the TypeServer2 record. CVTypeDumper TypeDumper(TDB); if (auto EC = TypeDumper.dump(Data, TDV)) fatal(EC, "CVTypeDumper::dump failed"); @@ -126,9 +148,9 @@ static void dumpDebugS(ScopedPrinter &W, ObjectFile *File) { if (Data.empty()) return; - msf::ByteStream Stream(Data); + BinaryByteStream Stream(Data, llvm::support::little); CVSymbolArray Symbols; - msf::StreamReader Reader(Stream); + BinaryStreamReader Reader(Stream); if (auto EC = Reader.readArray(Symbols, Reader.getLength())) fatal(EC, "StreamReader.readArray<CVSymbolArray> failed"); @@ -148,17 +170,6 @@ static void dumpCodeView(SymbolTable *Symtab) { } } -static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder, - ArrayRef<uint8_t> Data) { - msf::ByteStream Stream(Data); - codeview::CVTypeArray Records; - msf::StreamReader Reader(Stream); - if (auto EC = Reader.readArray(Records, Reader.getLength())) - fatal(EC, "Reader.readArray failed"); - for (const codeview::CVType &Rec : Records) - TpiBuilder.addTypeRecord(Rec); -} - // Creates a PDB file. void coff::createPDB(StringRef Path, SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable, @@ -177,9 +188,12 @@ void coff::createPDB(StringRef Path, SymbolTable *Symtab, // Add an Info stream. auto &InfoBuilder = Builder.getInfoBuilder(); - InfoBuilder.setAge(DI->PDB70.Age); - InfoBuilder.setGuid( - *reinterpret_cast<const pdb::PDB_UniqueId *>(&DI->PDB70.Signature)); + InfoBuilder.setAge(DI ? DI->PDB70.Age : 0); + + pdb::PDB_UniqueId uuid{}; + if (DI) + memcpy(&uuid, &DI->PDB70.Signature, sizeof(uuid)); + InfoBuilder.setGuid(uuid); // Should be the current time, but set 0 for reproducibilty. InfoBuilder.setSignature(0); InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70); @@ -188,18 +202,9 @@ void coff::createPDB(StringRef Path, SymbolTable *Symtab, auto &DbiBuilder = Builder.getDbiBuilder(); DbiBuilder.setVersionHeader(pdb::PdbDbiV110); - // Add an empty TPI stream. - auto &TpiBuilder = Builder.getTpiBuilder(); - TpiBuilder.setVersionHeader(pdb::PdbTpiV80); - std::vector<uint8_t> TpiData; - if (Config->DebugPdb) { - TpiData = mergeDebugT(Symtab); - addTypeInfo(TpiBuilder, TpiData); - } - - // Add an empty IPI stream. - auto &IpiBuilder = Builder.getIpiBuilder(); - IpiBuilder.setVersionHeader(pdb::PdbTpiV80); + codeview::TypeTableBuilder TypeTable(BAlloc); + codeview::TypeTableBuilder IDTable(BAlloc); + mergeDebugT(Symtab, Builder, TypeTable, IDTable); // Add Section Contributions. std::vector<pdb::SectionContrib> Contribs = @@ -214,7 +219,7 @@ void coff::createPDB(StringRef Path, SymbolTable *Symtab, pdb::DbiStreamBuilder::createSectionMap(Sections); DbiBuilder.setSectionMap(SectionMap); - ExitOnErr(DbiBuilder.addModuleInfo("", "* Linker *")); + ExitOnErr(DbiBuilder.addModuleInfo("* Linker *")); // Add COFF section header stream. ExitOnErr( |
