ELFDumper.cpp revision 167957fa095bc7200b908e6e142be3e604bcfeea
1//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===// 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/// \file 11/// \brief This file implements the ELF-specific dumper for llvm-readobj. 12/// 13//===----------------------------------------------------------------------===// 14 15#include "llvm-readobj.h" 16#include "Error.h" 17#include "ObjDumper.h" 18#include "StreamWriter.h" 19 20#include "llvm/ADT/SmallString.h" 21#include "llvm/Object/ELF.h" 22#include "llvm/Support/Compiler.h" 23#include "llvm/Support/Format.h" 24#include "llvm/Support/MathExtras.h" 25#include "llvm/Support/raw_ostream.h" 26 27using namespace llvm; 28using namespace llvm::object; 29using namespace ELF; 30 31 32#define LLVM_READOBJ_ENUM_CASE(ns, enum) \ 33 case ns::enum: return #enum; 34 35namespace { 36 37template<typename ELFT> 38class ELFDumper : public ObjDumper { 39public: 40 ELFDumper(const ELFObjectFile<ELFT> *Obj, StreamWriter& Writer) 41 : ObjDumper(Writer) 42 , Obj(Obj) { } 43 44 virtual void printFileHeaders() LLVM_OVERRIDE; 45 virtual void printSections() LLVM_OVERRIDE; 46 virtual void printRelocations() LLVM_OVERRIDE; 47 virtual void printSymbols() LLVM_OVERRIDE; 48 virtual void printDynamicSymbols() LLVM_OVERRIDE; 49 virtual void printUnwindInfo() LLVM_OVERRIDE; 50 51 virtual void printDynamicTable() LLVM_OVERRIDE; 52 virtual void printNeededLibraries() LLVM_OVERRIDE; 53 virtual void printProgramHeaders() LLVM_OVERRIDE; 54 55private: 56 typedef ELFObjectFile<ELFT> ELFO; 57 typedef typename ELFO::Elf_Shdr Elf_Shdr; 58 typedef typename ELFO::Elf_Sym Elf_Sym; 59 60 void printSymbol(symbol_iterator SymI, bool IsDynamic = false); 61 62 void printRelocation(section_iterator SecI, relocation_iterator RelI); 63 64 const ELFO *Obj; 65}; 66 67} // namespace 68 69 70namespace llvm { 71 72error_code createELFDumper(const object::ObjectFile *Obj, 73 StreamWriter& Writer, 74 OwningPtr<ObjDumper> &Result) { 75 typedef ELFType<support::little, 4, false> Little32ELF; 76 typedef ELFType<support::big, 4, false> Big32ELF; 77 typedef ELFType<support::little, 4, true > Little64ELF; 78 typedef ELFType<support::big, 8, true > Big64ELF; 79 80 typedef ELFObjectFile<Little32ELF> LittleELF32Obj; 81 typedef ELFObjectFile<Big32ELF > BigELF32Obj; 82 typedef ELFObjectFile<Little64ELF> LittleELF64Obj; 83 typedef ELFObjectFile<Big64ELF > BigELF64Obj; 84 85 // Little-endian 32-bit 86 if (const LittleELF32Obj *ELFObj = dyn_cast<LittleELF32Obj>(Obj)) { 87 Result.reset(new ELFDumper<Little32ELF>(ELFObj, Writer)); 88 return readobj_error::success; 89 } 90 91 // Big-endian 32-bit 92 if (const BigELF32Obj *ELFObj = dyn_cast<BigELF32Obj>(Obj)) { 93 Result.reset(new ELFDumper<Big32ELF>(ELFObj, Writer)); 94 return readobj_error::success; 95 } 96 97 // Little-endian 64-bit 98 if (const LittleELF64Obj *ELFObj = dyn_cast<LittleELF64Obj>(Obj)) { 99 Result.reset(new ELFDumper<Little64ELF>(ELFObj, Writer)); 100 return readobj_error::success; 101 } 102 103 // Big-endian 64-bit 104 if (const BigELF64Obj *ELFObj = dyn_cast<BigELF64Obj>(Obj)) { 105 Result.reset(new ELFDumper<Big64ELF>(ELFObj, Writer)); 106 return readobj_error::success; 107 } 108 109 return readobj_error::unsupported_obj_file_format; 110} 111 112} // namespace llvm 113 114 115static const EnumEntry<unsigned> ElfClass[] = { 116 { "None", ELF::ELFCLASSNONE }, 117 { "32-bit", ELF::ELFCLASS32 }, 118 { "64-bit", ELF::ELFCLASS64 }, 119}; 120 121static const EnumEntry<unsigned> ElfDataEncoding[] = { 122 { "None", ELF::ELFDATANONE }, 123 { "LittleEndian", ELF::ELFDATA2LSB }, 124 { "BigEndian", ELF::ELFDATA2MSB }, 125}; 126 127static const EnumEntry<unsigned> ElfObjectFileType[] = { 128 { "None", ELF::ET_NONE }, 129 { "Relocatable", ELF::ET_REL }, 130 { "Executable", ELF::ET_EXEC }, 131 { "SharedObject", ELF::ET_DYN }, 132 { "Core", ELF::ET_CORE }, 133}; 134 135static const EnumEntry<unsigned> ElfOSABI[] = { 136 { "SystemV", ELF::ELFOSABI_NONE }, 137 { "HPUX", ELF::ELFOSABI_HPUX }, 138 { "NetBSD", ELF::ELFOSABI_NETBSD }, 139 { "GNU/Linux", ELF::ELFOSABI_LINUX }, 140 { "GNU/Hurd", ELF::ELFOSABI_HURD }, 141 { "Solaris", ELF::ELFOSABI_SOLARIS }, 142 { "AIX", ELF::ELFOSABI_AIX }, 143 { "IRIX", ELF::ELFOSABI_IRIX }, 144 { "FreeBSD", ELF::ELFOSABI_FREEBSD }, 145 { "TRU64", ELF::ELFOSABI_TRU64 }, 146 { "Modesto", ELF::ELFOSABI_MODESTO }, 147 { "OpenBSD", ELF::ELFOSABI_OPENBSD }, 148 { "OpenVMS", ELF::ELFOSABI_OPENVMS }, 149 { "NSK", ELF::ELFOSABI_NSK }, 150 { "AROS", ELF::ELFOSABI_AROS }, 151 { "FenixOS", ELF::ELFOSABI_FENIXOS }, 152 { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI }, 153 { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX }, 154 { "ARM", ELF::ELFOSABI_ARM }, 155 { "Standalone" , ELF::ELFOSABI_STANDALONE } 156}; 157 158static const EnumEntry<unsigned> ElfMachineType[] = { 159 LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE ), 160 LLVM_READOBJ_ENUM_ENT(ELF, EM_M32 ), 161 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC ), 162 LLVM_READOBJ_ENUM_ENT(ELF, EM_386 ), 163 LLVM_READOBJ_ENUM_ENT(ELF, EM_68K ), 164 LLVM_READOBJ_ENUM_ENT(ELF, EM_88K ), 165 LLVM_READOBJ_ENUM_ENT(ELF, EM_486 ), 166 LLVM_READOBJ_ENUM_ENT(ELF, EM_860 ), 167 LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS ), 168 LLVM_READOBJ_ENUM_ENT(ELF, EM_S370 ), 169 LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE ), 170 LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC ), 171 LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500 ), 172 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS ), 173 LLVM_READOBJ_ENUM_ENT(ELF, EM_960 ), 174 LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC ), 175 LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64 ), 176 LLVM_READOBJ_ENUM_ENT(ELF, EM_S390 ), 177 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU ), 178 LLVM_READOBJ_ENUM_ENT(ELF, EM_V800 ), 179 LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20 ), 180 LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32 ), 181 LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE ), 182 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM ), 183 LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA ), 184 LLVM_READOBJ_ENUM_ENT(ELF, EM_SH ), 185 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9 ), 186 LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE ), 187 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC ), 188 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300 ), 189 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H ), 190 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S ), 191 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500 ), 192 LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64 ), 193 LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X ), 194 LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE ), 195 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12 ), 196 LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA ), 197 LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP ), 198 LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU ), 199 LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1 ), 200 LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE ), 201 LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16 ), 202 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100 ), 203 LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ ), 204 LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64 ), 205 LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP ), 206 LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10 ), 207 LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11 ), 208 LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66 ), 209 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS ), 210 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7 ), 211 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16 ), 212 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11 ), 213 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08 ), 214 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05 ), 215 LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX ), 216 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19 ), 217 LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX ), 218 LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS ), 219 LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN ), 220 LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH ), 221 LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP ), 222 LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX ), 223 LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY ), 224 LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM ), 225 LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR ), 226 LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30 ), 227 LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V ), 228 LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V ), 229 LLVM_READOBJ_ENUM_ENT(ELF, EM_V850 ), 230 LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R ), 231 LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300 ), 232 LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200 ), 233 LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ ), 234 LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC ), 235 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT ), 236 LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA ), 237 LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE ), 238 LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP ), 239 LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K ), 240 LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC ), 241 LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K ), 242 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200 ), 243 LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K ), 244 LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX ), 245 LLVM_READOBJ_ENUM_ENT(ELF, EM_CR ), 246 LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16 ), 247 LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430 ), 248 LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN ), 249 LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33 ), 250 LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP ), 251 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA ), 252 LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE ), 253 LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS ), 254 LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP ), 255 LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ), 256 LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX ), 257 LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE ), 258 LLVM_READOBJ_ENUM_ENT(ELF, EM_C166 ), 259 LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C ), 260 LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F ), 261 LLVM_READOBJ_ENUM_ENT(ELF, EM_CE ), 262 LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C ), 263 LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000 ), 264 LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08 ), 265 LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC ), 266 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2 ), 267 LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7 ), 268 LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24 ), 269 LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3 ), 270 LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32), 271 LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17 ), 272 LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000 ), 273 LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000 ), 274 LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500 ), 275 LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS ), 276 LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C ), 277 LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C ), 278 LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA ), 279 LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON ), 280 LLVM_READOBJ_ENUM_ENT(ELF, EM_8051 ), 281 LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X ), 282 LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32 ), 283 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1 ), 284 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X ), 285 LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30 ), 286 LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16 ), 287 LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK ), 288 LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2 ), 289 LLVM_READOBJ_ENUM_ENT(ELF, EM_RX ), 290 LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG ), 291 LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS ), 292 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16 ), 293 LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16 ), 294 LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU ), 295 LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X ), 296 LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M ), 297 LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M ), 298 LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64 ), 299 LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32 ), 300 LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8 ), 301 LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64 ), 302 LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO ), 303 LLVM_READOBJ_ENUM_ENT(ELF, EM_MICROBLAZE ), 304 LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA ), 305 LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX ), 306 LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD ), 307 LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST ), 308 LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND ), 309 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ), 310 LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8 ), 311 LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ), 312 LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ), 313 LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ), 314 LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ), 315 LLVM_READOBJ_ENUM_ENT(ELF, EM_MBLAZE ) 316}; 317 318static const EnumEntry<unsigned> ElfSymbolBindings[] = { 319 { "Local", ELF::STB_LOCAL }, 320 { "Global", ELF::STB_GLOBAL }, 321 { "Weak", ELF::STB_WEAK } 322}; 323 324static const EnumEntry<unsigned> ElfSymbolTypes[] = { 325 { "None", ELF::STT_NOTYPE }, 326 { "Object", ELF::STT_OBJECT }, 327 { "Function", ELF::STT_FUNC }, 328 { "Section", ELF::STT_SECTION }, 329 { "File", ELF::STT_FILE }, 330 { "Common", ELF::STT_COMMON }, 331 { "TLS", ELF::STT_TLS }, 332 { "GNU_IFunc", ELF::STT_GNU_IFUNC } 333}; 334 335static const char *getElfSectionType(unsigned Arch, unsigned Type) { 336 switch (Arch) { 337 case Triple::arm: 338 switch (Type) { 339 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); 340 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); 341 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); 342 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); 343 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); 344 } 345 case Triple::hexagon: 346 switch (Type) { 347 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); 348 } 349 case Triple::x86_64: 350 switch (Type) { 351 LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); 352 } 353 case Triple::mips: 354 case Triple::mipsel: 355 switch (Type) { 356 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); 357 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); 358 } 359 } 360 361 switch (Type) { 362 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL ); 363 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS ); 364 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB ); 365 LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB ); 366 LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA ); 367 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH ); 368 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC ); 369 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE ); 370 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS ); 371 LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL ); 372 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB ); 373 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM ); 374 LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY ); 375 LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY ); 376 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY ); 377 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP ); 378 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX ); 379 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES ); 380 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH ); 381 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef ); 382 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed ); 383 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym ); 384 default: return ""; 385 } 386} 387 388static const EnumEntry<unsigned> ElfSectionFlags[] = { 389 LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ), 390 LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ), 391 LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ), 392 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ), 393 LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ), 394 LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK ), 395 LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER ), 396 LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING), 397 LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP ), 398 LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS ), 399 LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION), 400 LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION), 401 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ) 402}; 403 404static const EnumEntry<unsigned> ElfSegmentTypes[] = { 405 LLVM_READOBJ_ENUM_ENT(ELF, PT_NULL ), 406 LLVM_READOBJ_ENUM_ENT(ELF, PT_LOAD ), 407 LLVM_READOBJ_ENUM_ENT(ELF, PT_DYNAMIC), 408 LLVM_READOBJ_ENUM_ENT(ELF, PT_INTERP ), 409 LLVM_READOBJ_ENUM_ENT(ELF, PT_NOTE ), 410 LLVM_READOBJ_ENUM_ENT(ELF, PT_SHLIB ), 411 LLVM_READOBJ_ENUM_ENT(ELF, PT_PHDR ), 412 LLVM_READOBJ_ENUM_ENT(ELF, PT_TLS ), 413 414 LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_EH_FRAME), 415 LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_EH_FRAME), 416 LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_UNWIND), 417 418 LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_STACK), 419 LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_RELRO), 420 421 LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_EXIDX), 422 LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_UNWIND) 423}; 424 425static const EnumEntry<unsigned> ElfSegmentFlags[] = { 426 LLVM_READOBJ_ENUM_ENT(ELF, PF_X), 427 LLVM_READOBJ_ENUM_ENT(ELF, PF_W), 428 LLVM_READOBJ_ENUM_ENT(ELF, PF_R) 429}; 430 431 432template<class ELFT> 433void ELFDumper<ELFT>::printFileHeaders() { 434 error_code EC; 435 436 const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader(); 437 438 { 439 DictScope D(W, "ElfHeader"); 440 { 441 DictScope D(W, "Ident"); 442 W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0, 443 4)); 444 W.printEnum ("Class", Header->e_ident[ELF::EI_CLASS], 445 makeArrayRef(ElfClass)); 446 W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA], 447 makeArrayRef(ElfDataEncoding)); 448 W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]); 449 W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], 450 makeArrayRef(ElfOSABI)); 451 W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]); 452 W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD)); 453 } 454 455 W.printEnum ("Type", Header->e_type, makeArrayRef(ElfObjectFileType)); 456 W.printEnum ("Machine", Header->e_machine, makeArrayRef(ElfMachineType)); 457 W.printNumber("Version", Header->e_version); 458 W.printHex ("Entry", Header->e_entry); 459 W.printHex ("ProgramHeaderOffset", Header->e_phoff); 460 W.printHex ("SectionHeaderOffset", Header->e_shoff); 461 W.printFlags ("Flags", Header->e_flags); 462 W.printNumber("HeaderSize", Header->e_ehsize); 463 W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize); 464 W.printNumber("ProgramHeaderCount", Header->e_phnum); 465 W.printNumber("SectionHeaderEntrySize", Header->e_shentsize); 466 W.printNumber("SectionHeaderCount", Header->e_shnum); 467 W.printNumber("StringTableSectionIndex", Header->e_shstrndx); 468 } 469} 470 471template<class ELFT> 472void ELFDumper<ELFT>::printSections() { 473 ListScope SectionsD(W, "Sections"); 474 475 int SectionIndex = -1; 476 error_code EC; 477 for (section_iterator SecI = Obj->begin_sections(), 478 SecE = Obj->end_sections(); 479 SecI != SecE; SecI.increment(EC)) { 480 if (error(EC)) break; 481 482 ++SectionIndex; 483 484 const Elf_Shdr *Section = Obj->getElfSection(SecI); 485 StringRef Name; 486 if (error(SecI->getName(Name))) 487 Name = ""; 488 489 DictScope SectionD(W, "Section"); 490 W.printNumber("Index", SectionIndex); 491 W.printNumber("Name", Name, Section->sh_name); 492 W.printHex ("Type", getElfSectionType(Obj->getArch(), Section->sh_type), 493 Section->sh_type); 494 W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); 495 W.printHex ("Address", Section->sh_addr); 496 W.printHex ("Offset", Section->sh_offset); 497 W.printNumber("Size", Section->sh_size); 498 W.printNumber("Link", Section->sh_link); 499 W.printNumber("Info", Section->sh_info); 500 W.printNumber("AddressAlignment", Section->sh_addralign); 501 W.printNumber("EntrySize", Section->sh_entsize); 502 503 if (opts::SectionRelocations) { 504 ListScope D(W, "Relocations"); 505 for (relocation_iterator RelI = SecI->begin_relocations(), 506 RelE = SecI->end_relocations(); 507 RelI != RelE; RelI.increment(EC)) { 508 if (error(EC)) break; 509 510 printRelocation(SecI, RelI); 511 } 512 } 513 514 if (opts::SectionSymbols) { 515 ListScope D(W, "Symbols"); 516 for (symbol_iterator SymI = Obj->begin_symbols(), 517 SymE = Obj->end_symbols(); 518 SymI != SymE; SymI.increment(EC)) { 519 if (error(EC)) break; 520 521 bool Contained = false; 522 if (SecI->containsSymbol(*SymI, Contained) || !Contained) 523 continue; 524 525 printSymbol(SymI); 526 } 527 } 528 529 if (opts::SectionData) { 530 StringRef Data; 531 if (error(SecI->getContents(Data))) break; 532 533 W.printBinaryBlock("SectionData", Data); 534 } 535 } 536} 537 538template<class ELFT> 539void ELFDumper<ELFT>::printRelocations() { 540 ListScope D(W, "Relocations"); 541 542 error_code EC; 543 int SectionNumber = -1; 544 for (section_iterator SecI = Obj->begin_sections(), 545 SecE = Obj->end_sections(); 546 SecI != SecE; SecI.increment(EC)) { 547 if (error(EC)) break; 548 549 ++SectionNumber; 550 StringRef Name; 551 if (error(SecI->getName(Name))) 552 continue; 553 554 bool PrintedGroup = false; 555 for (relocation_iterator RelI = SecI->begin_relocations(), 556 RelE = SecI->end_relocations(); 557 RelI != RelE; RelI.increment(EC)) { 558 if (error(EC)) break; 559 560 if (!PrintedGroup) { 561 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; 562 W.indent(); 563 PrintedGroup = true; 564 } 565 566 printRelocation(SecI, RelI); 567 } 568 569 if (PrintedGroup) { 570 W.unindent(); 571 W.startLine() << "}\n"; 572 } 573 } 574} 575 576template<class ELFT> 577void ELFDumper<ELFT>::printRelocation(section_iterator Sec, 578 relocation_iterator RelI) { 579 uint64_t Offset; 580 uint64_t RelocType; 581 SmallString<32> RelocName; 582 int64_t Addend; 583 StringRef SymbolName; 584 SymbolRef Symbol; 585 if (Obj->getElfHeader()->e_type == ELF::ET_REL){ 586 if (error(RelI->getOffset(Offset))) return; 587 } else { 588 if (error(RelI->getAddress(Offset))) return; 589 } 590 if (error(RelI->getType(RelocType))) return; 591 if (error(RelI->getTypeName(RelocName))) return; 592 if (error(getELFRelocationAddend(*RelI, Addend))) return; 593 if (error(RelI->getSymbol(Symbol))) return; 594 if (error(Symbol.getName(SymbolName))) return; 595 596 if (opts::ExpandRelocs) { 597 DictScope Group(W, "Relocation"); 598 W.printHex("Offset", Offset); 599 W.printNumber("Type", RelocName, RelocType); 600 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); 601 W.printHex("Addend", Addend); 602 } else { 603 raw_ostream& OS = W.startLine(); 604 OS << W.hex(Offset) 605 << " " << RelocName 606 << " " << (SymbolName.size() > 0 ? SymbolName : "-") 607 << " " << W.hex(Addend) 608 << "\n"; 609 } 610} 611 612template<class ELFT> 613void ELFDumper<ELFT>::printSymbols() { 614 ListScope Group(W, "Symbols"); 615 616 error_code EC; 617 for (symbol_iterator SymI = Obj->begin_symbols(), SymE = Obj->end_symbols(); 618 SymI != SymE; SymI.increment(EC)) { 619 if (error(EC)) break; 620 621 printSymbol(SymI); 622 } 623} 624 625template<class ELFT> 626void ELFDumper<ELFT>::printDynamicSymbols() { 627 ListScope Group(W, "DynamicSymbols"); 628 629 error_code EC; 630 for (symbol_iterator SymI = Obj->begin_dynamic_symbols(), 631 SymE = Obj->end_dynamic_symbols(); 632 SymI != SymE; SymI.increment(EC)) { 633 if (error(EC)) break; 634 635 printSymbol(SymI, true); 636 } 637} 638 639template<class ELFT> 640void ELFDumper<ELFT>::printSymbol(symbol_iterator SymI, bool IsDynamic) { 641 error_code EC; 642 643 const Elf_Sym *Symbol = Obj->getElfSymbol(SymI); 644 const Elf_Shdr *Section = Obj->getSection(Symbol); 645 646 StringRef SymbolName; 647 if (SymI->getName(SymbolName)) 648 SymbolName = ""; 649 650 StringRef SectionName = ""; 651 if (Section) 652 Obj->getSectionName(Section, SectionName); 653 654 std::string FullSymbolName(SymbolName); 655 if (IsDynamic) { 656 StringRef Version; 657 bool IsDefault; 658 if (error(Obj->getSymbolVersion(*SymI, Version, IsDefault))) 659 return; 660 if (!Version.empty()) { 661 FullSymbolName += (IsDefault ? "@@" : "@"); 662 FullSymbolName += Version; 663 } 664 } 665 666 DictScope D(W, "Symbol"); 667 W.printNumber("Name", FullSymbolName, Symbol->st_name); 668 W.printHex ("Value", Symbol->st_value); 669 W.printNumber("Size", Symbol->st_size); 670 W.printEnum ("Binding", Symbol->getBinding(), 671 makeArrayRef(ElfSymbolBindings)); 672 W.printEnum ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes)); 673 W.printNumber("Other", Symbol->st_other); 674 W.printHex ("Section", SectionName, Symbol->st_shndx); 675} 676 677#define LLVM_READOBJ_TYPE_CASE(name) \ 678 case DT_##name: return #name 679 680static const char *getTypeString(uint64_t Type) { 681 switch (Type) { 682 LLVM_READOBJ_TYPE_CASE(BIND_NOW); 683 LLVM_READOBJ_TYPE_CASE(DEBUG); 684 LLVM_READOBJ_TYPE_CASE(FINI); 685 LLVM_READOBJ_TYPE_CASE(FINI_ARRAY); 686 LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ); 687 LLVM_READOBJ_TYPE_CASE(FLAGS); 688 LLVM_READOBJ_TYPE_CASE(HASH); 689 LLVM_READOBJ_TYPE_CASE(INIT); 690 LLVM_READOBJ_TYPE_CASE(INIT_ARRAY); 691 LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ); 692 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY); 693 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ); 694 LLVM_READOBJ_TYPE_CASE(JMPREL); 695 LLVM_READOBJ_TYPE_CASE(NEEDED); 696 LLVM_READOBJ_TYPE_CASE(NULL); 697 LLVM_READOBJ_TYPE_CASE(PLTGOT); 698 LLVM_READOBJ_TYPE_CASE(PLTREL); 699 LLVM_READOBJ_TYPE_CASE(PLTRELSZ); 700 LLVM_READOBJ_TYPE_CASE(REL); 701 LLVM_READOBJ_TYPE_CASE(RELA); 702 LLVM_READOBJ_TYPE_CASE(RELENT); 703 LLVM_READOBJ_TYPE_CASE(RELSZ); 704 LLVM_READOBJ_TYPE_CASE(RELAENT); 705 LLVM_READOBJ_TYPE_CASE(RELASZ); 706 LLVM_READOBJ_TYPE_CASE(RPATH); 707 LLVM_READOBJ_TYPE_CASE(RUNPATH); 708 LLVM_READOBJ_TYPE_CASE(SONAME); 709 LLVM_READOBJ_TYPE_CASE(STRSZ); 710 LLVM_READOBJ_TYPE_CASE(STRTAB); 711 LLVM_READOBJ_TYPE_CASE(SYMBOLIC); 712 LLVM_READOBJ_TYPE_CASE(SYMENT); 713 LLVM_READOBJ_TYPE_CASE(SYMTAB); 714 LLVM_READOBJ_TYPE_CASE(TEXTREL); 715 default: return "unknown"; 716 } 717} 718 719#undef LLVM_READOBJ_TYPE_CASE 720 721template<class ELFT> 722static void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, 723 uint64_t Value, bool Is64, raw_ostream &OS) { 724 switch (Type) { 725 case DT_PLTREL: 726 if (Value == DT_REL) { 727 OS << "REL"; 728 break; 729 } else if (Value == DT_RELA) { 730 OS << "RELA"; 731 break; 732 } 733 // Fallthrough. 734 case DT_PLTGOT: 735 case DT_HASH: 736 case DT_STRTAB: 737 case DT_SYMTAB: 738 case DT_RELA: 739 case DT_INIT: 740 case DT_FINI: 741 case DT_REL: 742 case DT_JMPREL: 743 case DT_INIT_ARRAY: 744 case DT_FINI_ARRAY: 745 case DT_PREINIT_ARRAY: 746 case DT_DEBUG: 747 case DT_NULL: 748 OS << format("0x%" PRIX64, Value); 749 break; 750 case DT_PLTRELSZ: 751 case DT_RELASZ: 752 case DT_RELAENT: 753 case DT_STRSZ: 754 case DT_SYMENT: 755 case DT_RELSZ: 756 case DT_RELENT: 757 case DT_INIT_ARRAYSZ: 758 case DT_FINI_ARRAYSZ: 759 case DT_PREINIT_ARRAYSZ: 760 OS << Value << " (bytes)"; 761 break; 762 case DT_NEEDED: 763 OS << "SharedLibrary (" 764 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; 765 break; 766 case DT_SONAME: 767 OS << "LibrarySoname (" 768 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; 769 break; 770 } 771} 772 773template<class ELFT> 774void ELFDumper<ELFT>::printUnwindInfo() { 775 W.startLine() << "UnwindInfo not implemented.\n"; 776} 777 778template<class ELFT> 779void ELFDumper<ELFT>::printDynamicTable() { 780 typedef typename ELFO::Elf_Dyn_iterator EDI; 781 EDI Start = Obj->begin_dynamic_table(), 782 End = Obj->end_dynamic_table(true); 783 784 if (Start == End) 785 return; 786 787 ptrdiff_t Total = std::distance(Start, End); 788 raw_ostream &OS = W.getOStream(); 789 W.startLine() << "DynamicSection [ (" << Total << " entries)\n"; 790 791 bool Is64 = Obj->getBytesInAddress() == 8; 792 793 W.startLine() 794 << " Tag" << (Is64 ? " " : " ") << "Type" 795 << " " << "Name/Value\n"; 796 for (; Start != End; ++Start) { 797 W.startLine() 798 << " " 799 << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Start->getTag()) 800 << " " << format("%-21s", getTypeString(Start->getTag())); 801 printValue(Obj, Start->getTag(), Start->getVal(), Is64, OS); 802 OS << "\n"; 803 } 804 805 W.startLine() << "]\n"; 806} 807 808static bool compareLibraryName(const LibraryRef &L, const LibraryRef &R) { 809 StringRef LPath, RPath; 810 L.getPath(LPath); 811 R.getPath(RPath); 812 return LPath < RPath; 813} 814 815template<class ELFT> 816void ELFDumper<ELFT>::printNeededLibraries() { 817 ListScope D(W, "NeededLibraries"); 818 819 error_code EC; 820 821 typedef std::vector<LibraryRef> LibsTy; 822 LibsTy Libs; 823 824 for (library_iterator I = Obj->begin_libraries_needed(), 825 E = Obj->end_libraries_needed(); 826 I != E; I.increment(EC)) { 827 if (EC) 828 report_fatal_error("Needed libraries iteration failed"); 829 830 Libs.push_back(*I); 831 } 832 833 std::sort(Libs.begin(), Libs.end(), &compareLibraryName); 834 835 for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); 836 I != E; ++I) { 837 StringRef Path; 838 I->getPath(Path); 839 outs() << " " << Path << "\n"; 840 } 841} 842 843template<class ELFT> 844void ELFDumper<ELFT>::printProgramHeaders() { 845 ListScope L(W, "ProgramHeaders"); 846 847 for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(), 848 PE = Obj->end_program_headers(); 849 PI != PE; ++PI) { 850 DictScope P(W, "ProgramHeader"); 851 W.printEnum ("Type", PI->p_type, makeArrayRef(ElfSegmentTypes)); 852 W.printHex ("Offset", PI->p_offset); 853 W.printHex ("VirtualAddress", PI->p_vaddr); 854 W.printHex ("PhysicalAddress", PI->p_paddr); 855 W.printNumber("FileSize", PI->p_filesz); 856 W.printNumber("MemSize", PI->p_memsz); 857 W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags)); 858 W.printNumber("Alignment", PI->p_align); 859 } 860} 861