summaryrefslogtreecommitdiffstats
path: root/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-07-17 15:36:56 +0000
committerdim <dim@FreeBSD.org>2011-07-17 15:36:56 +0000
commit1176aa52646fe641a4243a246aa7f960c708a274 (patch)
treec8086addb211fa670a9d2b1038d8c2e453229755 /tools/llvm-objdump/llvm-objdump.cpp
parentece02cd5829cea836e9365b0845a8ef042d17b0a (diff)
downloadFreeBSD-src-1176aa52646fe641a4243a246aa7f960c708a274.zip
FreeBSD-src-1176aa52646fe641a4243a246aa7f960c708a274.tar.gz
Vendor import of llvm trunk r135360:
http://llvm.org/svn/llvm-project/llvm/trunk@135360
Diffstat (limited to 'tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp126
1 files changed, 78 insertions, 48 deletions
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index a17624a..4079e4a 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -14,14 +14,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/ObjectFile.h"
-// This config must be included before llvm-config.h.
-#include "llvm/Config/config.h"
-#include "../../lib/MC/MCDisassembler/EDDisassembler.h"
-#include "../../lib/MC/MCDisassembler/EDInst.h"
-#include "../../lib/MC/MCDisassembler/EDOperand.h"
-#include "../../lib/MC/MCDisassembler/EDToken.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
@@ -38,12 +33,9 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetSelect.h"
#include <algorithm>
-#include <cctype>
-#include <cerrno>
#include <cstring>
using namespace llvm;
using namespace object;
@@ -69,6 +61,14 @@ namespace {
"see -version for available targets"));
StringRef ToolName;
+
+ bool error(error_code ec) {
+ if (!ec) return false;
+
+ outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
+ outs().flush();
+ return true;
+ }
}
static const Target *GetTarget(const ObjectFile *Obj = NULL) {
@@ -159,17 +159,46 @@ static void DisassembleInput(const StringRef &Filename) {
outs() << '\n';
outs() << Filename
- << ":\tfile format " << Obj->getFileFormatName() << "\n\n\n";
+ << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
+ error_code ec;
for (ObjectFile::section_iterator i = Obj->begin_sections(),
e = Obj->end_sections();
- i != e; ++i) {
- if (!i->isText())
- continue;
- outs() << "Disassembly of section " << i->getName() << ":\n\n";
+ i != e; i.increment(ec)) {
+ if (error(ec)) break;
+ bool text;
+ if (error(i->isText(text))) break;
+ if (!text) continue;
+
+ // Make a list of all the symbols in this section.
+ std::vector<std::pair<uint64_t, StringRef> > Symbols;
+ for (ObjectFile::symbol_iterator si = Obj->begin_symbols(),
+ se = Obj->end_symbols();
+ si != se; si.increment(ec)) {
+ bool contains;
+ if (!error(i->containsSymbol(*si, contains)) && contains) {
+ uint64_t Address;
+ if (error(si->getAddress(Address))) break;
+ StringRef Name;
+ if (error(si->getName(Name))) break;
+ Symbols.push_back(std::make_pair(Address, Name));
+ }
+ }
+
+ // Sort the symbols by address, just in case they didn't come in that way.
+ array_pod_sort(Symbols.begin(), Symbols.end());
+
+ StringRef name;
+ if (error(i->getName(name))) break;
+ outs() << "Disassembly of section " << name << ':';
+
+ // If the section has no symbols just insert a dummy one and disassemble
+ // the whole section.
+ if (Symbols.empty())
+ Symbols.push_back(std::make_pair(0, name));
// Set up disassembler.
- OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createAsmInfo(TripleName));
+ OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
if (!AsmInfo) {
errs() << "error: no assembly info for target " << TripleName << "\n";
@@ -182,49 +211,49 @@ static void DisassembleInput(const StringRef &Filename) {
return;
}
- // FIXME: We shouldn't need to do this (and link in codegen).
- // When we split this out, we should do it in a way that makes
- // it straightforward to switch subtargets on the fly (.e.g,
- // the .cpu and .code16 directives).
- std::string FeaturesStr;
- OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName,
- FeaturesStr));
- if (!TM) {
- errs() << "error: could not create target for triple " << TripleName << "\n";
- return;
- }
-
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
- *TM, AsmPrinterVariant, *AsmInfo));
+ AsmPrinterVariant, *AsmInfo));
if (!IP) {
errs() << "error: no instruction printer for target " << TripleName << '\n';
return;
}
- StringRef Bytes = i->getContents();
+ StringRef Bytes;
+ if (error(i->getContents(Bytes))) break;
StringRefMemoryObject memoryObject(Bytes);
uint64_t Size;
uint64_t Index;
-
- for (Index = 0; Index < Bytes.size(); Index += Size) {
- MCInst Inst;
-
-# ifndef NDEBUG
- raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
-# else
- raw_ostream &DebugOut = nulls();
-# endif
-
- if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) {
- outs() << format("%8x:\t", i->getAddress() + Index);
- DumpBytes(StringRef(Bytes.data() + Index, Size));
- IP->printInst(&Inst, outs());
- outs() << "\n";
- } else {
- errs() << ToolName << ": warning: invalid instruction encoding\n";
- if (Size == 0)
- Size = 1; // skip illegible bytes
+ uint64_t SectSize;
+ if (error(i->getSize(SectSize))) break;
+
+ // Disassemble symbol by symbol.
+ for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
+ uint64_t Start = Symbols[si].first;
+ uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1;
+ outs() << '\n' << Symbols[si].second << ":\n";
+
+ for (Index = Start; Index < End; Index += Size) {
+ MCInst Inst;
+
+#ifndef NDEBUG
+ raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
+#else
+ raw_ostream &DebugOut = nulls();
+#endif
+
+ if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) {
+ uint64_t addr;
+ if (error(i->getAddress(addr))) break;
+ outs() << format("%8x:\t", addr + Index);
+ DumpBytes(StringRef(Bytes.data() + Index, Size));
+ IP->printInst(&Inst, outs());
+ outs() << "\n";
+ } else {
+ errs() << ToolName << ": warning: invalid instruction encoding\n";
+ if (Size == 0)
+ Size = 1; // skip illegible bytes
+ }
}
}
}
@@ -240,6 +269,7 @@ int main(int argc, char **argv) {
llvm::InitializeAllTargetInfos();
// FIXME: We shouldn't need to initialize the Target(Machine)s.
llvm::InitializeAllTargets();
+ llvm::InitializeAllMCAsmInfos();
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
OpenPOWER on IntegriCloud