HIP: Heterogenous-computing Interface for Portability
elfio_dump.hpp
1 /*
2 Copyright (C) 2001-2015 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.hpp"
32 
33 namespace ELFIO {
34 
35 
36 static struct class_table_t {
37  const char key;
38  const char* str;
39 } class_table[] = {
40  {ELFCLASS32, "ELF32"},
41  {ELFCLASS64, "ELF64"},
42 };
43 
44 
45 static struct endian_table_t {
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 
55 static struct version_table_t {
56  const Elf64_Word key;
57  const char* str;
58 } version_table[] = {
59  {EV_NONE, "None"},
60  {EV_CURRENT, "Current"},
61 };
62 
63 
64 static struct type_table_t {
65  const Elf32_Half key;
66  const char* str;
67 } type_table[] = {
68  {ET_NONE, "No file type"}, {ET_REL, "Relocatable file"}, {ET_EXEC, "Executable file"},
69  {ET_DYN, "Shared object file"}, {ET_CORE, "Core file"},
70 };
71 
72 
73 static struct machine_table_t {
74  const Elf64_Half key;
75  const char* str;
76 } machine_table[] = {
77  {EM_NONE, "No machine"},
78  {EM_M32, "AT&T WE 32100"},
79  {EM_SPARC, "SUN SPARC"},
80  {EM_386, "Intel 80386"},
81  {EM_68K, "Motorola m68k family"},
82  {EM_88K, "Motorola m88k family"},
83  {EM_486, "Intel 80486// Reserved for future use"},
84  {EM_860, "Intel 80860"},
85  {EM_MIPS, "MIPS R3000 (officially, big-endian only)"},
86  {EM_S370, "IBM System/370"},
87  {EM_MIPS_RS3_LE, "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated"},
88  {EM_res011, "Reserved"},
89  {EM_res012, "Reserved"},
90  {EM_res013, "Reserved"},
91  {EM_res014, "Reserved"},
92  {EM_PARISC, "HPPA"},
93  {EM_res016, "Reserved"},
94  {EM_VPP550, "Fujitsu VPP500"},
95  {EM_SPARC32PLUS, "Sun's v8plus"},
96  {EM_960, "Intel 80960"},
97  {EM_PPC, "PowerPC"},
98  {EM_PPC64, "64-bit PowerPC"},
99  {EM_S390, "IBM S/390"},
100  {EM_SPU, "Sony/Toshiba/IBM SPU"},
101  {EM_res024, "Reserved"},
102  {EM_res025, "Reserved"},
103  {EM_res026, "Reserved"},
104  {EM_res027, "Reserved"},
105  {EM_res028, "Reserved"},
106  {EM_res029, "Reserved"},
107  {EM_res030, "Reserved"},
108  {EM_res031, "Reserved"},
109  {EM_res032, "Reserved"},
110  {EM_res033, "Reserved"},
111  {EM_res034, "Reserved"},
112  {EM_res035, "Reserved"},
113  {EM_V800, "NEC V800 series"},
114  {EM_FR20, "Fujitsu FR20"},
115  {EM_RH32, "TRW RH32"},
116  {EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA"},
117  {EM_RCE, "Old name for MCore"},
118  {EM_ARM, "ARM"},
119  {EM_OLD_ALPHA, "Digital Alpha"},
120  {EM_SH, "Renesas (formerly Hitachi) / SuperH SH"},
121  {EM_SPARCV9, "SPARC v9 64-bit"},
122  {EM_TRICORE, "Siemens Tricore embedded processor"},
123  {EM_ARC, "ARC Cores"},
124  {EM_H8_300, "Renesas (formerly Hitachi) H8/300"},
125  {EM_H8_300H, "Renesas (formerly Hitachi) H8/300H"},
126  {EM_H8S, "Renesas (formerly Hitachi) H8S"},
127  {EM_H8_500, "Renesas (formerly Hitachi) H8/500"},
128  {EM_IA_64, "Intel IA-64 Processor"},
129  {EM_MIPS_X, "Stanford MIPS-X"},
130  {EM_COLDFIRE, "Motorola Coldfire"},
131  {EM_68HC12, "Motorola M68HC12"},
132  {EM_MMA, "Fujitsu Multimedia Accelerator"},
133  {EM_PCP, "Siemens PCP"},
134  {EM_NCPU, "Sony nCPU embedded RISC processor"},
135  {EM_NDR1, "Denso NDR1 microprocesspr"},
136  {EM_STARCORE, "Motorola Star*Core processor"},
137  {EM_ME16, "Toyota ME16 processor"},
138  {EM_ST100, "STMicroelectronics ST100 processor"},
139  {EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor"},
140  {EM_X86_64, "Advanced Micro Devices X86-64 processor"},
141  {EM_PDSP, "Sony DSP Processor"},
142  {EM_PDP10, "Digital Equipment Corp. PDP-10"},
143  {EM_PDP11, "Digital Equipment Corp. PDP-11"},
144  {EM_FX66, "Siemens FX66 microcontroller"},
145  {EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller"},
146  {EM_ST7, "STMicroelectronics ST7 8-bit microcontroller"},
147  {EM_68HC16, "Motorola MC68HC16 Microcontroller"},
148  {EM_68HC11, "Motorola MC68HC11 Microcontroller"},
149  {EM_68HC08, "Motorola MC68HC08 Microcontroller"},
150  {EM_68HC05, "Motorola MC68HC05 Microcontroller"},
151  {EM_SVX, "Silicon Graphics SVx"},
152  {EM_ST19, "STMicroelectronics ST19 8-bit cpu"},
153  {EM_VAX, "Digital VAX"},
154  {EM_CRIS, "Axis Communications 32-bit embedded processor"},
155  {EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu"},
156  {EM_FIREPATH, "Element 14 64-bit DSP processor"},
157  {EM_ZSP, "LSI Logic's 16-bit DSP processor"},
158  {EM_MMIX, "Donald Knuth's educational 64-bit processor"},
159  {EM_HUANY, "Harvard's machine-independent format"},
160  {EM_PRISM, "SiTera Prism"},
161  {EM_AVR, "Atmel AVR 8-bit microcontroller"},
162  {EM_FR30, "Fujitsu FR30"},
163  {EM_D10V, "Mitsubishi D10V"},
164  {EM_D30V, "Mitsubishi D30V"},
165  {EM_V850, "NEC v850"},
166  {EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)"},
167  {EM_MN10300, "Matsushita MN10300"},
168  {EM_MN10200, "Matsushita MN10200"},
169  {EM_PJ, "picoJava"},
170  {EM_OPENRISC, "OpenRISC 32-bit embedded processor"},
171  {EM_ARC_A5, "ARC Cores Tangent-A5"},
172  {EM_XTENSA, "Tensilica Xtensa Architecture"},
173  {EM_VIDEOCORE, "Alphamosaic VideoCore processor"},
174  {EM_TMM_GPP, "Thompson Multimedia General Purpose Processor"},
175  {EM_NS32K, "National Semiconductor 32000 series"},
176  {EM_TPC, "Tenor Network TPC processor"},
177  {EM_SNP1K, "Trebia SNP 1000 processor"},
178  {EM_ST200, "STMicroelectronics ST200 microcontroller"},
179  {EM_IP2K, "Ubicom IP2022 micro controller"},
180  {EM_MAX, "MAX Processor"},
181  {EM_CR, "National Semiconductor CompactRISC"},
182  {EM_F2MC16, "Fujitsu F2MC16"},
183  {EM_MSP430, "TI msp430 micro controller"},
184  {EM_BLACKFIN, "ADI Blackfin"},
185  {EM_SE_C33, "S1C33 Family of Seiko Epson processors"},
186  {EM_SEP, "Sharp embedded microprocessor"},
187  {EM_ARCA, "Arca RISC Microprocessor"},
188  {EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University"},
189  {EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU"},
190  {EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor"},
191  {EM_ALTERA_NIOS2, "Altera Nios II soft-core processor"},
192  {EM_CRX, "National Semiconductor CRX"},
193  {EM_XGATE, "Motorola XGATE embedded processor"},
194  {EM_C166, "Infineon C16x/XC16x processor"},
195  {EM_M16C, "Renesas M16C series microprocessors"},
196  {EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller"},
197  {EM_CE, "Freescale Communication Engine RISC core"},
198  {EM_M32C, "Renesas M32C series microprocessors"},
199  {EM_res121, "Reserved"},
200  {EM_res122, "Reserved"},
201  {EM_res123, "Reserved"},
202  {EM_res124, "Reserved"},
203  {EM_res125, "Reserved"},
204  {EM_res126, "Reserved"},
205  {EM_res127, "Reserved"},
206  {EM_res128, "Reserved"},
207  {EM_res129, "Reserved"},
208  {EM_res130, "Reserved"},
209  {EM_TSK3000, "Altium TSK3000 core"},
210  {EM_RS08, "Freescale RS08 embedded processor"},
211  {EM_res133, "Reserved"},
212  {EM_ECOG2, "Cyan Technology eCOG2 microprocessor"},
213  {EM_SCORE, "Sunplus Score"},
214  {EM_SCORE7, "Sunplus S+core7 RISC processor"},
215  {EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor"},
216  {EM_VIDEOCORE3, "Broadcom VideoCore III processor"},
217  {EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture"},
218  {EM_SE_C17, "Seiko Epson C17 family"},
219  {EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family"},
220  {EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family"},
221  {EM_TI_C5500, "Texas Instruments TMS320C55x DSP family"},
222  {EM_res143, "Reserved"},
223  {EM_res144, "Reserved"},
224  {EM_res145, "Reserved"},
225  {EM_res146, "Reserved"},
226  {EM_res147, "Reserved"},
227  {EM_res148, "Reserved"},
228  {EM_res149, "Reserved"},
229  {EM_res150, "Reserved"},
230  {EM_res151, "Reserved"},
231  {EM_res152, "Reserved"},
232  {EM_res153, "Reserved"},
233  {EM_res154, "Reserved"},
234  {EM_res155, "Reserved"},
235  {EM_res156, "Reserved"},
236  {EM_res157, "Reserved"},
237  {EM_res158, "Reserved"},
238  {EM_res159, "Reserved"},
239  {EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor"},
240  {EM_CYPRESS_M8C, "Cypress M8C microprocessor"},
241  {EM_R32C, "Renesas R32C series microprocessors"},
242  {EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family"},
243  {EM_QDSP6, "QUALCOMM DSP6 Processor"},
244  {EM_8051, "Intel 8051 and variants"},
245  {EM_STXP7X, "STMicroelectronics STxP7x family"},
246  {EM_NDS32, "Andes Technology compact code size embedded RISC processor family"},
247  {EM_ECOG1, "Cyan Technology eCOG1X family"},
248  {EM_ECOG1X, "Cyan Technology eCOG1X family"},
249  {EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers"},
250  {EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor"},
251  {EM_MANIK, "M2000 Reconfigurable RISC Microprocessor"},
252  {EM_CRAYNV2, "Cray Inc. NV2 vector architecture"},
253  {EM_RX, "Renesas RX family"},
254  {EM_METAG, "Imagination Technologies META processor architecture"},
255  {EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture"},
256  {EM_ECOG16, "Cyan Technology eCOG16 family"},
257  {EM_CR16, "National Semiconductor CompactRISC 16-bit processor"},
258  {EM_ETPU, "Freescale Extended Time Processing Unit"},
259  {EM_SLE9X, "Infineon Technologies SLE9X core"},
260  {EM_L1OM, "Intel L1OM"},
261  {EM_INTEL181, "Reserved by Intel"},
262  {EM_INTEL182, "Reserved by Intel"},
263  {EM_res183, "Reserved by ARM"},
264  {EM_res184, "Reserved by ARM"},
265  {EM_AVR32, "Atmel Corporation 32-bit microprocessor family"},
266  {EM_STM8, "STMicroeletronics STM8 8-bit microcontroller"},
267  {EM_TILE64, "Tilera TILE64 multicore architecture family"},
268  {EM_TILEPRO, "Tilera TILEPro multicore architecture family"},
269  {EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core"},
270  {EM_CUDA, "NVIDIA CUDA architecture "},
271 };
272 
273 
274 static struct section_type_table_t {
275  const Elf64_Half key;
276  const char* str;
277 } section_type_table[] = {
278  {SHT_NULL, "NULL"},
279  {SHT_PROGBITS, "PROGBITS"},
280  {SHT_SYMTAB, "SYMTAB"},
281  {SHT_STRTAB, "STRTAB"},
282  {SHT_RELA, "RELA"},
283  {SHT_HASH, "HASH"},
284  {SHT_DYNAMIC, "DYNAMIC"},
285  {SHT_NOTE, "NOTE"},
286  {SHT_NOBITS, "NOBITS"},
287  {SHT_REL, "REL"},
288  {SHT_SHLIB, "SHLIB"},
289  {SHT_DYNSYM, "DYNSYM"},
290  {SHT_INIT_ARRAY, "INIT_ARRAY"},
291  {SHT_FINI_ARRAY, "FINI_ARRAY"},
292  {SHT_PREINIT_ARRAY, "PREINIT_ARRAY"},
293  {SHT_GROUP, "GROUP"},
294  {SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX "},
295 };
296 
297 
298 static struct segment_type_table_t {
299  const Elf_Word key;
300  const char* str;
301 } segment_type_table[] = {
302  {PT_NULL, "NULL"}, {PT_LOAD, "LOAD"}, {PT_DYNAMIC, "DYNAMIC"}, {PT_INTERP, "INTERP"},
303  {PT_NOTE, "NOTE"}, {PT_SHLIB, "SHLIB"}, {PT_PHDR, "PHDR"}, {PT_TLS, "TLS"},
304 };
305 
306 
307 static struct segment_flag_table_t {
308  const Elf_Word key;
309  const char* str;
310 } segment_flag_table[] = {
311  {0, ""}, {1, "X"}, {2, "W"}, {3, "WX"}, {4, "R"}, {5, "RX"}, {6, "RW"}, {7, "RWX"},
312 };
313 
314 
315 static struct symbol_bind_t {
316  const Elf_Word key;
317  const char* str;
318 } symbol_bind_table[] = {
319  {STB_LOCAL, "LOCAL"}, {STB_GLOBAL, "GLOBAL"}, {STB_WEAK, "WEAK"},
320  {STB_LOOS, "LOOS"}, {STB_HIOS, "HIOS"}, {STB_MULTIDEF, "MULTIDEF"},
321  {STB_LOPROC, "LOPROC"}, {STB_HIPROC, "HIPROC"},
322 };
323 
324 
325 static struct symbol_type_t {
326  const Elf_Word key;
327  const char* str;
328 } symbol_type_table[] = {
329  {STT_NOTYPE, "NOTYPE"}, {STT_OBJECT, "OBJECT"}, {STT_FUNC, "FUNC"},
330  {STT_SECTION, "SECTION"}, {STT_FILE, "FILE"}, {STT_COMMON, "COMMON"},
331  {STT_TLS, "TLS"}, {STT_LOOS, "LOOS"}, {STT_HIOS, "HIOS"},
332  {STT_LOPROC, "LOPROC"}, {STT_HIPROC, "HIPROC"},
333 };
334 
335 
336 static struct dynamic_tag_t {
337  const Elf_Word key;
338  const char* str;
339 } dynamic_tag_table[] = {
340  {DT_NULL, "NULL"},
341  {DT_NEEDED, "NEEDED"},
342  {DT_PLTRELSZ, "PLTRELSZ"},
343  {DT_PLTGOT, "PLTGOT"},
344  {DT_HASH, "HASH"},
345  {DT_STRTAB, "STRTAB"},
346  {DT_SYMTAB, "SYMTAB"},
347  {DT_RELA, "RELA"},
348  {DT_RELASZ, "RELASZ"},
349  {DT_RELAENT, "RELAENT"},
350  {DT_STRSZ, "STRSZ"},
351  {DT_SYMENT, "SYMENT"},
352  {DT_INIT, "INIT"},
353  {DT_FINI, "FINI"},
354  {DT_SONAME, "SONAME"},
355  {DT_RPATH, "RPATH"},
356  {DT_SYMBOLIC, "SYMBOLIC"},
357  {DT_REL, "REL"},
358  {DT_RELSZ, "RELSZ"},
359  {DT_RELENT, "RELENT"},
360  {DT_PLTREL, "PLTREL"},
361  {DT_DEBUG, "DEBUG"},
362  {DT_TEXTREL, "TEXTREL"},
363  {DT_JMPREL, "JMPREL"},
364  {DT_BIND_NOW, "BIND_NOW"},
365  {DT_INIT_ARRAY, "INIT_ARRAY"},
366  {DT_FINI_ARRAY, "FINI_ARRAY"},
367  {DT_INIT_ARRAYSZ, "INIT_ARRAYSZ"},
368  {DT_FINI_ARRAYSZ, "FINI_ARRAYSZ"},
369  {DT_RUNPATH, "RUNPATH"},
370  {DT_FLAGS, "FLAGS"},
371  {DT_ENCODING, "ENCODING"},
372  {DT_PREINIT_ARRAY, "PREINIT_ARRAY"},
373  {DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ"},
374  {DT_MAXPOSTAGS, "MAXPOSTAGS"},
375 };
376 
377 static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64;
378 
379 //------------------------------------------------------------------------------
380 class dump {
381 #define DUMP_DEC_FORMAT(width) std::setw(width) << std::setfill(' ') << std::dec << std::right
382 #define DUMP_HEX_FORMAT(width) std::setw(width) << std::setfill('0') << std::hex << std::right
383 #define DUMP_STR_FORMAT(width) std::setw(width) << std::setfill(' ') << std::hex << std::left
384 
385  public:
386  //------------------------------------------------------------------------------
387  static void header(std::ostream& out, const elfio& reader) {
388  out << "ELF Header" << std::endl
389  << std::endl
390  << " Class: " << str_class(reader.get_class()) << std::endl
391  << " Encoding: " << str_endian(reader.get_encoding()) << std::endl
392  << " ELFVersion: " << str_version(reader.get_elf_version()) << std::endl
393  << " Type: " << str_type(reader.get_type()) << std::endl
394  << " Machine: " << str_machine(reader.get_machine()) << std::endl
395  << " Version: " << str_version(reader.get_version()) << std::endl
396  << " Entry: "
397  << "0x" << std::hex << reader.get_entry() << std::endl
398  << " Flags: "
399  << "0x" << std::hex << reader.get_flags() << std::endl
400  << std::endl;
401  }
402 
403  //------------------------------------------------------------------------------
404  static void section_headers(std::ostream& out, const elfio& reader) {
405  Elf_Half n = reader.sections.size();
406 
407  if (n == 0) {
408  return;
409  }
410 
411  out << "Section Headers:" << std::endl;
412  if (reader.get_class() == ELFCLASS32) { // Output for 32-bit
413  out << "[ Nr ] Type Addr Size ES Flg Lk Inf Al Name" << std::endl;
414  } else { // Output for 64-bit
415  out << "[ Nr ] Type Addr Size ES Flg"
416  << std::endl
417  << " Lk Inf Al Name" << std::endl;
418  }
419 
420  for (Elf_Half i = 0; i < n; ++i) { // For all sections
421  section* sec = reader.sections[i];
422  section_header(out, i, sec, reader.get_class());
423  }
424 
425  out << "Key to Flags: W (write), A (alloc), X (execute)\n\n" << std::endl;
426  }
427 
428  //------------------------------------------------------------------------------
429  static void section_header(std::ostream& out, Elf_Half no, const section* sec,
430  unsigned char elf_class) {
431  std::ios_base::fmtflags original_flags = out.flags();
432 
433  if (elf_class == ELFCLASS32) { // Output for 32-bit
434  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_STR_FORMAT(17)
435  << str_section_type(sec->get_type()) << " " << DUMP_HEX_FORMAT(8)
436  << sec->get_address() << " " << DUMP_HEX_FORMAT(8) << sec->get_size() << " "
437  << DUMP_HEX_FORMAT(2) << sec->get_entry_size() << " " << DUMP_STR_FORMAT(3)
438  << section_flags(sec->get_flags()) << " " << DUMP_HEX_FORMAT(2) << sec->get_link()
439  << " " << DUMP_HEX_FORMAT(3) << sec->get_info() << " " << DUMP_HEX_FORMAT(2)
440  << sec->get_addr_align() << " " << DUMP_STR_FORMAT(17) << sec->get_name() << " "
441  << std::endl;
442  } else { // Output for 64-bit
443  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_STR_FORMAT(17)
444  << str_section_type(sec->get_type()) << " " << DUMP_HEX_FORMAT(16)
445  << sec->get_address() << " " << DUMP_HEX_FORMAT(16) << sec->get_size() << " "
446  << DUMP_HEX_FORMAT(4) << sec->get_entry_size() << " " << DUMP_STR_FORMAT(3)
447  << section_flags(sec->get_flags()) << " " << std::endl
448  << " " << DUMP_HEX_FORMAT(4) << sec->get_link() << " " << DUMP_HEX_FORMAT(4)
449  << sec->get_info() << " " << DUMP_HEX_FORMAT(4) << sec->get_addr_align() << " "
450  << DUMP_STR_FORMAT(17) << sec->get_name() << " " << std::endl;
451  }
452 
453  out.flags(original_flags);
454 
455  return;
456  }
457 
458  //------------------------------------------------------------------------------
459  static void segment_headers(std::ostream& out, const elfio& reader) {
460  Elf_Half n = reader.segments.size();
461  if (n == 0) {
462  return;
463  }
464 
465  out << "Segment headers:" << std::endl;
466  if (reader.get_class() == ELFCLASS32) { // Output for 32-bit
467  out << "[ Nr ] Type VirtAddr PhysAddr FileSize Mem.Size Flags Align"
468  << std::endl;
469  } else { // Output for 64-bit
470  out << "[ Nr ] Type VirtAddr PhysAddr Flags" << std::endl
471  << " FileSize Mem.Size Align" << std::endl;
472  }
473 
474  for (Elf_Half i = 0; i < n; ++i) {
475  segment* seg = reader.segments[i];
476  segment_header(out, i, seg, reader.get_class());
477  }
478 
479  out << std::endl;
480  }
481 
482  //------------------------------------------------------------------------------
483  static void segment_header(std::ostream& out, Elf_Half no, const segment* seg,
484  unsigned int elf_class) {
485  std::ios_base::fmtflags original_flags = out.flags();
486 
487  if (elf_class == ELFCLASS32) { // Output for 32-bit
488  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_STR_FORMAT(14)
489  << str_segment_type(seg->get_type()) << " " << DUMP_HEX_FORMAT(8)
490  << seg->get_virtual_address() << " " << DUMP_HEX_FORMAT(8)
491  << seg->get_physical_address() << " " << DUMP_HEX_FORMAT(8) << seg->get_file_size()
492  << " " << DUMP_HEX_FORMAT(8) << seg->get_memory_size() << " " << DUMP_STR_FORMAT(8)
493  << str_segment_flag(seg->get_flags()) << " " << DUMP_HEX_FORMAT(8)
494  << seg->get_align() << " " << std::endl;
495  } else { // Output for 64-bit
496  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_STR_FORMAT(14)
497  << str_segment_type(seg->get_type()) << " " << DUMP_HEX_FORMAT(16)
498  << seg->get_virtual_address() << " " << DUMP_HEX_FORMAT(16)
499  << seg->get_physical_address() << " " << DUMP_STR_FORMAT(16)
500  << str_segment_flag(seg->get_flags()) << " " << std::endl
501  << " " << DUMP_HEX_FORMAT(16) << seg->get_file_size() << " "
502  << DUMP_HEX_FORMAT(16) << seg->get_memory_size() << " " << DUMP_HEX_FORMAT(16)
503  << seg->get_align() << " " << std::endl;
504  }
505 
506  out.flags(original_flags);
507  }
508 
509  //------------------------------------------------------------------------------
510  static void symbol_tables(std::ostream& out, const elfio& reader) {
511  Elf_Half n = reader.sections.size();
512  for (Elf_Half i = 0; i < n; ++i) { // For all sections
513  section* sec = reader.sections[i];
514  if (SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type()) {
515  symbol_section_accessor symbols(reader, sec);
516 
517  Elf_Xword sym_no = symbols.get_symbols_num();
518  if (sym_no > 0) {
519  out << "Symbol table (" << sec->get_name() << ")" << std::endl;
520  if (reader.get_class() == ELFCLASS32) { // Output for 32-bit
521  out << "[ Nr ] Value Size Type Bind Sect Name" << std::endl;
522  } else { // Output for 64-bit
523  out << "[ Nr ] Value Size Type Bind Sect"
524  << std::endl
525  << " Name" << std::endl;
526  }
527  for (Elf_Half i = 0; i < sym_no; ++i) {
528  std::string name;
529  Elf64_Addr value = 0;
530  Elf_Xword size = 0;
531  unsigned char bind = 0;
532  unsigned char type = 0;
533  Elf_Half section = 0;
534  unsigned char other = 0;
535  symbols.get_symbol(i, name, value, size, bind, type, section, other);
536  symbol_table(out, i, name, value, size, bind, type, section,
537  reader.get_class());
538  }
539 
540  out << std::endl;
541  }
542  }
543  }
544  }
545 
546  //------------------------------------------------------------------------------
547  static void symbol_table(std::ostream& out, Elf_Half no, std::string& name, Elf64_Addr value,
548  Elf_Xword size, unsigned char bind, unsigned char type,
549  Elf_Half section, unsigned int elf_class) {
550  std::ios_base::fmtflags original_flags = out.flags();
551 
552  if (elf_class == ELFCLASS32) { // Output for 32-bit
553  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_HEX_FORMAT(8) << value << " "
554  << DUMP_HEX_FORMAT(8) << size << " " << DUMP_STR_FORMAT(7) << str_symbol_type(type)
555  << " " << DUMP_STR_FORMAT(8) << str_symbol_bind(bind) << " " << DUMP_DEC_FORMAT(5)
556  << section << " " << DUMP_STR_FORMAT(1) << name << " " << std::endl;
557  } else { // Output for 64-bit
558  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_HEX_FORMAT(16) << value << " "
559  << DUMP_HEX_FORMAT(16) << size << " " << DUMP_STR_FORMAT(7) << str_symbol_type(type)
560  << " " << DUMP_STR_FORMAT(8) << str_symbol_bind(bind) << " " << DUMP_DEC_FORMAT(5)
561  << section << " " << std::endl
562  << " " << DUMP_STR_FORMAT(1) << name << " " << std::endl;
563  }
564 
565  out.flags(original_flags);
566  }
567 
568  //------------------------------------------------------------------------------
569  static void notes(std::ostream& out, const elfio& reader) {
570  Elf_Half no = reader.sections.size();
571  for (Elf_Half i = 0; i < no; ++i) { // For all sections
572  section* sec = reader.sections[i];
573  if (SHT_NOTE == sec->get_type()) { // Look at notes
574  note_section_accessor notes(reader, sec);
575  int no_notes = notes.get_notes_num();
576  if (no > 0) {
577  out << "Note section (" << sec->get_name() << ")" << std::endl
578  << " No Type Name" << std::endl;
579  for (int j = 0; j < no_notes; ++j) { // For all notes
580  Elf_Word type;
581  std::string name;
582  void* desc;
583  Elf_Word descsz;
584 
585  if (notes.get_note(j, type, name, desc, descsz)) {
586  // 'name' usually contains \0 at the end. Try to fix it
587  name = name.c_str();
588  note(out, j, type, name);
589  }
590  }
591 
592  out << std::endl;
593  }
594  }
595  }
596  }
597 
598  //------------------------------------------------------------------------------
599  static void note(std::ostream& out, int no, Elf_Word type, const std::string& name) {
600  out << " [" << DUMP_DEC_FORMAT(2) << no << "] " << DUMP_HEX_FORMAT(8) << type << " "
601  << DUMP_STR_FORMAT(1) << name << std::endl;
602  }
603 
604  //------------------------------------------------------------------------------
605  static void dynamic_tags(std::ostream& out, const elfio& reader) {
606  Elf_Half n = reader.sections.size();
607  for (Elf_Half i = 0; i < n; ++i) { // For all sections
608  section* sec = reader.sections[i];
609  if (SHT_DYNAMIC == sec->get_type()) {
610  dynamic_section_accessor dynamic(reader, sec);
611 
612  Elf_Xword dyn_no = dynamic.get_entries_num();
613  if (dyn_no > 0) {
614  out << "Dynamic section (" << sec->get_name() << ")" << std::endl;
615  out << "[ Nr ] Tag Name/Value" << std::endl;
616  for (int i = 0; i < dyn_no; ++i) {
617  Elf_Xword tag = 0;
618  Elf_Xword value = 0;
619  std::string str;
620  dynamic.get_entry(i, tag, value, str);
621  dynamic_tag(out, i, tag, value, str, reader.get_class());
622  if (DT_NULL == tag) {
623  break;
624  }
625  }
626 
627  out << std::endl;
628  }
629  }
630  }
631  }
632 
633  //------------------------------------------------------------------------------
634  static void dynamic_tag(std::ostream& out, int no, Elf_Xword tag, Elf_Xword value,
635  std::string str, unsigned int /*elf_class*/) {
636  out << "[" << DUMP_DEC_FORMAT(5) << no << "] " << DUMP_STR_FORMAT(16)
637  << str_dynamic_tag(tag) << " ";
638  if (str.empty()) {
639  out << DUMP_HEX_FORMAT(16) << value << " ";
640  } else {
641  out << DUMP_STR_FORMAT(32) << str << " ";
642  }
643  out << std::endl;
644  }
645 
646  //------------------------------------------------------------------------------
647  static void section_data(std::ostream& out, const section* sec) {
648  std::ios_base::fmtflags original_flags = out.flags();
649 
650  out << sec->get_name() << std::endl;
651  const char* pdata = sec->get_data();
652  if (pdata) {
653  ELFIO::Elf_Xword i;
654  for (i = 0; i < std::min(sec->get_size(), MAX_DATA_ENTRIES); ++i) {
655  if (i % 16 == 0) {
656  out << "[" << DUMP_HEX_FORMAT(8) << i << "]";
657  }
658 
659  out << " " << DUMP_HEX_FORMAT(2) << (pdata[i] & 0x000000FF);
660 
661  if (i % 16 == 15) {
662  out << std::endl;
663  }
664  }
665  if (i % 16 != 0) {
666  out << std::endl;
667  }
668 
669  out.flags(original_flags);
670  }
671 
672  return;
673  }
674 
675  //------------------------------------------------------------------------------
676  static void section_datas(std::ostream& out, const elfio& reader) {
677  Elf_Half n = reader.sections.size();
678 
679  if (n == 0) {
680  return;
681  }
682 
683  out << "Section Data:" << std::endl;
684 
685  for (Elf_Half i = 1; i < n; ++i) { // For all sections
686  section* sec = reader.sections[i];
687  if (sec->get_type() == SHT_NOBITS) {
688  continue;
689  }
690  section_data(out, sec);
691  }
692 
693  out << std::endl;
694  }
695 
696  //------------------------------------------------------------------------------
697  static void segment_data(std::ostream& out, Elf_Half no, const segment* seg) {
698  std::ios_base::fmtflags original_flags = out.flags();
699 
700  out << "Segment # " << no << std::endl;
701  const char* pdata = seg->get_data();
702  if (pdata) {
703  ELFIO::Elf_Xword i;
704  for (i = 0; i < std::min(seg->get_file_size(), MAX_DATA_ENTRIES); ++i) {
705  if (i % 16 == 0) {
706  out << "[" << DUMP_HEX_FORMAT(8) << i << "]";
707  }
708 
709  out << " " << DUMP_HEX_FORMAT(2) << (pdata[i] & 0x000000FF);
710 
711  if (i % 16 == 15) {
712  out << std::endl;
713  }
714  }
715  if (i % 16 != 0) {
716  out << std::endl;
717  }
718 
719  out.flags(original_flags);
720  }
721 
722  return;
723  }
724 
725  //------------------------------------------------------------------------------
726  static void segment_datas(std::ostream& out, const elfio& reader) {
727  Elf_Half n = reader.segments.size();
728 
729  if (n == 0) {
730  return;
731  }
732 
733  out << "Segment Data:" << std::endl;
734 
735  for (Elf_Half i = 0; i < n; ++i) { // For all sections
736  segment* seg = reader.segments[i];
737  segment_data(out, i, seg);
738  }
739 
740  out << std::endl;
741  }
742 
743  private:
744  //------------------------------------------------------------------------------
745  template <typename T, typename K>
746  std::string static find_value_in_table(const T& table, const K& key) {
747  std::string res = "?";
748  for (unsigned int i = 0; i < sizeof(table) / sizeof(table[0]); ++i) {
749  if (table[i].key == key) {
750  res = table[i].str;
751  break;
752  }
753  }
754 
755  return res;
756  }
757 
758 
759  //------------------------------------------------------------------------------
760  template <typename T, typename K>
761  static std::string format_assoc(const T& table, const K& key) {
762  std::string str = find_value_in_table(table, key);
763  if (str == "?") {
764  std::ostringstream oss;
765  oss << str << " (0x" << std::hex << key << ")";
766  str = oss.str();
767  }
768 
769  return str;
770  }
771 
772 
773  //------------------------------------------------------------------------------
774  template <typename T>
775  static std::string format_assoc(const T& table, const char key) {
776  return format_assoc(table, (const int)key);
777  }
778 
779 
780  //------------------------------------------------------------------------------
781  static std::string section_flags(Elf_Xword flags) {
782  std::string ret = "";
783  if (flags & SHF_WRITE) {
784  ret += "W";
785  }
786  if (flags & SHF_ALLOC) {
787  ret += "A";
788  }
789  if (flags & SHF_EXECINSTR) {
790  ret += "X";
791  }
792 
793  return ret;
794  }
795 
796 
797 //------------------------------------------------------------------------------
798 #define STR_FUNC_TABLE(name) \
799  template <typename T> \
800  static std::string str_##name(const T key) { \
801  return format_assoc(name##_table, key); \
802  }
803 
804  STR_FUNC_TABLE(class)
805  STR_FUNC_TABLE(endian)
806  STR_FUNC_TABLE(version)
807  STR_FUNC_TABLE(type)
808  STR_FUNC_TABLE(machine)
809  STR_FUNC_TABLE(section_type)
810  STR_FUNC_TABLE(segment_type)
811  STR_FUNC_TABLE(segment_flag)
812  STR_FUNC_TABLE(symbol_bind)
813  STR_FUNC_TABLE(symbol_type)
814  STR_FUNC_TABLE(dynamic_tag)
815 
816 #undef STR_FUNC_TABLE
817 #undef DUMP_DEC_FORMAT
818 #undef DUMP_HEX_FORMAT
819 #undef DUMP_STR_FORMAT
820 }; // class dump
821 
822 
823 }; // namespace ELFIO
824 
825 #endif // ELFIO_DUMP_HPP
ELFIO::dynamic_section_accessor
Definition: elfio_dynamic.hpp:29
ELFIO::elfio
Definition: elfio.hpp:59
ELFIO::symbol_section_accessor
Definition: elfio_symbols.hpp:29
ELFIO::dump
Definition: elfio_dump.hpp:380
ELFIO::section
Definition: elfio_section.hpp:31
ELFIO::note_section_accessor
Definition: elfio_note.hpp:41
ELFIO::segment
Definition: elfio_segment.hpp:31