[objdump] Add --private-headers, -p.

This currently prints the ELF program headers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171649 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp
new file mode 100644
index 0000000..f018eed
--- /dev/null
+++ b/tools/llvm-objdump/ELFDump.cpp
@@ -0,0 +1,87 @@
+//===-- ELFDump.cpp - ELF-specific dumper -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements the ELF-specific dumper for llvm-objdump.
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm-objdump.h"
+
+#include "llvm/Object/ELF.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void printProgramHeaders(
+    const ELFObjectFile<target_endianness, max_alignment, is64Bits> *o) {
+  typedef ELFObjectFile<target_endianness, max_alignment, is64Bits> ELFO;
+  outs() << "Program Header:\n";
+  for (typename ELFO::Elf_Phdr_Iter pi = o->begin_program_headers(),
+                                    pe = o->end_program_headers();
+                                    pi != pe; ++pi) {
+    switch (pi->p_type) {
+    case ELF::PT_LOAD:
+      outs() << "    LOAD ";
+      break;
+    case ELF::PT_GNU_STACK:
+      outs() << "   STACK ";
+      break;
+    case ELF::PT_GNU_EH_FRAME:
+      outs() << "EH_FRAME ";
+      break;
+    default:
+      outs() << " UNKNOWN ";
+    }
+
+    outs() << "off    "
+           << format(is64Bits ? "0x%016x " : "0x%08x ", pi->p_offset)
+           << "vaddr "
+           << format(is64Bits ? "0x%016x " : "0x%08x ", pi->p_vaddr)
+           << "paddr "
+           << format(is64Bits ? "0x%016x " : "0x%08x ", pi->p_paddr)
+           << format("align 2**%d\n", CountTrailingZeros_32(pi->p_align))
+           << "         filesz "
+           << format(is64Bits ? "0x%016x " : "0x%08x ", pi->p_filesz)
+           << "memsz "
+           << format(is64Bits ? "0x%016x " : "0x%08x ", pi->p_memsz)
+           << "flags "
+           << ((pi->p_flags & ELF::PF_R) ? "r" : "-")
+           << ((pi->p_flags & ELF::PF_W) ? "w" : "-")
+           << ((pi->p_flags & ELF::PF_X) ? "x" : "-")
+           << "\n";
+  }
+  outs() << "\n";
+}
+
+void llvm::printELFFileHeader(const object::ObjectFile *Obj) {
+  // Little-endian 32-bit
+  if (const ELFObjectFile<support::little, 4, false> *ELFObj =
+          dyn_cast<ELFObjectFile<support::little, 4, false> >(Obj))
+    printProgramHeaders(ELFObj);
+
+  // Big-endian 32-bit
+  if (const ELFObjectFile<support::big, 4, false> *ELFObj =
+          dyn_cast<ELFObjectFile<support::big, 4, false> >(Obj))
+    printProgramHeaders(ELFObj);
+
+  // Little-endian 64-bit
+  if (const ELFObjectFile<support::little, 8, true> *ELFObj =
+          dyn_cast<ELFObjectFile<support::little, 8, true> >(Obj))
+    printProgramHeaders(ELFObj);
+
+  // Big-endian 64-bit
+  if (const ELFObjectFile<support::big, 8, true> *ELFObj =
+          dyn_cast<ELFObjectFile<support::big, 8, true> >(Obj))
+    printProgramHeaders(ELFObj);
+}