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