summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-07-16 18:04:26 +0000
committerNico Weber <nicolasweber@gmx.de>2019-07-16 18:04:26 +0000
commitd100b5dd0197df615ac0ffc1619aec796cbdc0be (patch)
tree62007d55a3c13a85269dea83c3c86a642304dfc9
parent17060f0a54b681b8c7cec2f9ab465f6a1e51d968 (diff)
downloadbcm5719-llvm-d100b5dd0197df615ac0ffc1619aec796cbdc0be.tar.gz
bcm5719-llvm-d100b5dd0197df615ac0ffc1619aec796cbdc0be.zip
Teach `llvm-pdbutil pretty -native` about `-injected-sources`
`pretty -native -injected-sources -injected-source-content` works with this patch, and produces identical output to the dia version. Differential Revision: https://reviews.llvm.org/D64428 llvm-svn: 366236
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h12
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/InjectedSourceStream.h44
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h43
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h6
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt2
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp65
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp121
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp13
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp57
-rw-r--r--llvm/test/tools/llvm-pdbutil/injected-sources-native.test30
-rw-r--r--llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp9
-rw-r--r--llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn2
12 files changed, 383 insertions, 21 deletions
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h b/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h
index e045cc28f71..aa38417bcf4 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h
@@ -72,6 +72,12 @@ public:
assert(Map->Present.test(Index));
return Map->Buckets[Index];
}
+
+ // Implement postfix op++ in terms of prefix op++ by using the superclass
+ // implementation.
+ using iterator_facade_base<HashTableIterator<ValueT>,
+ std::forward_iterator_tag,
+ const std::pair<uint32_t, ValueT>>::operator++;
HashTableIterator &operator++() {
while (Index < Map->Buckets.size()) {
++Index;
@@ -94,9 +100,6 @@ private:
template <typename ValueT>
class HashTable {
- using const_iterator = HashTableIterator<ValueT>;
- friend const_iterator;
-
struct Header {
support::ulittle32_t Size;
support::ulittle32_t Capacity;
@@ -105,6 +108,9 @@ class HashTable {
using BucketList = std::vector<std::pair<uint32_t, ValueT>>;
public:
+ using const_iterator = HashTableIterator<ValueT>;
+ friend const_iterator;
+
HashTable() { Buckets.resize(8); }
explicit HashTable(uint32_t Capacity) {
Buckets.resize(Capacity);
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/InjectedSourceStream.h b/llvm/include/llvm/DebugInfo/PDB/Native/InjectedSourceStream.h
new file mode 100644
index 00000000000..d0cac3749bc
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/InjectedSourceStream.h
@@ -0,0 +1,44 @@
+//===- InjectedSourceStream.h - PDB Headerblock Stream Access ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_RAW_PDBINJECTEDSOURCESTREAM_H
+#define LLVM_DEBUGINFO_PDB_RAW_PDBINJECTEDSOURCESTREAM_H
+
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace msf {
+class MappedBlockStream;
+}
+namespace pdb {
+class PDBFile;
+class PDBStringTable;
+
+class InjectedSourceStream {
+public:
+ InjectedSourceStream(std::unique_ptr<msf::MappedBlockStream> Stream);
+ Error reload(const PDBStringTable &Strings);
+
+ using const_iterator = HashTable<SrcHeaderBlockEntry>::const_iterator;
+ const_iterator begin() const { return InjectedSourceTable.begin(); }
+ const_iterator end() const { return InjectedSourceTable.end(); }
+
+ uint32_t size() const { return InjectedSourceTable.size(); }
+
+private:
+ std::unique_ptr<msf::MappedBlockStream> Stream;
+
+ const SrcHeaderBlockHeader* Header;
+ HashTable<SrcHeaderBlockEntry> InjectedSourceTable;
+};
+}
+}
+
+#endif
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h b/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h
new file mode 100644
index 00000000000..ca1e22bd82a
--- /dev/null
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h
@@ -0,0 +1,43 @@
+//==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMINJECTEDSOURCES_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMINJECTEDSOURCES_H
+
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
+#include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
+
+namespace llvm {
+namespace pdb {
+
+class InjectedSourceStream;
+class PDBStringTable;
+
+class NativeEnumInjectedSources : public IPDBEnumChildren<IPDBInjectedSource> {
+public:
+ NativeEnumInjectedSources(PDBFile &File, const InjectedSourceStream &IJS,
+ const PDBStringTable &Strings);
+
+ uint32_t getChildCount() const override;
+ std::unique_ptr<IPDBInjectedSource>
+ getChildAtIndex(uint32_t Index) const override;
+ std::unique_ptr<IPDBInjectedSource> getNext() override;
+ void reset() override;
+
+private:
+ PDBFile &File;
+ const InjectedSourceStream &Stream;
+ const PDBStringTable &Strings;
+ InjectedSourceStream::const_iterator Cur;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
index 92c1e0fe2fe..56de4030167 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/PDBFile.h
@@ -32,6 +32,7 @@ namespace pdb {
class DbiStream;
class GlobalsStream;
class InfoStream;
+class InjectedSourceStream;
class PDBStringTable;
class PDBFileBuilder;
class PublicsStream;
@@ -87,6 +88,8 @@ public:
createIndexedStream(uint16_t SN) const;
Expected<std::unique_ptr<msf::MappedBlockStream>>
safelyCreateIndexedStream(uint32_t StreamIndex) const;
+ Expected<std::unique_ptr<msf::MappedBlockStream>>
+ safelyCreateNamedStream(StringRef Name);
msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const;
msf::MSFStreamLayout getFpmStreamLayout() const;
@@ -102,6 +105,7 @@ public:
Expected<PublicsStream &> getPDBPublicsStream();
Expected<SymbolStream &> getPDBSymbolStream();
Expected<PDBStringTable &> getStringTable();
+ Expected<InjectedSourceStream &> getInjectedSourceStream();
BumpPtrAllocator &getAllocator() { return Allocator; }
@@ -113,6 +117,7 @@ public:
bool hasPDBSymbolStream();
bool hasPDBTpiStream() const;
bool hasPDBStringTable();
+ bool hasPDBInjectedSourceStream();
uint32_t getPointerSize();
@@ -133,6 +138,7 @@ private:
std::unique_ptr<SymbolStream> Symbols;
std::unique_ptr<msf::MappedBlockStream> DirectoryStream;
std::unique_ptr<msf::MappedBlockStream> StringTableStream;
+ std::unique_ptr<InjectedSourceStream> InjectedSources;
std::unique_ptr<PDBStringTable> Strings;
};
}
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index d9d379f6d09..0e842af9f18 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -47,9 +47,11 @@ add_pdb_impl_folder(Native
Native/HashTable.cpp
Native/InfoStream.cpp
Native/InfoStreamBuilder.cpp
+ Native/InjectedSourceStream.cpp
Native/ModuleDebugStream.cpp
Native/NativeCompilandSymbol.cpp
Native/NativeEnumGlobals.cpp
+ Native/NativeEnumInjectedSources.cpp
Native/NativeEnumModules.cpp
Native/NativeEnumTypes.cpp
Native/NativeExeSymbol.cpp
diff --git a/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp b/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
new file mode 100644
index 00000000000..3f4101db7b9
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
@@ -0,0 +1,65 @@
+//===- InjectedSourceStream.cpp - PDB Headerblock Stream Access -----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
+
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::support;
+using namespace llvm::pdb;
+
+InjectedSourceStream::InjectedSourceStream(
+ std::unique_ptr<MappedBlockStream> Stream)
+ : Stream(std::move(Stream)) {}
+
+Error InjectedSourceStream::reload(const PDBStringTable &Strings) {
+ BinaryStreamReader Reader(*Stream);
+
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+
+ if (Header->Version !=
+ static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid headerblock header version");
+
+ if (auto EC = InjectedSourceTable.load(Reader))
+ return EC;
+
+ for (const auto& Entry : *this) {
+ if (Entry.second.Size != sizeof(SrcHeaderBlockEntry))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid headerbock entry size");
+ if (Entry.second.Version !=
+ static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid headerbock entry version");
+
+ // Check that all name references are valid.
+ auto Name = Strings.getStringForID(Entry.second.FileNI);
+ if (!Name)
+ return Name.takeError();
+ auto ObjName = Strings.getStringForID(Entry.second.ObjNI);
+ if (!ObjName)
+ return ObjName.takeError();
+ auto VName = Strings.getStringForID(Entry.second.VFileNI);
+ if (!VName)
+ return VName.takeError();
+ }
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
new file mode 100644
index 00000000000..7c7901b708c
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
@@ -0,0 +1,121 @@
+//==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
+
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+
+namespace llvm {
+namespace pdb {
+
+namespace {
+
+Expected<std::string> readStreamData(BinaryStream &Stream) {
+ uint32_t Offset = 0, DataLength = Stream.getLength();
+ std::string Result;
+ Result.reserve(DataLength);
+ while (Offset < DataLength) {
+ ArrayRef<uint8_t> Data;
+ if (auto E = Stream.readLongestContiguousChunk(Offset, Data))
+ return std::move(E);
+ Offset += Data.size();
+ Result += toStringRef(Data);
+ }
+ return Result;
+}
+
+class NativeInjectedSource final : public IPDBInjectedSource {
+ const SrcHeaderBlockEntry &Entry;
+ const PDBStringTable &Strings;
+ PDBFile &File;
+
+public:
+ NativeInjectedSource(const SrcHeaderBlockEntry &Entry,
+ PDBFile &File, const PDBStringTable &Strings)
+ : Entry(Entry), Strings(Strings), File(File) {}
+
+ uint32_t getCrc32() const override { return Entry.CRC; }
+ uint64_t getCodeByteSize() const override { return Entry.FileSize; }
+
+ std::string getFileName() const override {
+ auto Name = Strings.getStringForID(Entry.FileNI);
+ assert(Name && "InjectedSourceStream should have rejected this");
+ return *Name;
+ }
+
+ std::string getObjectFileName() const override {
+ auto ObjName = Strings.getStringForID(Entry.ObjNI);
+ assert(ObjName && "InjectedSourceStream should have rejected this");
+ return *ObjName;
+ }
+
+ std::string getVirtualFileName() const override {
+ auto VName = Strings.getStringForID(Entry.VFileNI);
+ assert(VName && "InjectedSourceStream should have rejected this");
+ return *VName;
+ }
+
+ PDB_SourceCompression getCompression() const override {
+ return static_cast<PDB_SourceCompression>(Entry.Compression);
+ }
+
+ std::string getCode() const override {
+ // Get name of stream storing the data.
+ auto VName = Strings.getStringForID(Entry.VFileNI);
+ assert(VName && "InjectedSourceStream should have rejected this");
+ std::string StreamName = ("/src/files/" + *VName).str();
+
+ // Find stream with that name and read its data.
+ // FIXME: Consider validating (or even loading) all this in
+ // InjectedSourceStream so that no error can happen here.
+ auto ExpectedFileStream = File.safelyCreateNamedStream(StreamName);
+ if (!ExpectedFileStream) {
+ consumeError(ExpectedFileStream.takeError());
+ return "(failed to open data stream)";
+ }
+
+ auto Data = readStreamData(**ExpectedFileStream);
+ if (!Data) {
+ consumeError(Data.takeError());
+ return "(failed to read data)";
+ }
+ return *Data;
+ }
+};
+
+} // namespace
+
+NativeEnumInjectedSources::NativeEnumInjectedSources(
+ PDBFile &File, const InjectedSourceStream &IJS,
+ const PDBStringTable &Strings)
+ : File(File), Stream(IJS), Strings(Strings), Cur(Stream.begin()) {}
+
+uint32_t NativeEnumInjectedSources::getChildCount() const {
+ return static_cast<uint32_t>(Stream.size());
+}
+
+std::unique_ptr<IPDBInjectedSource>
+NativeEnumInjectedSources::getChildAtIndex(uint32_t N) const {
+ if (N >= getChildCount())
+ return nullptr;
+ return make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
+ File, Strings);
+}
+
+std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
+ if (Cur == Stream.end())
+ return nullptr;
+ return make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
+}
+
+void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
+
+}
+}
diff --git a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 5fb2ea3fec5..8a49cb1c596 100644
--- a/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -13,6 +13,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
@@ -191,7 +192,17 @@ std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
std::unique_ptr<IPDBEnumInjectedSources>
NativeSession::getInjectedSources() const {
- return nullptr;
+ auto ISS = Pdb->getInjectedSourceStream();
+ if (!ISS) {
+ consumeError(ISS.takeError());
+ return nullptr;
+ }
+ auto Strings = Pdb->getStringTable();
+ if (!Strings) {
+ consumeError(Strings.takeError());
+ return nullptr;
+ }
+ return make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
}
std::unique_ptr<IPDBEnumSectionContribs>
diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
index f1255d5d677..983031dfcb7 100644
--- a/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
@@ -365,16 +366,7 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
Expected<PDBStringTable &> PDBFile::getStringTable() {
if (!Strings) {
- auto IS = getPDBInfoStream();
- if (!IS)
- return IS.takeError();
-
- Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
- if (!ExpectedNSI)
- return ExpectedNSI.takeError();
- uint32_t NameStreamIndex = *ExpectedNSI;
-
- auto NS = safelyCreateIndexedStream(NameStreamIndex);
+ auto NS = safelyCreateNamedStream("/names");
if (!NS)
return NS.takeError();
@@ -389,6 +381,24 @@ Expected<PDBStringTable &> PDBFile::getStringTable() {
return *Strings;
}
+Expected<InjectedSourceStream &> PDBFile::getInjectedSourceStream() {
+ if (!InjectedSources) {
+ auto IJS = safelyCreateNamedStream("/src/headerblock");
+ if (!IJS)
+ return IJS.takeError();
+
+ auto Strings = getStringTable();
+ if (!Strings)
+ return Strings.takeError();
+
+ auto IJ = llvm::make_unique<InjectedSourceStream>(std::move(*IJS));
+ if (auto EC = IJ->reload(*Strings))
+ return std::move(EC);
+ InjectedSources = std::move(IJ);
+ }
+ return *InjectedSources;
+}
+
uint32_t PDBFile::getPointerSize() {
auto DbiS = getPDBDbiStream();
if (!DbiS)
@@ -457,6 +467,19 @@ bool PDBFile::hasPDBStringTable() {
return true;
}
+bool PDBFile::hasPDBInjectedSourceStream() {
+ auto IS = getPDBInfoStream();
+ if (!IS)
+ return false;
+ Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/src/headerblock");
+ if (!ExpectedNSI) {
+ consumeError(ExpectedNSI.takeError());
+ return false;
+ }
+ assert(*ExpectedNSI < getNumStreams());
+ return true;
+}
+
/// Wrapper around MappedBlockStream::createIndexedStream() that checks if a
/// stream with that index actually exists. If it does not, the return value
/// will have an MSFError with code msf_error_code::no_stream. Else, the return
@@ -468,3 +491,17 @@ PDBFile::safelyCreateIndexedStream(uint32_t StreamIndex) const {
return make_error<RawError>(raw_error_code::no_stream);
return createIndexedStream(StreamIndex);
}
+
+Expected<std::unique_ptr<MappedBlockStream>>
+PDBFile::safelyCreateNamedStream(StringRef Name) {
+ auto IS = getPDBInfoStream();
+ if (!IS)
+ return IS.takeError();
+
+ Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex(Name);
+ if (!ExpectedNSI)
+ return ExpectedNSI.takeError();
+ uint32_t NameStreamIndex = *ExpectedNSI;
+
+ return safelyCreateIndexedStream(NameStreamIndex);
+}
diff --git a/llvm/test/tools/llvm-pdbutil/injected-sources-native.test b/llvm/test/tools/llvm-pdbutil/injected-sources-native.test
new file mode 100644
index 00000000000..374f14fc321
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbutil/injected-sources-native.test
@@ -0,0 +1,30 @@
+; This is identical to injected-sources.test, except that it uses the -native
+; mode of pretty (and hence doesn't require diasdk and runs on all platforms).
+
+; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
+; RUN: %p/Inputs/InjectedSource.pdb | FileCheck %s
+; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
+; RUN: %p/Inputs/ClassLayoutTest.pdb | FileCheck --check-prefix=NEGATIVE %s
+
+; CHECK: ---INJECTED SOURCES---
+; CHECK: c.natvis (140 bytes): obj=<null>, vname=c.natvis, crc=334478030, compression=None
+; CHECK-NEXT: <?xml version="1.0" encoding="utf-8"?>
+; CHECK-NEXT: <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+; CHECK-NEXT: </AutoVisualizer>
+; CHECK: a.natvis (140 bytes): obj=<null>, vname=a.natvis, crc=334478030, compression=None
+; CHECK-NEXT: <?xml version="1.0" encoding="utf-8"?>
+; CHECK-NEXT: <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+; CHECK-NEXT: </AutoVisualizer>
+; CHECK: b.natvis (294 bytes): obj=<null>, vname=b.natvis, crc=2059731902, compression=None
+; CHECK-NEXT: <?xml version="1.0" encoding="utf-8"?>
+; CHECK-NEXT: <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+; CHECK-NEXT: <Type Name="Baz">
+; CHECK-NEXT: <DisplayString>Third test</DisplayString>
+; CHECK-NEXT: </Type>
+; CHECK-NEXT: <Type Name="Buzz">
+; CHECK-NEXT: <DisplayString>Fourth test</DisplayString>
+; CHECK-NEXT: </Type>
+; CHECK-NEXT: </AutoVisualizer>
+
+; NEGATIVE: ---INJECTED SOURCES---
+; NEGATIVE-NEXT: There are no injected sources.
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index a19257af38d..e6e89d4bf22 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -934,7 +934,7 @@ static std::string stringOr(std::string Str, std::string IfEmpty) {
static void dumpInjectedSources(LinePrinter &Printer, IPDBSession &Session) {
auto Sources = Session.getInjectedSources();
- if (0 == Sources->getChildCount()) {
+ if (!Sources || !Sources->getChildCount()) {
Printer.printLine("There are no injected sources.");
return;
}
@@ -1279,12 +1279,7 @@ static void dumpPretty(StringRef Path) {
WithColor(Printer, PDB_ColorItem::SectionHeader).get()
<< "---INJECTED SOURCES---";
AutoIndent Indent1(Printer);
-
- if (ReaderType == PDB_ReaderType::Native)
- Printer.printLine(
- "Injected sources are not supported with the native reader.");
- else
- dumpInjectedSources(Printer, *Session);
+ dumpInjectedSources(Printer, *Session);
}
Printer.NewLine();
diff --git a/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
index 7b8adb3b49a..d38b2bb214c 100644
--- a/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/DebugInfo/PDB/BUILD.gn
@@ -24,10 +24,12 @@ static_library("PDB") {
"Native/HashTable.cpp",
"Native/InfoStream.cpp",
"Native/InfoStreamBuilder.cpp",
+ "Native/InjectedSourceStream.cpp",
"Native/ModuleDebugStream.cpp",
"Native/NamedStreamMap.cpp",
"Native/NativeCompilandSymbol.cpp",
"Native/NativeEnumGlobals.cpp",
+ "Native/NativeEnumInjectedSources.cpp",
"Native/NativeEnumModules.cpp",
"Native/NativeEnumTypes.cpp",
"Native/NativeExeSymbol.cpp",
OpenPOWER on IntegriCloud