summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/Line.h6
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h2
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h10
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h5
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h5
-rw-r--r--llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp26
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp22
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/RawError.cpp4
-rw-r--r--llvm/test/DebugInfo/PDB/pdbdump-headers.test4
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp54
11 files changed, 104 insertions, 36 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/Line.h b/llvm/include/llvm/DebugInfo/CodeView/Line.h
index 278400742b1..975b503fe30 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/Line.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/Line.h
@@ -142,9 +142,9 @@ struct InlineeSourceLine {
};
struct FileChecksum {
- ulittle32_t FileNameOffset; // Offset of filename in string table substream.
- uint8_t ChecksumSize;
- uint8_t ChecksumKind; // FileChecksumKind
+ ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
+ uint8_t ChecksumSize; // Number of bytes of checksum.
+ uint8_t ChecksumKind; // FileChecksumKind
// Checksum bytes follow.
};
diff --git a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
index 0de564d82b4..6affac801d4 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstream.h
@@ -35,7 +35,7 @@ struct LineSubstreamHeader {
// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
struct LineFileBlockHeader {
- support::ulittle32_t FileOffset;
+ support::ulittle32_t NameIndex; // Index in DBI name buffer of filename.
support::ulittle32_t NumLines; // Number of lines
support::ulittle32_t BlockSize; // Code size of block, in bytes.
// The following two variable length arrays appear immediately after the
diff --git a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
index 1c15512e98b..6df23090371 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h
@@ -21,7 +21,7 @@ namespace llvm {
namespace codeview {
struct LineColumnEntry {
- support::ulittle32_t Offset;
+ support::ulittle32_t NameIndex;
FixedStreamArray<LineNumberEntry> LineNumbers;
FixedStreamArray<ColumnNumberEntry> Columns;
};
@@ -50,7 +50,7 @@ public:
// The value recorded in BlockHeader->BlockSize includes the size of
// LineFileBlockHeader.
Len = BlockHeader->BlockSize;
- Item.Offset = BlockHeader->FileOffset;
+ Item.NameIndex = BlockHeader->NameIndex;
if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
return EC;
if (HasColumn) {
@@ -65,9 +65,9 @@ private:
};
struct FileChecksumEntry {
- uint32_t FileNameOffset;
- FileChecksumKind Kind;
- ArrayRef<uint8_t> Checksum;
+ uint32_t FileNameOffset; // Byte offset of filename in global stringtable.
+ FileChecksumKind Kind; // The type of checksum.
+ ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
};
template <> class VarStreamArrayExtractor<FileChecksumEntry> {
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
index c3b00271628..132dfda5506 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/DbiStream.h
@@ -61,6 +61,8 @@ public:
ArrayRef<ModuleInfoEx> modules() const;
+ Expected<StringRef> getFileNameForIndex(uint32_t Index) const;
+
codeview::FixedStreamArray<object::coff_section> getSectionHeaders();
codeview::FixedStreamArray<SecMapEntry> getSectionMap() const;
@@ -85,12 +87,15 @@ private:
codeview::StreamRef TypeServerMapSubstream;
codeview::StreamRef ECSubstream;
+ codeview::StreamRef NamesBuffer;
+
codeview::FixedStreamArray<support::ulittle16_t> DbgStreams;
PdbRaw_DbiSecContribVer SectionContribVersion;
codeview::FixedStreamArray<SectionContrib> SectionContribs;
codeview::FixedStreamArray<SectionContrib2> SectionContribs2;
codeview::FixedStreamArray<SecMapEntry> SectionMap;
+ codeview::FixedStreamArray<support::little32_t> FileNameOffsets;
std::unique_ptr<MappedBlockStream> SectionHeaderStream;
codeview::FixedStreamArray<object::coff_section> SectionHeaders;
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
index e6eada8c09d..1b8dbb898be 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBFile.h
@@ -25,6 +25,8 @@ namespace pdb {
struct PDBFileContext;
class DbiStream;
class InfoStream;
+class MappedBlockStream;
+class NameHashTable;
class PublicsStream;
class SymbolStream;
class TpiStream;
@@ -69,6 +71,7 @@ public:
Expected<TpiStream &> getPDBIpiStream();
Expected<PublicsStream &> getPDBPublicsStream();
Expected<SymbolStream &> getPDBSymbolStream();
+ Expected<NameHashTable &> getStringTable();
private:
std::unique_ptr<PDBFileContext> Context;
@@ -78,6 +81,8 @@ private:
std::unique_ptr<TpiStream> Ipi;
std::unique_ptr<PublicsStream> Publics;
std::unique_ptr<SymbolStream> Symbols;
+ std::unique_ptr<MappedBlockStream> StringTableStream;
+ std::unique_ptr<NameHashTable> StringTable;
};
}
}
diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h b/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
index b3c491a8bdc..5a1614fc82e 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Raw/RawError.h
@@ -21,6 +21,8 @@ enum class raw_error_code {
feature_unsupported,
corrupt_file,
insufficient_buffer,
+ no_stream,
+ index_out_of_bounds
};
/// Base class for errors originating when parsing raw PDB files
diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
index 8c46957706e..e79d6572be1 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp
@@ -345,7 +345,6 @@ Error DbiStream::initializeFileInfo() {
FixedStreamArray<ulittle16_t> ModIndexArray;
FixedStreamArray<ulittle16_t> ModFileCountArray;
- FixedStreamArray<little32_t> FileNameOffsets;
// First is an array of `NumModules` module indices. This is not used for the
// same reason that `NumSourceFiles` is not used. It's an array of uint16's,
@@ -373,10 +372,8 @@ Error DbiStream::initializeFileInfo() {
if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
return EC;
- StreamRef NamesBufferRef;
- if (auto EC = FISR.readStreamRef(NamesBufferRef))
+ if (auto EC = FISR.readStreamRef(NamesBuffer))
return EC;
- StreamReader Names(NamesBufferRef);
// We go through each ModuleInfo, determine the number N of source files for
// that module, and then get the next N offsets from the Offsets array, using
@@ -387,10 +384,10 @@ Error DbiStream::initializeFileInfo() {
uint32_t NumFiles = ModFileCountArray[I];
ModuleInfos[I].SourceFiles.resize(NumFiles);
for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) {
- uint32_t FileOffset = FileNameOffsets[NextFileIndex];
- Names.setOffset(FileOffset);
- if (auto EC = Names.readZeroString(ModuleInfos[I].SourceFiles[J]))
- return EC;
+ if (auto Name = getFileNameForIndex(NextFileIndex))
+ ModuleInfos[I].SourceFiles[J] = Name.get();
+ else
+ return Name.takeError();
}
}
@@ -400,3 +397,16 @@ Error DbiStream::initializeFileInfo() {
uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
return DbgStreams[static_cast<uint16_t>(Type)];
}
+
+Expected<StringRef> DbiStream::getFileNameForIndex(uint32_t Index) const {
+ StreamReader Names(NamesBuffer);
+ if (Index >= FileNameOffsets.size())
+ return make_error<RawError>(raw_error_code::index_out_of_bounds);
+
+ uint32_t FileOffset = FileNameOffsets[Index];
+ Names.setOffset(FileOffset);
+ StringRef Name;
+ if (auto EC = Names.readZeroString(Name))
+ return std::move(EC);
+ return Name;
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index d0fbb142ec3..73d8eef570f 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Raw/NameHashTable.h"
#include "llvm/DebugInfo/PDB/Raw/PublicsStream.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/SymbolStream.h"
@@ -359,3 +360,24 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
}
return *Symbols;
}
+
+Expected<NameHashTable &> PDBFile::getStringTable() {
+ if (!StringTable || !StringTableStream) {
+ auto InfoS = getPDBInfoStream();
+ if (auto EC = InfoS.takeError())
+ return std::move(EC);
+ auto &IS = InfoS.get();
+ uint32_t NameStreamIndex = IS.getNamedStreamIndex("/names");
+
+ if (NameStreamIndex == 0)
+ return make_error<RawError>(raw_error_code::no_stream);
+ auto S = llvm::make_unique<MappedBlockStream>(NameStreamIndex, *this);
+ codeview::StreamReader Reader(*S);
+ auto N = llvm::make_unique<NameHashTable>();
+ if (auto EC = N->load(Reader))
+ return std::move(EC);
+ StringTable = std::move(N);
+ StringTableStream = std::move(S);
+ }
+ return *StringTable;
+}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp b/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp
index 037a1aab4b1..bcfa55a8b01 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/RawError.cpp
@@ -24,6 +24,10 @@ public:
case raw_error_code::insufficient_buffer:
return "The buffer is not large enough to read the requested number of "
"bytes.";
+ case raw_error_code::no_stream:
+ return "The specified stream could not be loaded.";
+ case raw_error_code::index_out_of_bounds:
+ return "The specified item does not exist in the array.";
}
llvm_unreachable("Unrecognized raw_error_code");
}
diff --git a/llvm/test/DebugInfo/PDB/pdbdump-headers.test b/llvm/test/DebugInfo/PDB/pdbdump-headers.test
index 136e4005ef9..902dae9f941 100644
--- a/llvm/test/DebugInfo/PDB/pdbdump-headers.test
+++ b/llvm/test/DebugInfo/PDB/pdbdump-headers.test
@@ -332,7 +332,7 @@
; EMPTY-NEXT: ]
; EMPTY-NEXT: LineInfo [
; EMPTY-NEXT: Lines {
-; EMPTY-NEXT: FileOffset: 0
+; EMPTY-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp
; EMPTY-NEXT: Line {
; EMPTY-NEXT: Offset: 0
; EMPTY-NEXT: LineNumberStart: 5
@@ -354,7 +354,7 @@
; EMPTY-NEXT: }
; EMPTY-NEXT: FileChecksums {
; EMPTY-NEXT: Checksum {
-; EMPTY-NEXT: FileNameOffset: 86
+; EMPTY-NEXT: FileName: d:\src\llvm\test\debuginfo\pdb\inputs\empty.cpp
; EMPTY-NEXT: Kind: MD5 (0x1)
; EMPTY-NEXT: Checksum (
; EMPTY-NEXT: 0000: A0A5BD0D 3ECD93FC 29D19DE8 26FBF4BC |....>...)...&...|
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index dcaf494ee5c..1a9d5583486 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -522,11 +522,19 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
// substream types types.
class RecordVisitor : public codeview::IModuleSubstreamVisitor {
public:
- RecordVisitor(ScopedPrinter &P) : P(P) {}
+ RecordVisitor(ScopedPrinter &P, PDBFile &F) : P(P), F(F) {}
Error visitUnknown(ModuleSubstreamKind Kind,
- StreamRef Data) override {
+ StreamRef Stream) override {
DictScope DD(P, "Unknown");
- return printBinaryData(Data);
+ ArrayRef<uint8_t> Data;
+ StreamReader R(Stream);
+ if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
+ return make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "DBI stream contained corrupt line info record");
+ }
+ P.printBinaryBlock("Data", Data);
+ return Error::success();
}
Error
visitFileChecksums(StreamRef Data,
@@ -534,7 +542,11 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
DictScope DD(P, "FileChecksums");
for (const auto &C : Checksums) {
DictScope DDD(P, "Checksum");
- P.printNumber("FileNameOffset", C.FileNameOffset);
+ if (auto Result = getFileNameForOffset(C.FileNameOffset))
+ P.printString("FileName", Result.get());
+ else
+ return Result.takeError();
+ P.flush();
P.printEnum("Kind", uint8_t(C.Kind), getFileChecksumNames());
P.printBinaryBlock("Checksum", C.Checksum);
}
@@ -545,7 +557,11 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
const LineInfoArray &Lines) override {
DictScope DD(P, "Lines");
for (const auto &L : Lines) {
- P.printNumber("FileOffset", L.Offset);
+ if (auto Result = getFileNameForOffset2(L.NameIndex))
+ P.printString("FileName", Result.get());
+ else
+ return Result.takeError();
+ P.flush();
for (const auto &N : L.LineNumbers) {
DictScope DDD(P, "Line");
LineInfo LI(N.Flags);
@@ -569,21 +585,25 @@ static Error dumpDbiStream(ScopedPrinter &P, PDBFile &File,
}
private:
- Error printBinaryData(StreamRef Stream) {
- ArrayRef<uint8_t> Data;
- StreamReader R(Stream);
- if (auto EC = R.readBytes(Data, R.bytesRemaining())) {
- return make_error<RawError>(
- raw_error_code::corrupt_file,
- "DBI stream contained corrupt line info record");
- }
- P.printBinaryBlock("Data", Data);
- P.flush();
- return Error::success();
+ Expected<StringRef> getFileNameForOffset(uint32_t Offset) {
+ auto StringT = F.getStringTable();
+ if (auto EC = StringT.takeError())
+ return std::move(EC);
+ NameHashTable &ST = StringT.get();
+ return ST.getStringForID(Offset);
+ }
+ Expected<StringRef> getFileNameForOffset2(uint32_t Offset) {
+ auto DbiS = F.getPDBDbiStream();
+ if (auto EC = DbiS.takeError())
+ return std::move(EC);
+ auto &DS = DbiS.get();
+ return DS.getFileNameForIndex(Offset);
}
ScopedPrinter &P;
+ PDBFile &F;
};
- RecordVisitor V(P);
+
+ RecordVisitor V(P, File);
for (const auto &L : ModS.lines(&HadError)) {
if (auto EC = codeview::visitModuleSubstream(L, V))
return EC;
OpenPOWER on IntegriCloud