Home | History | Annotate | Download | only in llvm-readobj
      1 //===- llvm-readobj/ELF.cpp - ELF Specific Dumper -------------------------===//
      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 #include "llvm-readobj.h"
     11 
     12 #include "llvm/Object/ELF.h"
     13 #include "llvm/Support/Casting.h"
     14 #include "llvm/Support/Format.h"
     15 
     16 namespace llvm {
     17 using namespace object;
     18 using namespace ELF;
     19 
     20 const char *getTypeString(uint64_t Type) {
     21   switch (Type) {
     22   case DT_BIND_NOW:
     23     return "(BIND_NOW)";
     24   case DT_DEBUG:
     25     return "(DEBUG)";
     26   case DT_FINI:
     27     return "(FINI)";
     28   case DT_FINI_ARRAY:
     29     return "(FINI_ARRAY)";
     30   case DT_FINI_ARRAYSZ:
     31     return "(FINI_ARRAYSZ)";
     32   case DT_FLAGS:
     33     return "(FLAGS)";
     34   case DT_HASH:
     35     return "(HASH)";
     36   case DT_INIT:
     37     return "(INIT)";
     38   case DT_INIT_ARRAY:
     39     return "(INIT_ARRAY)";
     40   case DT_INIT_ARRAYSZ:
     41     return "(INIT_ARRAYSZ)";
     42   case DT_PREINIT_ARRAY:
     43     return "(PREINIT_ARRAY)";
     44   case DT_PREINIT_ARRAYSZ:
     45     return "(PREINIT_ARRAYSZ)";
     46   case DT_JMPREL:
     47     return "(JMPREL)";
     48   case DT_NEEDED:
     49     return "(NEEDED)";
     50   case DT_NULL:
     51     return "(NULL)";
     52   case DT_PLTGOT:
     53     return "(PLTGOT)";
     54   case DT_PLTREL:
     55     return "(PLTREL)";
     56   case DT_PLTRELSZ:
     57     return "(PLTRELSZ)";
     58   case DT_REL:
     59     return "(REL)";
     60   case DT_RELA:
     61     return "(RELA)";
     62   case DT_RELENT:
     63     return "(RELENT)";
     64   case DT_RELSZ:
     65     return "(RELSZ)";
     66   case DT_RELAENT:
     67     return "(RELAENT)";
     68   case DT_RELASZ:
     69     return "(RELASZ)";
     70   case DT_RPATH:
     71     return "(RPATH)";
     72   case DT_RUNPATH:
     73     return "(RUNPATH)";
     74   case DT_SONAME:
     75     return "(SONAME)";
     76   case DT_STRSZ:
     77     return "(STRSZ)";
     78   case DT_STRTAB:
     79     return "(STRTAB)";
     80   case DT_SYMBOLIC:
     81     return "(SYMBOLIC)";
     82   case DT_SYMENT:
     83     return "(SYMENT)";
     84   case DT_SYMTAB:
     85     return "(SYMTAB)";
     86   case DT_TEXTREL:
     87     return "(TEXTREL)";
     88   default:
     89     return "unknown";
     90   }
     91 }
     92 
     93 template <class ELFT>
     94 void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, uint64_t Value,
     95                 bool Is64, raw_ostream &OS) {
     96   switch (Type) {
     97   case DT_PLTREL:
     98     if (Value == DT_REL) {
     99       OS << "REL";
    100       break;
    101     } else if (Value == DT_RELA) {
    102       OS << "RELA";
    103       break;
    104     }
    105   // Fallthrough.
    106   case DT_PLTGOT:
    107   case DT_HASH:
    108   case DT_STRTAB:
    109   case DT_SYMTAB:
    110   case DT_RELA:
    111   case DT_INIT:
    112   case DT_FINI:
    113   case DT_REL:
    114   case DT_JMPREL:
    115   case DT_INIT_ARRAY:
    116   case DT_FINI_ARRAY:
    117   case DT_PREINIT_ARRAY:
    118   case DT_DEBUG:
    119   case DT_NULL:
    120     OS << format("0x%" PRIx64, Value);
    121     break;
    122   case DT_PLTRELSZ:
    123   case DT_RELASZ:
    124   case DT_RELAENT:
    125   case DT_STRSZ:
    126   case DT_SYMENT:
    127   case DT_RELSZ:
    128   case DT_RELENT:
    129   case DT_INIT_ARRAYSZ:
    130   case DT_FINI_ARRAYSZ:
    131   case DT_PREINIT_ARRAYSZ:
    132     OS << Value << " (bytes)";
    133     break;
    134   case DT_NEEDED:
    135     OS << "Shared library: ["
    136        << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
    137     break;
    138   case DT_SONAME:
    139     OS << "Library soname: ["
    140        << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
    141     break;
    142   }
    143 }
    144 
    145 template <class ELFT>
    146 ErrorOr<void> dumpDynamicTable(const ELFObjectFile<ELFT> *O, raw_ostream &OS) {
    147   typedef ELFObjectFile<ELFT> ELFO;
    148   typedef typename ELFO::Elf_Dyn_iterator EDI;
    149   EDI Start = O->begin_dynamic_table(),
    150       End = O->end_dynamic_table(true);
    151 
    152   if (Start == End)
    153     return error_code::success();
    154 
    155   ptrdiff_t Total = std::distance(Start, End);
    156   OS << "Dynamic section contains " << Total << " entries\n";
    157 
    158   bool Is64 = O->getBytesInAddress() == 8;
    159 
    160   OS << "  Tag" << (Is64 ? "                " : "        ") << "Type"
    161      << "                 " << "Name/Value\n";
    162   for (; Start != End; ++Start) {
    163     OS << " "
    164        << format(Is64 ? "0x%016" PRIx64 : "0x%08" PRIx64, Start->getTag())
    165        << " " << format("%-21s", getTypeString(Start->getTag()));
    166     printValue(O, Start->getTag(), Start->getVal(), Is64, OS);
    167     OS << "\n";
    168   }
    169 
    170   OS << "  Total: " << Total << "\n\n";
    171   return error_code::success();
    172 }
    173 
    174 ErrorOr<void> dumpELFDynamicTable(ObjectFile *O, raw_ostream &OS) {
    175   // Little-endian 32-bit
    176   if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj =
    177           dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(O))
    178     return dumpDynamicTable(ELFObj, OS);
    179 
    180   // Big-endian 32-bit
    181   if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj =
    182           dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(O))
    183     return dumpDynamicTable(ELFObj, OS);
    184 
    185   // Little-endian 64-bit
    186   if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj =
    187           dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(O))
    188     return dumpDynamicTable(ELFObj, OS);
    189 
    190   // Big-endian 64-bit
    191   if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj =
    192           dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(O))
    193     return dumpDynamicTable(ELFObj, OS);
    194   return error_code(object_error::invalid_file_type);
    195 }
    196 } // end namespace llvm
    197