forked from OSchip/llvm-project
[pdb] Write the IPI stream.
The IPI stream is structurally identical to the TPI stream, but it contains different record types. So we just re-use the TPI writing code. llvm-svn: 281638
This commit is contained in:
parent
d93c4c0137
commit
de9ba15511
|
@ -42,6 +42,7 @@ public:
|
|||
InfoStreamBuilder &getInfoBuilder();
|
||||
DbiStreamBuilder &getDbiBuilder();
|
||||
TpiStreamBuilder &getTpiBuilder();
|
||||
TpiStreamBuilder &getIpiBuilder();
|
||||
|
||||
Expected<std::unique_ptr<PDBFile>>
|
||||
build(std::unique_ptr<msf::WritableStream> PdbFileBuffer);
|
||||
|
@ -57,6 +58,7 @@ private:
|
|||
std::unique_ptr<InfoStreamBuilder> Info;
|
||||
std::unique_ptr<DbiStreamBuilder> Dbi;
|
||||
std::unique_ptr<TpiStreamBuilder> Tpi;
|
||||
std::unique_ptr<TpiStreamBuilder> Ipi;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ struct TpiStreamHeader;
|
|||
|
||||
class TpiStreamBuilder {
|
||||
public:
|
||||
explicit TpiStreamBuilder(msf::MSFBuilder &Msf);
|
||||
explicit TpiStreamBuilder(msf::MSFBuilder &Msf, uint32_t StreamIdx);
|
||||
~TpiStreamBuilder();
|
||||
|
||||
TpiStreamBuilder(const TpiStreamBuilder &) = delete;
|
||||
|
@ -77,6 +77,7 @@ private:
|
|||
std::unique_ptr<msf::ByteStream> HashValueStream;
|
||||
|
||||
const TpiStreamHeader *Header;
|
||||
uint32_t Idx;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,16 @@ DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
|
|||
|
||||
TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
|
||||
if (!Tpi)
|
||||
Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf);
|
||||
Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
|
||||
return *Tpi;
|
||||
}
|
||||
|
||||
TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
|
||||
if (!Ipi)
|
||||
Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
|
||||
return *Ipi;
|
||||
}
|
||||
|
||||
Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
|
||||
if (Info) {
|
||||
if (auto EC = Info->finalizeMsfLayout())
|
||||
|
@ -79,6 +85,10 @@ Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
|
|||
if (auto EC = Tpi->finalizeMsfLayout())
|
||||
return std::move(EC);
|
||||
}
|
||||
if (Ipi) {
|
||||
if (auto EC = Ipi->finalizeMsfLayout())
|
||||
return std::move(EC);
|
||||
}
|
||||
|
||||
return Msf->build();
|
||||
}
|
||||
|
@ -113,6 +123,13 @@ PDBFileBuilder::build(std::unique_ptr<msf::WritableStream> PdbFileBuffer) {
|
|||
File->Tpi = std::move(*ExpectedTpi);
|
||||
}
|
||||
|
||||
if (Ipi) {
|
||||
auto ExpectedIpi = Ipi->build(*File, *PdbFileBuffer);
|
||||
if (!ExpectedIpi)
|
||||
return ExpectedIpi.takeError();
|
||||
File->Ipi = std::move(*ExpectedIpi);
|
||||
}
|
||||
|
||||
if (File->Info && File->Dbi && File->Info->getAge() != File->Dbi->getAge())
|
||||
return llvm::make_error<RawError>(
|
||||
raw_error_code::corrupt_file,
|
||||
|
@ -166,5 +183,10 @@ Error PDBFileBuilder::commit(const msf::WritableStream &Buffer) {
|
|||
return EC;
|
||||
}
|
||||
|
||||
if (Ipi) {
|
||||
if (auto EC = Ipi->commit(Layout, Buffer))
|
||||
return EC;
|
||||
}
|
||||
|
||||
return Buffer.commit();
|
||||
}
|
|
@ -15,8 +15,9 @@ using namespace llvm::msf;
|
|||
using namespace llvm::pdb;
|
||||
using namespace llvm::support;
|
||||
|
||||
TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf)
|
||||
: Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr) {}
|
||||
TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx)
|
||||
: Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {
|
||||
}
|
||||
|
||||
TpiStreamBuilder::~TpiStreamBuilder() {}
|
||||
|
||||
|
@ -75,7 +76,7 @@ uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
|
|||
|
||||
Error TpiStreamBuilder::finalizeMsfLayout() {
|
||||
uint32_t Length = calculateSerializedLength();
|
||||
if (auto EC = Msf.setStreamSize(StreamTPI, Length))
|
||||
if (auto EC = Msf.setStreamSize(Idx, Length))
|
||||
return EC;
|
||||
|
||||
uint32_t HashBufferSize = calculateHashBufferSize();
|
||||
|
@ -106,8 +107,8 @@ TpiStreamBuilder::build(PDBFile &File, const msf::WritableStream &Buffer) {
|
|||
if (auto EC = finalize())
|
||||
return std::move(EC);
|
||||
|
||||
auto StreamData = MappedBlockStream::createIndexedStream(File.getMsfLayout(),
|
||||
Buffer, StreamTPI);
|
||||
auto StreamData =
|
||||
MappedBlockStream::createIndexedStream(File.getMsfLayout(), Buffer, Idx);
|
||||
auto Tpi = llvm::make_unique<TpiStream>(File, std::move(StreamData));
|
||||
Tpi->Header = Header;
|
||||
Tpi->TypeRecords = VarStreamArray<codeview::CVType>(TypeRecordStream);
|
||||
|
@ -126,7 +127,7 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
|
|||
return EC;
|
||||
|
||||
auto InfoS =
|
||||
WritableMappedBlockStream::createIndexedStream(Layout, Buffer, StreamTPI);
|
||||
WritableMappedBlockStream::createIndexedStream(Layout, Buffer, Idx);
|
||||
|
||||
StreamWriter Writer(*InfoS);
|
||||
if (auto EC = Writer.writeObject(*Header))
|
||||
|
|
|
@ -138,6 +138,7 @@ void MappingTraits<PdbObject>::mapping(IO &IO, PdbObject &Obj) {
|
|||
IO.mapOptional("PdbStream", Obj.PdbStream);
|
||||
IO.mapOptional("DbiStream", Obj.DbiStream);
|
||||
IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Obj.Allocator);
|
||||
IO.mapOptionalWithContext("IpiStream", Obj.IpiStream, Obj.Allocator);
|
||||
}
|
||||
|
||||
void MappingTraits<MSFHeaders>::mapping(IO &IO, MSFHeaders &Obj) {
|
||||
|
|
|
@ -93,6 +93,7 @@ struct PdbObject {
|
|||
Optional<PdbInfoStream> PdbStream;
|
||||
Optional<PdbDbiStream> DbiStream;
|
||||
Optional<PdbTpiStream> TpiStream;
|
||||
Optional<PdbTpiStream> IpiStream;
|
||||
|
||||
BumpPtrAllocator &Allocator;
|
||||
};
|
||||
|
|
|
@ -50,6 +50,9 @@ Error YAMLOutputStyle::dump() {
|
|||
if (auto EC = dumpTpiStream())
|
||||
return EC;
|
||||
|
||||
if (auto EC = dumpIpiStream())
|
||||
return EC;
|
||||
|
||||
flush();
|
||||
return Error::success();
|
||||
}
|
||||
|
@ -179,6 +182,26 @@ Error YAMLOutputStyle::dumpTpiStream() {
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
Error YAMLOutputStyle::dumpIpiStream() {
|
||||
if (!opts::pdb2yaml::IpiStream)
|
||||
return Error::success();
|
||||
|
||||
auto IpiS = File.getPDBIpiStream();
|
||||
if (!IpiS)
|
||||
return IpiS.takeError();
|
||||
|
||||
auto &IS = IpiS.get();
|
||||
Obj.IpiStream.emplace();
|
||||
Obj.IpiStream->Version = IS.getTpiVersion();
|
||||
for (auto &Record : IS.types(nullptr)) {
|
||||
yaml::PdbTpiRecord R;
|
||||
R.Record = Record;
|
||||
Obj.IpiStream->Records.push_back(R);
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void YAMLOutputStyle::flush() {
|
||||
Out << Obj;
|
||||
outs().flush();
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
Error dumpPDBStream();
|
||||
Error dumpDbiStream();
|
||||
Error dumpTpiStream();
|
||||
Error dumpIpiStream();
|
||||
|
||||
void flush();
|
||||
|
||||
|
|
|
@ -290,6 +290,10 @@ cl::opt<bool> TpiStream("tpi-stream",
|
|||
cl::desc("Dump the TPI Stream (Stream 3)"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
|
||||
cl::opt<bool> IpiStream("ipi-stream",
|
||||
cl::desc("Dump the IPI Stream (Stream 5)"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
|
||||
cl::list<std::string> InputFilename(cl::Positional,
|
||||
cl::desc("<input PDB file>"), cl::Required,
|
||||
cl::sub(PdbToYamlSubcommand));
|
||||
|
@ -371,6 +375,13 @@ static void yamlToPdb(StringRef Path) {
|
|||
TpiBuilder.addTypeRecord(R.Record);
|
||||
}
|
||||
|
||||
if (YamlObj.IpiStream.hasValue()) {
|
||||
auto &IpiBuilder = Builder.getIpiBuilder();
|
||||
IpiBuilder.setVersionHeader(YamlObj.IpiStream->Version);
|
||||
for (const auto &R : YamlObj.IpiStream->Records)
|
||||
IpiBuilder.addTypeRecord(R.Record);
|
||||
}
|
||||
|
||||
ExitOnErr(Builder.commit(*FileByteStream));
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ extern llvm::cl::opt<bool> DbiStream;
|
|||
extern llvm::cl::opt<bool> DbiModuleInfo;
|
||||
extern llvm::cl::opt<bool> DbiModuleSourceFileInfo;
|
||||
extern llvm::cl::opt<bool> TpiStream;
|
||||
extern llvm::cl::opt<bool> IpiStream;
|
||||
extern llvm::cl::list<std::string> InputFilename;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue