llvm-object: Add inline relocation information to disassembly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141897 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index e2a583b..4ae13be 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -144,7 +144,14 @@
   outs() << output;
 }
 
-static void DisassembleObject(const ObjectFile *Obj) {
+static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
+  uint64_t a_addr, b_addr;
+  if (error(a.getAddress(a_addr))) return false;
+  if (error(b.getAddress(b_addr))) return false;
+  return a_addr < b_addr;
+}
+
+static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
   const Target *TheTarget = GetTarget(Obj);
   if (!TheTarget) {
     // GetTarget prints out stuff.
@@ -164,6 +171,9 @@
     if (error(i->isText(text))) break;
     if (!text) continue;
 
+    uint64_t SectionAddr;
+    if (error(i->getAddress(SectionAddr))) break;
+
     // Make a list of all the symbols in this section.
     std::vector<std::pair<uint64_t, StringRef> > Symbols;
     for (symbol_iterator si = Obj->begin_symbols(),
@@ -182,6 +192,20 @@
     // Sort the symbols by address, just in case they didn't come in that way.
     array_pod_sort(Symbols.begin(), Symbols.end());
 
+    // Make a list of all the relocations for this section.
+    std::vector<RelocationRef> Rels;
+    if (InlineRelocs) {
+      for (relocation_iterator ri = i->begin_relocations(),
+                               re = i->end_relocations();
+                              ri != re; ri.increment(ec)) {
+        if (error(ec)) break;
+        Rels.push_back(*ri);
+      }
+    }
+
+    // Sort relocations by address.
+    std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
+
     StringRef name;
     if (error(i->getName(name))) break;
     outs() << "Disassembly of section " << name << ':';
@@ -231,6 +255,8 @@
     uint64_t SectSize;
     if (error(i->getSize(SectSize))) break;
 
+    std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
+    std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
     // Disassemble symbol by symbol.
     for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
       uint64_t Start = Symbols[si].first;
@@ -259,9 +285,7 @@
 
         if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
                                    DebugOut, nulls())) {
-          uint64_t addr;
-          if (error(i->getAddress(addr))) break;
-          outs() << format("%8x:\t", addr + Index);
+          outs() << format("%8x:\t", SectionAddr + Index);
           DumpBytes(StringRef(Bytes.data() + Index, Size));
           IP->printInst(&Inst, outs(), "");
           outs() << "\n";
@@ -270,6 +294,24 @@
           if (Size == 0)
             Size = 1; // skip illegible bytes
         }
+
+        // Print relocation for instruction.
+        while (rel_cur != rel_end) {
+          uint64_t addr;
+          SmallString<16> name;
+          SmallString<32> val;
+          if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
+          // Stop when rel_cur's address is past the current instruction.
+          if (addr > Index + Size) break;
+          if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
+          if (error(rel_cur->getValueString(val))) goto skip_print_rel;
+
+          outs() << format("\t\t\t%8x: ", SectionAddr + addr) << name << "\t"
+                 << val << "\n";
+
+        skip_print_rel:
+          ++rel_cur;
+        }
       }
     }
   }
@@ -330,8 +372,8 @@
 
 static void DumpObject(const ObjectFile *o) {
   if (Disassemble)
-    DisassembleObject(o);
-  if (Relocations)
+    DisassembleObject(o, Relocations);
+  if (Relocations && !Disassemble)
     PrintRelocations(o);
   if (SectionHeaders)
     PrintSectionHeaders(o);