Move TargetRegistry and TargetSelect from Target to Support where they belong.
[oota-llvm.git] / tools / llvm-objdump / llvm-objdump.cpp
1 //===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This program is a utility that works like binutils "objdump", that is, it
11 // dumps out a plethora of information about an object file depending on the
12 // flags.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "MCFunction.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/ADT/OwningPtr.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/MC/MCDisassembler.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstPrinter.h"
25 #include "llvm/MC/MCInstrAnalysis.h"
26 #include "llvm/MC/MCInstrDesc.h"
27 #include "llvm/MC/MCInstrInfo.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/Format.h"
31 #include "llvm/Support/GraphWriter.h"
32 #include "llvm/Support/Host.h"
33 #include "llvm/Support/ManagedStatic.h"
34 #include "llvm/Support/MemoryBuffer.h"
35 #include "llvm/Support/MemoryObject.h"
36 #include "llvm/Support/PrettyStackTrace.h"
37 #include "llvm/Support/Signals.h"
38 #include "llvm/Support/SourceMgr.h"
39 #include "llvm/Support/TargetRegistry.h"
40 #include "llvm/Support/TargetSelect.h"
41 #include "llvm/Support/raw_ostream.h"
42 #include "llvm/Support/system_error.h"
43 #include <algorithm>
44 #include <cstring>
45 using namespace llvm;
46 using namespace object;
47
48 namespace {
49   cl::list<std::string>
50   InputFilenames(cl::Positional, cl::desc("<input object files>"),
51                  cl::ZeroOrMore);
52
53   cl::opt<bool>
54   Disassemble("disassemble",
55     cl::desc("Display assembler mnemonics for the machine instructions"));
56   cl::alias
57   Disassembled("d", cl::desc("Alias for --disassemble"),
58                cl::aliasopt(Disassemble));
59
60   cl::opt<bool>
61   CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and"
62                       "write it to a graphviz file"));
63
64   cl::opt<std::string>
65   TripleName("triple", cl::desc("Target triple to disassemble for, "
66                                 "see -version for available targets"));
67
68   cl::opt<std::string>
69   ArchName("arch", cl::desc("Target arch to disassemble for, "
70                             "see -version for available targets"));
71
72   StringRef ToolName;
73
74   bool error(error_code ec) {
75     if (!ec) return false;
76
77     outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
78     outs().flush();
79     return true;
80   }
81 }
82
83 static const Target *GetTarget(const ObjectFile *Obj = NULL) {
84   // Figure out the target triple.
85   llvm::Triple TT("unknown-unknown-unknown");
86   if (TripleName.empty()) {
87     if (Obj)
88       TT.setArch(Triple::ArchType(Obj->getArch()));
89   } else
90     TT.setTriple(Triple::normalize(TripleName));
91
92   if (!ArchName.empty())
93     TT.setArchName(ArchName);
94
95   TripleName = TT.str();
96
97   // Get the target specific parser.
98   std::string Error;
99   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
100   if (TheTarget)
101     return TheTarget;
102
103   errs() << ToolName << ": error: unable to get target for '" << TripleName
104          << "', see --version and --triple.\n";
105   return 0;
106 }
107
108 namespace {
109 class StringRefMemoryObject : public MemoryObject {
110 private:
111   StringRef Bytes;
112 public:
113   StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {}
114
115   uint64_t getBase() const { return 0; }
116   uint64_t getExtent() const { return Bytes.size(); }
117
118   int readByte(uint64_t Addr, uint8_t *Byte) const {
119     if (Addr >= getExtent())
120       return -1;
121     *Byte = Bytes[Addr];
122     return 0;
123   }
124 };
125 }
126
127 static void DumpBytes(StringRef bytes) {
128   static char hex_rep[] = "0123456789abcdef";
129   // FIXME: The real way to do this is to figure out the longest instruction
130   //        and align to that size before printing. I'll fix this when I get
131   //        around to outputting relocations.
132   // 15 is the longest x86 instruction
133   // 3 is for the hex rep of a byte + a space.
134   // 1 is for the null terminator.
135   enum { OutputSize = (15 * 3) + 1 };
136   char output[OutputSize];
137
138   assert(bytes.size() <= 15
139     && "DumpBytes only supports instructions of up to 15 bytes");
140   memset(output, ' ', sizeof(output));
141   unsigned index = 0;
142   for (StringRef::iterator i = bytes.begin(),
143                            e = bytes.end(); i != e; ++i) {
144     output[index] = hex_rep[(*i & 0xF0) >> 4];
145     output[index + 1] = hex_rep[*i & 0xF];
146     index += 3;
147   }
148
149   output[sizeof(output) - 1] = 0;
150   outs() << output;
151 }
152
153 static void DisassembleInput(const StringRef &Filename) {
154   OwningPtr<MemoryBuffer> Buff;
155
156   if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
157     errs() << ToolName << ": " << Filename << ": " << ec.message() << "\n";
158     return;
159   }
160
161   OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
162
163   const Target *TheTarget = GetTarget(Obj.get());
164   if (!TheTarget) {
165     // GetTarget prints out stuff.
166     return;
167   }
168   const MCInstrInfo *InstrInfo = TheTarget->createMCInstrInfo();
169   OwningPtr<MCInstrAnalysis>
170     InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo));
171
172   outs() << '\n';
173   outs() << Filename
174          << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
175
176   error_code ec;
177   for (ObjectFile::section_iterator i = Obj->begin_sections(),
178                                     e = Obj->end_sections();
179                                     i != e; i.increment(ec)) {
180     if (error(ec)) break;
181     bool text;
182     if (error(i->isText(text))) break;
183     if (!text) continue;
184
185     // Make a list of all the symbols in this section.
186     std::vector<std::pair<uint64_t, StringRef> > Symbols;
187     for (ObjectFile::symbol_iterator si = Obj->begin_symbols(),
188                                      se = Obj->end_symbols();
189                                      si != se; si.increment(ec)) {
190       bool contains;
191       if (!error(i->containsSymbol(*si, contains)) && contains) {
192         uint64_t Address;
193         if (error(si->getAddress(Address))) break;
194         StringRef Name;
195         if (error(si->getName(Name))) break;
196         Symbols.push_back(std::make_pair(Address, Name));
197       }
198     }
199
200     // Sort the symbols by address, just in case they didn't come in that way.
201     array_pod_sort(Symbols.begin(), Symbols.end());
202
203     StringRef name;
204     if (error(i->getName(name))) break;
205     outs() << "Disassembly of section " << name << ':';
206
207     // If the section has no symbols just insert a dummy one and disassemble
208     // the whole section.
209     if (Symbols.empty())
210       Symbols.push_back(std::make_pair(0, name));
211
212     // Set up disassembler.
213     OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
214
215     if (!AsmInfo) {
216       errs() << "error: no assembly info for target " << TripleName << "\n";
217       return;
218     }
219
220     OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler());
221     if (!DisAsm) {
222       errs() << "error: no disassembler for target " << TripleName << "\n";
223       return;
224     }
225
226     int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
227     OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
228                                   AsmPrinterVariant, *AsmInfo));
229     if (!IP) {
230       errs() << "error: no instruction printer for target " << TripleName << '\n';
231       return;
232     }
233
234     StringRef Bytes;
235     if (error(i->getContents(Bytes))) break;
236     StringRefMemoryObject memoryObject(Bytes);
237     uint64_t Size;
238     uint64_t Index;
239     uint64_t SectSize;
240     if (error(i->getSize(SectSize))) break;
241
242     // Disassemble symbol by symbol.
243     for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
244       uint64_t Start = Symbols[si].first;
245       uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1;
246       outs() << '\n' << Symbols[si].second << ":\n";
247
248 #ifndef NDEBUG
249         raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
250 #else
251         raw_ostream &DebugOut = nulls();
252 #endif
253
254       if (!CFG) {
255         for (Index = Start; Index < End; Index += Size) {
256           MCInst Inst;
257           if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
258                                      DebugOut)) {
259             uint64_t addr;
260             if (error(i->getAddress(addr))) break;
261             outs() << format("%8x:\t", addr + Index);
262             DumpBytes(StringRef(Bytes.data() + Index, Size));
263             IP->printInst(&Inst, outs());
264             outs() << "\n";
265           } else {
266             errs() << ToolName << ": warning: invalid instruction encoding\n";
267             if (Size == 0)
268               Size = 1; // skip illegible bytes
269           }
270         }
271
272       } else {
273         // Create CFG and use it for disassembly.
274         MCFunction f =
275           MCFunction::createFunctionFromMC(Symbols[si].second, DisAsm.get(),
276                                            memoryObject, Start, End,
277                                            InstrAnalysis.get(), DebugOut);
278
279         for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){
280           bool hasPreds = false;
281           // Only print blocks that have predecessors.
282           // FIXME: Slow.
283           for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
284               ++pi)
285             if (pi->second.contains(&fi->second)) {
286               hasPreds = true;
287               break;
288             }
289
290           // Data block.
291           if (!hasPreds && fi != f.begin()) {
292             uint64_t End = llvm::next(fi) == fe ? SectSize :
293                                                   llvm::next(fi)->first;
294             uint64_t addr;
295             if (error(i->getAddress(addr))) break;
296             outs() << "# " << End-fi->first << " bytes of data:\n";
297             for (unsigned pos = fi->first; pos != End; ++pos) {
298               outs() << format("%8x:\t", addr + pos);
299               DumpBytes(StringRef(Bytes.data() + pos, 1));
300               outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
301             }
302             continue;
303           }
304
305           if (fi->second.contains(&fi->second))
306             outs() << "# Loop begin:\n";
307
308           for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
309                ++ii) {
310             uint64_t addr;
311             if (error(i->getAddress(addr))) break;
312             const MCDecodedInst &Inst = fi->second.getInsts()[ii];
313             outs() << format("%8x:\t", addr + Inst.Address);
314             DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
315             // Simple loops.
316             if (fi->second.contains(&fi->second))
317               outs() << '\t';
318             IP->printInst(&Inst.Inst, outs());
319             outs() << '\n';
320           }
321         }
322
323         // Start a new dot file.
324         std::string Error;
325         raw_fd_ostream Out((f.getName().str() + ".dot").c_str(), Error);
326         if (!Error.empty()) {
327           errs() << ToolName << ": warning: " << Error << '\n';
328           continue;
329         }
330
331         Out << "digraph " << f.getName() << " {\n";
332         Out << "graph [ rankdir = \"LR\" ];\n";
333         for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) {
334           bool hasPreds = false;
335           // Only print blocks that have predecessors.
336           // FIXME: Slow.
337           for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
338                ++pi)
339             if (pi->second.contains(&i->second)) {
340               hasPreds = true;
341               break;
342             }
343
344           if (!hasPreds && i != f.begin())
345             continue;
346
347           Out << '"' << (uintptr_t)&i->second << "\" [ label=\"<a>";
348           // Print instructions.
349           for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie;
350                ++ii) {
351             // Escape special chars and print the instruction in mnemonic form.
352             std::string Str;
353             raw_string_ostream OS(Str);
354             IP->printInst(&i->second.getInsts()[ii].Inst, OS);
355             Out << DOT::EscapeString(OS.str()) << '|';
356           }
357           Out << "<o>\" shape=\"record\" ];\n";
358
359           // Add edges.
360           for (MCBasicBlock::succ_iterator si = i->second.succ_begin(),
361               se = i->second.succ_end(); si != se; ++si)
362             Out << (uintptr_t)&i->second << ":o -> " << (uintptr_t)*si <<":a\n";
363         }
364         Out << "}\n";
365       }
366     }
367   }
368 }
369
370 int main(int argc, char **argv) {
371   // Print a stack trace if we signal out.
372   sys::PrintStackTraceOnErrorSignal();
373   PrettyStackTraceProgram X(argc, argv);
374   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
375
376   // Initialize targets and assembly printers/parsers.
377   llvm::InitializeAllTargetInfos();
378   llvm::InitializeAllTargetMCs();
379   llvm::InitializeAllAsmParsers();
380   llvm::InitializeAllDisassemblers();
381
382   cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
383   TripleName = Triple::normalize(TripleName);
384
385   ToolName = argv[0];
386
387   // Defaults to a.out if no filenames specified.
388   if (InputFilenames.size() == 0)
389     InputFilenames.push_back("a.out");
390
391   // -d is the only flag that is currently implemented, so just print help if
392   // it is not set.
393   if (!Disassemble) {
394     cl::PrintHelpMessage();
395     return 2;
396   }
397
398   std::for_each(InputFilenames.begin(), InputFilenames.end(),
399                 DisassembleInput);
400
401   return 0;
402 }