mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-25 02:28:18 +00:00
[pdb] Write the Named Stream mapping to Yaml and binary.
Differential Revision: https://reviews.llvm.org/D28919 llvm-svn: 292665
This commit is contained in:
parent
60667ca0b2
commit
760ad4da60
@ -29,6 +29,7 @@
|
||||
#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/StringTableBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
|
||||
#include "llvm/Object/COFF.h"
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
uint32_t getAge() const;
|
||||
PDB_UniqueId getGuid() const;
|
||||
|
||||
const NamedStreamMap &getNamedStreams() const;
|
||||
|
||||
uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
|
||||
iterator_range<StringMapConstIterator<uint32_t>> named_streams() const;
|
||||
|
||||
|
@ -25,10 +25,11 @@ class StreamWriter;
|
||||
}
|
||||
namespace pdb {
|
||||
class PDBFile;
|
||||
class NamedStreamMap;
|
||||
|
||||
class InfoStreamBuilder {
|
||||
public:
|
||||
InfoStreamBuilder(msf::MSFBuilder &Msf);
|
||||
InfoStreamBuilder(msf::MSFBuilder &Msf, NamedStreamMap &NamedStreams);
|
||||
InfoStreamBuilder(const InfoStreamBuilder &) = delete;
|
||||
InfoStreamBuilder &operator=(const InfoStreamBuilder &) = delete;
|
||||
|
||||
@ -37,8 +38,6 @@ public:
|
||||
void setAge(uint32_t A);
|
||||
void setGuid(PDB_UniqueId G);
|
||||
|
||||
NamedStreamMap &getNamedStreamsBuilder();
|
||||
|
||||
uint32_t finalize();
|
||||
|
||||
Error finalizeMsfLayout();
|
||||
@ -54,7 +53,7 @@ private:
|
||||
uint32_t Age;
|
||||
PDB_UniqueId Guid;
|
||||
|
||||
NamedStreamMap NamedStreams;
|
||||
NamedStreamMap &NamedStreams;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,10 @@
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/NamedStreamMap.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
@ -44,11 +46,13 @@ public:
|
||||
DbiStreamBuilder &getDbiBuilder();
|
||||
TpiStreamBuilder &getTpiBuilder();
|
||||
TpiStreamBuilder &getIpiBuilder();
|
||||
StringTableBuilder &getStringTableBuilder();
|
||||
|
||||
Error commit(StringRef Filename);
|
||||
|
||||
private:
|
||||
Expected<msf::MSFLayout> finalizeMsfLayout() const;
|
||||
Error addNamedStream(StringRef Name, uint32_t Size);
|
||||
Expected<msf::MSFLayout> finalizeMsfLayout();
|
||||
|
||||
BumpPtrAllocator &Allocator;
|
||||
|
||||
@ -57,6 +61,9 @@ private:
|
||||
std::unique_ptr<DbiStreamBuilder> Dbi;
|
||||
std::unique_ptr<TpiStreamBuilder> Tpi;
|
||||
std::unique_ptr<TpiStreamBuilder> Ipi;
|
||||
|
||||
StringTableBuilder Strings;
|
||||
NamedStreamMap NamedStreams;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
// Returns the ID for S.
|
||||
uint32_t insert(StringRef S);
|
||||
|
||||
uint32_t calculateSerializedLength() const;
|
||||
uint32_t finalize();
|
||||
Error commit(msf::StreamWriter &Writer) const;
|
||||
|
||||
private:
|
||||
|
@ -75,3 +75,7 @@ uint32_t InfoStream::getSignature() const { return Signature; }
|
||||
uint32_t InfoStream::getAge() const { return Age; }
|
||||
|
||||
PDB_UniqueId InfoStream::getGuid() const { return Guid; }
|
||||
|
||||
const NamedStreamMap &InfoStream::getNamedStreams() const {
|
||||
return NamedStreams;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
|
||||
#include "llvm/DebugInfo/MSF/StreamWriter.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/NamedStreamMap.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/PDBFileBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
|
||||
|
||||
@ -21,8 +23,10 @@ using namespace llvm::codeview;
|
||||
using namespace llvm::msf;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf)
|
||||
: Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0) {}
|
||||
InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
|
||||
NamedStreamMap &NamedStreams)
|
||||
: Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Sig(-1), Age(0),
|
||||
NamedStreams(NamedStreams) {}
|
||||
|
||||
void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
|
||||
|
||||
@ -32,10 +36,6 @@ void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
|
||||
|
||||
void InfoStreamBuilder::setGuid(PDB_UniqueId G) { Guid = G; }
|
||||
|
||||
NamedStreamMap &InfoStreamBuilder::getNamedStreamsBuilder() {
|
||||
return NamedStreams;
|
||||
}
|
||||
|
||||
Error InfoStreamBuilder::finalizeMsfLayout() {
|
||||
uint32_t Length = sizeof(InfoStreamHeader) + NamedStreams.finalize();
|
||||
if (auto EC = Msf.setStreamSize(StreamPDB, Length))
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/InfoStreamBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
|
||||
|
||||
@ -44,7 +45,7 @@ MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
|
||||
|
||||
InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
|
||||
if (!Info)
|
||||
Info = llvm::make_unique<InfoStreamBuilder>(*Msf);
|
||||
Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
|
||||
return *Info;
|
||||
}
|
||||
|
||||
@ -66,7 +67,26 @@ TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
|
||||
return *Ipi;
|
||||
}
|
||||
|
||||
Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() const {
|
||||
StringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; }
|
||||
|
||||
Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
|
||||
auto ExpectedStream = Msf->addStream(Size);
|
||||
if (!ExpectedStream)
|
||||
return ExpectedStream.takeError();
|
||||
NamedStreams.set(Name, *ExpectedStream);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Expected<msf::MSFLayout> PDBFileBuilder::finalizeMsfLayout() {
|
||||
uint32_t StringTableSize = Strings.finalize();
|
||||
|
||||
if (auto EC = addNamedStream("/names", StringTableSize))
|
||||
return std::move(EC);
|
||||
if (auto EC = addNamedStream("/LinkInfo", 0))
|
||||
return std::move(EC);
|
||||
if (auto EC = addNamedStream("/src/headerblock", 0))
|
||||
return std::move(EC);
|
||||
|
||||
if (Info) {
|
||||
if (auto EC = Info->finalizeMsfLayout())
|
||||
return std::move(EC);
|
||||
@ -124,6 +144,16 @@ Error PDBFileBuilder::commit(StringRef Filename) {
|
||||
return EC;
|
||||
}
|
||||
|
||||
uint32_t StringTableStreamNo = 0;
|
||||
if (!NamedStreams.get("/names", StringTableStreamNo))
|
||||
return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
|
||||
|
||||
auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
|
||||
StringTableStreamNo);
|
||||
StreamWriter NSWriter(*NS);
|
||||
if (auto EC = Strings.commit(NSWriter))
|
||||
return EC;
|
||||
|
||||
if (Info) {
|
||||
if (auto EC = Info->commit(Layout, Buffer))
|
||||
return EC;
|
||||
|
@ -38,16 +38,17 @@ static uint32_t computeBucketCount(uint32_t NumStrings) {
|
||||
return (NumStrings + 1) * 1.25;
|
||||
}
|
||||
|
||||
uint32_t StringTableBuilder::calculateSerializedLength() const {
|
||||
uint32_t StringTableBuilder::finalize() {
|
||||
uint32_t Size = 0;
|
||||
Size += sizeof(StringTableHeader);
|
||||
Size += StringSize;
|
||||
Size += 4; // Hash table begins with 4-byte size field.
|
||||
Size += sizeof(uint32_t); // Hash table begins with 4-byte size field.
|
||||
|
||||
uint32_t BucketCount = computeBucketCount(Strings.size());
|
||||
Size += BucketCount * 4;
|
||||
Size += BucketCount * sizeof(uint32_t);
|
||||
|
||||
Size += 4; // The /names stream ends with the number of strings.
|
||||
Size +=
|
||||
sizeof(uint32_t); // The /names stream ends with the number of strings.
|
||||
return Size;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llvm-pdbdump raw -headers -tpi-records -tpi-record-bytes -module-syms \
|
||||
; RUN: llvm-pdbdump raw -headers -string-table -tpi-records -tpi-record-bytes -module-syms \
|
||||
; RUN: -sym-record-bytes -globals -publics -module-files \
|
||||
; RUN: -stream-summary -stream-blocks -ipi-records -ipi-record-bytes \
|
||||
; RUN: -section-contribs -section-map -section-headers -line-info \
|
||||
@ -61,11 +61,21 @@
|
||||
; EMPTY-NEXT: Stream 15: [21]
|
||||
; EMPTY-NEXT: Stream 16: [22]
|
||||
; EMPTY-NEXT: ]
|
||||
; EMPTY-NEXT: String Table {
|
||||
; EMPTY-NEXT: 'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
|
||||
; EMPTY-NEXT: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
|
||||
; EMPTY-NEXT: '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
|
||||
; EMPTY-NEXT: }
|
||||
; EMPTY-NEXT: PDB Stream {
|
||||
; EMPTY-NEXT: Version: 20000404
|
||||
; EMPTY-NEXT: Signature: 0x54E507E2
|
||||
; EMPTY-NEXT: Age: 1
|
||||
; EMPTY-NEXT: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
|
||||
; EMPTY-NEXT: Named Streams {
|
||||
; EMPTY-NEXT: /names: 13
|
||||
; EMPTY-NEXT: /LinkInfo: 5
|
||||
; EMPTY-NEXT: /src/headerblock: 9
|
||||
; EMPTY-NEXT: }
|
||||
; EMPTY-NEXT: }
|
||||
; EMPTY-NEXT: Type Info Stream (TPI) {
|
||||
; EMPTY-NEXT: TPI Version: 20040203
|
||||
@ -1692,6 +1702,11 @@
|
||||
; BIG-NEXT: Signature: 0x571FFE67
|
||||
; BIG-NEXT: Age: 1
|
||||
; BIG-NEXT: Guid: {880ECC89-DF81-0B4F-839C-58CBD052E937}
|
||||
; BIG-NEXT: Named Streams {
|
||||
; BIG-NEXT: /names: 13
|
||||
; BIG-NEXT: /LinkInfo: 5
|
||||
; BIG-NEXT: /src/headerblock: 61
|
||||
; BIG-NEXT: }
|
||||
; BIG-NEXT: }
|
||||
; BIG-NEXT: DBI Stream {
|
||||
; BIG-NEXT: Dbi Version: 19990903
|
||||
|
@ -1,10 +1,10 @@
|
||||
RUN: llvm-pdbdump pdb2yaml -dbi-module-info -dbi-module-source-info \
|
||||
RUN: -dbi-stream -pdb-stream -tpi-stream -stream-directory \
|
||||
RUN: -dbi-stream -pdb-stream -string-table -tpi-stream -stream-directory \
|
||||
RUN: -stream-metadata %p/Inputs/empty.pdb > %t.1
|
||||
RUN: llvm-pdbdump yaml2pdb -pdb=%t.2 %t.1
|
||||
|
||||
RUN: llvm-pdbdump raw -headers -tpi-records %p/Inputs/empty.pdb | FileCheck %s
|
||||
RUN: llvm-pdbdump raw -headers -tpi-records %t.2 | FileCheck %s
|
||||
RUN: llvm-pdbdump raw -headers -string-table -tpi-records %p/Inputs/empty.pdb | FileCheck %s
|
||||
RUN: llvm-pdbdump raw -headers -string-table -tpi-records %t.2 | FileCheck %s
|
||||
|
||||
CHECK: FileHeaders {
|
||||
CHECK-NEXT: BlockSize: 4096
|
||||
@ -17,11 +17,19 @@ CHECK-NEXT: NumDirectoryBlocks: 1
|
||||
CHECK-NEXT: DirectoryBlocks:
|
||||
CHECK-NEXT: NumStreams:
|
||||
CHECK-NEXT: }
|
||||
CHECK: String Table {
|
||||
CHECK-DAG: 'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
|
||||
CHECK-DAG: 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
|
||||
CHECK-DAG: '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
|
||||
CHECK-NEXT: }
|
||||
CHECK: PDB Stream {
|
||||
CHECK-NEXT: Version: 20000404
|
||||
CHECK-NEXT: Signature: 0x54E507E2
|
||||
CHECK-NEXT: Age: 1
|
||||
CHECK-NEXT: Guid: {0B355641-86A0-A249-896F-9988FAE52FF0}
|
||||
CHECK-NEXT: Named Streams {
|
||||
CHECK: /names:
|
||||
CHECK: }
|
||||
CHECK-NEXT: }
|
||||
CHECK: Type Info Stream (TPI) {
|
||||
CHECK-NEXT: TPI Version: 20040203
|
||||
|
@ -10,8 +10,11 @@
|
||||
; stream metadata, since the layout of the MSF file might be different
|
||||
; (for example if we don't write the entire stream)
|
||||
;
|
||||
; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream -tpi-stream %p/Inputs/empty.pdb > %t.1
|
||||
; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory \
|
||||
; RUN: -pdb-stream -tpi-stream %p/Inputs/empty.pdb > %t.1
|
||||
; RUN: llvm-pdbdump yaml2pdb -pdb=%t.2 %t.1
|
||||
; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream -no-file-headers %p/Inputs/empty.pdb > %t.3
|
||||
; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream -no-file-headers %t.2 > %t.4
|
||||
; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream \
|
||||
; RUN: -no-file-headers %p/Inputs/empty.pdb > %t.3
|
||||
; RUN: llvm-pdbdump pdb2yaml -pdb-stream -tpi-stream \
|
||||
; RUN: -no-file-headers %t.2 > %t.4
|
||||
; RUN: diff %t.3 %t.4
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream %p/Inputs/empty.pdb \
|
||||
; RUN: | FileCheck -check-prefix=YAML %s
|
||||
; RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -string-table -pdb-stream \
|
||||
; RUN: %p/Inputs/empty.pdb | FileCheck -check-prefix=YAML %s
|
||||
; RUN: llvm-pdbdump pdb2yaml -no-file-headers -stream-metadata -stream-directory -pdb-stream \
|
||||
; RUN: %p/Inputs/empty.pdb | FileCheck -check-prefix=NO-HEADERS %s
|
||||
|
||||
@ -36,18 +36,15 @@
|
||||
; YAML-NEXT: - Stream: [ 7 ]
|
||||
; YAML-NEXT: - Stream: [ 21 ]
|
||||
; YAML-NEXT: - Stream: [ 22 ]
|
||||
; YAML-NEXT: StringTable:
|
||||
; YAML-NEXT: - 'd:\src\llvm\test\debuginfo\pdb\inputs\predefined c++ attributes (compiler internal)'
|
||||
; YAML-NEXT: - 'd:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp'
|
||||
; YAML-NEXT: - '$T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = '
|
||||
; YAML-NEXT: PdbStream:
|
||||
; YAML-NEXT: Age: 1
|
||||
; YAML-NEXT: Guid: '{0B355641-86A0-A249-896F-9988FAE52FF0}'
|
||||
; YAML-NEXT: Signature: 1424295906
|
||||
; YAML-NEXT: Version: VC70
|
||||
; YAML-NEXT: NamedStreams:
|
||||
; YAML-NEXT: - Name: /names
|
||||
; YAML-NEXT: StreamNum: 13
|
||||
; YAML-NEXT: - Name: /LinkInfo
|
||||
; YAML-NEXT: StreamNum: 5
|
||||
; YAML-NEXT: - Name: /src/headerblock
|
||||
; YAML-NEXT: StreamNum: 9
|
||||
; YAML-NEXT: ...
|
||||
|
||||
; NO-HEADERS: ---
|
||||
|
@ -113,6 +113,9 @@ Error LLVMOutputStyle::dump() {
|
||||
if (auto EC = dumpStreamBytes())
|
||||
return EC;
|
||||
|
||||
if (auto EC = dumpStringTable())
|
||||
return EC;
|
||||
|
||||
if (auto EC = dumpInfoStream())
|
||||
return EC;
|
||||
|
||||
@ -456,6 +459,28 @@ Error LLVMOutputStyle::dumpStreamBytes() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error LLVMOutputStyle::dumpStringTable() {
|
||||
if (!opts::raw::DumpStringTable)
|
||||
return Error::success();
|
||||
|
||||
auto IS = File.getStringTable();
|
||||
if (!IS)
|
||||
return IS.takeError();
|
||||
|
||||
DictScope D(P, "String Table");
|
||||
for (uint32_t I : IS->name_ids()) {
|
||||
StringRef S = IS->getStringForID(I);
|
||||
if (!S.empty()) {
|
||||
llvm::SmallString<32> Str;
|
||||
Str.append("'");
|
||||
Str.append(S);
|
||||
Str.append("'");
|
||||
P.printString(Str);
|
||||
}
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error LLVMOutputStyle::dumpInfoStream() {
|
||||
if (!opts::raw::DumpHeaders)
|
||||
return Error::success();
|
||||
@ -472,6 +497,11 @@ Error LLVMOutputStyle::dumpInfoStream() {
|
||||
P.printHex("Signature", IS->getSignature());
|
||||
P.printNumber("Age", IS->getAge());
|
||||
P.printObject("Guid", IS->getGuid());
|
||||
{
|
||||
DictScope DD(P, "Named Streams");
|
||||
for (const auto &S : IS->getNamedStreams().entries())
|
||||
P.printObject(S.getKey(), S.getValue());
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
Error dumpGlobalsStream();
|
||||
Error dumpStreamBytes();
|
||||
Error dumpStreamBlocks();
|
||||
Error dumpStringTable();
|
||||
Error dumpInfoStream();
|
||||
Error dumpTpiStream(uint32_t StreamIdx);
|
||||
Error dumpDbiStream();
|
||||
|
@ -140,6 +140,7 @@ 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("StringTable", Obj.StringTable);
|
||||
IO.mapOptional("PdbStream", Obj.PdbStream);
|
||||
IO.mapOptional("DbiStream", Obj.DbiStream);
|
||||
IO.mapOptionalWithContext("TpiStream", Obj.TpiStream, Obj.Allocator);
|
||||
@ -176,7 +177,6 @@ void MappingTraits<PdbInfoStream>::mapping(IO &IO, PdbInfoStream &Obj) {
|
||||
IO.mapRequired("Guid", Obj.Guid);
|
||||
IO.mapRequired("Signature", Obj.Signature);
|
||||
IO.mapRequired("Version", Obj.Version);
|
||||
IO.mapRequired("NamedStreams", Obj.NamedStreams);
|
||||
}
|
||||
|
||||
void MappingTraits<PdbDbiStream>::mapping(IO &IO, PdbDbiStream &Obj) {
|
||||
|
@ -107,6 +107,8 @@ struct PdbObject {
|
||||
Optional<PdbTpiStream> TpiStream;
|
||||
Optional<PdbTpiStream> IpiStream;
|
||||
|
||||
Optional<std::vector<StringRef>> StringTable;
|
||||
|
||||
BumpPtrAllocator &Allocator;
|
||||
};
|
||||
}
|
||||
|
@ -45,6 +45,9 @@ Error YAMLOutputStyle::dump() {
|
||||
if (auto EC = dumpStreamDirectory())
|
||||
return EC;
|
||||
|
||||
if (auto EC = dumpStringTable())
|
||||
return EC;
|
||||
|
||||
if (auto EC = dumpPDBStream())
|
||||
return EC;
|
||||
|
||||
@ -83,6 +86,24 @@ Error YAMLOutputStyle::dumpFileHeaders() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error YAMLOutputStyle::dumpStringTable() {
|
||||
if (!opts::pdb2yaml::StringTable)
|
||||
return Error::success();
|
||||
|
||||
Obj.StringTable.emplace();
|
||||
auto ExpectedST = File.getStringTable();
|
||||
if (!ExpectedST)
|
||||
return ExpectedST.takeError();
|
||||
|
||||
const auto &ST = ExpectedST.get();
|
||||
for (auto ID : ST.name_ids()) {
|
||||
StringRef S = ST.getStringForID(ID);
|
||||
if (!S.empty())
|
||||
Obj.StringTable->push_back(S);
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error YAMLOutputStyle::dumpStreamMetadata() {
|
||||
if (!opts::pdb2yaml::StreamMetadata)
|
||||
return Error::success();
|
||||
@ -122,12 +143,6 @@ Error YAMLOutputStyle::dumpPDBStream() {
|
||||
Obj.PdbStream->Guid = InfoS.getGuid();
|
||||
Obj.PdbStream->Signature = InfoS.getSignature();
|
||||
Obj.PdbStream->Version = InfoS.getVersion();
|
||||
for (auto &NS : InfoS.named_streams()) {
|
||||
yaml::NamedStreamMapping Mapping;
|
||||
Mapping.StreamName = NS.getKey();
|
||||
Mapping.StreamNumber = NS.getValue();
|
||||
Obj.PdbStream->NamedStreams.push_back(Mapping);
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
Error dump() override;
|
||||
|
||||
private:
|
||||
Error dumpStringTable();
|
||||
Error dumpFileHeaders();
|
||||
Error dumpStreamMetadata();
|
||||
Error dumpStreamDirectory();
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/RawSession.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/StringTableBuilder.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
|
||||
#include "llvm/DebugInfo/PDB/Raw/TpiStreamBuilder.h"
|
||||
#include "llvm/Support/COM.h"
|
||||
@ -232,6 +233,9 @@ cl::opt<bool>
|
||||
cl::cat(SymbolOptions), cl::sub(RawSubcommand));
|
||||
|
||||
// MISCELLANEOUS OPTIONS
|
||||
cl::opt<bool> DumpStringTable("string-table", cl::desc("dump PDB String Table"),
|
||||
cl::cat(MiscOptions), cl::sub(RawSubcommand));
|
||||
|
||||
cl::opt<bool> DumpSectionContribs("section-contribs",
|
||||
cl::desc("dump section contributions"),
|
||||
cl::cat(MiscOptions), cl::sub(RawSubcommand));
|
||||
@ -279,6 +283,10 @@ cl::opt<bool> StreamDirectory(
|
||||
cl::opt<bool> PdbStream("pdb-stream",
|
||||
cl::desc("Dump the PDB Stream (Stream 1)"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
|
||||
cl::opt<bool> StringTable("string-table", cl::desc("Dump the PDB String Table"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
|
||||
cl::opt<bool> DbiStream("dbi-stream",
|
||||
cl::desc("Dump the DBI Stream (Stream 2)"),
|
||||
cl::sub(PdbToYamlSubcommand), cl::init(false));
|
||||
@ -345,14 +353,18 @@ static void yamlToPdb(StringRef Path) {
|
||||
for (uint32_t I = 0; I < kSpecialStreamCount; ++I)
|
||||
ExitOnErr(Builder.getMsfBuilder().addStream(0));
|
||||
|
||||
if (YamlObj.StringTable.hasValue()) {
|
||||
auto &Strings = Builder.getStringTableBuilder();
|
||||
for (auto S : *YamlObj.StringTable)
|
||||
Strings.insert(S);
|
||||
}
|
||||
|
||||
if (YamlObj.PdbStream.hasValue()) {
|
||||
auto &InfoBuilder = Builder.getInfoBuilder();
|
||||
InfoBuilder.setAge(YamlObj.PdbStream->Age);
|
||||
InfoBuilder.setGuid(YamlObj.PdbStream->Guid);
|
||||
InfoBuilder.setSignature(YamlObj.PdbStream->Signature);
|
||||
InfoBuilder.setVersion(YamlObj.PdbStream->Version);
|
||||
for (auto &NM : YamlObj.PdbStream->NamedStreams)
|
||||
InfoBuilder.getNamedStreamsBuilder().set(NM.StreamName, NM.StreamNumber);
|
||||
}
|
||||
|
||||
if (YamlObj.DbiStream.hasValue()) {
|
||||
@ -579,6 +591,7 @@ int main(int argc_, const char *argv_[]) {
|
||||
opts::raw::DumpSectionContribs = true;
|
||||
opts::raw::DumpLineInfo = true;
|
||||
opts::raw::DumpFpo = true;
|
||||
opts::raw::DumpStringTable = true;
|
||||
}
|
||||
|
||||
if (opts::raw::CompactRecords &&
|
||||
|
@ -64,12 +64,14 @@ extern llvm::cl::opt<bool> DumpSectionMap;
|
||||
extern llvm::cl::opt<bool> DumpSymRecordBytes;
|
||||
extern llvm::cl::opt<bool> DumpSectionHeaders;
|
||||
extern llvm::cl::opt<bool> DumpFpo;
|
||||
extern llvm::cl::opt<bool> DumpStringTable;
|
||||
}
|
||||
|
||||
namespace pdb2yaml {
|
||||
extern llvm::cl::opt<bool> NoFileHeaders;
|
||||
extern llvm::cl::opt<bool> StreamMetadata;
|
||||
extern llvm::cl::opt<bool> StreamDirectory;
|
||||
extern llvm::cl::opt<bool> StringTable;
|
||||
extern llvm::cl::opt<bool> PdbStream;
|
||||
extern llvm::cl::opt<bool> DbiStream;
|
||||
extern llvm::cl::opt<bool> DbiModuleInfo;
|
||||
|
@ -32,7 +32,7 @@ TEST_F(StringTableBuilderTest, Simple) {
|
||||
EXPECT_EQ(1U, Builder.insert("foo"));
|
||||
EXPECT_EQ(9U, Builder.insert("baz"));
|
||||
|
||||
std::vector<uint8_t> Buffer(Builder.calculateSerializedLength());
|
||||
std::vector<uint8_t> Buffer(Builder.finalize());
|
||||
msf::MutableByteStream OutStream(Buffer);
|
||||
msf::StreamWriter Writer(OutStream);
|
||||
EXPECT_NO_ERROR(Builder.commit(Writer));
|
||||
|
Loading…
x
Reference in New Issue
Block a user