#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAM_H
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
PDB_UniqueId getGuid() const;
uint32_t getNamedStreamMapByteSize() const;
+ PdbRaw_Features getFeatures() const;
+ ArrayRef<PdbRaw_FeatureSig> getFeatureSignatures() const;
+
const NamedStreamMap &getNamedStreams() const;
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
// universally unique.
PDB_UniqueId Guid;
+ std::vector<PdbRaw_FeatureSig> FeatureSignatures;
+ PdbRaw_Features Features = PdbFeatureNone;
+
uint32_t NamedStreamMapByteSize = 0;
NamedStreamMap NamedStreams;
void setSignature(uint32_t S);
void setAge(uint32_t A);
void setGuid(PDB_UniqueId G);
+ void addFeature(PdbRaw_FeatureSig Sig);
uint32_t finalize();
private:
msf::MSFBuilder &Msf;
+ std::vector<PdbRaw_FeatureSig> Features;
PdbRaw_ImplVer Ver;
uint32_t Sig;
uint32_t Age;
#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
#define LLVM_DEBUGINFO_PDB_RAW_PDBRAWCONSTANTS_H
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include <cstdint>
PdbImplVC140 = 20140508,
};
+enum class PdbRaw_FeatureSig : uint32_t {
+ VC110 = PdbImplVC110,
+ VC140 = PdbImplVC140,
+ NoTypeMerge = 0x4D544F4E,
+ MinimalDebugInfo = 0x494E494D,
+};
+
+enum PdbRaw_Features : uint32_t {
+ PdbFeatureNone = 0x0,
+ PdbFeatureContainsIdStream = 0x1,
+ PdbFeatureMinimalDebugInfo = 0x2,
+ PdbFeatureNoTypeMerging = 0x4,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PdbFeatureNoTypeMerging)
+};
+
enum PdbRaw_DbiVer : uint32_t {
PdbDbiVC41 = 930803,
PdbDbiV50 = 19960307,
return EC;
uint32_t NewOffset = Reader.getOffset();
NamedStreamMapByteSize = NewOffset - Offset;
+
+ bool Stop = false;
+ while (!Stop && !Reader.empty()) {
+ PdbRaw_FeatureSig Sig;
+ if (auto EC = Reader.readEnum(Sig))
+ return EC;
+ switch (Sig) {
+ case PdbRaw_FeatureSig::VC110:
+ // No other flags for VC110 PDB.
+ Stop = true;
+ LLVM_FALLTHROUGH;
+ case PdbRaw_FeatureSig::VC140:
+ Features |= PdbFeatureContainsIdStream;
+ break;
+ case PdbRaw_FeatureSig::NoTypeMerge:
+ Features |= PdbFeatureNoTypeMerging;
+ break;
+ case PdbRaw_FeatureSig::MinimalDebugInfo:
+ Features |= PdbFeatureMinimalDebugInfo;
+ default:
+ continue;
+ }
+ FeatureSignatures.push_back(Sig);
+ }
return Error::success();
}
return NamedStreamMapByteSize;
}
+PdbRaw_Features InfoStream::getFeatures() const { return Features; }
+
+ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
+ return FeatureSignatures;
+}
+
const NamedStreamMap &InfoStream::getNamedStreams() const {
return NamedStreams;
}
void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
+void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
+ Features.push_back(Sig);
+}
+
Error InfoStreamBuilder::finalizeMsfLayout() {
- uint32_t Length = sizeof(InfoStreamHeader) + NamedStreams.finalize();
+ uint32_t Length = sizeof(InfoStreamHeader) + NamedStreams.finalize() +
+ (Features.size() + 1) * sizeof(uint32_t);
if (auto EC = Msf.setStreamSize(StreamPDB, Length))
return EC;
return Error::success();
if (auto EC = Writer.writeObject(H))
return EC;
- return NamedStreams.commit(Writer);
+ if (auto EC = NamedStreams.commit(Writer))
+ return EC;
+ if (auto EC = Writer.writeInteger(0))
+ return EC;
+ for (auto E : Features) {
+ if (auto EC = Writer.writeEnum(E))
+ return EC;
+ }
+ return Error::success();
}
; EMPTY-NEXT: Signature: 0x54E507E2
; EMPTY-NEXT: Age: 1
; EMPTY-NEXT: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
+; EMPTY-NEXT: Features: 0x1
; EMPTY-NEXT: Named Streams {
; EMPTY-NEXT: /names: 13
; EMPTY-NEXT: /LinkInfo: 5
; ALL: Signature: 0x54E507E2
; ALL: Age: 1
; ALL: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
+; ALL: Features: 0x1
; ALL: }
; ALL: Type Info Stream (IPI) {
; ALL: IPI Version: 20040203
; BIG-NEXT: Signature: 0x571FFE67
; BIG-NEXT: Age: 1
; BIG-NEXT: Guid: {880ECC89-DF81-0B4F-839C-58CBD052E937}
+; BIG-NEXT: Features: 0x1
; BIG-NEXT: Named Streams {
; BIG-NEXT: /names: 13
; BIG-NEXT: /LinkInfo: 5
CHECK-NEXT: Signature: 0x54E507E2
CHECK-NEXT: Age: 1
CHECK-NEXT: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
+CHECK-NEXT: Features: 0x1
CHECK-NEXT: Named Streams {
CHECK: /names:
CHECK: }
; YAML-NEXT: Age: 1
; YAML-NEXT: Guid: '{0B355641-86A0-A249-896F-9988FAE52FF0}'
; YAML-NEXT: Signature: 1424295906
+; YAML-NEXT: Features: [ VC110 ]
; YAML-NEXT: Version: VC70
; YAML-NEXT: ...
#include "llvm/DebugInfo/PDB/Native/StringTable.h"
#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::pdb;
+namespace llvm {
+template <> struct format_provider<PdbRaw_FeatureSig> {
+ static void format(const PdbRaw_FeatureSig &Sig, raw_ostream &Stream,
+ StringRef Style) {
+ switch (Sig) {
+ case PdbRaw_FeatureSig::MinimalDebugInfo:
+ Stream << "MinimalDebugInfo";
+ break;
+ case PdbRaw_FeatureSig::NoTypeMerge:
+ Stream << "NoTypeMerge";
+ break;
+ case PdbRaw_FeatureSig::VC110:
+ Stream << "VC110";
+ break;
+ case PdbRaw_FeatureSig::VC140:
+ Stream << "VC140";
+ break;
+ }
+ }
+};
+}
+
template <typename R> using ValueOfRange = llvm::detail::ValueOfRange<R>;
template <typename Range, typename Comp>
return true;
}
+template <typename T>
+static bool diffAndPrint(StringRef Label, PDBFile &File1, PDBFile &File2,
+ ArrayRef<T> V1, ArrayRef<T> V2) {
+ if (V1 == V2) {
+ outs() << formatv(" {0}: No differences detected!\n", Label);
+ return false;
+ }
+
+ outs().indent(2) << Label << "\n";
+ outs().indent(4) << formatv("{0}: {1}\n", File1.getFilePath(),
+ make_range(V1.begin(), V1.end()));
+ outs().indent(4) << formatv("{0}: {1}\n", File2.getFilePath(),
+ make_range(V2.begin(), V2.end()));
+ return true;
+}
+
template <typename T>
static bool printSymmetricDifferences(PDBFile &File1, PDBFile &File2,
T &&OnlyRange1, T &&OnlyRange2,
IS2.getSignature());
HasDiff |=
diffAndPrint("Version", File1, File2, IS1.getVersion(), IS2.getVersion());
+ HasDiff |= diffAndPrint("Features", File1, File2, IS1.getFeatureSignatures(),
+ IS2.getFeatureSignatures());
HasDiff |= diffAndPrint("Named Stream Byte Size", File1, File2,
IS1.getNamedStreamMapByteSize(),
IS2.getNamedStreamMapByteSize());
P.printHex("Signature", IS->getSignature());
P.printNumber("Age", IS->getAge());
P.printObject("Guid", IS->getGuid());
+ P.printHex("Features", IS->getFeatures());
{
DictScope DD(P, "Named Streams");
for (const auto &S : IS->getNamedStreams().entries())
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbSymbolRecord)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbTpiRecord)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::pdb::PdbRaw_FeatureSig)
namespace llvm {
namespace yaml {
io.enumCase(Value, "VC80", llvm::pdb::PdbRaw_TpiVer::PdbTpiV80);
}
};
+
+template <> struct ScalarEnumerationTraits<llvm::pdb::PdbRaw_FeatureSig> {
+ static void enumeration(IO &io, PdbRaw_FeatureSig &Features) {
+ io.enumCase(Features, "MinimalDebugInfo",
+ PdbRaw_FeatureSig::MinimalDebugInfo);
+ io.enumCase(Features, "NoTypeMerge", PdbRaw_FeatureSig::NoTypeMerge);
+ io.enumCase(Features, "VC110", PdbRaw_FeatureSig::VC110);
+ io.enumCase(Features, "VC140", PdbRaw_FeatureSig::VC140);
+ }
+};
}
}
IO.mapOptional("Age", Obj.Age, 1U);
IO.mapOptional("Guid", Obj.Guid);
IO.mapOptional("Signature", Obj.Signature, 0U);
+ IO.mapOptional("Features", Obj.Features);
IO.mapOptional("Version", Obj.Version, PdbImplVC70);
}
uint32_t Signature = 0;
uint32_t Age = 1;
PDB_UniqueId Guid;
+ std::vector<PdbRaw_FeatureSig> Features;
std::vector<NamedStreamMapping> NamedStreams;
};
Obj.PdbStream->Guid = InfoS.getGuid();
Obj.PdbStream->Signature = InfoS.getSignature();
Obj.PdbStream->Version = InfoS.getVersion();
+ Obj.PdbStream->Features = InfoS.getFeatureSignatures();
return Error::success();
}
InfoBuilder.setGuid(Info.Guid);
InfoBuilder.setSignature(Info.Signature);
InfoBuilder.setVersion(Info.Version);
+ for (auto F : Info.Features)
+ InfoBuilder.addFeature(F);
const auto &Dbi = YamlObj.DbiStream.getValueOr(DefaultDbiStream);
auto &DbiBuilder = Builder.getDbiBuilder();
DbiBuilder.setPdbDllVersion(Dbi.PdbDllVersion);
DbiBuilder.setVersionHeader(Dbi.VerHeader);
for (const auto &MI : Dbi.ModInfos) {
- auto &ModiBuilder = ExitOnErr(DbiBuilder.addModuleInfo(MI.Obj));
+ auto &ModiBuilder = ExitOnErr(DbiBuilder.addModuleInfo(MI.Mod));
for (auto S : MI.SourceFiles)
ExitOnErr(DbiBuilder.addModuleSourceFile(MI.Mod, S));