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