summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-06-03 05:52:57 +0000
committerZachary Turner <zturner@google.com>2016-06-03 05:52:57 +0000
commit3df1bfaaec1c70c6501f01868bcd81764c9582e9 (patch)
treeb1451ece7ed3236beda44a10c3e9f514decd66dd /llvm
parente7ae106147bfa93390e1b275829c93cc60712aa4 (diff)
downloadbcm5719-llvm-3df1bfaaec1c70c6501f01868bcd81764c9582e9.tar.gz
bcm5719-llvm-3df1bfaaec1c70c6501f01868bcd81764c9582e9.zip
[pdb] Print out file names instead of file offsets.
When printing line information and file checksums, we were printing the file offset field from the struct header. This teaches llvm-pdbdump how to turn those numbers into the filename. In the case of file checksums, this is done by looking in the global string table. In the case of line contributions, this is done by indexing into the file names buffer of the DBI stream. Why they use a different technique I don't know. llvm-svn: 271630
Diffstat (limited to 'llvm')
-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