summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorBob Haarman <llvm@inglorion.net>2016-12-05 22:44:00 +0000
committerBob Haarman <llvm@inglorion.net>2016-12-05 22:44:00 +0000
commita5b4358956135e2aa747d7dfca4d361ebf99e99d (patch)
tree4d8f6b707d36857f15be8163b17fc5a7e80e24e5 /llvm
parent317dcc3f2f37c95619a4db9c6d4c084983fdf7ba (diff)
downloadbcm5719-llvm-a5b4358956135e2aa747d7dfca4d361ebf99e99d.tar.gz
bcm5719-llvm-a5b4358956135e2aa747d7dfca4d361ebf99e99d.zip
[pdb] handle missing pdb streams more gracefully
Summary: The code we use to read PDBs assumed that streams we ask it to read exist, and would read memory outside a vector and crash if this wasn't the case. This would, for example, cause llvm-pdbdump to crash on PDBs generated by lld. This patch handles such cases more gracefully: the PDB reading code in LLVM now reports errors when asked to get a stream that is not present, and llvm-pdbdump will report missing streams and continue processing streams that are present. Reviewers: ruiu, zturner Subscribers: thakis, amccarth Differential Revision: https://reviews.llvm.org/D27325 llvm-svn: 288722
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h16
-rw-r--r--llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp103
-rw-r--r--llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp54
4 files changed, 140 insertions, 35 deletions
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
index ede5eafbbf4..29f5b2163d8 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
@@ -26,7 +26,6 @@ namespace llvm {
namespace msf {
class MappedBlockStream;
-class WritableStream;
}
namespace pdb {
@@ -96,7 +95,20 @@ public:
BumpPtrAllocator &getAllocator() { return Allocator; }
-private:
+ bool hasPDBDbiStream() const;
+ bool hasPDBGlobalsStream();
+ bool hasPDBInfoStream();
+ bool hasPDBIpiStream() const;
+ bool hasPDBPublicsStream();
+ bool hasPDBSymbolStream();
+ bool hasPDBTpiStream() const;
+ bool hasStringTable();
+
+ private:
+ Expected<std::unique_ptr<msf::MappedBlockStream>> safelyCreateIndexedStream(
+ const msf::MSFLayout &Layout, const msf::ReadableStream &MsfData,
+ uint32_t StreamIndex) const;
+
BumpPtrAllocator &Allocator;
std::unique_ptr<msf::ReadableStream> Buffer;
diff --git a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
index 403c02b4268..e52c88a5bfb 100644
--- a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
+++ b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp
@@ -63,6 +63,7 @@ std::unique_ptr<MappedBlockStream>
MappedBlockStream::createIndexedStream(const MSFLayout &Layout,
const ReadableStream &MsfData,
uint32_t StreamIndex) {
+ assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
MSFStreamLayout SL;
SL.Blocks = Layout.StreamMap[StreamIndex];
SL.Length = Layout.StreamSizes[StreamIndex];
@@ -334,6 +335,7 @@ std::unique_ptr<WritableMappedBlockStream>
WritableMappedBlockStream::createIndexedStream(const MSFLayout &Layout,
const WritableStream &MsfData,
uint32_t StreamIndex) {
+ assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
MSFStreamLayout SL;
SL.Blocks = Layout.StreamMap[StreamIndex];
SL.Length = Layout.StreamSizes[StreamIndex];
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index b429d21b4b9..53491518b8c 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -227,9 +227,10 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
if (!DbiS)
return DbiS.takeError();
- auto GlobalS = MappedBlockStream::createIndexedStream(
+ auto GlobalS = safelyCreateIndexedStream(
ContainerLayout, *Buffer, DbiS->getGlobalSymbolStreamIndex());
- auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(GlobalS));
+ if (!GlobalS) return GlobalS.takeError();
+ auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(*GlobalS));
if (auto EC = TempGlobals->reload())
return std::move(EC);
Globals = std::move(TempGlobals);
@@ -239,9 +240,9 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
Expected<InfoStream &> PDBFile::getPDBInfoStream() {
if (!Info) {
- auto InfoS = MappedBlockStream::createIndexedStream(ContainerLayout,
- *Buffer, StreamPDB);
- auto TempInfo = llvm::make_unique<InfoStream>(std::move(InfoS));
+ auto InfoS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamPDB);
+ if (!InfoS) return InfoS.takeError();
+ auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
if (auto EC = TempInfo->reload())
return std::move(EC);
Info = std::move(TempInfo);
@@ -251,9 +252,9 @@ Expected<InfoStream &> PDBFile::getPDBInfoStream() {
Expected<DbiStream &> PDBFile::getPDBDbiStream() {
if (!Dbi) {
- auto DbiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
- StreamDBI);
- auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(DbiS));
+ auto DbiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamDBI);
+ if (!DbiS) return DbiS.takeError();
+ auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(*DbiS));
if (auto EC = TempDbi->reload())
return std::move(EC);
Dbi = std::move(TempDbi);
@@ -263,9 +264,9 @@ Expected<DbiStream &> PDBFile::getPDBDbiStream() {
Expected<TpiStream &> PDBFile::getPDBTpiStream() {
if (!Tpi) {
- auto TpiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
- StreamTPI);
- auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(TpiS));
+ auto TpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamTPI);
+ if (!TpiS) return TpiS.takeError();
+ auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
if (auto EC = TempTpi->reload())
return std::move(EC);
Tpi = std::move(TempTpi);
@@ -275,9 +276,9 @@ Expected<TpiStream &> PDBFile::getPDBTpiStream() {
Expected<TpiStream &> PDBFile::getPDBIpiStream() {
if (!Ipi) {
- auto IpiS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
- StreamIPI);
- auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(IpiS));
+ auto IpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamIPI);
+ if (!IpiS) return IpiS.takeError();
+ auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
if (auto EC = TempIpi->reload())
return std::move(EC);
Ipi = std::move(TempIpi);
@@ -291,12 +292,11 @@ Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
if (!DbiS)
return DbiS.takeError();
- uint32_t PublicsStreamNum = DbiS->getPublicSymbolStreamIndex();
-
- auto PublicS = MappedBlockStream::createIndexedStream(
- ContainerLayout, *Buffer, PublicsStreamNum);
+ auto PublicS = safelyCreateIndexedStream(
+ ContainerLayout, *Buffer, DbiS->getPublicSymbolStreamIndex());
+ if (!PublicS) return PublicS.takeError();
auto TempPublics =
- llvm::make_unique<PublicsStream>(*this, std::move(PublicS));
+ llvm::make_unique<PublicsStream>(*this, std::move(*PublicS));
if (auto EC = TempPublics->reload())
return std::move(EC);
Publics = std::move(TempPublics);
@@ -311,10 +311,11 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
return DbiS.takeError();
uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
- auto SymbolS = MappedBlockStream::createIndexedStream(
- ContainerLayout, *Buffer, SymbolStreamNum);
+ auto SymbolS =
+ safelyCreateIndexedStream(ContainerLayout, *Buffer, SymbolStreamNum);
+ if (!SymbolS) return SymbolS.takeError();
- auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(SymbolS));
+ auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
if (auto EC = TempSymbols->reload())
return std::move(EC);
Symbols = std::move(TempSymbols);
@@ -330,19 +331,61 @@ Expected<NameHashTable &> PDBFile::getStringTable() {
uint32_t NameStreamIndex = IS->getNamedStreamIndex("/names");
- if (NameStreamIndex == 0)
- return make_error<RawError>(raw_error_code::no_stream);
- if (NameStreamIndex >= getNumStreams())
- return make_error<RawError>(raw_error_code::no_stream);
- auto NS = MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer,
- NameStreamIndex);
+ auto NS =
+ safelyCreateIndexedStream(ContainerLayout, *Buffer, NameStreamIndex);
+ if (!NS) return NS.takeError();
- StreamReader Reader(*NS);
+ StreamReader Reader(**NS);
auto N = llvm::make_unique<NameHashTable>();
if (auto EC = N->load(Reader))
return std::move(EC);
StringTable = std::move(N);
- StringTableStream = std::move(NS);
+ StringTableStream = std::move(*NS);
}
return *StringTable;
}
+
+bool PDBFile::hasPDBDbiStream() const { return StreamDBI < getNumStreams(); }
+
+bool PDBFile::hasPDBGlobalsStream() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS) return false;
+ return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();
+}
+
+bool PDBFile::hasPDBInfoStream() { return StreamPDB < getNumStreams(); }
+
+bool PDBFile::hasPDBIpiStream() const { return StreamIPI < getNumStreams(); }
+
+bool PDBFile::hasPDBPublicsStream() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS) return false;
+ return DbiS->getPublicSymbolStreamIndex() < getNumStreams();
+}
+
+bool PDBFile::hasPDBSymbolStream() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS) return false;
+ return DbiS->getSymRecordStreamIndex() < getNumStreams();
+}
+
+bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }
+
+bool PDBFile::hasStringTable() {
+ auto IS = getPDBInfoStream();
+ if (!IS) return false;
+ return IS->getNamedStreamIndex("/names") < getNumStreams();
+}
+
+/// 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 value will
+/// contain the stream returned by createIndexedStream().
+Expected<std::unique_ptr<MappedBlockStream>> PDBFile::safelyCreateIndexedStream(
+ const MSFLayout &Layout, const ReadableStream &MsfData,
+ uint32_t StreamIndex) const {
+ if (StreamIndex >= getNumStreams())
+ return make_error<RawError>(raw_error_code::no_stream);
+ return MappedBlockStream::createIndexedStream(Layout, MsfData, StreamIndex);
+}
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index 2287e0d143c..b6bf5cf9190 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -350,11 +350,23 @@ void LLVMOutputStyle::dumpBitVector(StringRef Name, const BitVector &V) {
Error LLVMOutputStyle::dumpGlobalsStream() {
if (!opts::raw::DumpGlobals)
return Error::success();
+ if (!File.hasPDBGlobalsStream()) {
+ P.printString("Globals Stream not present");
+ return Error::success();
+ }
- DictScope D(P, "Globals Stream");
auto Globals = File.getPDBGlobalsStream();
if (!Globals)
- return Globals.takeError();
+ return handleErrors(Globals.takeError(),
+ [&](const msf::MSFError &E) -> Error {
+ if (E.Code == msf::msf_error_code::no_stream) {
+ P.printString("Globals Stream not present");
+ return Error::success();
+ } else {
+ return make_error<msf::MSFError>(E);
+ }
+ });
+ DictScope D(P, "Globals Stream");
auto Dbi = File.getPDBDbiStream();
if (!Dbi)
@@ -447,6 +459,10 @@ Error LLVMOutputStyle::dumpStreamBytes() {
Error LLVMOutputStyle::dumpInfoStream() {
if (!opts::raw::DumpHeaders)
return Error::success();
+ if (!File.hasPDBInfoStream()) {
+ P.printString("PDB Stream not present");
+ return Error::success();
+ }
auto IS = File.getPDBInfoStream();
if (!IS)
return IS.takeError();
@@ -485,11 +501,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
StringRef Label;
StringRef VerLabel;
if (StreamIdx == StreamTPI) {
+ if (!File.hasPDBTpiStream()) {
+ P.printString("Type Info Stream (TPI) not present");
+ return Error::success();
+ }
DumpRecordBytes = opts::raw::DumpTpiRecordBytes;
DumpRecords = opts::raw::DumpTpiRecords;
Label = "Type Info Stream (TPI)";
VerLabel = "TPI Version";
} else if (StreamIdx == StreamIPI) {
+ if (!File.hasPDBIpiStream()) {
+ P.printString("Type Info Stream (IPI) not present");
+ return Error::success();
+ }
DumpRecordBytes = opts::raw::DumpIpiRecordBytes;
DumpRecords = opts::raw::DumpIpiRecords;
Label = "Type Info Stream (IPI)";
@@ -556,6 +580,10 @@ Error LLVMOutputStyle::dumpDbiStream() {
opts::raw::DumpModuleFiles || opts::raw::DumpLineInfo;
if (!opts::raw::DumpHeaders && !DumpModules)
return Error::success();
+ if (!File.hasPDBDbiStream()) {
+ P.printString("DBI Stream not present");
+ return Error::success();
+ }
auto DS = File.getPDBDbiStream();
if (!DS)
@@ -742,6 +770,10 @@ Error LLVMOutputStyle::dumpDbiStream() {
Error LLVMOutputStyle::dumpSectionContribs() {
if (!opts::raw::DumpSectionContribs)
return Error::success();
+ if (!File.hasPDBDbiStream()) {
+ P.printString("DBI Stream not present");
+ return Error::success();
+ }
auto Dbi = File.getPDBDbiStream();
if (!Dbi)
@@ -789,6 +821,10 @@ Error LLVMOutputStyle::dumpSectionContribs() {
Error LLVMOutputStyle::dumpSectionMap() {
if (!opts::raw::DumpSectionMap)
return Error::success();
+ if (!File.hasPDBDbiStream()) {
+ P.printString("DBI Stream not present");
+ return Error::success();
+ }
auto Dbi = File.getPDBDbiStream();
if (!Dbi)
@@ -813,11 +849,15 @@ Error LLVMOutputStyle::dumpSectionMap() {
Error LLVMOutputStyle::dumpPublicsStream() {
if (!opts::raw::DumpPublics)
return Error::success();
+ if (!File.hasPDBPublicsStream()) {
+ P.printString("Publics Stream not present");
+ return Error::success();
+ }
- DictScope D(P, "Publics Stream");
auto Publics = File.getPDBPublicsStream();
if (!Publics)
return Publics.takeError();
+ DictScope D(P, "Publics Stream");
auto Dbi = File.getPDBDbiStream();
if (!Dbi)
@@ -856,6 +896,10 @@ Error LLVMOutputStyle::dumpPublicsStream() {
Error LLVMOutputStyle::dumpSectionHeaders() {
if (!opts::raw::DumpSectionHeaders)
return Error::success();
+ if (!File.hasPDBDbiStream()) {
+ P.printString("DBI Stream not present");
+ return Error::success();
+ }
auto Dbi = File.getPDBDbiStream();
if (!Dbi)
@@ -885,6 +929,10 @@ Error LLVMOutputStyle::dumpSectionHeaders() {
Error LLVMOutputStyle::dumpFpoStream() {
if (!opts::raw::DumpFpo)
return Error::success();
+ if (!File.hasPDBDbiStream()) {
+ P.printString("DBI Stream not present");
+ return Error::success();
+ }
auto Dbi = File.getPDBDbiStream();
if (!Dbi)
OpenPOWER on IntegriCloud