diff options
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/llvm-pdbdump/Diff.cpp | 133 |
1 files changed, 110 insertions, 23 deletions
diff --git a/llvm/tools/llvm-pdbdump/Diff.cpp b/llvm/tools/llvm-pdbdump/Diff.cpp index d78c07f1019..529e57da5c1 100644 --- a/llvm/tools/llvm-pdbdump/Diff.cpp +++ b/llvm/tools/llvm-pdbdump/Diff.cpp @@ -12,6 +12,8 @@ #include "StreamUtil.h" #include "llvm-pdbdump.h" +#include "llvm/DebugInfo/PDB/Native/Formatters.h" +#include "llvm/DebugInfo/PDB/Native/InfoStream.h" #include "llvm/DebugInfo/PDB/Native/PDBFile.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/StringTable.h" @@ -114,12 +116,37 @@ Error DiffStyle::dump() { template <typename T> static bool diffAndPrint(StringRef Label, PDBFile &File1, PDBFile &File2, T V1, T V2) { - if (V1 != V2) { - outs().indent(2) << Label << "\n"; - outs().indent(4) << formatv("{0}: {1}\n", File1.getFilePath(), V1); - outs().indent(4) << formatv("{0}: {1}\n", File2.getFilePath(), V2); + if (V1 == V2) { + outs() << formatv(" {0}: No differences detected!\n", Label); + return false; } - return (V1 != V2); + + outs().indent(2) << Label << "\n"; + outs().indent(4) << formatv("{0}: {1}\n", File1.getFilePath(), V1); + outs().indent(4) << formatv("{0}: {1}\n", File2.getFilePath(), V2); + return true; +} + +template <typename T> +static bool printSymmetricDifferences(PDBFile &File1, PDBFile &File2, + T &&OnlyRange1, T &&OnlyRange2, + StringRef Label) { + bool HasDiff = false; + if (!OnlyRange1.empty()) { + HasDiff = true; + outs() << formatv(" {0} {1}(s) only in ({2})\n", OnlyRange1.size(), Label, + File1.getFilePath()); + for (const auto &Item : OnlyRange1) + outs() << formatv(" {0}\n", Label, Item); + } + if (!OnlyRange2.empty()) { + HasDiff = true; + outs() << formatv(" {0} {1}(s) only in ({2})\n", OnlyRange2.size(), + File2.getFilePath()); + for (const auto &Item : OnlyRange2) + outs() << formatv(" {0}\n", Item); + } + return HasDiff; } Error DiffStyle::diffSuperBlock() { @@ -299,8 +326,16 @@ Error DiffStyle::diffStringTable() { auto &ST1 = *ExpectedST1; auto &ST2 = *ExpectedST2; - HasDiff |= diffAndPrint("Stream Size", File1, File2, ST1.getByteSize(), - ST2.getByteSize()); + if (ST1.getByteSize() != ST2.getByteSize()) { + outs() << " Stream Size\n"; + outs() << formatv(" {0} - {1} byte(s)\n", File1.getFilePath(), + ST1.getByteSize()); + outs() << formatv(" {0} - {1} byte(s)\n", File2.getFilePath(), + ST2.getByteSize()); + outs() << formatv(" Difference: {0} bytes\n", + AbsoluteDifference(ST1.getByteSize(), ST2.getByteSize())); + HasDiff = true; + } HasDiff |= diffAndPrint("Hash Version", File1, File2, ST1.getHashVersion(), ST1.getHashVersion()); HasDiff |= diffAndPrint("Signature", File1, File2, ST1.getSignature(), @@ -351,22 +386,21 @@ Error DiffStyle::diffStringTable() { SmallVector<StringRef, 64> OnlyP; SmallVector<StringRef, 64> OnlyQ; - + auto End1 = std::remove(Strings1.begin(), Strings1.end(), ""); + auto End2 = std::remove(Strings2.begin(), Strings2.end(), ""); + uint32_t Empty1 = std::distance(End1, Strings1.end()); + uint32_t Empty2 = std::distance(End2, Strings2.end()); + Strings1.erase(End1, Strings1.end()); + Strings2.erase(End2, Strings2.end()); set_differences(Strings1, Strings2, &OnlyP, &OnlyQ); - - if (!OnlyP.empty()) { - HasDiff = true; - outs() << formatv(" {0} String(s) only in ({1})\n", OnlyP.size(), - File1.getFilePath()); - for (auto Item : OnlyP) - outs() << formatv(" {2}\n", Item); - } - if (!OnlyQ.empty()) { - HasDiff = true; - outs() << formatv(" {0} String(s) only in ({1})\n", OnlyQ.size(), - File2.getFilePath()); - for (auto Item : OnlyQ) - outs() << formatv(" {2}\n", Item); + printSymmetricDifferences(File1, File2, OnlyP, OnlyQ, "String"); + + if (Empty1 != Empty2) { + PDBFile &MoreF = (Empty1 > Empty2) ? File1 : File2; + PDBFile &LessF = (Empty1 < Empty2) ? File1 : File2; + uint32_t Difference = AbsoluteDifference(Empty1, Empty2); + outs() << formatv(" {0} had {1} more empty strings than {2}\n", + MoreF.getFilePath(), Difference, LessF.getFilePath()); } } if (!HasDiff) @@ -376,7 +410,60 @@ Error DiffStyle::diffStringTable() { Error DiffStyle::diffFreePageMap() { return Error::success(); } -Error DiffStyle::diffInfoStream() { return Error::success(); } +Error DiffStyle::diffInfoStream() { + auto ExpectedInfo1 = File1.getPDBInfoStream(); + auto ExpectedInfo2 = File2.getPDBInfoStream(); + + outs() << "PDB Stream: Searching for differences...\n"; + bool Has1 = !!ExpectedInfo1; + bool Has2 = !!ExpectedInfo2; + if (!(Has1 && Has2)) { + if (Has1 != Has2) + outs() << formatv("{0} does not have a PDB Stream!\n", + Has1 ? File1.getFilePath() : File2.getFilePath()); + consumeError(ExpectedInfo2.takeError()); + consumeError(ExpectedInfo2.takeError()); + return Error::success(); + } + + bool HasDiff = false; + auto &IS1 = *ExpectedInfo1; + auto &IS2 = *ExpectedInfo2; + if (IS1.getStreamSize() != IS2.getStreamSize()) { + outs() << " Stream Size\n"; + outs() << formatv(" {0} - {1} byte(s)\n", File1.getFilePath(), + IS1.getStreamSize()); + outs() << formatv(" {0} - {1} byte(s)\n", File2.getFilePath(), + IS2.getStreamSize()); + outs() << formatv( + " Difference: {0} bytes\n", + AbsoluteDifference(IS1.getStreamSize(), IS2.getStreamSize())); + HasDiff = true; + } + HasDiff |= diffAndPrint("Age", File1, File2, IS1.getAge(), IS2.getAge()); + HasDiff |= diffAndPrint("Guid", File1, File2, IS1.getGuid(), IS2.getGuid()); + HasDiff |= diffAndPrint("Signature", File1, File2, IS1.getSignature(), + IS2.getSignature()); + HasDiff |= + diffAndPrint("Version", File1, File2, IS1.getVersion(), IS2.getVersion()); + HasDiff |= diffAndPrint("Named Stream Byte Size", File1, File2, + IS1.getNamedStreamMapByteSize(), + IS2.getNamedStreamMapByteSize()); + SmallVector<StringRef, 4> NS1; + SmallVector<StringRef, 4> NS2; + for (const auto &X : IS1.getNamedStreams().entries()) + NS1.push_back(X.getKey()); + for (const auto &X : IS2.getNamedStreams().entries()) + NS2.push_back(X.getKey()); + SmallVector<StringRef, 4> OnlyP; + SmallVector<StringRef, 4> OnlyQ; + set_differences(NS1, NS2, &OnlyP, &OnlyQ); + printSymmetricDifferences(File1, File2, OnlyP, OnlyQ, "Named Streams"); + if (!HasDiff) + outs() << "PDB Stream: No differences detected!\n"; + + return Error::success(); +} Error DiffStyle::diffDbiStream() { return Error::success(); } |

