using namespace llvm::object;
static bool error(error_code ec) {
- if (!ec) return false;
+ if (!ec) return false;
- outs() << "error reading file: " << ec.message() << ".\n";
- outs().flush();
- return true;
+ outs() << "error reading file: " << ec.message() << ".\n";
+ outs().flush();
+ return true;
}
static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
- uint64_t a_addr, b_addr;
- if (error(a.getOffset(a_addr))) return false;
- if (error(b.getOffset(b_addr))) return false;
- return a_addr < b_addr;
+ uint64_t a_addr, b_addr;
+ if (error(a.getOffset(a_addr))) return false;
+ if (error(b.getOffset(b_addr))) return false;
+ return a_addr < b_addr;
}
static void DumpBytes(StringRef bytes) {
- static const char hex_rep[] = "0123456789abcdef";
- // FIXME: The real way to do this is to figure out the longest instruction
- // and align to that size before printing. I'll fix this when I get
- // around to outputting relocations.
- // 15 is the longest x86 instruction
- // 3 is for the hex rep of a byte + a space.
- // 1 is for the null terminator.
- enum { OutputSize = (15 * 3) + 1 };
- char output[OutputSize];
-
- assert(bytes.size() <= 15
- && "DumpBytes only supports instructions of up to 15 bytes");
- memset(output, ' ', sizeof(output));
- unsigned index = 0;
- for (StringRef::iterator i = bytes.begin(),
- e = bytes.end(); i != e; ++i) {
- output[index] = hex_rep[(*i & 0xF0) >> 4];
- output[index + 1] = hex_rep[*i & 0xF];
- index += 3;
- }
-
- output[sizeof(output) - 1] = 0;
- outs() << output;
+ static const char hex_rep[] = "0123456789abcdef";
+ // FIXME: The real way to do this is to figure out the longest instruction
+ // and align to that size before printing. I'll fix this when I get
+ // around to outputting relocations.
+ // 15 is the longest x86 instruction
+ // 3 is for the hex rep of a byte + a space.
+ // 1 is for the null terminator.
+ enum { OutputSize = (15 * 3) + 1 };
+ char output[OutputSize];
+
+ assert(bytes.size() <= 15
+ && "DumpBytes only supports instructions of up to 15 bytes");
+ memset(output, ' ', sizeof(output));
+ unsigned index = 0;
+ for (StringRef::iterator i = bytes.begin(),
+ e = bytes.end(); i != e; ++i) {
+ output[index] = hex_rep[(*i & 0xF0) >> 4];
+ output[index + 1] = hex_rep[*i & 0xF];
+ index += 3;
+ }
+
+ output[sizeof(output) - 1] = 0;
+ outs() << output;
}
::Binary::Binary(const std::string& filename)
StringRef Name;
if (error(si->getName(Name))) break;
+
+ outs() << "\nXXX " << Name << "\n";
+
Symbols.push_back(std::make_pair(Address, Name));
}
}
}
}
}
+
+void ::Binary::disassemble_cfg() {
+ for (MCModule::const_func_iterator FI = Mod->func_begin(),
+ FE = Mod->func_end();
+ FI != FE; ++FI) {
+ static int filenum = 0;
+ std::string FileName = std::string("dot/") + (Twine((*FI)->getName()) + "_" + utostr(filenum) + ".dot").str();
+
+ std::cerr << FileName << std::endl;
+
+ // Start a new dot file.
+ std::string Error;
+ raw_fd_ostream Out(FileName.c_str(), Error);
+ if (!Error.empty()) {
+ errs() << "llvm-objdump: warning: " << Error << '\n';
+ return;
+ }
+
+ Out << "digraph \"" << (*FI)->getName() << "\" {\n";
+ Out << "graph [ rankdir = \"LR\" ];\n";
+ for (MCFunction::const_iterator i = (*FI)->begin(), e = (*FI)->end(); i != e; ++i) {
+ // Only print blocks that have predecessors.
+ bool hasPreds = (*i)->pred_begin() != (*i)->pred_end();
+
+ if (!hasPreds && i != (*FI)->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";
+
+ ++filenum;
+ }
+}