[llvm] r297901 - [llvm-pdbdump] Add support for diffing the String Table.
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 20 09:34:12 PDT 2017
Test coverage?
On Wed, Mar 15, 2017 at 3:31 PM Zachary Turner via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: zturner
> Date: Wed Mar 15 17:19:30 2017
> New Revision: 297901
>
> URL: http://llvm.org/viewvc/llvm-project?rev=297901&view=rev
> Log:
> [llvm-pdbdump] Add support for diffing the String Table.
>
> Modified:
> llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h
> llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp
> llvm/trunk/tools/llvm-pdbdump/Diff.cpp
>
> Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h?rev=297901&r1=297900&r2=297901&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h (original)
> +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/StringTable.h Wed Mar 15
> 17:19:30 2017
> @@ -30,6 +30,8 @@ public:
>
> Error load(BinaryStreamReader &Stream);
>
> + uint32_t getByteSize() const;
> +
> uint32_t getNameCount() const { return NameCount; }
> uint32_t getHashVersion() const { return HashVersion; }
> uint32_t getSignature() const { return Signature; }
> @@ -42,9 +44,10 @@ public:
> private:
> BinaryStreamRef NamesBuffer;
> FixedStreamArray<support::ulittle32_t> IDs;
> - uint32_t Signature;
> - uint32_t HashVersion;
> - uint32_t NameCount;
> + uint32_t ByteSize = 0;
> + uint32_t Signature = 0;
> + uint32_t HashVersion = 0;
> + uint32_t NameCount = 0;
> };
>
> } // end namespace pdb
>
> Modified: llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp?rev=297901&r1=297900&r2=297901&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp (original)
> +++ llvm/trunk/lib/DebugInfo/PDB/Native/StringTable.cpp Wed Mar 15
> 17:19:30 2017
> @@ -20,9 +20,11 @@ using namespace llvm;
> using namespace llvm::support;
> using namespace llvm::pdb;
>
> -StringTable::StringTable() : Signature(0), HashVersion(0), NameCount(0) {}
> +StringTable::StringTable() {}
>
> Error StringTable::load(BinaryStreamReader &Stream) {
> + ByteSize = Stream.getLength();
> +
> const StringTableHeader *H;
> if (auto EC = Stream.readObject(H))
> return EC;
> @@ -56,9 +58,18 @@ Error StringTable::load(BinaryStreamRead
>
> if (auto EC = Stream.readInteger(NameCount))
> return EC;
> +
> + if (Stream.bytesRemaining() > 0)
> + return make_error<RawError>(raw_error_code::stream_too_long,
> + "Unexpected bytes found in string table");
> +
> return Error::success();
> }
>
> +uint32_t StringTable::getByteSize() const {
> + return ByteSize;
> +}
> +
> StringRef StringTable::getStringForID(uint32_t ID) const {
> if (ID == IDs[0])
> return StringRef();
>
> Modified: llvm/trunk/tools/llvm-pdbdump/Diff.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/Diff.cpp?rev=297901&r1=297900&r2=297901&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/llvm-pdbdump/Diff.cpp (original)
> +++ llvm/trunk/tools/llvm-pdbdump/Diff.cpp Wed Mar 15 17:19:30 2017
> @@ -14,6 +14,7 @@
>
> #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
> #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
> +#include "llvm/DebugInfo/PDB/Native/StringTable.h"
>
> #include "llvm/Support/FormatAdapters.h"
> #include "llvm/Support/FormatVariadic.h"
> @@ -21,6 +22,48 @@
> using namespace llvm;
> using namespace llvm::pdb;
>
> +template<typename R>
> +using ValueOfRange = llvm::detail::ValueOfRange<R>;
> +
> +template<typename Range, typename Comp>
> +static void set_differences(Range &&R1, Range &&R2,
> + SmallVectorImpl<ValueOfRange<Range>> *OnlyLeft,
> + SmallVectorImpl<ValueOfRange<Range>> *OnlyRight,
> + SmallVectorImpl<ValueOfRange<Range>> *Intersection, Comp Comparator) {
> +
> + std::sort(R1.begin(), R1.end(), Comparator);
> + std::sort(R2.begin(), R2.end(), Comparator);
> +
> + if (OnlyLeft) {
> + OnlyLeft->reserve(R1.size());
> + auto End = std::set_difference(R1.begin(), R1.end(), R2.begin(),
> R2.end(),
> + OnlyLeft->begin(), Comparator);
> + OnlyLeft->set_size(std::distance(OnlyLeft->begin(), End));
> + }
> + if (OnlyRight) {
> + OnlyLeft->reserve(R2.size());
> + auto End = std::set_difference(R2.begin(), R2.end(), R1.begin(),
> R1.end(),
> + OnlyRight->begin(), Comparator);
> + OnlyRight->set_size(std::distance(OnlyRight->begin(), End));
> + }
> + if (Intersection) {
> + Intersection->reserve(std::min(R1.size(), R2.size()));
> + auto End = std::set_intersection(R1.begin(), R1.end(), R2.begin(),
> + R2.end(), Intersection->begin(), Comparator);
> + Intersection->set_size(std::distance(Intersection->begin(), End));
> + }
> +}
> +
> +template<typename Range>
> +static void set_differences(Range &&R1, Range &&R2,
> + SmallVectorImpl<ValueOfRange<Range>> *OnlyLeft,
> + SmallVectorImpl<ValueOfRange<Range>> *OnlyRight,
> + SmallVectorImpl<ValueOfRange<Range>> *Intersection) {
> + std::less<ValueOfRange<Range>> Comp;
> + set_differences(std::forward<Range>(R1), std::forward<Range>(R2),
> OnlyLeft, OnlyRight, Intersection, Comp);
> +}
> +
> +
> DiffStyle::DiffStyle(PDBFile &File1, PDBFile &File2)
> : File1(File1), File2(File2) {}
>
> @@ -162,26 +205,12 @@ Error DiffStyle::diffStreamDirectory() {
> auto Comparator = [](const value_type &I1, const value_type &I2) {
> return I1.value() < I2.value();
> };
> - std::sort(PI.begin(), PI.end(), Comparator);
> - std::sort(QI.begin(), QI.end(), Comparator);
>
> decltype(PI) OnlyP;
> decltype(QI) OnlyQ;
> decltype(PI) Common;
>
> - OnlyP.reserve(P.size());
> - OnlyQ.reserve(Q.size());
> - Common.reserve(Q.size());
> -
> - auto PEnd = std::set_difference(PI.begin(), PI.end(), QI.begin(),
> QI.end(),
> - OnlyP.begin(), Comparator);
> - auto QEnd = std::set_difference(QI.begin(), QI.end(), PI.begin(),
> PI.end(),
> - OnlyQ.begin(), Comparator);
> - auto ComEnd = std::set_intersection(PI.begin(), PI.end(), QI.begin(),
> - QI.end(), Common.begin(),
> Comparator);
> - OnlyP.set_size(std::distance(OnlyP.begin(), PEnd));
> - OnlyQ.set_size(std::distance(OnlyQ.begin(), QEnd));
> - Common.set_size(std::distance(Common.begin(), ComEnd));
> + set_differences(PI, QI, &OnlyP, &OnlyQ, &Common, Comparator);
>
> if (!OnlyP.empty()) {
> HasDifferences = true;
> @@ -238,7 +267,98 @@ Error DiffStyle::diffStreamDirectory() {
> return Error::success();
> }
>
> -Error DiffStyle::diffStringTable() { return Error::success(); }
> +Error DiffStyle::diffStringTable() {
> + auto ExpectedST1 = File1.getStringTable();
> + auto ExpectedST2 = File2.getStringTable();
> + outs() << "String Table: Searching for differences...\n";
> + bool Has1 = !!ExpectedST1;
> + bool Has2 = !!ExpectedST2;
> + if (!(Has1 && Has2)) {
> + // If one has a string table and the other doesn't, we can print less
> output.
> + if (Has1 != Has2) {
> + if (Has1) {
> + outs() << formatv(" {0}: ({1} strings)\n", File1.getFilePath(),
> ExpectedST1->getNameCount());
> + outs() << formatv(" {0}: (string table not present)\n",
> File2.getFilePath());
> + } else {
> + outs() << formatv(" {0}: (string table not present)\n",
> File1.getFilePath());
> + outs() << formatv(" {0}: ({1})\n", File2.getFilePath(),
> ExpectedST2->getNameCount());
> + }
> + }
> + consumeError(ExpectedST1.takeError());
> + consumeError(ExpectedST2.takeError());
> + return Error::success();
> + }
> +
> + bool HasDiff = false;
> + auto &ST1 = *ExpectedST1;
> + auto &ST2 = *ExpectedST2;
> +
> + HasDiff |= diffAndPrint("Stream Size", File1, File2, ST1.getByteSize(),
> ST2.getByteSize());
> + HasDiff |= diffAndPrint("Hash Version", File1, File2,
> ST1.getHashVersion(), ST1.getHashVersion());
> + HasDiff |= diffAndPrint("Signature", File1, File2, ST1.getSignature(),
> ST1.getSignature());
> +
> + // Both have a valid string table, dive in and compare individual
> strings.
> +
> + auto IdList1 = ST1.name_ids();
> + auto IdList2 = ST2.name_ids();
> + if (opts::diff::Pedantic) {
> + // In pedantic mode, we compare index by index (i.e. the strings are
> in the same order
> + // in both tables.
> + uint32_t Max = std::max(IdList1.size(), IdList2.size());
> + for (uint32_t I = 0; I < Max; ++I) {
> + Optional<uint32_t> Id1, Id2;
> + StringRef S1, S2;
> + if (I < IdList1.size()) {
> + Id1 = IdList1[I];
> + S1 = ST1.getStringForID(*Id1);
> + }
> + if (I < IdList2.size()) {
> + Id2 = IdList2[I];
> + S2 = ST2.getStringForID(*Id2);
> + }
> + if (Id1 == Id2 && S1 == S2)
> + continue;
> +
> + std::string OutId1 = Id1 ? formatv("{0}", *Id1).str() : "(index not
> present)";
> + std::string OutId2 = Id2 ? formatv("{0}", *Id2).str() : "(index not
> present)";
> + outs() << formatv(" String {0}\n", I);
> + outs() << formatv(" {0}: Hash - {1}, Value - {2}\n",
> File1.getFilePath(), OutId1, S1);
> + outs() << formatv(" {0}: Hash - {1}, Value - {2}\n",
> File2.getFilePath(), OutId2, S2);
> + HasDiff = true;
> + }
> + } else {
> + std::vector<StringRef> Strings1, Strings2;
> + Strings1.reserve(IdList1.size());
> + Strings2.reserve(IdList2.size());
> + for (auto ID : IdList1)
> + Strings1.push_back(ST1.getStringForID(ID));
> + for (auto ID : IdList2)
> + Strings2.push_back(ST2.getStringForID(ID));
> +
> + SmallVector<StringRef, 64> OnlyP;
> + SmallVector<StringRef, 64> OnlyQ;
> +
> + set_differences(Strings1, Strings2, &OnlyP, &OnlyQ, nullptr);
> +
> + 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);
> + }
> + }
> + if (!HasDiff)
> + outs() << "String Table: No differences detected!\n";
> + return Error::success();
> +}
>
> Error DiffStyle::diffFreePageMap() { return Error::success(); }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170320/0728de65/attachment-0001.html>
More information about the llvm-commits
mailing list