1 /* 2 Copyright (C) 2001-present by Serge Lamikhov-Center 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to deal 6 in the Software without restriction, including without limitation the rights 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 THE SOFTWARE. 21 */ 22 23 #ifndef ELFIO_DUMP_HPP 24 #define ELFIO_DUMP_HPP 25 26 #include <algorithm> 27 #include <string> 28 #include <ostream> 29 #include <sstream> 30 #include <iomanip> 31 #include <elfio/elfio.hpp> 32 33 namespace ELFIO { 34 35 static struct class_table_t 36 { 37 const char key; 38 const char* str; 39 } class_table[] = { 40 { ELFCLASS32, "ELF32" }, 41 { ELFCLASS64, "ELF64" }, 42 }; 43 44 static struct endian_table_t 45 { 46 const char key; 47 const char* str; 48 } endian_table[] = { 49 { ELFDATANONE, "None" }, 50 { ELFDATA2LSB, "Little endian" }, 51 { ELFDATA2MSB, "Big endian" }, 52 }; 53 54 static struct version_table_t 55 { 56 const Elf64_Word key; 57 const char* str; 58 } version_table[] = { 59 { EV_NONE, "None" }, 60 { EV_CURRENT, "Current" }, 61 }; 62 63 static struct type_table_t 64 { 65 const Elf32_Half key; 66 const char* str; 67 } type_table[] = { 68 { ET_NONE, "No file type" }, { ET_REL, "Relocatable file" }, 69 { ET_EXEC, "Executable file" }, { ET_DYN, "Shared object file" }, 70 { ET_CORE, "Core file" }, 71 }; 72 73 static struct machine_table_t 74 { 75 const Elf64_Half key; 76 const char* str; 77 } machine_table[] = { 78 { EM_NONE, "No machine" }, 79 { EM_M32, "AT&T WE 32100" }, 80 { EM_SPARC, "SUN SPARC" }, 81 { EM_386, "Intel 80386" }, 82 { EM_68K, "Motorola m68k family" }, 83 { EM_88K, "Motorola m88k family" }, 84 { EM_486, "Intel 80486// Reserved for future use" }, 85 { EM_860, "Intel 80860" }, 86 { EM_MIPS, "MIPS R3000 (officially, big-endian only)" }, 87 { EM_S370, "IBM System/370" }, 88 { EM_MIPS_RS3_LE, 89 "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" }, 90 { EM_res011, "Reserved" }, 91 { EM_res012, "Reserved" }, 92 { EM_res013, "Reserved" }, 93 { EM_res014, "Reserved" }, 94 { EM_PARISC, "HPPA" }, 95 { EM_res016, "Reserved" }, 96 { EM_VPP550, "Fujitsu VPP500" }, 97 { EM_SPARC32PLUS, "Sun's v8plus" }, 98 { EM_960, "Intel 80960" }, 99 { EM_PPC, "PowerPC" }, 100 { EM_PPC64, "64-bit PowerPC" }, 101 { EM_S390, "IBM S/390" }, 102 { EM_SPU, "Sony/Toshiba/IBM SPU" }, 103 { EM_res024, "Reserved" }, 104 { EM_res025, "Reserved" }, 105 { EM_res026, "Reserved" }, 106 { EM_res027, "Reserved" }, 107 { EM_res028, "Reserved" }, 108 { EM_res029, "Reserved" }, 109 { EM_res030, "Reserved" }, 110 { EM_res031, "Reserved" }, 111 { EM_res032, "Reserved" }, 112 { EM_res033, "Reserved" }, 113 { EM_res034, "Reserved" }, 114 { EM_res035, "Reserved" }, 115 { EM_V800, "NEC V800 series" }, 116 { EM_FR20, "Fujitsu FR20" }, 117 { EM_RH32, "TRW RH32" }, 118 { EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA" }, 119 { EM_RCE, "Old name for MCore" }, 120 { EM_ARM, "ARM" }, 121 { EM_OLD_ALPHA, "Digital Alpha" }, 122 { EM_SH, "Renesas (formerly Hitachi) / SuperH SH" }, 123 { EM_SPARCV9, "SPARC v9 64-bit" }, 124 { EM_TRICORE, "Siemens Tricore embedded processor" }, 125 { EM_ARC, "ARC Cores" }, 126 { EM_H8_300, "Renesas (formerly Hitachi) H8/300" }, 127 { EM_H8_300H, "Renesas (formerly Hitachi) H8/300H" }, 128 { EM_H8S, "Renesas (formerly Hitachi) H8S" }, 129 { EM_H8_500, "Renesas (formerly Hitachi) H8/500" }, 130 { EM_IA_64, "Intel IA-64 Processor" }, 131 { EM_MIPS_X, "Stanford MIPS-X" }, 132 { EM_COLDFIRE, "Motorola Coldfire" }, 133 { EM_68HC12, "Motorola M68HC12" }, 134 { EM_MMA, "Fujitsu Multimedia Accelerator" }, 135 { EM_PCP, "Siemens PCP" }, 136 { EM_NCPU, "Sony nCPU embedded RISC processor" }, 137 { EM_NDR1, "Denso NDR1 microprocesspr" }, 138 { EM_STARCORE, "Motorola Star*Core processor" }, 139 { EM_ME16, "Toyota ME16 processor" }, 140 { EM_ST100, "STMicroelectronics ST100 processor" }, 141 { EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor" }, 142 { EM_X86_64, "Advanced Micro Devices X86-64 processor" }, 143 { EM_PDSP, "Sony DSP Processor" }, 144 { EM_PDP10, "Digital Equipment Corp. PDP-10" }, 145 { EM_PDP11, "Digital Equipment Corp. PDP-11" }, 146 { EM_FX66, "Siemens FX66 microcontroller" }, 147 { EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller" }, 148 { EM_ST7, "STMicroelectronics ST7 8-bit microcontroller" }, 149 { EM_68HC16, "Motorola MC68HC16 Microcontroller" }, 150 { EM_68HC11, "Motorola MC68HC11 Microcontroller" }, 151 { EM_68HC08, "Motorola MC68HC08 Microcontroller" }, 152 { EM_68HC05, "Motorola MC68HC05 Microcontroller" }, 153 { EM_SVX, "Silicon Graphics SVx" }, 154 { EM_ST19, "STMicroelectronics ST19 8-bit cpu" }, 155 { EM_VAX, "Digital VAX" }, 156 { EM_CRIS, "Axis Communications 32-bit embedded processor" }, 157 { EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu" }, 158 { EM_FIREPATH, "Element 14 64-bit DSP processor" }, 159 { EM_ZSP, "LSI Logic's 16-bit DSP processor" }, 160 { EM_MMIX, "Donald Knuth's educational 64-bit processor" }, 161 { EM_HUANY, "Harvard's machine-independent format" }, 162 { EM_PRISM, "SiTera Prism" }, 163 { EM_AVR, "Atmel AVR 8-bit microcontroller" }, 164 { EM_FR30, "Fujitsu FR30" }, 165 { EM_D10V, "Mitsubishi D10V" }, 166 { EM_D30V, "Mitsubishi D30V" }, 167 { EM_V850, "NEC v850" }, 168 { EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)" }, 169 { EM_MN10300, "Matsushita MN10300" }, 170 { EM_MN10200, "Matsushita MN10200" }, 171 { EM_PJ, "picoJava" }, 172 { EM_OPENRISC, "OpenRISC 32-bit embedded processor" }, 173 { EM_ARC_A5, "ARC Cores Tangent-A5" }, 174 { EM_XTENSA, "Tensilica Xtensa Architecture" }, 175 { EM_VIDEOCORE, "Alphamosaic VideoCore processor" }, 176 { EM_TMM_GPP, "Thompson Multimedia General Purpose Processor" }, 177 { EM_NS32K, "National Semiconductor 32000 series" }, 178 { EM_TPC, "Tenor Network TPC processor" }, 179 { EM_SNP1K, "Trebia SNP 1000 processor" }, 180 { EM_ST200, "STMicroelectronics ST200 microcontroller" }, 181 { EM_IP2K, "Ubicom IP2022 micro controller" }, 182 { EM_MAX, "MAX Processor" }, 183 { EM_CR, "National Semiconductor CompactRISC" }, 184 { EM_F2MC16, "Fujitsu F2MC16" }, 185 { EM_MSP430, "TI msp430 micro controller" }, 186 { EM_BLACKFIN, "ADI Blackfin" }, 187 { EM_SE_C33, "S1C33 Family of Seiko Epson processors" }, 188 { EM_SEP, "Sharp embedded microprocessor" }, 189 { EM_ARCA, "Arca RISC Microprocessor" }, 190 { EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of " 191 "Peking University" }, 192 { EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU" }, 193 { EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor" }, 194 { EM_ALTERA_NIOS2, "Altera Nios II soft-core processor" }, 195 { EM_CRX, "National Semiconductor CRX" }, 196 { EM_XGATE, "Motorola XGATE embedded processor" }, 197 { EM_C166, "Infineon C16x/XC16x processor" }, 198 { EM_M16C, "Renesas M16C series microprocessors" }, 199 { EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller" }, 200 { EM_CE, "Freescale Communication Engine RISC core" }, 201 { EM_M32C, "Renesas M32C series microprocessors" }, 202 { EM_res121, "Reserved" }, 203 { EM_res122, "Reserved" }, 204 { EM_res123, "Reserved" }, 205 { EM_res124, "Reserved" }, 206 { EM_res125, "Reserved" }, 207 { EM_res126, "Reserved" }, 208 { EM_res127, "Reserved" }, 209 { EM_res128, "Reserved" }, 210 { EM_res129, "Reserved" }, 211 { EM_res130, "Reserved" }, 212 { EM_TSK3000, "Altium TSK3000 core" }, 213 { EM_RS08, "Freescale RS08 embedded processor" }, 214 { EM_res133, "Reserved" }, 215 { EM_ECOG2, "Cyan Technology eCOG2 microprocessor" }, 216 { EM_SCORE, "Sunplus Score" }, 217 { EM_SCORE7, "Sunplus S+core7 RISC processor" }, 218 { EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor" }, 219 { EM_VIDEOCORE3, "Broadcom VideoCore III processor" }, 220 { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" }, 221 { EM_SE_C17, "Seiko Epson C17 family" }, 222 { EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family" }, 223 { EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family" }, 224 { EM_TI_C5500, "Texas Instruments TMS320C55x DSP family" }, 225 { EM_res143, "Reserved" }, 226 { EM_res144, "Reserved" }, 227 { EM_res145, "Reserved" }, 228 { EM_res146, "Reserved" }, 229 { EM_res147, "Reserved" }, 230 { EM_res148, "Reserved" }, 231 { EM_res149, "Reserved" }, 232 { EM_res150, "Reserved" }, 233 { EM_res151, "Reserved" }, 234 { EM_res152, "Reserved" }, 235 { EM_res153, "Reserved" }, 236 { EM_res154, "Reserved" }, 237 { EM_res155, "Reserved" }, 238 { EM_res156, "Reserved" }, 239 { EM_res157, "Reserved" }, 240 { EM_res158, "Reserved" }, 241 { EM_res159, "Reserved" }, 242 { EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor" }, 243 { EM_CYPRESS_M8C, "Cypress M8C microprocessor" }, 244 { EM_R32C, "Renesas R32C series microprocessors" }, 245 { EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family" }, 246 { EM_QDSP6, "QUALCOMM DSP6 Processor" }, 247 { EM_8051, "Intel 8051 and variants" }, 248 { EM_STXP7X, "STMicroelectronics STxP7x family" }, 249 { EM_NDS32, 250 "Andes Technology compact code size embedded RISC processor family" }, 251 { EM_ECOG1, "Cyan Technology eCOG1X family" }, 252 { EM_ECOG1X, "Cyan Technology eCOG1X family" }, 253 { EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers" }, 254 { EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor" }, 255 { EM_MANIK, "M2000 Reconfigurable RISC Microprocessor" }, 256 { EM_CRAYNV2, "Cray Inc. NV2 vector architecture" }, 257 { EM_RX, "Renesas RX family" }, 258 { EM_METAG, "Imagination Technologies META processor architecture" }, 259 { EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture" }, 260 { EM_ECOG16, "Cyan Technology eCOG16 family" }, 261 { EM_CR16, "National Semiconductor CompactRISC 16-bit processor" }, 262 { EM_ETPU, "Freescale Extended Time Processing Unit" }, 263 { EM_SLE9X, "Infineon Technologies SLE9X core" }, 264 { EM_L1OM, "Intel L1OM" }, 265 { EM_INTEL181, "Reserved by Intel" }, 266 { EM_INTEL182, "Reserved by Intel" }, 267 { EM_res183, "Reserved by ARM" }, 268 { EM_res184, "Reserved by ARM" }, 269 { EM_AVR32, "Atmel Corporation 32-bit microprocessor family" }, 270 { EM_STM8, "STMicroeletronics STM8 8-bit microcontroller" }, 271 { EM_TILE64, "Tilera TILE64 multicore architecture family" }, 272 { EM_TILEPRO, "Tilera TILEPro multicore architecture family" }, 273 { EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core" }, 274 { EM_CUDA, "NVIDIA CUDA architecture " }, 275 { EM_TILEGX, "Tilera TILE-Gx multicore architecture family" }, 276 { EM_CLOUDSHIELD, "CloudShield architecture family" }, 277 { EM_COREA_1ST, "KIPO-KAIST Core-A 1st generation processor family" }, 278 { EM_COREA_2ND, "KIPO-KAIST Core-A 2nd generation processor family" }, 279 { EM_ARC_COMPACT2, "Synopsys ARCompact V2" }, 280 { EM_OPEN8, "Open8 8-bit RISC soft processor core" }, 281 { EM_RL78, "Renesas RL78 family" }, 282 { EM_VIDEOCORE5, "Broadcom VideoCore V processor" }, 283 { EM_78KOR, "Renesas 78KOR family" }, 284 { EM_56800EX, "Freescale 56800EX Digital Signal Controller (DSC)" }, 285 { EM_BA1, "Beyond BA1 CPU architecture" }, 286 { EM_BA2, "Beyond BA2 CPU architecture" }, 287 { EM_XCORE, "XMOS xCORE processor family" }, 288 { EM_MCHP_PIC, "Microchip 8-bit PIC(r) family" }, 289 { EM_INTEL205, "Reserved by Intel" }, 290 { EM_INTEL206, "Reserved by Intel" }, 291 { EM_INTEL207, "Reserved by Intel" }, 292 { EM_INTEL208, "Reserved by Intel" }, 293 { EM_INTEL209, "Reserved by Intel" }, 294 { EM_KM32, "KM211 KM32 32-bit processor" }, 295 { EM_KMX32, "KM211 KMX32 32-bit processor" }, 296 { EM_KMX16, "KM211 KMX16 16-bit processor" }, 297 { EM_KMX8, "KM211 KMX8 8-bit processor" }, 298 { EM_KVARC, "KM211 KVARC processor" }, 299 { EM_CDP, "Paneve CDP architecture family" }, 300 { EM_COGE, "Cognitive Smart Memory Processor" }, 301 { EM_COOL, "iCelero CoolEngine" }, 302 { EM_NORC, "Nanoradio Optimized RISC" }, 303 { EM_CSR_KALIMBA, "CSR Kalimba architecture family" }, 304 { EM_Z80, "Zilog Z80" }, 305 { EM_VISIUM, "Controls and Data Services VISIUMcore processor" }, 306 { EM_FT32, "FTDI Chip FT32 high performance 32-bit RISC architecture" }, 307 { EM_MOXIE, "Moxie processor family" }, 308 { EM_AMDGPU, "AMD GPU architecture" }, 309 { EM_RISCV, "RISC-V" }, 310 { EM_LANAI, "Lanai processor" }, 311 { EM_CEVA, "CEVA Processor Architecture Family" }, 312 { EM_CEVA_X2, "CEVA X2 Processor Family" }, 313 { EM_BPF, "Linux BPF – in-kernel virtual machine" }, 314 { EM_GRAPHCORE_IPU, "Graphcore Intelligent Processing Unit" }, 315 { EM_IMG1, "Imagination Technologies" }, 316 { EM_NFP, "Netronome Flow Processor (P)" }, 317 { EM_CSKY, "C-SKY processor family" }, 318 { EM_ARC_COMPACT3_64, "Synopsys ARCv2.3 64-bit" }, 319 { EM_MCS6502, "MOS Technology MCS 6502 processor" }, 320 { EM_ARC_COMPACT3, "Synopsys ARCv2.3 32-bit" }, 321 { EM_KVX, "Kalray VLIW core of the MPPA processor family" }, 322 { EM_65816, "WDC 65816/65C816" }, 323 { EM_LOONGARCH, "Loongson Loongarch" }, 324 { EM_KF32, "ChipON KungFu32" }, 325 { EM_MT, "Morpho Techologies MT processor" }, 326 { EM_ALPHA, "Alpha" }, 327 { EM_WEBASSEMBLY, "Web Assembly" }, 328 { EM_DLX, "OpenDLX" }, 329 { EM_XSTORMY16, "Sanyo XStormy16 CPU core" }, 330 { EM_IQ2000, "Vitesse IQ2000" }, 331 { EM_M32C_OLD, "M32C_OLD" }, 332 { EM_NIOS32, "Altera Nios" }, 333 { EM_CYGNUS_MEP, "Toshiba MeP Media Engine" }, 334 { EM_ADAPTEVA_EPIPHANY, "Adapteva EPIPHANY" }, 335 { EM_CYGNUS_FRV, "Fujitsu FR-V" }, 336 { EM_S12Z, "Freescale S12Z" }, 337 }; 338 339 static struct section_type_table_t 340 { 341 const Elf64_Half key; 342 const char* str; 343 } section_type_table[] = { 344 { SHT_NULL, "NULL" }, 345 { SHT_PROGBITS, "PROGBITS" }, 346 { SHT_SYMTAB, "SYMTAB" }, 347 { SHT_STRTAB, "STRTAB" }, 348 { SHT_RELA, "RELA" }, 349 { SHT_HASH, "HASH" }, 350 { SHT_DYNAMIC, "DYNAMIC" }, 351 { SHT_NOTE, "NOTE" }, 352 { SHT_NOBITS, "NOBITS" }, 353 { SHT_REL, "REL" }, 354 { SHT_SHLIB, "SHLIB" }, 355 { SHT_DYNSYM, "DYNSYM" }, 356 { SHT_INIT_ARRAY, "INIT_ARRAY" }, 357 { SHT_FINI_ARRAY, "FINI_ARRAY" }, 358 { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, 359 { SHT_GROUP, "GROUP" }, 360 { SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX " }, 361 }; 362 363 static struct segment_type_table_t 364 { 365 const Elf_Word key; 366 const char* str; 367 } segment_type_table[] = { 368 { PT_NULL, "NULL" }, { PT_LOAD, "LOAD" }, { PT_DYNAMIC, "DYNAMIC" }, 369 { PT_INTERP, "INTERP" }, { PT_NOTE, "NOTE" }, { PT_SHLIB, "SHLIB" }, 370 { PT_PHDR, "PHDR" }, { PT_TLS, "TLS" }, 371 }; 372 373 static struct segment_flag_table_t 374 { 375 const Elf_Word key; 376 const char* str; 377 } segment_flag_table[] = { 378 { 0, "" }, { 1, "X" }, { 2, "W" }, { 3, "WX" }, 379 { 4, "R" }, { 5, "RX" }, { 6, "RW" }, { 7, "RWX" }, 380 }; 381 382 static struct symbol_bind_t 383 { 384 const Elf_Word key; 385 const char* str; 386 } symbol_bind_table[] = { 387 { STB_LOCAL, "LOCAL" }, { STB_GLOBAL, "GLOBAL" }, 388 { STB_WEAK, "WEAK" }, { STB_LOOS, "LOOS" }, 389 { STB_HIOS, "HIOS" }, { STB_MULTIDEF, "MULTIDEF" }, 390 { STB_LOPROC, "LOPROC" }, { STB_HIPROC, "HIPROC" }, 391 }; 392 393 static struct symbol_type_t 394 { 395 const Elf_Word key; 396 const char* str; 397 } symbol_type_table[] = { 398 { STT_NOTYPE, "NOTYPE" }, { STT_OBJECT, "OBJECT" }, 399 { STT_FUNC, "FUNC" }, { STT_SECTION, "SECTION" }, 400 { STT_FILE, "FILE" }, { STT_COMMON, "COMMON" }, 401 { STT_TLS, "TLS" }, { STT_LOOS, "LOOS" }, 402 { STT_HIOS, "HIOS" }, { STT_LOPROC, "LOPROC" }, 403 { STT_HIPROC, "HIPROC" }, 404 }; 405 406 static struct dynamic_tag_t 407 { 408 const Elf_Word key; 409 const char* str; 410 } dynamic_tag_table[] = { 411 { DT_NULL, "NULL" }, 412 { DT_NEEDED, "NEEDED" }, 413 { DT_PLTRELSZ, "PLTRELSZ" }, 414 { DT_PLTGOT, "PLTGOT" }, 415 { DT_HASH, "HASH" }, 416 { DT_STRTAB, "STRTAB" }, 417 { DT_SYMTAB, "SYMTAB" }, 418 { DT_RELA, "RELA" }, 419 { DT_RELASZ, "RELASZ" }, 420 { DT_RELAENT, "RELAENT" }, 421 { DT_STRSZ, "STRSZ" }, 422 { DT_SYMENT, "SYMENT" }, 423 { DT_INIT, "INIT" }, 424 { DT_FINI, "FINI" }, 425 { DT_SONAME, "SONAME" }, 426 { DT_RPATH, "RPATH" }, 427 { DT_SYMBOLIC, "SYMBOLIC" }, 428 { DT_REL, "REL" }, 429 { DT_RELSZ, "RELSZ" }, 430 { DT_RELENT, "RELENT" }, 431 { DT_PLTREL, "PLTREL" }, 432 { DT_DEBUG, "DEBUG" }, 433 { DT_TEXTREL, "TEXTREL" }, 434 { DT_JMPREL, "JMPREL" }, 435 { DT_BIND_NOW, "BIND_NOW" }, 436 { DT_INIT_ARRAY, "INIT_ARRAY" }, 437 { DT_FINI_ARRAY, "FINI_ARRAY" }, 438 { DT_INIT_ARRAYSZ, "INIT_ARRAYSZ" }, 439 { DT_FINI_ARRAYSZ, "FINI_ARRAYSZ" }, 440 { DT_RUNPATH, "RUNPATH" }, 441 { DT_FLAGS, "FLAGS" }, 442 { DT_ENCODING, "ENCODING" }, 443 { DT_PREINIT_ARRAY, "PREINIT_ARRAY" }, 444 { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" }, 445 { DT_MAXPOSTAGS, "MAXPOSTAGS" }, 446 }; 447 448 static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64; 449 450 //------------------------------------------------------------------------------ 451 class dump 452 { 453 #define DUMP_DEC_FORMAT( width ) \ 454 std::setw( width ) << std::setfill( ' ' ) << std::dec << std::right 455 #define DUMP_HEX_FORMAT( width ) \ 456 std::setw( width ) << std::setfill( '0' ) << std::hex << std::right 457 #define DUMP_STR_FORMAT( width ) \ 458 std::setw( width ) << std::setfill( ' ' ) << std::hex << std::left 459 460 public: 461 //------------------------------------------------------------------------------ header(std::ostream & out,const elfio & reader)462 static void header( std::ostream& out, const elfio& reader ) 463 { 464 if ( !reader.get_header_size() ) { 465 return; 466 } 467 out << "ELF Header" << std::endl 468 << std::endl 469 << " Class: " << str_class( reader.get_class() ) << std::endl 470 << " Encoding: " << str_endian( reader.get_encoding() ) 471 << std::endl 472 << " ELFVersion: " << str_version( reader.get_elf_version() ) 473 << std::endl 474 << " Type: " << str_type( reader.get_type() ) << std::endl 475 << " Machine: " << str_machine( reader.get_machine() ) 476 << std::endl 477 << " Version: " << str_version( reader.get_version() ) 478 << std::endl 479 << " Entry: " 480 << "0x" << std::hex << reader.get_entry() << std::endl 481 << " Flags: " 482 << "0x" << std::hex << reader.get_flags() << std::endl 483 << std::endl; 484 } 485 486 //------------------------------------------------------------------------------ section_headers(std::ostream & out,const elfio & reader)487 static void section_headers( std::ostream& out, const elfio& reader ) 488 { 489 Elf_Half n = reader.sections.size(); 490 491 if ( n == 0 ) { 492 return; 493 } 494 495 out << "Section Headers:" << std::endl; 496 if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit 497 out << "[ Nr ] Type Addr Size ES Flg Lk Inf " 498 "Al Name" 499 << std::endl; 500 } 501 else { // Output for 64-bit 502 out << "[ Nr ] Type Addr Size " 503 " ES Flg" 504 << std::endl 505 << " Lk Inf Al Name" << std::endl; 506 } 507 508 for ( Elf_Half i = 0; i < n; ++i ) { // For all sections 509 section* sec = reader.sections[i]; 510 section_header( out, i, sec, reader.get_class() ); 511 } 512 513 out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" 514 << std::endl; 515 } 516 517 //------------------------------------------------------------------------------ section_header(std::ostream & out,Elf_Half no,const section * sec,unsigned char elf_class)518 static void section_header( std::ostream& out, 519 Elf_Half no, 520 const section* sec, 521 unsigned char elf_class ) 522 { 523 std::ios_base::fmtflags original_flags = out.flags(); 524 525 if ( elf_class == ELFCLASS32 ) { // Output for 32-bit 526 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 527 << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) 528 << " " << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " " 529 << DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " " 530 << DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " " 531 << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) 532 << " " << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " " 533 << DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " " 534 << DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " " 535 << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; 536 } 537 else { // Output for 64-bit 538 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 539 << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) 540 << " " << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " " 541 << DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " " 542 << DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " " 543 << DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() ) 544 << " " << std::endl 545 << " " << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " " 546 << DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " " 547 << DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << " " 548 << DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl; 549 } 550 551 out.flags( original_flags ); 552 553 return; 554 } 555 556 //------------------------------------------------------------------------------ segment_headers(std::ostream & out,const elfio & reader)557 static void segment_headers( std::ostream& out, const elfio& reader ) 558 { 559 Elf_Half n = reader.segments.size(); 560 if ( n == 0 ) { 561 return; 562 } 563 564 out << "Segment headers:" << std::endl; 565 if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit 566 out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size " 567 "Flags Align" 568 << std::endl; 569 } 570 else { // Output for 64-bit 571 out << "[ Nr ] Type VirtAddr PhysAddr " 572 "Flags" 573 << std::endl 574 << " FileSize Mem.Size " 575 "Align" 576 << std::endl; 577 } 578 579 for ( Elf_Half i = 0; i < n; ++i ) { 580 segment* seg = reader.segments[i]; 581 segment_header( out, i, seg, reader.get_class() ); 582 } 583 584 out << std::endl; 585 } 586 587 //------------------------------------------------------------------------------ segment_header(std::ostream & out,Elf_Half no,const segment * seg,unsigned int elf_class)588 static void segment_header( std::ostream& out, 589 Elf_Half no, 590 const segment* seg, 591 unsigned int elf_class ) 592 { 593 std::ios_base::fmtflags original_flags = out.flags(); 594 595 if ( elf_class == ELFCLASS32 ) { // Output for 32-bit 596 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 597 << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) 598 << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address() 599 << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address() 600 << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " " 601 << DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " " 602 << DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() ) 603 << " " << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " " 604 << std::endl; 605 } 606 else { // Output for 64-bit 607 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 608 << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() ) 609 << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address() 610 << " " << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address() 611 << " " << DUMP_STR_FORMAT( 16 ) 612 << str_segment_flag( seg->get_flags() ) << " " << std::endl 613 << " " << DUMP_HEX_FORMAT( 16 ) 614 << seg->get_file_size() << " " << DUMP_HEX_FORMAT( 16 ) 615 << seg->get_memory_size() << " " << DUMP_HEX_FORMAT( 16 ) 616 << seg->get_align() << " " << std::endl; 617 } 618 619 out.flags( original_flags ); 620 } 621 622 //------------------------------------------------------------------------------ symbol_tables(std::ostream & out,const elfio & reader)623 static void symbol_tables( std::ostream& out, const elfio& reader ) 624 { 625 Elf_Half n = reader.sections.size(); 626 for ( Elf_Half i = 0; i < n; ++i ) { // For all sections 627 section* sec = reader.sections[i]; 628 if ( SHT_SYMTAB == sec->get_type() || 629 SHT_DYNSYM == sec->get_type() ) { 630 symbol_section_accessor symbols( reader, sec ); 631 632 Elf_Xword sym_no = symbols.get_symbols_num(); 633 if ( sym_no > 0 ) { 634 out << "Symbol table (" << sec->get_name() << ")" 635 << std::endl; 636 if ( reader.get_class() == 637 ELFCLASS32 ) { // Output for 32-bit 638 out << "[ Nr ] Value Size Type Bind " 639 "Sect Name" 640 << std::endl; 641 } 642 else { // Output for 64-bit 643 out << "[ Nr ] Value Size Type " 644 " Bind Sect" 645 << std::endl 646 << " Name" << std::endl; 647 } 648 for ( Elf_Xword i = 0; i < sym_no; ++i ) { 649 std::string name; 650 Elf64_Addr value = 0; 651 Elf_Xword size = 0; 652 unsigned char bind = 0; 653 unsigned char type = 0; 654 Elf_Half section = 0; 655 unsigned char other = 0; 656 symbols.get_symbol( i, name, value, size, bind, type, 657 section, other ); 658 symbol_table( out, i, name, value, size, bind, type, 659 section, reader.get_class() ); 660 } 661 662 out << std::endl; 663 } 664 } 665 } 666 } 667 668 //------------------------------------------------------------------------------ symbol_table(std::ostream & out,Elf_Xword no,std::string & name,Elf64_Addr value,Elf_Xword size,unsigned char bind,unsigned char type,Elf_Half section,unsigned int elf_class)669 static void symbol_table( std::ostream& out, 670 Elf_Xword no, 671 std::string& name, 672 Elf64_Addr value, 673 Elf_Xword size, 674 unsigned char bind, 675 unsigned char type, 676 Elf_Half section, 677 unsigned int elf_class ) 678 { 679 std::ios_base::fmtflags original_flags = out.flags(); 680 681 if ( elf_class == ELFCLASS32 ) { // Output for 32-bit 682 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 683 << DUMP_HEX_FORMAT( 8 ) << value << " " << DUMP_HEX_FORMAT( 8 ) 684 << size << " " << DUMP_STR_FORMAT( 7 ) 685 << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) 686 << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) 687 << section << " " << DUMP_STR_FORMAT( 1 ) << name << " " 688 << std::endl; 689 } 690 else { // Output for 64-bit 691 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 692 << DUMP_HEX_FORMAT( 16 ) << value << " " 693 << DUMP_HEX_FORMAT( 16 ) << size << " " << DUMP_STR_FORMAT( 7 ) 694 << str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 ) 695 << str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 ) 696 << section << " " << std::endl 697 << " " << DUMP_STR_FORMAT( 1 ) << name << " " 698 << std::endl; 699 } 700 701 out.flags( original_flags ); 702 } 703 704 //------------------------------------------------------------------------------ notes(std::ostream & out,const elfio & reader)705 static void notes( std::ostream& out, const elfio& reader ) 706 { 707 Elf_Half no = reader.sections.size(); 708 for ( Elf_Half i = 0; i < no; ++i ) { // For all sections 709 section* sec = reader.sections[i]; 710 if ( SHT_NOTE == sec->get_type() ) { // Look at notes 711 note_section_accessor notes( reader, sec ); 712 Elf_Word no_notes = notes.get_notes_num(); 713 if ( no > 0 ) { 714 out << "Note section (" << sec->get_name() << ")" 715 << std::endl 716 << " No Type Name" << std::endl; 717 for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes 718 Elf_Word type; 719 std::string name; 720 void* desc; 721 Elf_Word descsz; 722 723 if ( notes.get_note( j, type, name, desc, descsz ) ) { 724 // 'name' usually contains \0 at the end. Try to fix it 725 name = name.c_str(); 726 note( out, j, type, name ); 727 } 728 } 729 730 out << std::endl; 731 } 732 } 733 } 734 } 735 736 //------------------------------------------------------------------------------ modinfo(std::ostream & out,const elfio & reader)737 static void modinfo( std::ostream& out, const elfio& reader ) 738 { 739 Elf_Half no = reader.sections.size(); 740 for ( Elf_Half i = 0; i < no; ++i ) { // For all sections 741 section* sec = reader.sections[i]; 742 if ( ".modinfo" == sec->get_name() ) { // Look for the section 743 out << "Section .modinfo" << std::endl; 744 745 const_modinfo_section_accessor modinfo( sec ); 746 for ( Elf_Word i = 0; i < modinfo.get_attribute_num(); i++ ) { 747 std::string field; 748 std::string value; 749 if ( modinfo.get_attribute( i, field, value ) ) { 750 out << " " << std::setw( 20 ) << field 751 << std::setw( 0 ) << " = " << value << std::endl; 752 } 753 } 754 755 out << std::endl; 756 break; 757 } 758 } 759 } 760 761 //------------------------------------------------------------------------------ 762 static void note(std::ostream & out,int no,Elf_Word type,const std::string & name)763 note( std::ostream& out, int no, Elf_Word type, const std::string& name ) 764 { 765 out << " [" << DUMP_DEC_FORMAT( 2 ) << no << "] " 766 << DUMP_HEX_FORMAT( 8 ) << type << " " << DUMP_STR_FORMAT( 1 ) 767 << name << std::endl; 768 } 769 770 //------------------------------------------------------------------------------ dynamic_tags(std::ostream & out,const elfio & reader)771 static void dynamic_tags( std::ostream& out, const elfio& reader ) 772 { 773 Elf_Half n = reader.sections.size(); 774 for ( Elf_Half i = 0; i < n; ++i ) { // For all sections 775 section* sec = reader.sections[i]; 776 if ( SHT_DYNAMIC == sec->get_type() ) { 777 dynamic_section_accessor dynamic( reader, sec ); 778 779 Elf_Xword dyn_no = dynamic.get_entries_num(); 780 if ( dyn_no > 0 ) { 781 out << "Dynamic section (" << sec->get_name() << ")" 782 << std::endl; 783 out << "[ Nr ] Tag Name/Value" << std::endl; 784 for ( Elf_Xword i = 0; i < dyn_no; ++i ) { 785 Elf_Xword tag = 0; 786 Elf_Xword value = 0; 787 std::string str; 788 dynamic.get_entry( i, tag, value, str ); 789 dynamic_tag( out, i, tag, value, str, 790 reader.get_class() ); 791 if ( DT_NULL == tag ) { 792 break; 793 } 794 } 795 796 out << std::endl; 797 } 798 } 799 } 800 } 801 802 //------------------------------------------------------------------------------ dynamic_tag(std::ostream & out,Elf_Xword no,Elf_Xword tag,Elf_Xword value,std::string str,unsigned int)803 static void dynamic_tag( std::ostream& out, 804 Elf_Xword no, 805 Elf_Xword tag, 806 Elf_Xword value, 807 std::string str, 808 unsigned int /*elf_class*/ ) 809 { 810 out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] " 811 << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " "; 812 if ( str.empty() ) { 813 out << DUMP_HEX_FORMAT( 16 ) << value << " "; 814 } 815 else { 816 out << DUMP_STR_FORMAT( 32 ) << str << " "; 817 } 818 out << std::endl; 819 } 820 821 //------------------------------------------------------------------------------ section_data(std::ostream & out,const section * sec)822 static void section_data( std::ostream& out, const section* sec ) 823 { 824 std::ios_base::fmtflags original_flags = out.flags(); 825 826 out << sec->get_name() << std::endl; 827 const char* pdata = sec->get_data(); 828 if ( pdata ) { 829 ELFIO::Elf_Xword i; 830 for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); 831 ++i ) { 832 if ( i % 16 == 0 ) { 833 out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; 834 } 835 836 out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); 837 838 if ( i % 16 == 15 ) { 839 out << std::endl; 840 } 841 } 842 if ( i % 16 != 0 ) { 843 out << std::endl; 844 } 845 846 out.flags( original_flags ); 847 } 848 849 return; 850 } 851 852 //------------------------------------------------------------------------------ section_datas(std::ostream & out,const elfio & reader)853 static void section_datas( std::ostream& out, const elfio& reader ) 854 { 855 Elf_Half n = reader.sections.size(); 856 857 if ( n == 0 ) { 858 return; 859 } 860 861 out << "Section Data:" << std::endl; 862 863 for ( Elf_Half i = 1; i < n; ++i ) { // For all sections 864 section* sec = reader.sections[i]; 865 if ( sec->get_type() == SHT_NOBITS ) { 866 continue; 867 } 868 section_data( out, sec ); 869 } 870 871 out << std::endl; 872 } 873 874 //------------------------------------------------------------------------------ 875 static void segment_data(std::ostream & out,Elf_Half no,const segment * seg)876 segment_data( std::ostream& out, Elf_Half no, const segment* seg ) 877 { 878 std::ios_base::fmtflags original_flags = out.flags(); 879 880 out << "Segment # " << no << std::endl; 881 const char* pdata = seg->get_data(); 882 if ( pdata ) { 883 ELFIO::Elf_Xword i; 884 for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); 885 ++i ) { 886 if ( i % 16 == 0 ) { 887 out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]"; 888 } 889 890 out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF ); 891 892 if ( i % 16 == 15 ) { 893 out << std::endl; 894 } 895 } 896 if ( i % 16 != 0 ) { 897 out << std::endl; 898 } 899 900 out.flags( original_flags ); 901 } 902 903 return; 904 } 905 906 //------------------------------------------------------------------------------ segment_datas(std::ostream & out,const elfio & reader)907 static void segment_datas( std::ostream& out, const elfio& reader ) 908 { 909 Elf_Half n = reader.segments.size(); 910 911 if ( n == 0 ) { 912 return; 913 } 914 915 out << "Segment Data:" << std::endl; 916 917 for ( Elf_Half i = 0; i < n; ++i ) { // For all sections 918 segment* seg = reader.segments[i]; 919 segment_data( out, i, seg ); 920 } 921 922 out << std::endl; 923 } 924 925 private: 926 //------------------------------------------------------------------------------ 927 template <typename T, typename K> find_value_in_table(const T & table,const K & key)928 std::string static find_value_in_table( const T& table, const K& key ) 929 { 930 std::string res = "?"; 931 for ( unsigned int i = 0; i < sizeof( table ) / sizeof( table[0] ); 932 ++i ) { 933 if ( table[i].key == key ) { 934 res = table[i].str; 935 break; 936 } 937 } 938 939 return res; 940 } 941 942 //------------------------------------------------------------------------------ 943 template <typename T, typename K> format_assoc(const T & table,const K & key)944 static std::string format_assoc( const T& table, const K& key ) 945 { 946 std::string str = find_value_in_table( table, key ); 947 if ( str == "?" ) { 948 std::ostringstream oss; 949 oss << str << " (0x" << std::hex << key << ")"; 950 str = oss.str(); 951 } 952 953 return str; 954 } 955 956 //------------------------------------------------------------------------------ 957 template <typename T> format_assoc(const T & table,const char key)958 static std::string format_assoc( const T& table, const char key ) 959 { 960 return format_assoc( table, (const int)key ); 961 } 962 963 //------------------------------------------------------------------------------ section_flags(Elf_Xword flags)964 static std::string section_flags( Elf_Xword flags ) 965 { 966 std::string ret = ""; 967 if ( flags & SHF_WRITE ) { 968 ret += "W"; 969 } 970 if ( flags & SHF_ALLOC ) { 971 ret += "A"; 972 } 973 if ( flags & SHF_EXECINSTR ) { 974 ret += "X"; 975 } 976 977 return ret; 978 } 979 980 //------------------------------------------------------------------------------ 981 #define STR_FUNC_TABLE( name ) \ 982 template <typename T> static std::string str_##name( const T key ) \ 983 { \ 984 return format_assoc( name##_table, key ); \ 985 } 986 987 STR_FUNC_TABLE( class ) 988 STR_FUNC_TABLE( endian ) 989 STR_FUNC_TABLE( version ) 990 STR_FUNC_TABLE( type ) 991 STR_FUNC_TABLE( machine ) 992 STR_FUNC_TABLE( section_type ) 993 STR_FUNC_TABLE( segment_type ) 994 STR_FUNC_TABLE( segment_flag ) 995 STR_FUNC_TABLE( symbol_bind ) 996 STR_FUNC_TABLE( symbol_type ) 997 STR_FUNC_TABLE( dynamic_tag ) 998 999 #undef STR_FUNC_TABLE 1000 #undef DUMP_DEC_FORMAT 1001 #undef DUMP_HEX_FORMAT 1002 #undef DUMP_STR_FORMAT 1003 }; // class dump 1004 1005 }; // namespace ELFIO 1006 1007 #endif // ELFIO_DUMP_HPP 1008