raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id);
+raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version);
--- /dev/null
+//===- PDBDbiStream.h - PDB Dbi Stream (Stream 3) Access --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H
+
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+class PDBFile;
+
+class PDBDbiStream {
+ struct HeaderInfo;
+
+public:
+ PDBDbiStream(PDBFile &File);
+ ~PDBDbiStream();
+ std::error_code reload();
+
+ PdbRaw_DbiVer getDbiVersion() const;
+ uint32_t getAge() const;
+
+ bool isIncrementallyLinked() const;
+ bool hasCTypes() const;
+ bool isStripped() const;
+
+ uint16_t getBuildMajorVersion() const;
+ uint16_t getBuildMinorVersion() const;
+
+ uint32_t getPdbDllVersion() const;
+
+ uint32_t getNumberOfSymbols() const;
+
+ PDB_Machine getMachineType() const;
+
+private:
+ PDBStream Stream;
+ PDBFile &Pdb;
+ std::unique_ptr<HeaderInfo> Header;
+};
+}
+
+#endif
class MemoryBuffer;
struct PDBFileContext;
-class PDBStream;
+class PDBDbiStream;
+class PDBInfoStream;
class PDBFile {
public:
return BlockNumber * BlockSize;
}
- PDBStream *getPDBStream() const;
+ PDBInfoStream &getPDBInfoStream();
+ PDBDbiStream &getPDBDbiStream();
private:
std::unique_ptr<PDBFileContext> Context;
+ std::unique_ptr<PDBInfoStream> InfoStream;
+ std::unique_ptr<PDBDbiStream> DbiStream;
};
}
namespace llvm {
enum PdbRaw_ImplVer : uint32_t {
- VC2 = 19941610,
- VC4 = 19950623,
- VC41 = 19950814,
- VC50 = 19960307,
- VC98 = 19970604,
- VC70Dep = 19990604, // deprecated
- VC70 = 20000404,
- VC80 = 20030901,
- VC110 = 20091201,
- VC140 = 20140508,
+ PdbImplVC2 = 19941610,
+ PdbImplVC4 = 19950623,
+ PdbImplVC41 = 19950814,
+ PdbImplVC50 = 19960307,
+ PdbImplVC98 = 19970604,
+ PdbImplVC70Dep = 19990604, // deprecated
+ PdbImplVC70 = 20000404,
+ PdbImplVC80 = 20030901,
+ PdbImplVC110 = 20091201,
+ PdbImplVC140 = 20140508,
+};
+
+enum PdbRaw_DbiVer : uint32_t {
+ PdbDbiVC41 = 930803,
+ PdbDbiV50 = 19960307,
+ PdbDbiV60 = 19970606,
+ PdbDbiV70 = 19990903,
+ PdbDbiV110 = 20091201
};
}
add_pdb_impl_folder(Raw
Raw/PDBFile.cpp
+ Raw/PDBDbiStream.cpp
Raw/PDBInfoStream.cpp
Raw/PDBNameMap.cpp
Raw/PDBStream.cpp
return OS;
}
+raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_Machine &Machine) {
+ switch (Machine) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Am33, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Amd64, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Arm, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, ArmNT, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Ebc, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, x86, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Ia64, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, M32R, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Mips16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, MipsFpu, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, MipsFpu16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, PowerPC, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, PowerPCFP, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, R4000, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH3, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH3DSP, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH4, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH5, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Thumb, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, WceMipsV2, OS)
+ default:
+ OS << "Unknown";
+ }
+ return OS;
+}
+
raw_ostream &llvm::operator<<(raw_ostream &OS, const Variant &Value) {
switch (Value.Type) {
case PDB_VariantType::Bool:
--- /dev/null
+//===- PDBDbiStream.cpp - PDB Dbi Stream (Stream 3) Access ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/PDBDbiStream.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h"
+
+using namespace llvm;
+using namespace llvm::support;
+
+namespace {
+// Some of the values are stored in bitfields. Since this needs to be portable
+// across compilers and architectures (big / little endian in particular) we
+// can't use the actual structures below, but must instead do the shifting
+// and masking ourselves. The struct definitions are provided for reference.
+
+// struct DbiFlags {
+// uint16_t IncrementalLinking : 1; // True if linked incrementally
+// uint16_t IsStripped : 1; // True if private symbols were stripped.
+// uint16_t HasCTypes : 1; // True if linked with /debug:ctypes.
+// uint16_t Reserved : 13;
+//};
+const uint16_t FlagIncrementalMask = 0x0001;
+const uint16_t FlagStrippedMask = 0x0002;
+const uint16_t FlagHasCTypesMask = 0x0004;
+
+// struct DbiBuildNo {
+// uint16_t MinorVersion : 8;
+// uint16_t MajorVersion : 7;
+// uint16_t NewVersionFormat : 1;
+//};
+const uint16_t BuildMinorMask = 0x00FF;
+const uint16_t BuildMinorShift = 0;
+
+const uint16_t BuildMajorMask = 0x7F00;
+const uint16_t BuildMajorShift = 8;
+
+const uint16_t BuildNewFormatMask = 0x8000;
+const uint16_t BuildNewFormatShift = 15;
+}
+
+struct PDBDbiStream::HeaderInfo {
+ ulittle32_t VersionSignature;
+ ulittle32_t VersionHeader;
+ ulittle32_t Age; // Should match PDBInfoStream.
+ ulittle16_t GSSyms;
+ ulittle16_t BuildNumber; // See DbiBuildNo structure.
+ ulittle16_t PSSyms;
+ ulittle16_t PdbDllVersion; // version of mspdbNNN.dll
+ ulittle16_t SymRecords; // Number of symbols
+ ulittle16_t PdbDllRbld; // rbld number of mspdbNNN.dll
+ little32_t ModiSubstreamSize; // Size of module info stream
+ little32_t SecContrSubstreamSize; // Size of sec. contribution stream
+ little32_t SectionMapSize;
+ little32_t FileInfoSize;
+ little32_t TypeServerSize; // Size of type server map
+ ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server
+ little32_t OptionalDbgHdrSize; // Size of DbgHeader info
+ little32_t ECSubstreamSize; // Size of EC stream (what is EC?)
+ ulittle16_t Flags; // See DbiFlags enum.
+ ulittle16_t MachineType; // See PDB_MachineType enum.
+
+ ulittle32_t Reserved; // Pad to 64 bytes
+};
+
+PDBDbiStream::PDBDbiStream(PDBFile &File) : Pdb(File), Stream(3, File) {
+ static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!");
+}
+
+PDBDbiStream::~PDBDbiStream() {}
+
+std::error_code PDBDbiStream::reload() {
+ Stream.setOffset(0);
+ Header.reset(new HeaderInfo());
+
+ if (Stream.getLength() < sizeof(HeaderInfo))
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+ Stream.readObject(Header.get());
+
+ if (Header->VersionSignature != -1)
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ // Prior to VC50 an old style header was used. We don't support this.
+ if (Header->VersionHeader < PdbDbiV50)
+ return std::make_error_code(std::errc::not_supported);
+
+ if (Header->Age != Pdb.getPDBInfoStream().getAge())
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ if (Stream.getLength() !=
+ sizeof(HeaderInfo) + Header->ModiSubstreamSize +
+ Header->SecContrSubstreamSize + Header->SectionMapSize +
+ Header->FileInfoSize + Header->TypeServerSize +
+ Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
+ return std::error_code();
+}
+
+PdbRaw_DbiVer PDBDbiStream::getDbiVersion() const {
+ uint32_t Value = Header->VersionHeader;
+ return static_cast<PdbRaw_DbiVer>(Value);
+}
+
+uint32_t PDBDbiStream::getAge() const { return Header->Age; }
+
+bool PDBDbiStream::isIncrementallyLinked() const {
+ return (Header->Flags & FlagIncrementalMask) != 0;
+}
+
+bool PDBDbiStream::hasCTypes() const {
+ return (Header->Flags & FlagHasCTypesMask) != 0;
+}
+
+bool PDBDbiStream::isStripped() const {
+ return (Header->Flags & FlagStrippedMask) != 0;
+}
+
+uint16_t PDBDbiStream::getBuildMajorVersion() const {
+ return (Header->BuildNumber & BuildMajorMask) >> BuildMajorShift;
+}
+
+uint16_t PDBDbiStream::getBuildMinorVersion() const {
+ return (Header->BuildNumber & BuildMinorMask) >> BuildMinorShift;
+}
+
+uint32_t PDBDbiStream::getPdbDllVersion() const {
+ return Header->PdbDllVersion;
+}
+
+uint32_t PDBDbiStream::getNumberOfSymbols() const { return Header->SymRecords; }
+
+PDB_Machine PDBDbiStream::getMachineType() const {
+ uint16_t Machine = Header->MachineType;
+ return static_cast<PDB_Machine>(Machine);
+}
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBDbiStream.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MemoryBuffer.h"
Context->Buffer->getBufferStart() + getBlockMapOffset()),
getNumDirectoryBlocks());
}
+
+PDBInfoStream &PDBFile::getPDBInfoStream() {
+ if (!InfoStream) {
+ InfoStream.reset(new PDBInfoStream(*this));
+ InfoStream->reload();
+ }
+ return *InfoStream;
+}
+
+PDBDbiStream &PDBFile::getPDBDbiStream() {
+ if (!DbiStream) {
+ DbiStream.reset(new PDBDbiStream(*this));
+ DbiStream->reload();
+ }
+ return *DbiStream;
+}
support::ulittle32_t Value;
Stream1.readObject(&Version);
- if (Version < PdbRaw_ImplVer::VC70)
+ if (Version < PdbRaw_ImplVer::PdbImplVC70)
return std::make_error_code(std::errc::not_supported);
Stream1.readObject(&Value);
; CHECK: NameStream: 13
; CHECK-NEXT: NameStreamSignature: effeeffe
; CHECK-NEXT: NameStreamVersion: 1
+
+; CHECK: Dbi Version: 19990903
+; CHECK-NEXT: Age: 1
+; CHECK-NEXT: Incremental Linking: 1
+; CHECK-NEXT: Has CTypes: 0
+; CHECK-NEXT: Is Stripped: 0
+; CHECK-NEXT: Machine Type: x86
+; CHECK-NEXT: Number of Symbols: 8
+; CHECK-NEXT: Toolchain Version: 12.0
+; CHECK-NEXT: mspdb120.dll version: 12.0.31101
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
+#include "llvm/DebugInfo/PDB/Raw/PDBDbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
}
}
- PDBInfoStream InfoStream(File);
- if (auto EC = InfoStream.reload())
- reportError("", EC);
-
+ PDBInfoStream &InfoStream = File.getPDBInfoStream();
outs() << "Version: " << InfoStream.getVersion() << '\n';
outs() << "Signature: ";
outs().write_hex(InfoStream.getSignature()) << '\n';
if (NameStreamSignature != 0xeffeeffe || NameStreamVersion != 1)
reportError("", std::make_error_code(std::errc::not_supported));
}
+
+ PDBDbiStream &DbiStream = File.getPDBDbiStream();
+ outs() << "Dbi Version: " << DbiStream.getDbiVersion() << '\n';
+ outs() << "Age: " << DbiStream.getAge() << '\n';
+ outs() << "Incremental Linking: " << DbiStream.isIncrementallyLinked()
+ << '\n';
+ outs() << "Has CTypes: " << DbiStream.hasCTypes() << '\n';
+ outs() << "Is Stripped: " << DbiStream.isStripped() << '\n';
+ outs() << "Machine Type: " << DbiStream.getMachineType() << '\n';
+ outs() << "Number of Symbols: " << DbiStream.getNumberOfSymbols() << '\n';
+
+ uint16_t Major = DbiStream.getBuildMajorVersion();
+ uint16_t Minor = DbiStream.getBuildMinorVersion();
+ outs() << "Toolchain Version: " << Major << "." << Minor << '\n';
+ outs() << "mspdb" << Major << Minor << ".dll version: " << Major << "."
+ << Minor << "." << DbiStream.getPdbDllVersion() << '\n';
}
static void dumpInput(StringRef Path) {