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