llvm-objdump: Use help of CFG to print assembly when --cfg is passed.
authorBenjamin Kramer <benny.kra@googlemail.com>
Mon, 8 Aug 2011 18:32:12 +0000 (18:32 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Mon, 8 Aug 2011 18:32:12 +0000 (18:32 +0000)
This way we can avoid printing unreachable code (data).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137057 91177308-0d34-0410-b5e6-96231b3b80d8

tools/llvm-objdump/llvm-objdump.cpp

index b1c74d298b3694cce30e630705bd2f380197d13d..7a5c9110fe4146ee6c5b14efade480b67c3bc8e9 100644 (file)
@@ -248,28 +248,57 @@ static void DisassembleInput(const StringRef &Filename) {
         raw_ostream &DebugOut = nulls();
 #endif
 
-      for (Index = Start; Index < End; Index += Size) {
-        MCInst Inst;
-        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
+      if (!CFG) {
+        for (Index = Start; Index < End; Index += Size) {
+          MCInst Inst;
+          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
+          }
         }
-      }
 
-      if (CFG) {
+      } else {
+        // Create CFG and use it for disassembly.
         MCFunction f =
           MCFunction::createFunctionFromMC(Symbols[si].second, DisAsm.get(),
                                            memoryObject, Start, End, InstrInfo,
                                            DebugOut);
 
+        for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){
+          bool hasPreds = false;
+          // Only print blocks that have predecessors.
+          // FIXME: Slow.
+          for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
+              ++pi)
+            if (pi->second.contains(&fi->second)) {
+              hasPreds = true;
+              break;
+            }
+
+          if (!hasPreds && fi != f.begin())
+            continue;
+
+          for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
+               ++ii) {
+            uint64_t addr;
+            if (error(i->getAddress(addr))) break;
+            const MCDecodedInst &Inst = fi->second.getInsts()[ii];
+            outs() << format("%8x:\t", addr + Inst.Address);
+            DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
+            IP->printInst(&Inst.Inst, outs());
+            outs() << '\n';
+          }
+        }
+
         // Start a new dot file.
         std::string Error;
         raw_fd_ostream Out((f.getName().str() + ".dot").c_str(), Error);