summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-07-06 18:05:57 +0000
committerZachary Turner <zturner@google.com>2016-07-06 18:05:57 +0000
commit8bf0aed731c5f9e3042186a8023a33649a073dac (patch)
tree7bcd70523260e5360c66b40cc9d6fe4e3a7db361 /tools
parentd1168ef803202c00bc52589d71d4fe182aaacd85 (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.cpp48
-rw-r--r--tools/llvm-pdbdump/PdbYaml.h14
-rw-r--r--tools/llvm-pdbdump/YAMLOutputStyle.cpp25
-rw-r--r--tools/llvm-pdbdump/YAMLOutputStyle.h1
-rw-r--r--tools/llvm-pdbdump/llvm-pdbdump.cpp45
-rw-r--r--tools/llvm-pdbdump/llvm-pdbdump.h1
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;
}
}