diff options
author | Zachary Turner <zturner@google.com> | 2016-07-06 18:05:57 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2016-07-06 18:05:57 +0000 |
commit | 8bf0aed731c5f9e3042186a8023a33649a073dac (patch) | |
tree | 7bcd70523260e5360c66b40cc9d6fe4e3a7db361 /tools | |
parent | d1168ef803202c00bc52589d71d4fe182aaacd85 (diff) |
[pdb] Round trip the PDB stream between YAML and binary PDB.
This gets writing of the PDB stream working.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274647 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/llvm-pdbdump/PdbYaml.cpp | 48 | ||||
-rw-r--r-- | tools/llvm-pdbdump/PdbYaml.h | 14 | ||||
-rw-r--r-- | tools/llvm-pdbdump/YAMLOutputStyle.cpp | 25 | ||||
-rw-r--r-- | tools/llvm-pdbdump/YAMLOutputStyle.h | 1 | ||||
-rw-r--r-- | tools/llvm-pdbdump/llvm-pdbdump.cpp | 45 | ||||
-rw-r--r-- | tools/llvm-pdbdump/llvm-pdbdump.h | 1 |
6 files changed, 125 insertions, 9 deletions
diff --git a/tools/llvm-pdbdump/PdbYaml.cpp b/tools/llvm-pdbdump/PdbYaml.cpp index fa15ff2b39d..b43316a601d 100644 --- a/tools/llvm-pdbdump/PdbYaml.cpp +++ b/tools/llvm-pdbdump/PdbYaml.cpp @@ -9,6 +9,7 @@ #include "PdbYaml.h" +#include "llvm/DebugInfo/PDB/PDBExtras.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" using namespace llvm; @@ -16,6 +17,45 @@ using namespace llvm::yaml; using namespace llvm::pdb; using namespace llvm::pdb::yaml; +namespace llvm { +namespace yaml { +template <> struct ScalarTraits<llvm::pdb::PDB_UniqueId> { + static void output(const llvm::pdb::PDB_UniqueId &S, void *, + llvm::raw_ostream &OS) { + OS << S; + } + + static StringRef input(StringRef Scalar, void *Ctx, + llvm::pdb::PDB_UniqueId &S) { + if (Scalar.size() != 38) + return "GUID strings are 38 characters long"; + if (Scalar[0] != '{' || Scalar[37] != '}') + return "GUID is not enclosed in {}"; + if (Scalar[9] != '-' || Scalar[14] != '-' || Scalar[19] != '-' || + Scalar[24] != '-') + return "GUID sections are not properly delineated with dashes"; + + char *OutBuffer = S.Guid; + for (auto Iter = Scalar.begin(); Iter != Scalar.end();) { + if (*Iter == '-' || *Iter == '{' || *Iter == '}') { + ++Iter; + continue; + } + uint8_t Value = (llvm::hexDigitValue(*Iter) << 4); + ++Iter; + Value |= llvm::hexDigitValue(*Iter); + ++Iter; + *OutBuffer++ = Value; + } + + return ""; + } + + static bool mustQuote(StringRef Scalar) { return needsQuotes(Scalar); } +}; +} +} + void MappingTraits<PDBFile::SuperBlock>::mapping(IO &IO, PDBFile::SuperBlock &SB) { if (!IO.outputting()) { @@ -47,4 +87,12 @@ 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); +}
\ No newline at end of file diff --git a/tools/llvm-pdbdump/PdbYaml.h b/tools/llvm-pdbdump/PdbYaml.h index f6e070f8398..96b7d7c8db2 100644 --- a/tools/llvm-pdbdump/PdbYaml.h +++ b/tools/llvm-pdbdump/PdbYaml.h @@ -13,7 +13,9 @@ #include "OutputStyle.h" #include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" +#include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/Support/Endian.h" #include "llvm/Support/YAMLTraits.h" @@ -36,10 +38,18 @@ struct StreamBlockList { std::vector<support::ulittle32_t> Blocks; }; +struct PdbInfoStream { + uint32_t Version; + uint32_t Signature; + uint32_t Age; + PDB_UniqueId Guid; +}; + struct PdbObject { MsfHeaders Headers; Optional<std::vector<support::ulittle32_t>> StreamSizes; Optional<std::vector<StreamBlockList>> StreamMap; + Optional<PdbInfoStream> PdbStream; }; } } @@ -63,6 +73,10 @@ template <> struct MappingTraits<pdb::yaml::MsfHeaders> { 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); +}; } } diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.cpp b/tools/llvm-pdbdump/YAMLOutputStyle.cpp index d4a3582f261..32f19414dd9 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.cpp +++ b/tools/llvm-pdbdump/YAMLOutputStyle.cpp @@ -12,6 +12,7 @@ #include "PdbYaml.h" #include "llvm-pdbdump.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" @@ -21,6 +22,9 @@ using namespace llvm::pdb; YAMLOutputStyle::YAMLOutputStyle(PDBFile &File) : File(File), Out(outs()) {} Error YAMLOutputStyle::dump() { + if (opts::pdb2yaml::StreamDirectory || opts::pdb2yaml::PdbStream) + opts::pdb2yaml::StreamMetadata = true; + if (auto EC = dumpFileHeaders()) return EC; @@ -30,6 +34,9 @@ Error YAMLOutputStyle::dump() { if (auto EC = dumpStreamDirectory()) return EC; + if (auto EC = dumpPDBStream()) + return EC; + flush(); return Error::success(); } @@ -76,6 +83,24 @@ Error YAMLOutputStyle::dumpStreamDirectory() { return Error::success(); } +Error YAMLOutputStyle::dumpPDBStream() { + if (!opts::pdb2yaml::PdbStream) + return Error::success(); + + auto IS = File.getPDBInfoStream(); + if (!IS) + return IS.takeError(); + + auto &InfoS = IS.get(); + Obj.PdbStream.emplace(); + Obj.PdbStream->Age = InfoS.getAge(); + Obj.PdbStream->Guid = InfoS.getGuid(); + Obj.PdbStream->Signature = InfoS.getSignature(); + Obj.PdbStream->Version = InfoS.getVersion(); + + return Error::success(); +} + void YAMLOutputStyle::flush() { Out << Obj; outs().flush(); diff --git a/tools/llvm-pdbdump/YAMLOutputStyle.h b/tools/llvm-pdbdump/YAMLOutputStyle.h index e2d39411fe6..1c7e8ace5ea 100644 --- a/tools/llvm-pdbdump/YAMLOutputStyle.h +++ b/tools/llvm-pdbdump/YAMLOutputStyle.h @@ -29,6 +29,7 @@ private: Error dumpFileHeaders(); Error dumpStreamMetadata(); Error dumpStreamDirectory(); + Error dumpPDBStream(); void flush(); diff --git a/tools/llvm-pdbdump/llvm-pdbdump.cpp b/tools/llvm-pdbdump/llvm-pdbdump.cpp index 94e25004fce..1b72a1927ca 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -40,6 +40,7 @@ #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/RawConstants.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h" @@ -268,6 +269,10 @@ cl::opt<bool> StreamDirectory( "stream-directory", cl::desc("Dump each stream's block map (implies -stream-metadata)"), cl::sub(PdbToYamlSubcommand)); +cl::opt<bool> PdbStream( + "pdb-stream", + cl::desc("Dump the PDB Stream (Stream 1) (implies -stream-metadata)"), + cl::sub(PdbToYamlSubcommand)); cl::list<std::string> InputFilename(cl::Positional, cl::desc("<input PDB file>"), cl::Required, @@ -302,31 +307,53 @@ static void yamlToPdb(StringRef Path) { llvm::make_unique<FileBufferByteStream>(std::move(*OutFileOrError)); PDBFile Pdb(std::move(FileByteStream)); ExitOnErr(Pdb.setSuperBlock(&YamlObj.Headers.SuperBlock)); + if (YamlObj.StreamSizes.hasValue()) { + Pdb.setStreamSizes(YamlObj.StreamSizes.getValue()); + } + Pdb.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(YamlObj.Headers.DirectoryBlocks, StreamMap); + Pdb.setStreamMap(StreamMap); + } else { + ExitOnErr(Pdb.generateSimpleStreamMap()); } - if (YamlObj.StreamSizes.hasValue()) { - Pdb.setStreamSizes(YamlObj.StreamSizes.getValue()); + + 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)); } ExitOnErr(Pdb.commit()); } +static void pdb2Yaml(StringRef Path) { + std::unique_ptr<IPDBSession> Session; + ExitOnErr(loadDataForPDB(PDB_ReaderType::Raw, Path, Session)); + + RawSession *RS = static_cast<RawSession *>(Session.get()); + PDBFile &File = RS->getPDBFile(); + auto O = llvm::make_unique<YAMLOutputStyle>(File); + O = llvm::make_unique<YAMLOutputStyle>(File); + + ExitOnErr(O->dump()); +} + static void dumpRaw(StringRef Path) { std::unique_ptr<IPDBSession> Session; ExitOnErr(loadDataForPDB(PDB_ReaderType::Raw, Path, Session)); RawSession *RS = static_cast<RawSession *>(Session.get()); PDBFile &File = RS->getPDBFile(); - std::unique_ptr<OutputStyle> O; - if (opts::PdbToYamlSubcommand) - O = llvm::make_unique<YAMLOutputStyle>(File); - else - O = llvm::make_unique<LLVMOutputStyle>(File); + auto O = llvm::make_unique<LLVMOutputStyle>(File); ExitOnErr(O->dump()); } @@ -486,7 +513,7 @@ int main(int argc_, const char *argv_[]) { llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); if (opts::PdbToYamlSubcommand) { - dumpRaw(opts::pdb2yaml::InputFilename.front()); + pdb2Yaml(opts::pdb2yaml::InputFilename.front()); } else if (opts::YamlToPdbSubcommand) { yamlToPdb(opts::yaml2pdb::InputFilename.front()); } else if (opts::PrettySubcommand) { diff --git a/tools/llvm-pdbdump/llvm-pdbdump.h b/tools/llvm-pdbdump/llvm-pdbdump.h index b6b85c074f9..412edaaec96 100644 --- a/tools/llvm-pdbdump/llvm-pdbdump.h +++ b/tools/llvm-pdbdump/llvm-pdbdump.h @@ -59,6 +59,7 @@ extern llvm::cl::opt<bool> DumpFpo; namespace pdb2yaml { extern llvm::cl::opt<bool> StreamMetadata; extern llvm::cl::opt<bool> StreamDirectory; +extern llvm::cl::opt<bool> PdbStream; extern llvm::cl::list<std::string> InputFilename; } } |