mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
[llvm-pdbutil] Remove the analyze subcommand.
Nobody has used this since it was introduced, and it doesn't have test coverage. llvm-svn: 348307
This commit is contained in:
parent
2e1b430a43
commit
0e5c8b1f04
@ -1,148 +0,0 @@
|
|||||||
//===- Analyze.cpp - PDB analysis functions ---------------------*- C++ -*-===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#include "Analyze.h"
|
|
||||||
|
|
||||||
#include "llvm/ADT/DenseSet.h"
|
|
||||||
#include "llvm/ADT/STLExtras.h"
|
|
||||||
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
|
|
||||||
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
|
|
||||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
|
||||||
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
|
|
||||||
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
|
|
||||||
#include "llvm/DebugInfo/PDB/Native/RawError.h"
|
|
||||||
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
|
|
||||||
|
|
||||||
#include "llvm/Support/FormatVariadic.h"
|
|
||||||
#include "llvm/Support/raw_ostream.h"
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
using namespace llvm::codeview;
|
|
||||||
using namespace llvm::pdb;
|
|
||||||
|
|
||||||
static StringRef getLeafTypeName(TypeLeafKind LT) {
|
|
||||||
switch (LT) {
|
|
||||||
#define TYPE_RECORD(ename, value, name) \
|
|
||||||
case ename: \
|
|
||||||
return #name;
|
|
||||||
#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return "UnknownLeaf";
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
struct HashLookupVisitor : public TypeVisitorCallbacks {
|
|
||||||
struct Entry {
|
|
||||||
TypeIndex TI;
|
|
||||||
CVType Record;
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit HashLookupVisitor(TpiStream &Tpi) : Tpi(Tpi) {}
|
|
||||||
|
|
||||||
Error visitTypeBegin(CVType &Record) override {
|
|
||||||
uint32_t H = Tpi.getHashValues()[I];
|
|
||||||
Record.Hash = H;
|
|
||||||
TypeIndex TI(I + TypeIndex::FirstNonSimpleIndex);
|
|
||||||
Lookup[H].push_back(Entry{TI, Record});
|
|
||||||
++I;
|
|
||||||
return Error::success();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t I = 0;
|
|
||||||
DenseMap<uint32_t, std::list<Entry>> Lookup;
|
|
||||||
TpiStream &Tpi;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
AnalysisStyle::AnalysisStyle(PDBFile &File) : File(File) {}
|
|
||||||
|
|
||||||
Error AnalysisStyle::dump() {
|
|
||||||
auto Tpi = File.getPDBTpiStream();
|
|
||||||
if (!Tpi)
|
|
||||||
return Tpi.takeError();
|
|
||||||
|
|
||||||
HashLookupVisitor Hasher(*Tpi);
|
|
||||||
|
|
||||||
uint32_t RecordCount = Tpi->getNumTypeRecords();
|
|
||||||
auto Offsets = Tpi->getTypeIndexOffsets();
|
|
||||||
auto Types = llvm::make_unique<LazyRandomTypeCollection>(
|
|
||||||
Tpi->typeArray(), RecordCount, Offsets);
|
|
||||||
|
|
||||||
if (auto EC = codeview::visitTypeStream(*Types, Hasher))
|
|
||||||
return EC;
|
|
||||||
|
|
||||||
auto &Adjusters = Tpi->getHashAdjusters();
|
|
||||||
DenseSet<uint32_t> AdjusterSet;
|
|
||||||
for (const auto &Adj : Adjusters) {
|
|
||||||
assert(AdjusterSet.find(Adj.second) == AdjusterSet.end());
|
|
||||||
AdjusterSet.insert(Adj.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Count = 0;
|
|
||||||
outs() << "Searching for hash collisions\n";
|
|
||||||
for (const auto &H : Hasher.Lookup) {
|
|
||||||
if (H.second.size() <= 1)
|
|
||||||
continue;
|
|
||||||
++Count;
|
|
||||||
outs() << formatv("Hash: {0}, Count: {1} records\n", H.first,
|
|
||||||
H.second.size());
|
|
||||||
for (const auto &R : H.second) {
|
|
||||||
auto Iter = AdjusterSet.find(R.TI.getIndex());
|
|
||||||
StringRef Prefix;
|
|
||||||
if (Iter != AdjusterSet.end()) {
|
|
||||||
Prefix = "[HEAD]";
|
|
||||||
AdjusterSet.erase(Iter);
|
|
||||||
}
|
|
||||||
StringRef LeafName = getLeafTypeName(R.Record.Type);
|
|
||||||
uint32_t TI = R.TI.getIndex();
|
|
||||||
StringRef TypeName = Types->getTypeName(R.TI);
|
|
||||||
outs() << formatv("{0,-6} {1} ({2:x}) {3}\n", Prefix, LeafName, TI,
|
|
||||||
TypeName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
outs() << "\n";
|
|
||||||
outs() << "Dumping hash adjustment chains\n";
|
|
||||||
for (const auto &A : Tpi->getHashAdjusters()) {
|
|
||||||
TypeIndex TI(A.second);
|
|
||||||
StringRef TypeName = Types->getTypeName(TI);
|
|
||||||
const CVType &HeadRecord = Types->getType(TI);
|
|
||||||
assert(HeadRecord.Hash.hasValue());
|
|
||||||
|
|
||||||
auto CollisionsIter = Hasher.Lookup.find(*HeadRecord.Hash);
|
|
||||||
if (CollisionsIter == Hasher.Lookup.end())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const auto &Collisions = CollisionsIter->second;
|
|
||||||
outs() << TypeName << "\n";
|
|
||||||
outs() << formatv(" [HEAD] {0:x} {1} {2}\n", uint32_t(A.second),
|
|
||||||
getLeafTypeName(HeadRecord.Type), TypeName);
|
|
||||||
for (const auto &Chain : Collisions) {
|
|
||||||
if (Chain.TI == TI)
|
|
||||||
continue;
|
|
||||||
const CVType &TailRecord = Types->getType(Chain.TI);
|
|
||||||
outs() << formatv(" {0:x} {1} {2}\n", Chain.TI.getIndex(),
|
|
||||||
getLeafTypeName(TailRecord.Type),
|
|
||||||
Types->getTypeName(Chain.TI));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outs() << formatv("There are {0} orphaned hash adjusters\n",
|
|
||||||
AdjusterSet.size());
|
|
||||||
for (const auto &Adj : AdjusterSet) {
|
|
||||||
outs() << formatv(" {0}\n", Adj);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t DistinctHashValues = Hasher.Lookup.size();
|
|
||||||
outs() << formatv("{0}/{1} hash collisions", Count, DistinctHashValues);
|
|
||||||
return Error::success();
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
//===- Analyze.h - PDB analysis functions -----------------------*- C++ -*-===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef LLVM_TOOLS_LLVMPDBDUMP_ANALYSIS_H
|
|
||||||
#define LLVM_TOOLS_LLVMPDBDUMP_ANALYSIS_H
|
|
||||||
|
|
||||||
#include "OutputStyle.h"
|
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
namespace pdb {
|
|
||||||
class PDBFile;
|
|
||||||
class AnalysisStyle : public OutputStyle {
|
|
||||||
public:
|
|
||||||
explicit AnalysisStyle(PDBFile &File);
|
|
||||||
|
|
||||||
Error dump() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
PDBFile &File;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -9,7 +9,6 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_llvm_tool(llvm-pdbutil
|
add_llvm_tool(llvm-pdbutil
|
||||||
Analyze.cpp
|
|
||||||
BytesOutputStyle.cpp
|
BytesOutputStyle.cpp
|
||||||
DumpOutputStyle.cpp
|
DumpOutputStyle.cpp
|
||||||
ExplainOutputStyle.cpp
|
ExplainOutputStyle.cpp
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include "llvm-pdbutil.h"
|
#include "llvm-pdbutil.h"
|
||||||
|
|
||||||
#include "Analyze.h"
|
|
||||||
#include "BytesOutputStyle.h"
|
#include "BytesOutputStyle.h"
|
||||||
#include "DumpOutputStyle.h"
|
#include "DumpOutputStyle.h"
|
||||||
#include "ExplainOutputStyle.h"
|
#include "ExplainOutputStyle.h"
|
||||||
@ -117,10 +116,6 @@ cl::SubCommand
|
|||||||
PdbToYamlSubcommand("pdb2yaml",
|
PdbToYamlSubcommand("pdb2yaml",
|
||||||
"Generate a detailed YAML description of a PDB File");
|
"Generate a detailed YAML description of a PDB File");
|
||||||
|
|
||||||
cl::SubCommand
|
|
||||||
AnalyzeSubcommand("analyze",
|
|
||||||
"Analyze various aspects of a PDB's structure");
|
|
||||||
|
|
||||||
cl::SubCommand MergeSubcommand("merge",
|
cl::SubCommand MergeSubcommand("merge",
|
||||||
"Merge multiple PDBs into a single PDB");
|
"Merge multiple PDBs into a single PDB");
|
||||||
|
|
||||||
@ -686,14 +681,6 @@ cl::list<std::string> InputFilename(cl::Positional,
|
|||||||
cl::sub(PdbToYamlSubcommand));
|
cl::sub(PdbToYamlSubcommand));
|
||||||
} // namespace pdb2yaml
|
} // namespace pdb2yaml
|
||||||
|
|
||||||
namespace analyze {
|
|
||||||
cl::opt<bool> StringTable("hash-collisions", cl::desc("Find hash collisions"),
|
|
||||||
cl::sub(AnalyzeSubcommand), cl::init(false));
|
|
||||||
cl::list<std::string> InputFilename(cl::Positional,
|
|
||||||
cl::desc("<input PDB file>"), cl::Required,
|
|
||||||
cl::sub(AnalyzeSubcommand));
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace merge {
|
namespace merge {
|
||||||
cl::list<std::string> InputFilenames(cl::Positional,
|
cl::list<std::string> InputFilenames(cl::Positional,
|
||||||
cl::desc("<input PDB files>"),
|
cl::desc("<input PDB files>"),
|
||||||
@ -891,14 +878,6 @@ static void dumpBytes(StringRef Path) {
|
|||||||
ExitOnErr(O->dump());
|
ExitOnErr(O->dump());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpAnalysis(StringRef Path) {
|
|
||||||
std::unique_ptr<IPDBSession> Session;
|
|
||||||
auto &File = loadPDB(Path, Session);
|
|
||||||
auto O = llvm::make_unique<AnalysisStyle>(File);
|
|
||||||
|
|
||||||
ExitOnErr(O->dump());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool opts::pretty::shouldDumpSymLevel(SymLevel Search) {
|
bool opts::pretty::shouldDumpSymLevel(SymLevel Search) {
|
||||||
if (SymTypes.empty())
|
if (SymTypes.empty())
|
||||||
return true;
|
return true;
|
||||||
@ -1526,8 +1505,6 @@ int main(int Argc, const char **Argv) {
|
|||||||
opts::yaml2pdb::YamlPdbOutputFile = OutputFilename.str();
|
opts::yaml2pdb::YamlPdbOutputFile = OutputFilename.str();
|
||||||
}
|
}
|
||||||
yamlToPdb(opts::yaml2pdb::InputFilename);
|
yamlToPdb(opts::yaml2pdb::InputFilename);
|
||||||
} else if (opts::AnalyzeSubcommand) {
|
|
||||||
dumpAnalysis(opts::analyze::InputFilename.front());
|
|
||||||
} else if (opts::DiaDumpSubcommand) {
|
} else if (opts::DiaDumpSubcommand) {
|
||||||
llvm::for_each(opts::diadump::InputFilenames, dumpDia);
|
llvm::for_each(opts::diadump::InputFilenames, dumpDia);
|
||||||
} else if (opts::PrettySubcommand) {
|
} else if (opts::PrettySubcommand) {
|
||||||
|
Loading…
Reference in New Issue
Block a user