mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-30 13:47:32 +00:00
Refactor the PDB writing to use a builder approach
llvm-svn: 275110
This commit is contained in:
parent
f6b9382467
commit
dbeaea7b35
@ -29,11 +29,36 @@ struct coff_section;
|
||||
}
|
||||
|
||||
namespace pdb {
|
||||
class DbiStreamBuilder;
|
||||
class PDBFile;
|
||||
class ISectionContribVisitor;
|
||||
|
||||
class DbiStream {
|
||||
struct HeaderInfo;
|
||||
friend class DbiStreamBuilder;
|
||||
|
||||
struct HeaderInfo {
|
||||
support::little32_t VersionSignature;
|
||||
support::ulittle32_t VersionHeader;
|
||||
support::ulittle32_t Age; // Should match InfoStream.
|
||||
support::ulittle16_t GlobalSymbolStreamIndex; // Global symbol stream #
|
||||
support::ulittle16_t BuildNumber; // See DbiBuildNo structure.
|
||||
support::ulittle16_t PublicSymbolStreamIndex; // Public symbols stream #
|
||||
support::ulittle16_t PdbDllVersion; // version of mspdbNNN.dll
|
||||
support::ulittle16_t SymRecordStreamIndex; // Symbol records stream #
|
||||
support::ulittle16_t PdbDllRbld; // rbld number of mspdbNNN.dll
|
||||
support::little32_t ModiSubstreamSize; // Size of module info stream
|
||||
support::little32_t SecContrSubstreamSize; // Size of sec. contrib stream
|
||||
support::little32_t SectionMapSize; // Size of sec. map substream
|
||||
support::little32_t FileInfoSize; // Size of file info substream
|
||||
support::little32_t TypeServerSize; // Size of type server map
|
||||
support::ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server
|
||||
support::little32_t OptionalDbgHdrSize; // Size of DbgHeader info
|
||||
support::little32_t ECSubstreamSize; // Size of EC stream (what is EC?)
|
||||
support::ulittle16_t Flags; // See DbiFlags enum.
|
||||
support::ulittle16_t MachineType; // See PDB_MachineType enum.
|
||||
|
||||
support::ulittle32_t Reserved; // Pad to 64 bytes
|
||||
};
|
||||
|
||||
public:
|
||||
DbiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream);
|
||||
@ -45,13 +70,16 @@ public:
|
||||
uint16_t getPublicSymbolStreamIndex() const;
|
||||
uint16_t getGlobalSymbolStreamIndex() const;
|
||||
|
||||
uint16_t getFlags() const;
|
||||
bool isIncrementallyLinked() const;
|
||||
bool hasCTypes() const;
|
||||
bool isStripped() const;
|
||||
|
||||
uint16_t getBuildNumber() const;
|
||||
uint16_t getBuildMajorVersion() const;
|
||||
uint16_t getBuildMinorVersion() const;
|
||||
|
||||
uint16_t getPdbDllRbld() const;
|
||||
uint32_t getPdbDllVersion() const;
|
||||
|
||||
uint32_t getSymRecordStreamIndex() const;
|
||||
|
55
llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
Normal file
55
llvm/include/llvm/DebugInfo/PDB/Raw/DbiStreamBuilder.h
Normal file
@ -0,0 +1,55 @@
|
||||
//===- DbiStreamBuilder.h - PDB Dbi Stream Creation -------------*- 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_PDBDBISTREAMBUILDER_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAMBUILDER_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace pdb {
|
||||
class DbiStream;
|
||||
class PDBFile;
|
||||
|
||||
class DbiStreamBuilder {
|
||||
public:
|
||||
DbiStreamBuilder(PDBFile &File);
|
||||
|
||||
DbiStreamBuilder(const DbiStreamBuilder &) = delete;
|
||||
DbiStreamBuilder &operator=(const DbiStreamBuilder &) = delete;
|
||||
|
||||
void setVersionHeader(PdbRaw_DbiVer V);
|
||||
void setAge(uint32_t A);
|
||||
void setBuildNumber(uint16_t B);
|
||||
void setPdbDllVersion(uint16_t V);
|
||||
void setPdbDllRbld(uint16_t R);
|
||||
void setFlags(uint16_t F);
|
||||
void setMachineType(PDB_Machine M);
|
||||
|
||||
Expected<std::unique_ptr<DbiStream>> build();
|
||||
|
||||
private:
|
||||
PDBFile &File;
|
||||
Optional<PdbRaw_DbiVer> VerHeader;
|
||||
uint32_t Age;
|
||||
uint16_t BuildNumber;
|
||||
uint16_t PdbDllVersion;
|
||||
uint16_t PdbDllRbld;
|
||||
uint16_t Flags;
|
||||
PDB_Machine MachineType;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -21,28 +21,33 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace pdb {
|
||||
class InfoStreamBuilder;
|
||||
class PDBFile;
|
||||
|
||||
class InfoStream {
|
||||
friend class InfoStreamBuilder;
|
||||
|
||||
struct Header {
|
||||
support::ulittle32_t Version;
|
||||
support::ulittle32_t Signature;
|
||||
support::ulittle32_t Age;
|
||||
PDB_UniqueId Guid;
|
||||
};
|
||||
|
||||
public:
|
||||
InfoStream(std::unique_ptr<MappedBlockStream> Stream);
|
||||
|
||||
Error reload();
|
||||
Error commit();
|
||||
|
||||
PdbRaw_ImplVer getVersion() const;
|
||||
uint32_t getSignature() const;
|
||||
uint32_t getAge() const;
|
||||
PDB_UniqueId getGuid() const;
|
||||
|
||||
void setVersion(PdbRaw_ImplVer Ver);
|
||||
void setSignature(uint32_t Sig);
|
||||
void setAge(uint32_t Age);
|
||||
void setGuid(PDB_UniqueId Guid);
|
||||
|
||||
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
|
||||
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
|
||||
|
||||
Error commit();
|
||||
|
||||
private:
|
||||
std::unique_ptr<MappedBlockStream> Stream;
|
||||
|
||||
|
50
llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
Normal file
50
llvm/include/llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h
Normal file
@ -0,0 +1,50 @@
|
||||
//===- InfoStreamBuilder.h - PDB Info Stream Creation -----------*- 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_PDBINFOSTREAMBUILDER_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_PDBINFOSTREAMBUILDER_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/NameMap.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace pdb {
|
||||
class NameMap;
|
||||
class PDBFile;
|
||||
|
||||
class InfoStreamBuilder {
|
||||
public:
|
||||
InfoStreamBuilder(IPDBFile &File);
|
||||
InfoStreamBuilder(const InfoStreamBuilder &) = delete;
|
||||
InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
|
||||
|
||||
void setVersion(PdbRaw_ImplVer V);
|
||||
void setSignature(uint32_t S);
|
||||
void setAge(uint32_t A);
|
||||
void setGuid(PDB_UniqueId G);
|
||||
|
||||
Expected<std::unique_ptr<InfoStream>> build();
|
||||
|
||||
private:
|
||||
IPDBFile &File;
|
||||
Optional<PdbRaw_ImplVer> Ver;
|
||||
Optional<uint32_t> Sig;
|
||||
Optional<uint32_t> Age;
|
||||
Optional<PDB_UniqueId> Guid;
|
||||
Optional<NameMap> NamedStreams;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -14,6 +14,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
@ -24,7 +25,6 @@ namespace llvm {
|
||||
namespace pdb {
|
||||
|
||||
class IPDBFile;
|
||||
class IPDBStreamData;
|
||||
class PDBFile;
|
||||
|
||||
class MappedBlockStream : public codeview::StreamInterface {
|
||||
@ -45,6 +45,8 @@ public:
|
||||
static Expected<std::unique_ptr<MappedBlockStream>>
|
||||
createDirectoryStream(const PDBFile &File);
|
||||
|
||||
llvm::BumpPtrAllocator &getAllocator() { return Pool; }
|
||||
|
||||
protected:
|
||||
MappedBlockStream(std::unique_ptr<IPDBStreamData> Data, const IPDBFile &File);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
||||
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
@ -31,6 +32,7 @@ class DbiStream;
|
||||
class InfoStream;
|
||||
class MappedBlockStream;
|
||||
class NameHashTable;
|
||||
class PDBFileBuilder;
|
||||
class PublicsStream;
|
||||
class SymbolStream;
|
||||
class TpiStream;
|
||||
@ -41,6 +43,8 @@ static const char MsfMagic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
|
||||
'\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'};
|
||||
|
||||
class PDBFile : public IPDBFile {
|
||||
friend PDBFileBuilder;
|
||||
|
||||
public:
|
||||
// The superblock is overlaid at the beginning of the file (offset 0).
|
||||
// It starts with a magic header and is followed by information which
|
||||
@ -107,8 +111,6 @@ public:
|
||||
return BlockNumber * BlockSize;
|
||||
}
|
||||
|
||||
Expected<InfoStream &> emplacePDBInfoStream();
|
||||
|
||||
Expected<InfoStream &> getPDBInfoStream();
|
||||
Expected<DbiStream &> getPDBDbiStream();
|
||||
Expected<TpiStream &> getPDBTpiStream();
|
||||
@ -117,14 +119,13 @@ public:
|
||||
Expected<SymbolStream &> getPDBSymbolStream();
|
||||
Expected<NameHashTable &> getStringTable();
|
||||
|
||||
Error setSuperBlock(const SuperBlock *Block);
|
||||
void setStreamSizes(ArrayRef<support::ulittle32_t> Sizes);
|
||||
void setDirectoryBlocks(ArrayRef<support::ulittle32_t> Directory);
|
||||
void setStreamMap(std::vector<ArrayRef<support::ulittle32_t>> &Streams);
|
||||
Error generateSimpleStreamMap();
|
||||
Error commit();
|
||||
|
||||
private:
|
||||
Error setSuperBlock(const SuperBlock *Block);
|
||||
|
||||
BumpPtrAllocator Allocator;
|
||||
|
||||
std::unique_ptr<codeview::StreamInterface> Buffer;
|
||||
const PDBFile::SuperBlock *SB;
|
||||
ArrayRef<support::ulittle32_t> StreamSizes;
|
||||
|
60
llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
Normal file
60
llvm/include/llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h
Normal file
@ -0,0 +1,60 @@
|
||||
//===- PDBFileBuilder.h - PDB File Creation ---------------------*- 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_PDBFILEBUILDER_H
|
||||
#define LLVM_DEBUGINFO_PDB_RAW_PDBFILEBUILDER_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
namespace codeview {
|
||||
class StreamInterface;
|
||||
}
|
||||
namespace pdb {
|
||||
class DbiStreamBuilder;
|
||||
class InfoStreamBuilder;
|
||||
class PDBFile;
|
||||
|
||||
class PDBFileBuilder {
|
||||
public:
|
||||
explicit PDBFileBuilder(
|
||||
std::unique_ptr<codeview::StreamInterface> PdbFileBuffer);
|
||||
PDBFileBuilder(const PDBFileBuilder &) = delete;
|
||||
PDBFileBuilder &operator=(const PDBFileBuilder &) = delete;
|
||||
|
||||
Error setSuperBlock(const PDBFile::SuperBlock &B);
|
||||
void setStreamSizes(ArrayRef<support::ulittle32_t> S);
|
||||
void setDirectoryBlocks(ArrayRef<support::ulittle32_t> D);
|
||||
void setStreamMap(const std::vector<ArrayRef<support::ulittle32_t>> &S);
|
||||
Error generateSimpleStreamMap();
|
||||
|
||||
InfoStreamBuilder &getInfoBuilder();
|
||||
DbiStreamBuilder &getDbiBuilder();
|
||||
|
||||
Expected<std::unique_ptr<PDBFile>> build();
|
||||
|
||||
private:
|
||||
std::unique_ptr<codeview::StreamInterface> PdbFileBuffer;
|
||||
std::unique_ptr<InfoStreamBuilder> Info;
|
||||
std::unique_ptr<DbiStreamBuilder> Dbi;
|
||||
|
||||
std::unique_ptr<PDBFile> File;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -29,16 +29,19 @@ endif()
|
||||
|
||||
add_pdb_impl_folder(Raw
|
||||
Raw/DbiStream.cpp
|
||||
Raw/DbiStreamBuilder.cpp
|
||||
Raw/EnumTables.cpp
|
||||
Raw/Hash.cpp
|
||||
Raw/IndexedStreamData.cpp
|
||||
Raw/InfoStream.cpp
|
||||
Raw/InfoStreamBuilder.cpp
|
||||
Raw/MappedBlockStream.cpp
|
||||
Raw/ModInfo.cpp
|
||||
Raw/ModStream.cpp
|
||||
Raw/NameHashTable.cpp
|
||||
Raw/NameMap.cpp
|
||||
Raw/PDBFile.cpp
|
||||
Raw/PDBFileBuilder.cpp
|
||||
Raw/PublicsStream.cpp
|
||||
Raw/RawError.cpp
|
||||
Raw/RawSession.cpp
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/StreamArray.h"
|
||||
#include "llvm/DebugInfo/CodeView/StreamReader.h"
|
||||
#include "llvm/DebugInfo/CodeView/StreamWriter.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/ISectionContribVisitor.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||
@ -53,31 +54,16 @@ const uint16_t BuildMinorShift = 0;
|
||||
|
||||
const uint16_t BuildMajorMask = 0x7F00;
|
||||
const uint16_t BuildMajorShift = 8;
|
||||
}
|
||||
|
||||
struct DbiStream::HeaderInfo {
|
||||
little32_t VersionSignature;
|
||||
ulittle32_t VersionHeader;
|
||||
ulittle32_t Age; // Should match InfoStream.
|
||||
ulittle16_t GlobalSymbolStreamIndex; // Global symbol stream #
|
||||
ulittle16_t BuildNumber; // See DbiBuildNo structure.
|
||||
ulittle16_t PublicSymbolStreamIndex; // Public symbols stream #
|
||||
ulittle16_t PdbDllVersion; // version of mspdbNNN.dll
|
||||
ulittle16_t SymRecordStreamIndex; // Symbol records stream #
|
||||
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; // Size of sec. map substream
|
||||
little32_t FileInfoSize; // Size of file info substream
|
||||
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
|
||||
struct FileInfoSubstreamHeader {
|
||||
ulittle16_t NumModules; // Total # of modules, should match number of
|
||||
// records in the ModuleInfo substream.
|
||||
ulittle16_t NumSourceFiles; // Total # of source files. This value is not
|
||||
// accurate because PDB actually supports more
|
||||
// than 64k source files, so we ignore it and
|
||||
// compute the value from other stream fields.
|
||||
};
|
||||
}
|
||||
|
||||
template <typename ContribType>
|
||||
static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
|
||||
@ -218,6 +204,8 @@ uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
|
||||
return Header->GlobalSymbolStreamIndex;
|
||||
}
|
||||
|
||||
uint16_t DbiStream::getFlags() const { return Header->Flags; }
|
||||
|
||||
bool DbiStream::isIncrementallyLinked() const {
|
||||
return (Header->Flags & FlagIncrementalMask) != 0;
|
||||
}
|
||||
@ -230,6 +218,8 @@ bool DbiStream::isStripped() const {
|
||||
return (Header->Flags & FlagStrippedMask) != 0;
|
||||
}
|
||||
|
||||
uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; }
|
||||
|
||||
uint16_t DbiStream::getBuildMajorVersion() const {
|
||||
return (Header->BuildNumber & BuildMajorMask) >> BuildMajorShift;
|
||||
}
|
||||
@ -238,6 +228,8 @@ uint16_t DbiStream::getBuildMinorVersion() const {
|
||||
return (Header->BuildNumber & BuildMinorMask) >> BuildMinorShift;
|
||||
}
|
||||
|
||||
uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; }
|
||||
|
||||
uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; }
|
||||
|
||||
uint32_t DbiStream::getSymRecordStreamIndex() const {
|
||||
@ -353,15 +345,6 @@ Error DbiStream::initializeSectionMapData() {
|
||||
}
|
||||
|
||||
Error DbiStream::initializeFileInfo() {
|
||||
struct FileInfoSubstreamHeader {
|
||||
ulittle16_t NumModules; // Total # of modules, should match number of
|
||||
// records in the ModuleInfo substream.
|
||||
ulittle16_t NumSourceFiles; // Total # of source files. This value is not
|
||||
// accurate because PDB actually supports more
|
||||
// than 64k source files, so we ignore it and
|
||||
// compute the value from other stream fields.
|
||||
};
|
||||
|
||||
// The layout of the FileInfoSubstream is like this:
|
||||
// struct {
|
||||
// ulittle16_t NumModules;
|
||||
|
76
llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
Normal file
76
llvm/lib/DebugInfo/PDB/Raw/DbiStreamBuilder.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===//
|
||||
//
|
||||
// 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/DbiStreamBuilder.h"
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/StreamWriter.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::codeview;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
DbiStreamBuilder::DbiStreamBuilder(PDBFile &File)
|
||||
: File(File), Age(1), BuildNumber(0), PdbDllVersion(0), PdbDllRbld(0),
|
||||
Flags(0), MachineType(PDB_Machine::x86) {}
|
||||
|
||||
void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
|
||||
|
||||
void DbiStreamBuilder::setAge(uint32_t A) { Age = A; }
|
||||
|
||||
void DbiStreamBuilder::setBuildNumber(uint16_t B) { BuildNumber = B; }
|
||||
|
||||
void DbiStreamBuilder::setPdbDllVersion(uint16_t V) { PdbDllVersion = V; }
|
||||
|
||||
void DbiStreamBuilder::setPdbDllRbld(uint16_t R) { PdbDllRbld = R; }
|
||||
|
||||
void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; }
|
||||
|
||||
void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
|
||||
|
||||
Expected<std::unique_ptr<DbiStream>> DbiStreamBuilder::build() {
|
||||
if (!VerHeader.hasValue())
|
||||
return make_error<RawError>(raw_error_code::unspecified,
|
||||
"Missing DBI Stream Version");
|
||||
|
||||
auto DbiS = MappedBlockStream::createIndexedStream(StreamDBI, File);
|
||||
if (!DbiS)
|
||||
return DbiS.takeError();
|
||||
auto DS = std::move(*DbiS);
|
||||
DbiStream::HeaderInfo *H =
|
||||
static_cast<DbiStream::HeaderInfo *>(DS->getAllocator().Allocate(
|
||||
sizeof(DbiStream::HeaderInfo),
|
||||
llvm::AlignOf<DbiStream::HeaderInfo>::Alignment));
|
||||
H->VersionHeader = *VerHeader;
|
||||
H->VersionSignature = -1;
|
||||
H->Age = Age;
|
||||
H->BuildNumber = BuildNumber;
|
||||
H->Flags = Flags;
|
||||
H->PdbDllRbld = PdbDllRbld;
|
||||
H->PdbDllVersion = PdbDllVersion;
|
||||
H->MachineType = static_cast<uint16_t>(MachineType);
|
||||
|
||||
H->ECSubstreamSize = 0;
|
||||
H->FileInfoSize = 0;
|
||||
H->ModiSubstreamSize = 0;
|
||||
H->OptionalDbgHdrSize = 0;
|
||||
H->SecContrSubstreamSize = 0;
|
||||
H->SectionMapSize = 0;
|
||||
H->TypeServerSize = 0;
|
||||
H->SymRecordStreamIndex = DbiStream::InvalidStreamIndex;
|
||||
H->PublicSymbolStreamIndex = DbiStream::InvalidStreamIndex;
|
||||
H->MFCTypeServerIndex = DbiStream::InvalidStreamIndex;
|
||||
H->GlobalSymbolStreamIndex = DbiStream::InvalidStreamIndex;
|
||||
|
||||
auto Dbi = llvm::make_unique<DbiStream>(File, std::move(DS));
|
||||
Dbi->Header = H;
|
||||
return std::move(Dbi);
|
||||
}
|
@ -21,15 +21,6 @@ using namespace llvm;
|
||||
using namespace llvm::codeview;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
namespace {
|
||||
struct Header {
|
||||
support::ulittle32_t Version;
|
||||
support::ulittle32_t Signature;
|
||||
support::ulittle32_t Age;
|
||||
PDB_UniqueId Guid;
|
||||
};
|
||||
}
|
||||
|
||||
InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
|
||||
: Stream(std::move(Stream)) {}
|
||||
|
||||
@ -84,16 +75,6 @@ uint32_t InfoStream::getAge() const { return Age; }
|
||||
|
||||
PDB_UniqueId InfoStream::getGuid() const { return Guid; }
|
||||
|
||||
void InfoStream::setVersion(PdbRaw_ImplVer Ver) {
|
||||
Version = static_cast<uint32_t>(Ver);
|
||||
}
|
||||
|
||||
void InfoStream::setSignature(uint32_t Sig) { Signature = Sig; }
|
||||
|
||||
void InfoStream::setAge(uint32_t Age) { this->Age = Age; }
|
||||
|
||||
void InfoStream::setGuid(PDB_UniqueId Guid) { this->Guid = Guid; }
|
||||
|
||||
Error InfoStream::commit() {
|
||||
StreamWriter Writer(*Stream);
|
||||
|
||||
@ -106,4 +87,4 @@ Error InfoStream::commit() {
|
||||
return EC;
|
||||
|
||||
return NamedStreams.commit(Writer);
|
||||
}
|
||||
}
|
54
llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
Normal file
54
llvm/lib/DebugInfo/PDB/Raw/InfoStreamBuilder.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
|
||||
//
|
||||
// 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/InfoStreamBuilder.h"
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/StreamWriter.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::codeview;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
InfoStreamBuilder::InfoStreamBuilder(IPDBFile &File) : File(File) {}
|
||||
|
||||
void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
|
||||
|
||||
void InfoStreamBuilder::setSignature(uint32_t S) { Sig = S; }
|
||||
|
||||
void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
|
||||
|
||||
void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
|
||||
|
||||
Expected<std::unique_ptr<InfoStream>> InfoStreamBuilder::build() {
|
||||
if (!Ver.hasValue())
|
||||
return make_error<RawError>(raw_error_code::unspecified,
|
||||
"Missing PDB Stream Version");
|
||||
if (!Sig.hasValue())
|
||||
return make_error<RawError>(raw_error_code::unspecified,
|
||||
"Missing PDB Stream Signature");
|
||||
if (!Age.hasValue())
|
||||
return make_error<RawError>(raw_error_code::unspecified,
|
||||
"Missing PDB Stream Age");
|
||||
if (!Guid.hasValue())
|
||||
return make_error<RawError>(raw_error_code::unspecified,
|
||||
"Missing PDB Stream Guid");
|
||||
|
||||
auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, File);
|
||||
if (!InfoS)
|
||||
return InfoS.takeError();
|
||||
auto Info = llvm::make_unique<InfoStream>(std::move(*InfoS));
|
||||
Info->Version = *Ver;
|
||||
Info->Signature = *Sig;
|
||||
Info->Age = *Age;
|
||||
Info->Guid = *Guid;
|
||||
return std::move(Info);
|
||||
}
|
@ -173,17 +173,6 @@ llvm::ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
|
||||
return DirectoryBlocks;
|
||||
}
|
||||
|
||||
Expected<InfoStream &> PDBFile::emplacePDBInfoStream() {
|
||||
if (Info)
|
||||
Info.reset();
|
||||
|
||||
auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this);
|
||||
if (!InfoS)
|
||||
return InfoS.takeError();
|
||||
Info = llvm::make_unique<InfoStream>(std::move(*InfoS));
|
||||
return *Info;
|
||||
}
|
||||
|
||||
Expected<InfoStream &> PDBFile::getPDBInfoStream() {
|
||||
if (!Info) {
|
||||
auto InfoS = MappedBlockStream::createIndexedStream(StreamPDB, *this);
|
||||
@ -352,64 +341,6 @@ Error PDBFile::setSuperBlock(const SuperBlock *Block) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void PDBFile::setStreamSizes(ArrayRef<support::ulittle32_t> Sizes) {
|
||||
StreamSizes = Sizes;
|
||||
}
|
||||
|
||||
void PDBFile::setStreamMap(
|
||||
std::vector<ArrayRef<support::ulittle32_t>> &Streams) {
|
||||
StreamMap = Streams;
|
||||
}
|
||||
|
||||
void PDBFile::setDirectoryBlocks(ArrayRef<support::ulittle32_t> Directory) {
|
||||
DirectoryBlocks = Directory;
|
||||
}
|
||||
|
||||
Error PDBFile::generateSimpleStreamMap() {
|
||||
if (StreamSizes.empty())
|
||||
return Error::success();
|
||||
|
||||
static std::vector<std::vector<support::ulittle32_t>> StaticMap;
|
||||
StreamMap.clear();
|
||||
StaticMap.clear();
|
||||
|
||||
// Figure out how many blocks are needed for all streams, and set the first
|
||||
// used block to the highest block so that we can write the rest of the
|
||||
// blocks contiguously.
|
||||
uint32_t TotalFileBlocks = getBlockCount();
|
||||
std::vector<support::ulittle32_t> ReservedBlocks;
|
||||
ReservedBlocks.push_back(support::ulittle32_t(0));
|
||||
ReservedBlocks.push_back(SB->BlockMapAddr);
|
||||
ReservedBlocks.insert(ReservedBlocks.end(), DirectoryBlocks.begin(),
|
||||
DirectoryBlocks.end());
|
||||
|
||||
uint32_t BlocksNeeded = 0;
|
||||
for (auto Size : StreamSizes)
|
||||
BlocksNeeded += bytesToBlocks(Size, getBlockSize());
|
||||
|
||||
support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded -
|
||||
ReservedBlocks.size());
|
||||
|
||||
StaticMap.resize(StreamSizes.size());
|
||||
for (uint32_t S = 0; S < StreamSizes.size(); ++S) {
|
||||
uint32_t Size = StreamSizes[S];
|
||||
uint32_t NumBlocks = bytesToBlocks(Size, getBlockSize());
|
||||
auto &ThisStream = StaticMap[S];
|
||||
for (uint32_t I = 0; I < NumBlocks;) {
|
||||
NextBlock += 1;
|
||||
if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) !=
|
||||
ReservedBlocks.end())
|
||||
continue;
|
||||
|
||||
++I;
|
||||
assert(NextBlock < getBlockCount());
|
||||
ThisStream.push_back(NextBlock);
|
||||
}
|
||||
StreamMap.push_back(ThisStream);
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error PDBFile::commit() {
|
||||
StreamWriter Writer(*Buffer);
|
||||
|
||||
|
127
llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
Normal file
127
llvm/lib/DebugInfo/PDB/Raw/PDBFileBuilder.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
|
||||
//
|
||||
// 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/PDBFileBuilder.h"
|
||||
|
||||
#include "llvm/DebugInfo/CodeView/StreamInterface.h"
|
||||
#include "llvm/DebugInfo/CodeView/StreamWriter.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/RawError.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::codeview;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
PDBFileBuilder::PDBFileBuilder(
|
||||
std::unique_ptr<codeview::StreamInterface> PdbFileBuffer)
|
||||
: File(llvm::make_unique<PDBFile>(std::move(PdbFileBuffer))) {}
|
||||
|
||||
Error PDBFileBuilder::setSuperBlock(const PDBFile::SuperBlock &B) {
|
||||
auto SB = static_cast<PDBFile::SuperBlock *>(
|
||||
File->Allocator.Allocate(sizeof(PDBFile::SuperBlock),
|
||||
llvm::AlignOf<PDBFile::SuperBlock>::Alignment));
|
||||
::memcpy(SB, &B, sizeof(PDBFile::SuperBlock));
|
||||
return File->setSuperBlock(SB);
|
||||
}
|
||||
|
||||
void PDBFileBuilder::setStreamSizes(ArrayRef<support::ulittle32_t> S) {
|
||||
File->StreamSizes = S;
|
||||
}
|
||||
|
||||
void PDBFileBuilder::setDirectoryBlocks(ArrayRef<support::ulittle32_t> D) {
|
||||
File->DirectoryBlocks = D;
|
||||
}
|
||||
|
||||
void PDBFileBuilder::setStreamMap(
|
||||
const std::vector<ArrayRef<support::ulittle32_t>> &S) {
|
||||
File->StreamMap = S;
|
||||
}
|
||||
|
||||
Error PDBFileBuilder::generateSimpleStreamMap() {
|
||||
if (File->StreamSizes.empty())
|
||||
return Error::success();
|
||||
|
||||
static std::vector<std::vector<support::ulittle32_t>> StaticMap;
|
||||
File->StreamMap.clear();
|
||||
StaticMap.clear();
|
||||
|
||||
// Figure out how many blocks are needed for all streams, and set the first
|
||||
// used block to the highest block so that we can write the rest of the
|
||||
// blocks contiguously.
|
||||
uint32_t TotalFileBlocks = File->getBlockCount();
|
||||
std::vector<support::ulittle32_t> ReservedBlocks;
|
||||
ReservedBlocks.push_back(support::ulittle32_t(0));
|
||||
ReservedBlocks.push_back(File->SB->BlockMapAddr);
|
||||
ReservedBlocks.insert(ReservedBlocks.end(), File->DirectoryBlocks.begin(),
|
||||
File->DirectoryBlocks.end());
|
||||
|
||||
uint32_t BlocksNeeded = 0;
|
||||
for (auto Size : File->StreamSizes)
|
||||
BlocksNeeded += File->bytesToBlocks(Size, File->getBlockSize());
|
||||
|
||||
support::ulittle32_t NextBlock(TotalFileBlocks - BlocksNeeded -
|
||||
ReservedBlocks.size());
|
||||
|
||||
StaticMap.resize(File->StreamSizes.size());
|
||||
for (uint32_t S = 0; S < File->StreamSizes.size(); ++S) {
|
||||
uint32_t Size = File->StreamSizes[S];
|
||||
uint32_t NumBlocks = File->bytesToBlocks(Size, File->getBlockSize());
|
||||
auto &ThisStream = StaticMap[S];
|
||||
for (uint32_t I = 0; I < NumBlocks;) {
|
||||
NextBlock += 1;
|
||||
if (std::find(ReservedBlocks.begin(), ReservedBlocks.end(), NextBlock) !=
|
||||
ReservedBlocks.end())
|
||||
continue;
|
||||
|
||||
++I;
|
||||
assert(NextBlock < File->getBlockCount());
|
||||
ThisStream.push_back(NextBlock);
|
||||
}
|
||||
File->StreamMap.push_back(ThisStream);
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
|
||||
if (!Info)
|
||||
Info = llvm::make_unique<InfoStreamBuilder>(*File);
|
||||
return *Info;
|
||||
}
|
||||
|
||||
DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
|
||||
if (!Dbi)
|
||||
Dbi = llvm::make_unique<DbiStreamBuilder>(*File);
|
||||
return *Dbi;
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<PDBFile>> PDBFileBuilder::build() {
|
||||
if (Info) {
|
||||
auto ExpectedInfo = Info->build();
|
||||
if (!ExpectedInfo)
|
||||
return ExpectedInfo.takeError();
|
||||
File->Info = std::move(*ExpectedInfo);
|
||||
}
|
||||
|
||||
if (Dbi) {
|
||||
auto ExpectedDbi = Dbi->build();
|
||||
if (!ExpectedDbi)
|
||||
return ExpectedDbi.takeError();
|
||||
File->Dbi = std::move(*ExpectedDbi);
|
||||
}
|
||||
|
||||
if (File->Info && File->Dbi && File->Info->getAge() != File->Dbi->getAge())
|
||||
return llvm::make_error<RawError>(
|
||||
raw_error_code::corrupt_file,
|
||||
"PDB Stream Age doesn't match Dbi Stream Age!");
|
||||
|
||||
return std::move(File);
|
||||
}
|
@ -74,7 +74,7 @@
|
||||
; YAML-NEXT: Age: 1
|
||||
; YAML-NEXT: Guid: '{0B355641-86A0-A249-896F-9988FAE52FF0}'
|
||||
; YAML-NEXT: Signature: 1424295906
|
||||
; YAML-NEXT: Version: 20000404
|
||||
; YAML-NEXT: Version: VC70
|
||||
; YAML-NEXT: ...
|
||||
|
||||
; NO-HEADERS: ---
|
||||
|
@ -53,9 +53,74 @@ template <> struct ScalarTraits<llvm::pdb::PDB_UniqueId> {
|
||||
|
||||
static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); }
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<llvm::pdb::PDB_Machine> {
|
||||
static void enumeration(IO &io, llvm::pdb::PDB_Machine &Value) {
|
||||
io.enumCase(Value, "Invalid", PDB_Machine::Invalid);
|
||||
io.enumCase(Value, "Am33", PDB_Machine::Am33);
|
||||
io.enumCase(Value, "Amd64", PDB_Machine::Amd64);
|
||||
io.enumCase(Value, "Arm", PDB_Machine::Arm);
|
||||
io.enumCase(Value, "ArmNT", PDB_Machine::ArmNT);
|
||||
io.enumCase(Value, "Ebc", PDB_Machine::Ebc);
|
||||
io.enumCase(Value, "x86", PDB_Machine::x86);
|
||||
io.enumCase(Value, "Ia64", PDB_Machine::Ia64);
|
||||
io.enumCase(Value, "M32R", PDB_Machine::M32R);
|
||||
io.enumCase(Value, "Mips16", PDB_Machine::Mips16);
|
||||
io.enumCase(Value, "MipsFpu", PDB_Machine::MipsFpu);
|
||||
io.enumCase(Value, "MipsFpu16", PDB_Machine::MipsFpu16);
|
||||
io.enumCase(Value, "PowerPCFP", PDB_Machine::PowerPCFP);
|
||||
io.enumCase(Value, "R4000", PDB_Machine::R4000);
|
||||
io.enumCase(Value, "SH3", PDB_Machine::SH3);
|
||||
io.enumCase(Value, "SH3DSP", PDB_Machine::SH3DSP);
|
||||
io.enumCase(Value, "Thumb", PDB_Machine::Thumb);
|
||||
io.enumCase(Value, "WceMipsV2", PDB_Machine::WceMipsV2);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<llvm::pdb::PdbRaw_DbiVer> {
|
||||
static void enumeration(IO &io, llvm::pdb::PdbRaw_DbiVer &Value) {
|
||||
io.enumCase(Value, "V41", llvm::pdb::PdbRaw_DbiVer::PdbDbiVC41);
|
||||
io.enumCase(Value, "V50", llvm::pdb::PdbRaw_DbiVer::PdbDbiV50);
|
||||
io.enumCase(Value, "V60", llvm::pdb::PdbRaw_DbiVer::PdbDbiV60);
|
||||
io.enumCase(Value, "V70", llvm::pdb::PdbRaw_DbiVer::PdbDbiV70);
|
||||
io.enumCase(Value, "V110", llvm::pdb::PdbRaw_DbiVer::PdbDbiV110);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<llvm::pdb::PdbRaw_ImplVer> {
|
||||
static void enumeration(IO &io, llvm::pdb::PdbRaw_ImplVer &Value) {
|
||||
io.enumCase(Value, "VC2", llvm::pdb::PdbRaw_ImplVer::PdbImplVC2);
|
||||
io.enumCase(Value, "VC4", llvm::pdb::PdbRaw_ImplVer::PdbImplVC4);
|
||||
io.enumCase(Value, "VC41", llvm::pdb::PdbRaw_ImplVer::PdbImplVC41);
|
||||
io.enumCase(Value, "VC50", llvm::pdb::PdbRaw_ImplVer::PdbImplVC50);
|
||||
io.enumCase(Value, "VC98", llvm::pdb::PdbRaw_ImplVer::PdbImplVC98);
|
||||
io.enumCase(Value, "VC70Dep", llvm::pdb::PdbRaw_ImplVer::PdbImplVC70Dep);
|
||||
io.enumCase(Value, "VC70", llvm::pdb::PdbRaw_ImplVer::PdbImplVC70);
|
||||
io.enumCase(Value, "VC80", llvm::pdb::PdbRaw_ImplVer::PdbImplVC80);
|
||||
io.enumCase(Value, "VC110", llvm::pdb::PdbRaw_ImplVer::PdbImplVC110);
|
||||
io.enumCase(Value, "VC140", llvm::pdb::PdbRaw_ImplVer::PdbImplVC140);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
|
||||
IO.mapOptional("MSF", Obj.Headers);
|
||||
IO.mapOptional("StreamSizes", Obj.StreamSizes);
|
||||
IO.mapOptional("StreamMap", Obj.StreamMap);
|
||||
IO.mapOptional("PdbStream", Obj.PdbStream);
|
||||
IO.mapOptional("DbiStream", Obj.DbiStream);
|
||||
}
|
||||
|
||||
void MappingTraits<MsfHeaders>::mapping(IO &IO, MsfHeaders &Obj) {
|
||||
IO.mapRequired("SuperBlock", Obj.SuperBlock);
|
||||
IO.mapRequired("NumDirectoryBlocks", Obj.NumDirectoryBlocks);
|
||||
IO.mapRequired("BlockMapOffset", Obj.BlockMapOffset);
|
||||
IO.mapRequired("DirectoryBlocks", Obj.DirectoryBlocks);
|
||||
IO.mapRequired("NumStreams", Obj.NumStreams);
|
||||
IO.mapRequired("FileSize", Obj.FileSize);
|
||||
}
|
||||
|
||||
void MappingTraits<PDBFile::SuperBlock>::mapping(IO &IO,
|
||||
PDBFile::SuperBlock &SB) {
|
||||
if (!IO.outputting()) {
|
||||
@ -74,25 +139,19 @@ void MappingTraits<StreamBlockList>::mapping(IO &IO, StreamBlockList &SB) {
|
||||
IO.mapRequired("Stream", SB.Blocks);
|
||||
}
|
||||
|
||||
void MappingTraits<MsfHeaders>::mapping(IO &IO, MsfHeaders &Obj) {
|
||||
IO.mapRequired("SuperBlock", Obj.SuperBlock);
|
||||
IO.mapRequired("NumDirectoryBlocks", Obj.NumDirectoryBlocks);
|
||||
IO.mapRequired("BlockMapOffset", Obj.BlockMapOffset);
|
||||
IO.mapRequired("DirectoryBlocks", Obj.DirectoryBlocks);
|
||||
IO.mapRequired("NumStreams", Obj.NumStreams);
|
||||
IO.mapRequired("FileSize", Obj.FileSize);
|
||||
}
|
||||
|
||||
void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
|
||||
IO.mapOptional("MSF", Obj.Headers);
|
||||
IO.mapOptional("StreamSizes", Obj.StreamSizes);
|
||||
IO.mapOptional("StreamMap", Obj.StreamMap);
|
||||
IO.mapOptional("PdbStream", Obj.PdbStream);
|
||||
}
|
||||
|
||||
void MappingTraits<PdbInfoStream>::mapping(IO &IO, PdbInfoStream &Obj) {
|
||||
IO.mapRequired("Age", Obj.Age);
|
||||
IO.mapRequired("Guid", Obj.Guid);
|
||||
IO.mapRequired("Signature", Obj.Signature);
|
||||
IO.mapRequired("Version", Obj.Version);
|
||||
}
|
||||
}
|
||||
|
||||
void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
|
||||
IO.mapRequired("VerHeader", Obj.VerHeader);
|
||||
IO.mapRequired("Age", Obj.Age);
|
||||
IO.mapRequired("BuildNumber", Obj.BuildNumber);
|
||||
IO.mapRequired("PdbDllVersion", Obj.PdbDllVersion);
|
||||
IO.mapRequired("PdbDllRbld", Obj.PdbDllRbld);
|
||||
IO.mapRequired("Flags", Obj.Flags);
|
||||
IO.mapRequired("MachineType", Obj.MachineType);
|
||||
}
|
||||
|
@ -39,17 +39,28 @@ struct StreamBlockList {
|
||||
};
|
||||
|
||||
struct PdbInfoStream {
|
||||
uint32_t Version;
|
||||
PdbRaw_ImplVer Version;
|
||||
uint32_t Signature;
|
||||
uint32_t Age;
|
||||
PDB_UniqueId Guid;
|
||||
};
|
||||
|
||||
struct PdbDbiStream {
|
||||
PdbRaw_DbiVer VerHeader;
|
||||
uint32_t Age;
|
||||
uint16_t BuildNumber;
|
||||
uint32_t PdbDllVersion;
|
||||
uint16_t PdbDllRbld;
|
||||
uint16_t Flags;
|
||||
PDB_Machine MachineType;
|
||||
};
|
||||
|
||||
struct PdbObject {
|
||||
Optional<MsfHeaders> Headers;
|
||||
Optional<std::vector<support::ulittle32_t>> StreamSizes;
|
||||
Optional<std::vector<StreamBlockList>> StreamMap;
|
||||
Optional<PdbInfoStream> PdbStream;
|
||||
Optional<PdbDbiStream> DbiStream;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -58,6 +69,14 @@ struct PdbObject {
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
|
||||
template <> struct MappingTraits<pdb::yaml::PdbObject> {
|
||||
static void mapping(IO &IO, pdb::yaml::PdbObject &Obj);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<pdb::yaml::MsfHeaders> {
|
||||
static void mapping(IO &IO, pdb::yaml::MsfHeaders &Obj);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<pdb::PDBFile::SuperBlock> {
|
||||
static void mapping(IO &IO, pdb::PDBFile::SuperBlock &SB);
|
||||
};
|
||||
@ -66,17 +85,13 @@ template <> struct MappingTraits<pdb::yaml::StreamBlockList> {
|
||||
static void mapping(IO &IO, pdb::yaml::StreamBlockList &SB);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<pdb::yaml::MsfHeaders> {
|
||||
static void mapping(IO &IO, pdb::yaml::MsfHeaders &Obj);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<pdb::yaml::PdbObject> {
|
||||
static void mapping(IO &IO, pdb::yaml::PdbObject &Obj);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<pdb::yaml::PdbInfoStream> {
|
||||
static void mapping(IO &IO, pdb::yaml::PdbInfoStream &Obj);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<pdb::yaml::PdbDbiStream> {
|
||||
static void mapping(IO &IO, pdb::yaml::PdbDbiStream &Obj);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "PdbYaml.h"
|
||||
#include "llvm-pdbdump.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||
@ -22,7 +23,8 @@ using namespace llvm::pdb;
|
||||
YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) : File(File), Out(outs()) {}
|
||||
|
||||
Error YAMLOutputStyle::dump() {
|
||||
if (opts::pdb2yaml::StreamDirectory || opts::pdb2yaml::PdbStream)
|
||||
if (opts::pdb2yaml::StreamDirectory || opts::pdb2yaml::PdbStream ||
|
||||
opts::pdb2yaml::DbiStream)
|
||||
opts::pdb2yaml::StreamMetadata = true;
|
||||
|
||||
if (auto EC = dumpFileHeaders())
|
||||
@ -37,6 +39,9 @@ Error YAMLOutputStyle::dump() {
|
||||
if (auto EC = dumpPDBStream())
|
||||
return EC;
|
||||
|
||||
if (auto EC = dumpDbiStream())
|
||||
return EC;
|
||||
|
||||
flush();
|
||||
return Error::success();
|
||||
}
|
||||
@ -105,6 +110,26 @@ Error YAMLOutputStyle::dumpPDBStream() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error YAMLOutputStyle::dumpDbiStream() {
|
||||
if (!opts::pdb2yaml::DbiStream)
|
||||
return Error::success();
|
||||
|
||||
auto DbiS = File.getPDBDbiStream();
|
||||
if (!DbiS)
|
||||
return DbiS.takeError();
|
||||
|
||||
auto &DS = DbiS.get();
|
||||
Obj.DbiStream.emplace();
|
||||
Obj.DbiStream->Age = DS.getAge();
|
||||
Obj.DbiStream->BuildNumber = DS.getBuildNumber();
|
||||
Obj.DbiStream->Flags = DS.getFlags();
|
||||
Obj.DbiStream->MachineType = DS.getMachineType();
|
||||
Obj.DbiStream->PdbDllRbld = DS.getPdbDllRbld();
|
||||
Obj.DbiStream->PdbDllVersion = DS.getPdbDllVersion();
|
||||
Obj.DbiStream->VerHeader = DS.getDbiVersion();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void YAMLOutputStyle::flush() {
|
||||
Out << Obj;
|
||||
outs().flush();
|
||||
|
@ -30,6 +30,7 @@ private:
|
||||
Error dumpStreamMetadata();
|
||||
Error dumpStreamDirectory();
|
||||
Error dumpPDBStream();
|
||||
Error dumpDbiStream();
|
||||
|
||||
void flush();
|
||||
|
||||
|
@ -40,8 +40,12 @@
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolThunk.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/RawConstants.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
|
||||
@ -279,6 +283,10 @@ cl::opt<bool> PdbStream(
|
||||
"pdb-stream",
|
||||
cl::desc("Dump the PDB Stream (Stream 1) (implies -stream-metadata)"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
cl::opt<bool> DbiStream(
|
||||
"dbi-stream",
|
||||
cl::desc("Dump the DBI Stream (Stream 2) (implies -stream-metadata)"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
|
||||
cl::list<std::string> InputFilename(cl::Positional,
|
||||
cl::desc("<input PDB file>"), cl::Required,
|
||||
@ -314,34 +322,48 @@ static void yamlToPdb(StringRef Path) {
|
||||
|
||||
auto FileByteStream =
|
||||
llvm::make_unique<FileBufferByteStream>(std::move(*OutFileOrError));
|
||||
PDBFile Pdb(std::move(FileByteStream));
|
||||
ExitOnErr(Pdb.setSuperBlock(&YamlObj.Headers->SuperBlock));
|
||||
PDBFileBuilder Builder(std::move(FileByteStream));
|
||||
|
||||
ExitOnErr(Builder.setSuperBlock(YamlObj.Headers->SuperBlock));
|
||||
if (YamlObj.StreamSizes.hasValue()) {
|
||||
Pdb.setStreamSizes(YamlObj.StreamSizes.getValue());
|
||||
Builder.setStreamSizes(YamlObj.StreamSizes.getValue());
|
||||
}
|
||||
Pdb.setDirectoryBlocks(YamlObj.Headers->DirectoryBlocks);
|
||||
Builder.setDirectoryBlocks(YamlObj.Headers->DirectoryBlocks);
|
||||
|
||||
if (YamlObj.StreamMap.hasValue()) {
|
||||
std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
|
||||
for (auto &E : YamlObj.StreamMap.getValue()) {
|
||||
StreamMap.push_back(E.Blocks);
|
||||
}
|
||||
Pdb.setStreamMap(StreamMap);
|
||||
Builder.setStreamMap(StreamMap);
|
||||
} else {
|
||||
ExitOnErr(Pdb.generateSimpleStreamMap());
|
||||
ExitOnErr(Builder.generateSimpleStreamMap());
|
||||
}
|
||||
|
||||
if (YamlObj.PdbStream.hasValue()) {
|
||||
auto IS = Pdb.emplacePDBInfoStream();
|
||||
ExitOnErr(IS.takeError());
|
||||
auto &InfoS = IS.get();
|
||||
InfoS.setAge(YamlObj.PdbStream->Age);
|
||||
InfoS.setGuid(YamlObj.PdbStream->Guid);
|
||||
InfoS.setSignature(YamlObj.PdbStream->Signature);
|
||||
InfoS.setVersion(static_cast<PdbRaw_ImplVer>(YamlObj.PdbStream->Version));
|
||||
auto &InfoBuilder = Builder.getInfoBuilder();
|
||||
InfoBuilder.setAge(YamlObj.PdbStream->Age);
|
||||
InfoBuilder.setGuid(YamlObj.PdbStream->Guid);
|
||||
InfoBuilder.setSignature(YamlObj.PdbStream->Signature);
|
||||
InfoBuilder.setVersion(YamlObj.PdbStream->Version);
|
||||
}
|
||||
|
||||
ExitOnErr(Pdb.commit());
|
||||
if (YamlObj.DbiStream.hasValue()) {
|
||||
auto &DbiBuilder = Builder.getDbiBuilder();
|
||||
DbiBuilder.setAge(YamlObj.DbiStream->Age);
|
||||
DbiBuilder.setBuildNumber(YamlObj.DbiStream->BuildNumber);
|
||||
DbiBuilder.setFlags(YamlObj.DbiStream->Flags);
|
||||
DbiBuilder.setMachineType(YamlObj.DbiStream->MachineType);
|
||||
DbiBuilder.setPdbDllRbld(YamlObj.DbiStream->PdbDllRbld);
|
||||
DbiBuilder.setPdbDllVersion(YamlObj.DbiStream->PdbDllVersion);
|
||||
DbiBuilder.setVersionHeader(YamlObj.DbiStream->VerHeader);
|
||||
}
|
||||
|
||||
auto Pdb = Builder.build();
|
||||
ExitOnErr(Pdb.takeError());
|
||||
|
||||
auto &PdbFile = *Pdb;
|
||||
ExitOnErr(PdbFile->commit());
|
||||
}
|
||||
|
||||
static void pdb2Yaml(StringRef Path) {
|
||||
|
@ -61,6 +61,7 @@ extern llvm::cl::opt<bool> NoFileHeaders;
|
||||
extern llvm::cl::opt<bool> StreamMetadata;
|
||||
extern llvm::cl::opt<bool> StreamDirectory;
|
||||
extern llvm::cl::opt<bool> PdbStream;
|
||||
extern llvm::cl::opt<bool> DbiStream;
|
||||
extern llvm::cl::list<std::string> InputFilename;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user