Nuke MCAnalysis.

The code is buggy and barely tested. It is also mostly boilerplate.
(This includes MCObjectDisassembler, which is the interface to that
functionality)

Following an IRC discussion with Jim Grosbach, it seems sensible to just
nuke the whole lot of functionality, and dig it up from VCS if
necessary (I hope not!).

All of this stuff appears to have been added in a huge patch dump (look
at the timeframe surrounding e.g. r182628) where almost every patch
seemed to be untested and not reviewed before being committed.
Post-review responses to the patches were never addressed. I don't think
any of it would have passed pre-commit review.

I doubt anyone is depending on this, since this code appears to be
extremely buggy. In limited testing that Michael Spencer and I did, we
couldn't find a single real-world object file that wouldn't crash the
CFG reconstruction stuff. The symbolizer stuff has O(n^2) behavior and
so is not much use to anyone anyway. It seemed simpler to remove them as
a whole. Most of this code is boilerplate, which is the only way it was
able to scrape by 60% coverage.

HEADSUP: Modules folks, some files I nuked were referenced from
include/llvm/module.modulemap; I just deleted the references. Hopefully
that is the right fix (one was a FIXME though!).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216983 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sean Silva
2014-09-02 22:32:20 +00:00
parent d5dd8ce2a5
commit 73d86aa56a
31 changed files with 5 additions and 2854 deletions

View File

@ -20,11 +20,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAnalysis/MCAtom.h"
#include "llvm/MC/MCAnalysis/MCFunction.h"
#include "llvm/MC/MCAnalysis/MCModule.h"
#include "llvm/MC/MCAnalysis/MCModuleYAML.h"
#include "llvm/MC/MCAnalysis/MCObjectSymbolizer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
@ -32,7 +27,6 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectDisassembler.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCRelocationInfo.h"
@ -141,20 +135,6 @@ static cl::alias
PrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
cl::aliasopt(PrivateHeaders));
static cl::opt<bool>
Symbolize("symbolize", cl::desc("When disassembling instructions, "
"try to symbolize operands."));
static cl::opt<bool>
CFG("cfg", cl::desc("Create a CFG for every function found in the object"
" and write it to a graphviz file"));
// FIXME: Does it make sense to have a dedicated tool for yaml cfg output?
static cl::opt<std::string>
YAMLCFG("yaml-cfg",
cl::desc("Create a CFG and write it as a YAML MCModule."),
cl::value_desc("yaml output file"));
static StringRef ToolName;
bool llvm::error(std::error_code EC) {
@ -200,53 +180,6 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) {
return TheTarget;
}
// Write a graphviz file for the CFG inside an MCFunction.
// FIXME: Use GraphWriter
static void emitDOTFile(const char *FileName, const MCFunction &f,
MCInstPrinter *IP) {
// Start a new dot file.
std::error_code EC;
raw_fd_ostream Out(FileName, EC, sys::fs::F_Text);
if (EC) {
errs() << "llvm-objdump: warning: " << EC.message() << '\n';
return;
}
Out << "digraph \"" << f.getName() << "\" {\n";
Out << "graph [ rankdir = \"LR\" ];\n";
for (MCFunction::const_iterator i = f.begin(), e = f.end(); i != e; ++i) {
// Only print blocks that have predecessors.
bool hasPreds = (*i)->pred_begin() != (*i)->pred_end();
if (!hasPreds && i != f.begin())
continue;
Out << '"' << (*i)->getInsts()->getBeginAddr() << "\" [ label=\"<a>";
// Print instructions.
for (unsigned ii = 0, ie = (*i)->getInsts()->size(); ii != ie;
++ii) {
if (ii != 0) // Not the first line, start a new row.
Out << '|';
if (ii + 1 == ie) // Last line, add an end id.
Out << "<o>";
// Escape special chars and print the instruction in mnemonic form.
std::string Str;
raw_string_ostream OS(Str);
IP->printInst(&(*i)->getInsts()->at(ii).Inst, OS, "");
Out << DOT::EscapeString(OS.str());
}
Out << "\" shape=\"record\" ];\n";
// Add edges.
for (MCBasicBlock::succ_const_iterator si = (*i)->succ_begin(),
se = (*i)->succ_end(); si != se; ++si)
Out << (*i)->getInsts()->getBeginAddr() << ":o -> "
<< (*si)->getInsts()->getBeginAddr() << ":a\n";
}
Out << "}\n";
}
void llvm::DumpBytes(StringRef bytes) {
static const char hex_rep[] = "0123456789abcdef";
// FIXME: The real way to do this is to figure out the longest instruction
@ -335,19 +268,6 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
return;
}
if (Symbolize) {
std::unique_ptr<MCRelocationInfo> RelInfo(
TheTarget->createMCRelocationInfo(TripleName, Ctx));
if (RelInfo) {
std::unique_ptr<MCSymbolizer> Symzer(
MCObjectSymbolizer::createObjectSymbolizer(Ctx, std::move(RelInfo),
Obj));
if (Symzer)
DisAsm->setSymbolizer(std::move(Symzer));
}
}
std::unique_ptr<const MCInstrAnalysis> MIA(
TheTarget->createMCInstrAnalysis(MII.get()));
@ -360,45 +280,6 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
return;
}
if (CFG || !YAMLCFG.empty()) {
std::unique_ptr<MCObjectDisassembler> OD(
new MCObjectDisassembler(*Obj, *DisAsm, *MIA));
std::unique_ptr<MCModule> Mod(OD->buildModule(/* withCFG */ true));
for (MCModule::const_atom_iterator AI = Mod->atom_begin(),
AE = Mod->atom_end();
AI != AE; ++AI) {
outs() << "Atom " << (*AI)->getName() << ": \n";
if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(*AI)) {
for (MCTextAtom::const_iterator II = TA->begin(), IE = TA->end();
II != IE;
++II) {
IP->printInst(&II->Inst, outs(), "");
outs() << "\n";
}
}
}
if (CFG) {
for (MCModule::const_func_iterator FI = Mod->func_begin(),
FE = Mod->func_end();
FI != FE; ++FI) {
static int filenum = 0;
emitDOTFile((Twine((*FI)->getName()) + "_" +
utostr(filenum) + ".dot").str().c_str(),
**FI, IP.get());
++filenum;
}
}
if (!YAMLCFG.empty()) {
std::error_code EC;
raw_fd_ostream YAMLOut(YAMLCFG, EC, sys::fs::F_Text);
if (EC) {
errs() << ToolName << ": warning: " << EC.message() << '\n';
return;
}
mcmodule2yaml(YAMLOut, *Mod, *MII, *MRI);
}
}
StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
"\t\t\t%08" PRIx64 ": ";