diff options
Diffstat (limited to 'llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp')
-rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index 1f6b778c4b2..a7d43ed064c 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" +#include "llvm/DebugInfo/CodeView/ByteStream.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/IPDBRawSymbol.h" @@ -46,6 +47,7 @@ #include "llvm/Support/COM.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" @@ -60,6 +62,21 @@ using namespace llvm; using namespace llvm::codeview; using namespace llvm::pdb; +namespace { +// A simple adapter that acts like a ByteStream but holds ownership over +// and underlying FileOutputBuffer. +class FileBufferByteStream : public ByteStream<true> { +public: + FileBufferByteStream(std::unique_ptr<FileOutputBuffer> Buffer) + : ByteStream(MutableArrayRef<uint8_t>(Buffer->getBufferStart(), + Buffer->getBufferEnd())), + FileBuffer(std::move(Buffer)) {} + +private: + std::unique_ptr<FileOutputBuffer> FileBuffer; +}; +} + namespace opts { enum class PDB_DumpType { ByType, ByObjFile, Both }; @@ -163,6 +180,14 @@ cl::opt<bool> cl::desc("Implies most other options in 'Native Options' category"), cl::cat(NativeOptions)); +cl::opt<bool> + YamlToPdb("yaml-to-pdb", + cl::desc("The input file is yaml, and the tool outputs a pdb"), + cl::cat(NativeOptions)); +cl::opt<std::string> YamlPdbOutputFile( + "pdb-output", cl::desc("When yaml-to-pdb is specified, the output file"), + cl::cat(NativeOptions)); + cl::list<std::string> ExcludeTypes("exclude-types", cl::desc("Exclude types by regular expression"), @@ -307,6 +332,45 @@ bool isRawDumpEnabled() { return false; } +static void yamlToPdb(StringRef Path) { + ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer = + MemoryBuffer::getFileOrSTDIN(Path, /*FileSize=*/-1, + /*RequiresNullTerminator=*/false); + + if (ErrorOrBuffer.getError()) { + ExitOnErr(make_error<GenericError>(generic_error_code::invalid_path, Path)); + } + + std::unique_ptr<MemoryBuffer> &Buffer = ErrorOrBuffer.get(); + + llvm::yaml::Input In(Buffer->getBuffer()); + pdb::yaml::PdbObject YamlObj; + In >> YamlObj; + + auto OutFileOrError = FileOutputBuffer::create(opts::YamlPdbOutputFile, + YamlObj.Headers.FileSize); + if (OutFileOrError.getError()) + ExitOnErr(make_error<GenericError>(generic_error_code::invalid_path, + opts::YamlPdbOutputFile)); + + auto FileByteStream = + llvm::make_unique<FileBufferByteStream>(std::move(*OutFileOrError)); + PDBFile Pdb(std::move(FileByteStream)); + Pdb.setSuperBlock(&YamlObj.Headers.SuperBlock); + 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); + } + if (YamlObj.StreamSizes.hasValue()) { + Pdb.setStreamSizes(YamlObj.StreamSizes.getValue()); + } + + Pdb.commit(); +} + static void dumpInput(StringRef Path) { std::unique_ptr<IPDBSession> Session; if (isRawDumpEnabled()) { @@ -494,8 +558,13 @@ int main(int argc_, const char *argv_[]) { llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); - std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), - dumpInput); + if (opts::YamlToPdb) { + std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), + yamlToPdb); + } else { + std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), + dumpInput); + } outs().flush(); return 0; |