summaryrefslogtreecommitdiff
path: root/COFF/PDB.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:03:39 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:03:39 +0000
commitd2d3ebb81992e107edf95c1c136d7a342d9b1418 (patch)
treebb1af8fff2b1400cf240e3b2532a1e5d22a121da /COFF/PDB.cpp
parent16787c9ce0b96aaa669d7fab3a495916b35ce758 (diff)
Notes
Diffstat (limited to 'COFF/PDB.cpp')
-rw-r--r--COFF/PDB.cpp109
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(