1b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//===-- ELFDump.cpp - ELF-specific dumper -----------------------*- C++ -*-===//
2b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//
3b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//                     The LLVM Compiler Infrastructure
4b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//
5b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer// This file is distributed under the University of Illinois Open Source
6b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer// License. See LICENSE.TXT for details.
7b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//
8b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//===----------------------------------------------------------------------===//
9b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer///
10b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer/// \file
11b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer/// \brief This file implements the ELF-specific dumper for llvm-objdump.
12b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer///
13b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer//===----------------------------------------------------------------------===//
14b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
15b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer#include "llvm-objdump.h"
16081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer#include "llvm/Object/ELFObjectFile.h"
17b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer#include "llvm/Support/Format.h"
18b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer#include "llvm/Support/MathExtras.h"
19b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer#include "llvm/Support/raw_ostream.h"
20b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
21b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencerusing namespace llvm;
22b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencerusing namespace llvm::object;
23b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
24081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencertemplate <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
25081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer  typedef ELFFile<ELFT> ELFO;
26b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  outs() << "Program Header:\n";
27b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  for (typename ELFO::Elf_Phdr_Iter pi = o->begin_program_headers(),
28b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer                                    pe = o->end_program_headers();
29b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer                                    pi != pe; ++pi) {
30b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    switch (pi->p_type) {
31b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    case ELF::PT_LOAD:
32b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      outs() << "    LOAD ";
33b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      break;
34b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    case ELF::PT_GNU_STACK:
35b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      outs() << "   STACK ";
36b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      break;
37b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    case ELF::PT_GNU_EH_FRAME:
38b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      outs() << "EH_FRAME ";
39b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      break;
408a3a1deed8e7b18b18dea73cb4245a8ef7c46a4fMichael J. Spencer    case ELF::PT_INTERP:
418a3a1deed8e7b18b18dea73cb4245a8ef7c46a4fMichael J. Spencer      outs() << "  INTERP ";
428a3a1deed8e7b18b18dea73cb4245a8ef7c46a4fMichael J. Spencer      break;
438a3a1deed8e7b18b18dea73cb4245a8ef7c46a4fMichael J. Spencer    case ELF::PT_DYNAMIC:
448a3a1deed8e7b18b18dea73cb4245a8ef7c46a4fMichael J. Spencer      outs() << " DYNAMIC ";
458a3a1deed8e7b18b18dea73cb4245a8ef7c46a4fMichael J. Spencer      break;
46561823009b41e144f49cc00f1dc3e55b8649d400Michael J. Spencer    case ELF::PT_PHDR:
47561823009b41e144f49cc00f1dc3e55b8649d400Michael J. Spencer      outs() << "    PHDR ";
48561823009b41e144f49cc00f1dc3e55b8649d400Michael J. Spencer      break;
49512685dacf7978af2729e86d022fab4d78784d43Shankar Easwaran    case ELF::PT_TLS:
50512685dacf7978af2729e86d022fab4d78784d43Shankar Easwaran      outs() << "    TLS ";
51512685dacf7978af2729e86d022fab4d78784d43Shankar Easwaran      break;
52b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    default:
53b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      outs() << " UNKNOWN ";
54b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    }
55b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
56ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer    const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " ";
5746418797cd3b24ddf92240eab76f52bc7ac72d9dMichael J. Spencer
58b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer    outs() << "off    "
5946418797cd3b24ddf92240eab76f52bc7ac72d9dMichael J. Spencer           << format(Fmt, (uint64_t)pi->p_offset)
60b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << "vaddr "
6146418797cd3b24ddf92240eab76f52bc7ac72d9dMichael J. Spencer           << format(Fmt, (uint64_t)pi->p_vaddr)
62b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << "paddr "
6346418797cd3b24ddf92240eab76f52bc7ac72d9dMichael J. Spencer           << format(Fmt, (uint64_t)pi->p_paddr)
64c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer           << format("align 2**%u\n", countTrailingZeros<uint64_t>(pi->p_align))
65b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << "         filesz "
6646418797cd3b24ddf92240eab76f52bc7ac72d9dMichael J. Spencer           << format(Fmt, (uint64_t)pi->p_filesz)
67b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << "memsz "
6846418797cd3b24ddf92240eab76f52bc7ac72d9dMichael J. Spencer           << format(Fmt, (uint64_t)pi->p_memsz)
69b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << "flags "
70b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << ((pi->p_flags & ELF::PF_R) ? "r" : "-")
71b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << ((pi->p_flags & ELF::PF_W) ? "w" : "-")
72b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << ((pi->p_flags & ELF::PF_X) ? "x" : "-")
73b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer           << "\n";
74b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  }
75b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  outs() << "\n";
76b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer}
77b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
78b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencervoid llvm::printELFFileHeader(const object::ObjectFile *Obj) {
79b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  // Little-endian 32-bit
80bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj))
81081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printProgramHeaders(ELFObj->getELFFile());
82b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
83b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  // Big-endian 32-bit
84bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj))
85081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printProgramHeaders(ELFObj->getELFFile());
86b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
87b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  // Little-endian 64-bit
88bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj))
89081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printProgramHeaders(ELFObj->getELFFile());
90b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
91b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer  // Big-endian 64-bit
92bed93b0de197c6b64357068ae8e1a883ddbb0e94Rafael Espindola  if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj))
93081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer    printProgramHeaders(ELFObj->getELFFile());
94b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer}
95