add d30v sanitization to readelf
[deliverable/binutils-gdb.git] / binutils / readelf.c
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998 Free Software Foundation, Inc.
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@cygnus.com>
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23 \f
24
25 #include <assert.h>
26 #include <sys/mman.h>
27 #include <sys/stat.h>
28
29 #include "readelf.h"
30 #include "bucomm.h"
31 #include "getopt.h"
32
33 #ifdef ANSI_PROTOTYPES
34 #include <stdarg.h>
35 #else
36 #include <varargs.h>
37 #endif
38
39 unsigned int dynamic_addr;
40 unsigned int dynamic_size;
41 char * pint = "";
42 char * program_name = "readelf";
43
44 int dynamic_info [DT_JMPREL + 1];
45 int version_info [16];
46
47 int must_swap = 0;
48
49 unsigned int rel_size;
50 int loadaddr = -1;
51
52 unsigned int rela_addr;
53 unsigned int rela_size;
54 char * strtab;
55 int symtab_index;
56 int lastmapped;
57 char * header;
58
59 Elf_Dyn * dpnt;
60 Elf_Rel * rpnt;
61 Elf_Shdr * elf_sections;
62 Elf_Ehdr * epnt;
63 Elf_Sym * symtab;
64
65 int show_name;
66 int do_dynamic;
67 int do_syms;
68 int do_reloc;
69 int do_section;
70 int do_load;
71 int do_using_dynamic;
72 int do_header;
73 int do_dump;
74 int do_version;
75 long int expected_endian;
76
77 char * dyntype[] =
78 {
79 "NULL", "NEEDED","PLTRELSZ","PLTGOT","HASH","STRTAB","SYMTAB","RELA",
80 "RELASZ","RELAENT","STRSZ","SYMENT","INIT","FINI","SONAME","RPATH",
81 "SYMBOLIC","REL","RELSZ","RELENT","PLTREL","DEBUG","TEXTREL","JMPREL"
82 };
83
84 char * vertype[] =
85 {
86 "VERNEEDNUM", "VERNEED", "VERDEFNUM", "VERDEF",
87 "", "", "", "", "", "", "", "", "", "", "", "VERSYM"
88 };
89
90 char * filtertype[] =
91 {
92 "FILTER", "USED", "AUXILIARY"
93 };
94
95
96 char * sttinfo[] = {"NOTYPE","OBJECT","FUNC","SECTION","FILE"};
97 char * stbinfo[] = {"LOCAL","GLOBAL","WEAK"};
98
99 #define SECTION_NAME(X) (& header [lastmapped + (X)->sh_name])
100
101 #define NUM_DUMP_SECTS 100
102 char dump_sects [NUM_DUMP_SECTS];
103 #define HEX_DUMP 1
104 #define DISASS_DUMP 2
105
106 /* Forward declarations for dumb compilers. */
107 static char * get_i386_rel_type PARAMS ((bfd_vma rtype));
108 static char * get_m68k_rel_type PARAMS ((bfd_vma rtype));
109 static char * get_sparc_rel_type PARAMS ((bfd_vma rtype));
110 static char * get_m32r_rel_type PARAMS ((bfd_vma rtype));
111 static char * get_v850_rel_type PARAMS ((bfd_vma rtype));
112 static char * get_d10v_rel_type PARAMS ((bfd_vma rtype));
113 /* start-sanitize-d30v */
114 static char * get_d30v_rel_type PARAMS ((bfd_vma rtype));
115 /* end-sanitize-d30v */
116 static char * get_sh_rel_type PARAMS ((bfd_vma rtype));
117 static char * get_mn10300_rel_type PARAMS ((bfd_vma rtype));
118 static char * get_mn10200_rel_type PARAMS ((bfd_vma rtype));
119 static char * get_ppc_rel_type PARAMS ((bfd_vma rtype));
120 static void dump_relocations PARAMS ((Elf_Rel * rpnt, int rel_size));
121 static char * get_file_type PARAMS ((unsigned e_type));
122 static char * get_machine_name PARAMS ((unsigned e_machine));
123 static char * get_machine_data PARAMS ((unsigned e_data));
124 static char * get_machine_flags PARAMS ((unsigned e_flags, unsigned e_machine));
125 static char * get_segment_type PARAMS ((unsigned long p_type));
126 static char * get_section_type_name PARAMS ((unsigned int sh_type));
127 static void usage PARAMS ((void));
128 static void parse_args PARAMS ((int argc, char ** argv));
129 static int process_elf_header PARAMS ((void));
130 static void process_program_headers PARAMS ((void));
131 static void process_section_headers PARAMS ((void));
132 static void process_dynamic_segment PARAMS ((void));
133 static void process_symbol_table PARAMS ((void));
134 static void process_section_contents PARAMS ((void));
135 static void process_file PARAMS ((char * file_name));
136
137
138 #define SWAP2(val) ( (((val) << 8) & (0xff << 8)) \
139 | (((val) >> 8) & (0xff << 0)))
140
141 #define SWAP4(val) ( (((val) << 24) & (0xff << 24)) \
142 | (((val) << 8) & (0xff << 16)) \
143 | (((val) >> 8) & (0xff << 8)) \
144 | (((val) >> 24) & (0xff << 0)))
145
146 /* Warning: This macro assumes 8 bits in a char. */
147 #define BYTE_SWAP(pointer, field) \
148 if (sizeof ((pointer)->field) == 2) \
149 { \
150 unsigned short val = (pointer)->field ; \
151 new_header->field = SWAP2 (val); \
152 } \
153 else if (sizeof ((pointer)->field) != 4) \
154 abort (); \
155 else \
156 { \
157 unsigned long val = (pointer)->field ; \
158 new_header->field = SWAP4 (val); \
159 }
160
161
162 #ifdef ANSI_PROTOTYPES
163 static void
164 error (const char * message, ...)
165 {
166 va_list args;
167
168 fprintf (stderr, _("%s: Error: "), program_name);
169 va_start (args, message);
170 vfprintf (stderr, message, args);
171 va_end (args);
172 return;
173 }
174
175 static void
176 warn (const char * message, ...)
177 {
178 va_list args;
179
180 fprintf (stderr, _("%s: Warning: "), program_name);
181 va_start (args, message);
182 vfprintf (stderr, message, args);
183 va_end (args);
184 return;
185 }
186 #else
187 static void
188 error (va_alist)
189 {
190 char * message;
191 va_list args;
192
193 fprintf (stderr, _("%s: Error: "), program_name);
194 va_start (args);
195 message = va_arg (args, char *);
196 vfprintf (stderr, message, args);
197 va_end (args);
198 return;
199 }
200
201 static void
202 warn (va_alist)
203 va_dcl;
204 {
205 char * message;
206 va_list args;
207
208 fprintf (stderr, _("%s: Warning: "), program_name);
209 va_start (args);
210 message = va_arg (args, char *);
211 vfprintf (stderr, message, args);
212 va_end (args);
213 return;
214 }
215 #endif
216
217
218 static char *
219 get_i386_rel_type (rtype)
220 bfd_vma rtype;
221 {
222 switch (rtype)
223 {
224 case 0: return "R_386_NONE";
225 case 1: return "R_386_32";
226 case 2: return "R_386_PC32";
227 case 3: return "R_386_GOT32";
228 case 4: return "R_386_PLT32";
229 case 5: return "R_386_COPY";
230 case 6: return "R_386_GLOB_DAT";
231 case 7: return "R_386_JMP_SLOT";
232 case 8: return "R_386_RELATIVE";
233 case 9: return "R_386_GOTOFF";
234 case 10: return "R_386_GOTPC";
235 case 20: return "R_386_16";
236 case 21: return "R_386_PC16";
237 case 22: return "R_386_PC8";
238 case 23: return "R_386_max";
239 default: return _("*INVALID*");
240 }
241 }
242
243 static char *
244 get_m68k_rel_type (rtype)
245 bfd_vma rtype;
246 {
247 switch (rtype)
248 {
249 case 0: return "R_68K_NONE";
250 case 1: return "R_68K_32";
251 case 2: return "R_68K_16";
252 case 3: return "R_68K_8";
253 case 4: return "R_68K_PC32";
254 case 5: return "R_68K_PC16";
255 case 6: return "R_68K_PC8";
256 case 7: return "R_68K_GOT32";
257 case 8: return "R_68K_GOT16";
258 case 9: return "R_68K_GOT8";
259 case 10: return "R_68K_GOT32O";
260 case 11: return "R_68K_GOT16O";
261 case 12: return "R_68K_GOT8O";
262 case 13: return "R_68K_PLT32";
263 case 14: return "R_68K_PLT16";
264 case 15: return "R_68K_PLT8";
265 case 16: return "R_68K_PLT32O";
266 case 17: return "R_68K_PLT16O";
267 case 18: return "R_68K_PLT8O";
268 case 19: return "R_68K_COPY";
269 case 20: return "R_68K_GLOB_DAT";
270 case 21: return "R_68K_JMP_SLOT";
271 case 22: return "R_68K_RELATIVE";
272 default: return _("*INVALID*");
273 }
274 }
275
276
277 static char *
278 get_sparc_rel_type (rtype)
279 bfd_vma rtype;
280 {
281 switch (rtype)
282 {
283 case 0: return "R_SPARC_NONE";
284 case 1: return "R_SPARC_8";
285 case 2: return "R_SPARC_16";
286 case 3: return "R_SPARC_32";
287 case 4: return "R_SPARC_DISP8";
288 case 5: return "R_SPARC_DISP16";
289 case 6: return "R_SPARC_DISP32";
290 case 7: return "R_SPARC_WDISP30";
291 case 8: return "R_SPARC_WDISP22";
292 case 9: return "R_SPARC_HI22";
293 case 10: return "R_SPARC_22";
294 case 11: return "R_SPARC_13";
295 case 12: return "R_SPARC_LO10";
296 case 13: return "R_SPARC_GOT10";
297 case 14: return "R_SPARC_GOT13";
298 case 15: return "R_SPARC_GOT22";
299 case 16: return "R_SPARC_PC10";
300 case 17: return "R_SPARC_PC22";
301 case 18: return "R_SPARC_WPLT30";
302 case 19: return "R_SPARC_COPY";
303 case 20: return "R_SPARC_GLOB_DAT";
304 case 21: return "R_SPARC_JMP_SLOT";
305 case 22: return "R_SPARC_RELATIVE";
306 case 23: return "R_SPARC_UA32";
307 case 24: return "R_SPARC_10";
308 case 25: return "R_SPARC_11";
309 case 26: return "R_SPARC_64";
310 case 27: return "R_SPARC_OLO10";
311 case 28: return "R_SPARC_HH22";
312 case 29: return "R_SPARC_HM10";
313 case 30: return "R_SPARC_LM22";
314 case 31: return "R_SPARC_PC_HH22";
315 case 32: return "R_SPARC_PC_HM10";
316 case 33: return "R_SPARC_PC_LM22";
317 case 34: return "R_SPARC_WDISP16";
318 case 35: return "R_SPARC_WDISP19";
319 case 36: return "R_SPARC_UNUSED_42";
320 case 37: return "R_SPARC_7";
321 case 38: return "R_SPARC_5";
322 case 39: return "R_SPARC_6";
323 case 40: return "R_SPARC_DISP64";
324 case 41: return "R_SPARC_PLT64";
325 case 42: return "R_SPARC_HIX22";
326 case 43: return "R_SPARC_LOX10";
327 case 44: return "R_SPARC_H44";
328 case 45: return "R_SPARC_M44";
329 case 46: return "R_SPARC_L44";
330 case 47: return "R_SPARC_REGISTER";
331 case 48: return "R_SPARC_UA64";
332 case 49: return "R_SPARC_UA16";
333 case 50: return "R_SPARC_32LE";
334 default: return _("*INVALID*");
335 }
336 }
337
338
339 static char *
340 get_m32r_rel_type (rtype)
341 bfd_vma rtype;
342 {
343 switch (rtype)
344 {
345 case 0: return "R_M32R_NONE";
346 case 1: return "R_M32R_16";
347 case 2: return "R_M32R_32";
348 case 3: return "R_M32R_24";
349 case 4: return "R_M32R_10_PCREL";
350 case 5: return "R_M32R_18_PCREL";
351 case 6: return "R_M32R_26_PCREL";
352 case 7: return "R_M32R_HI16_ULO";
353 case 8: return "R_M32R_HI16_SLO";
354 case 9: return "R_M32R_LO16";
355 case 10: return "R_M32R_SDA16";
356 default: return _("*INVALID*");
357 }
358 }
359
360
361 static char *
362 get_v850_rel_type (rtype)
363 bfd_vma rtype;
364 {
365 switch (rtype)
366 {
367 case 0: return "R_V850_NONE";
368 case 1: return "R_V850_9_PCREL";
369 case 2: return "R_V850_22_PCREL";
370 case 3: return "R_V850_HI16_S";
371 case 4: return "R_V850_HI16";
372 case 5: return "R_V850_LO16";
373 case 6: return "R_V850_32";
374 case 7: return "R_V850_16";
375 case 8: return "R_V850_8";
376 case 9: return "R_V850_SDA_16_16_OFFSET";
377 case 10: return "R_V850_SDA_15_16_OFFSET";
378 case 11: return "R_V850_ZDA_16_16_OFFSET";
379 case 12: return "R_V850_ZDA_15_16_OFFSET";
380 case 13: return "R_V850_TDA_6_8_OFFSET";
381 case 14: return "R_V850_TDA_7_8_OFFSET";
382 case 15: return "R_V850_TDA_7_7_OFFSET";
383 case 16: return "R_V850_TDA_16_16_OFFSET";
384 /* start-sanitize-v850e */
385 case 17: return "R_V850_TDA_4_5_OFFSET";
386 case 18: return "R_V850_TDA_4_4_OFFSET";
387 case 19: return "R_V850_SDA_16_16_SPLIT_OFFSET";
388 case 20: return "R_V850_ZDA_16_16_SPLIT_OFFSET";
389 case 21: return "R_V850_CALLT_6_7_OFFSET";
390 case 22: return "R_V850_CALLT_16_16_OFFSET";
391 /* end-sanitize-v850e */
392 default: return _("*INVALID*");
393 }
394 }
395
396
397 static char *
398 get_d10v_rel_type (rtype)
399 bfd_vma rtype;
400 {
401 switch (rtype)
402 {
403 case 0: return "R_D10V_NONE";
404 case 1: return "R_D10V_10_PCREL_R";
405 case 2: return "R_D10V_10_PCREL_L";
406 case 3: return "R_D10V_16";
407 case 4: return "R_D10V_18";
408 case 5: return "R_D10V_18_PCREL";
409 case 6: return "R_D10V_32";
410 default: return _("*INVALID*");
411 }
412 }
413
414 /* start-sanitize-d30v */
415 static char *
416 get_d30v_rel_type (rtype)
417 bfd_vma rtype;
418 {
419 switch (rtype)
420 {
421 case 0: return "R_D30V_NONE";
422 case 1: return "R_D30V_6";
423 case 2: return "R_D30V_9_PCREL";
424 case 3: return "R_D30V_9_PCREL_R";
425 case 4: return "R_D30V_15";
426 case 5: return "R_D30V_15_PCREL";
427 case 6: return "R_D30V_15_PCREL_R";
428 case 7: return "R_D30V_21";
429 case 8: return "R_D30V_21_PCREL";
430 case 9: return "R_D30V_21_PCREL_R";
431 case 10: return "R_D30V_32";
432 case 11: return "R_D30V_32_PCREL";
433 case 12: return "R_D30V_32_NORMAL";
434 default: return _("*INVALID*");
435 }
436 }
437
438 /* end-sanitize-d30v */
439 static char *
440 get_sh_rel_type (rtype)
441 bfd_vma rtype;
442 {
443 switch (rtype)
444 {
445 case 0: return "R_SH_NONE";
446 case 1: return "R_SH_DIR32";
447 case 2: return "R_SH_REL32";
448 case 3: return "R_SH_DIR8WPN";
449 case 4: return "R_SH_IND12W";
450 case 5: return "R_SH_DIR8WPL";
451 case 6: return "R_SH_DIR8WPZ";
452 case 7: return "R_SH_DIR8BP";
453 case 8: return "R_SH_DIR8W";
454 case 9: return "R_SH_DIR8L";
455 case 25: return "R_SH_SWITCH16";
456 case 26: return "R_SH_SWITCH32";
457 case 27: return "R_SH_USES";
458 case 28: return "R_SH_COUNT";
459 case 29: return "R_SH_ALIGN";
460 case 30: return "R_SH_CODE";
461 case 31: return "R_SH_DATA";
462 case 32: return "R_SH_LABEL";
463 default: return _("*INVALID*");
464 }
465 }
466
467
468 static char *
469 get_mn10300_rel_type (rtype)
470 bfd_vma rtype;
471 {
472 switch (rtype)
473 {
474 case 0: return "R_MN10300_NONE";
475 case 1: return "R_MN10300_32";
476 case 2: return "R_MN10300_16";
477 case 3: return "R_MN10300_8";
478 case 4: return "R_MN10300_PCREL32";
479 case 5: return "R_MN10300_PCREL16";
480 case 6: return "R_MN10300_PCREL8";
481 default: return _("*INVALID*");
482 }
483 }
484
485
486 static char *
487 get_mn10200_rel_type (rtype)
488 bfd_vma rtype;
489 {
490 switch (rtype)
491 {
492 case 0: return "R_MN10200_NONE";
493 case 1: return "R_MN10200_32";
494 case 2: return "R_MN10200_16";
495 case 3: return "R_MN10200_8";
496 case 4: return "R_MN10200_24";
497 case 5: return "R_MN10200_PCREL8";
498 case 6: return "R_MN10200_PCREL16";
499 case 7: return "R_MN10200_PCREL24";
500 default: return _("*INVALID*");
501 }
502 }
503
504
505 static char *
506 get_ppc_rel_type (rtype)
507 bfd_vma rtype;
508 {
509 switch (rtype)
510 {
511 case 0: return "R_PPC_NONE,";
512 case 1: return "R_PPC_ADDR32,";
513 case 2: return "R_PPC_ADDR24,";
514 case 3: return "R_PPC_ADDR16,";
515 case 4: return "R_PPC_ADDR16_LO,";
516 case 5: return "R_PPC_ADDR16_HI,";
517 case 6: return "R_PPC_ADDR16_HA,";
518 case 7: return "R_PPC_ADDR14,";
519 case 8: return "R_PPC_ADDR14_BRTAKEN,";
520 case 9: return "R_PPC_ADDR14_BRNTAKEN,";
521 case 10: return "R_PPC_REL24,";
522 case 11: return "R_PPC_REL14,";
523 case 12: return "R_PPC_REL14_BRTAKEN,";
524 case 13: return "R_PPC_REL14_BRNTAKEN,";
525 case 14: return "R_PPC_GOT16,";
526 case 15: return "R_PPC_GOT16_LO,";
527 case 16: return "R_PPC_GOT16_HI,";
528 case 17: return "R_PPC_GOT16_HA,";
529 case 18: return "R_PPC_PLT24,";
530 case 19: return "R_PPC_COPY,";
531 case 21: return "R_PPC_JMP_SLOT,";
532 case 22: return "R_PPC_RELATIVE,";
533 case 23: return "R_PPC_LOCAL24PC,";
534 case 24: return "R_PPC_UADDR32,";
535 case 25: return "R_PPC_UADDR16,";
536 case 26: return "R_PPC_REL32,";
537 case 27: return "R_PPC_PLT32,";
538 case 28: return "R_PPC_PLTREL32,";
539 case 29: return "R_PPC_PLT16_LO,";
540 case 30: return "R_PPC_PLT16_HI,";
541 case 31: return "R_PPC_PLT16_HA,";
542 case 32: return "R_PPC_SDAREL,";
543 case 33: return "R_PPC_SECTOFF,";
544 case 34: return "R_PPC_SECTOFF_LO,";
545 case 35: return "R_PPC_SECTOFF_HI,";
546 case 36: return "R_PPC_SECTOFF_HA,";
547 case 101: return "R_PPC_EMB_NADDR32,";
548 case 102: return "R_PPC_EMB_NADDR16,";
549 case 103: return "R_PPC_EMB_NADDR16_LO,";
550 case 104: return "R_PPC_EMB_NADDR16_HI,";
551 case 105: return "R_PPC_EMB_NADDR16_HA,";
552 case 106: return "R_PPC_EMB_SDAI16,";
553 case 107: return "R_PPC_EMB_SDA2I16,";
554 case 108: return "R_PPC_EMB_SDA2REL,";
555 case 109: return "R_PPC_EMB_SDA21,";
556 case 110: return "R_PPC_EMB_MRKREF,";
557 case 111: return "R_PPC_EMB_RELSEC16,";
558 case 112: return "R_PPC_EMB_RELST_LO,";
559 case 113: return "R_PPC_EMB_RELST_HI,";
560 case 114: return "R_PPC_EMB_RELST_HA,";
561 case 115: return "R_PPC_EMB_BIT_FLD,";
562 case 116: return "R_PPC_EMB_RELSDA,";
563 default: return _("*INVALID*");
564 }
565 }
566
567
568 static void
569 dump_relocations (rpnt, rel_size)
570 Elf_Rel * rpnt;
571 int rel_size;
572 {
573 int i;
574 int is_rela;
575 Elf_Rela * rapnt;
576 Elf_Rela * relocs = NULL;
577
578
579 rapnt = (Elf_Rela *) rpnt;
580
581 /* Compute number of relocations. */
582 switch (epnt->e_machine)
583 {
584 case EM_386:
585 case EM_486:
586 case EM_CYGNUS_M32R:
587 case EM_CYGNUS_D10V:
588 rel_size = rel_size / sizeof (Elf_Rel);
589
590 if (must_swap)
591 {
592 Elf_Rel * new_header = malloc (sizeof (* new_header) * rel_size);
593
594 if (new_header == NULL)
595 {
596 error (_("out of memory\n"));
597 return;
598 }
599
600 memcpy (new_header, rpnt, sizeof (* new_header) * rel_size);
601
602 rpnt = new_header;
603 relocs = (Elf_Rela *) new_header;
604
605 for (i = 0; i < rel_size; i++)
606 {
607 BYTE_SWAP (rpnt + i, r_offset);
608 BYTE_SWAP (rpnt + i, r_info);
609
610 new_header ++;
611 }
612 }
613
614 is_rela = 0;
615 break;
616
617 case EM_68K:
618 case EM_SPARC:
619 case EM_PPC:
620 case EM_CYGNUS_V850:
621 /* start-sanitize-d30v */
622 case EM_CYGNUS_D30V:
623 /* end-sanitize-d30v */
624 case EM_CYGNUS_MN10200:
625 case EM_CYGNUS_MN10300:
626 case EM_SH:
627 rel_size = rel_size / sizeof (Elf_Rela);
628
629 if (must_swap)
630 {
631 Elf_Rela * new_header = malloc (sizeof (* new_header) * rel_size);
632
633 if (new_header == NULL)
634 {
635 error (_("out of memory\n"));
636 return;
637 }
638
639 memcpy (new_header, rpnt, sizeof (* new_header) * rel_size);
640
641 relocs = rapnt = new_header;
642
643 for (i = rel_size; i--;)
644 {
645 BYTE_SWAP (new_header, r_offset);
646 BYTE_SWAP (new_header, r_info);
647 BYTE_SWAP (new_header, r_addend);
648
649 new_header ++;
650 }
651 }
652
653 is_rela = 1;
654 break;
655
656 default:
657 warn (_("Don't know about relocations on this machine architecture\n"));
658 return;
659 }
660
661 if (is_rela)
662 printf (_(" Offset Value Type Symbol's Value Symbol Name Addend\n"));
663 else
664 printf (_(" Offset Value Type Symbol's Value Symbol Name\n"));
665
666 for (i = 0; i < rel_size; i++)
667 {
668 char * rtype;
669
670 if (is_rela)
671 rpnt = (Elf_Rel *) rapnt;
672
673 printf (" %5.5lx %5.5lx ", rpnt->r_offset, rpnt->r_info);
674
675 switch (epnt->e_machine)
676 {
677 default:
678 rtype = "UGG!";
679 break;
680
681 case EM_CYGNUS_M32R:
682 rtype = get_m32r_rel_type (ELF32_R_TYPE (rpnt->r_info));
683 break;
684
685 case EM_386:
686 case EM_486:
687 rtype = get_i386_rel_type (ELF32_R_TYPE (rpnt->r_info));
688 break;
689
690 case EM_68K:
691 rtype = get_m68k_rel_type (ELF32_R_TYPE (rpnt->r_info));
692 break;
693
694 case EM_SPARC:
695 rtype = get_sparc_rel_type (ELF32_R_TYPE (rapnt->r_info));
696 break;
697
698 case EM_CYGNUS_V850:
699 rtype = get_v850_rel_type (ELF32_R_TYPE (rpnt->r_info));
700 break;
701
702 case EM_CYGNUS_D10V:
703 rtype = get_d10v_rel_type (ELF32_R_TYPE (rpnt->r_info));
704 break;
705
706 /* start-sanitize-d30v */
707 case EM_CYGNUS_D30V:
708 rtype = get_d30v_rel_type (ELF32_R_TYPE (rpnt->r_info));
709 break;
710
711 /* end-sanitize-d30v */
712 case EM_SH:
713 rtype = get_sh_rel_type (ELF32_R_TYPE (rpnt->r_info));
714 break;
715
716 case EM_CYGNUS_MN10300:
717 rtype = get_mn10300_rel_type (ELF32_R_TYPE (rpnt->r_info));
718 break;
719
720 case EM_CYGNUS_MN10200:
721 rtype = get_mn10200_rel_type (ELF32_R_TYPE (rpnt->r_info));
722 break;
723
724 case EM_PPC:
725 rtype = get_ppc_rel_type (ELF32_R_TYPE (rpnt->r_info));
726 break;
727 }
728
729 printf ("%-18s", rtype);
730
731 symtab_index = ELF32_R_SYM (rpnt->r_info);
732
733 if (symtab_index)
734 {
735 Elf_Sym ssym;
736 Elf_Sym * psym;
737
738 psym = symtab + symtab_index;
739
740 if (must_swap)
741 {
742 Elf_Sym * new_header = & ssym;
743
744 ssym = * psym;
745
746 BYTE_SWAP (psym, st_name);
747 BYTE_SWAP (psym, st_value);
748 /* BYTE_SWAP (psym, st_size); */
749 BYTE_SWAP (psym, st_shndx);
750
751 psym = new_header;
752 }
753
754 if (psym->st_name == 0)
755 printf (" %08lx %-15s", psym->st_value,
756 SECTION_NAME (elf_sections + psym->st_shndx));
757 else
758 printf (" %08lx %-15s", psym->st_value, strtab + psym->st_name);
759
760 if (is_rela)
761 printf (" + %lx", rapnt->r_addend);
762 }
763
764 putchar ('\n');
765 rapnt ++;
766 rpnt ++;
767 }
768
769 if (relocs != NULL)
770 free (relocs);
771 }
772
773 static char *
774 get_file_type (e_type)
775 unsigned e_type;
776 {
777 static char buff [32];
778
779 switch (e_type)
780 {
781 case ET_NONE: return _("None");
782 case ET_REL: return _("Relocatable file");
783 case ET_EXEC: return _("Executable file");
784 case ET_DYN: return _("Shared object file");
785 case ET_CORE: return _("Core file");
786
787 default:
788 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
789 sprintf (buff, _("Processor Specific: (%x)"), e_type);
790 else
791 sprintf (buff, _("<unknown>: %x"), e_type);
792 return buff;
793 }
794 }
795
796 static char *
797 get_machine_name (e_machine)
798 unsigned e_machine;
799 {
800 static char buff [32];
801
802 switch (e_machine)
803 {
804 case EM_NONE: return _("None");
805 case EM_M32: return "WE32100";
806 case EM_SPARC: return "Sparc";
807 case EM_386: return "80386";
808 case EM_68K: return "MC68000";
809 case EM_88K: return "MC88000";
810 case EM_486: return "Intel 80486";
811 case EM_860: return "Intel 80860";
812 case EM_MIPS: return "MIPS R3000 big-endian";
813 case EM_S370: return "Amdahl";
814 case EM_MIPS_RS4_BE: return "MIPS R400 big-endian";
815 case EM_PARISC: return "HPPA";
816 case EM_SPARC32PLUS: return "Sparc v8+" ;
817 case EM_PPC: return "PowerPC";
818 case EM_SPARCV9: return "Sparc v9";
819 case EM_ARM: return "ARM";
820 case EM_SH: return "Hitachi SH";
821 case EM_ALPHA: return "Alpha";
822 case EM_CYGNUS_D10V: return "d10v";
823 /* start-sanitize-d30v */
824 case EM_CYGNUS_D30V: return "d30v";
825 /* end-sanitize-d30v */
826 case EM_CYGNUS_M32R: return "M32r";
827 case EM_CYGNUS_V850: return "v850";
828 case EM_CYGNUS_MN10300: return "mn10300";
829 case EM_CYGNUS_MN10200: return "mn10200";
830
831 default:
832 sprintf (buff, _("<unknown>: %x"), e_machine);
833 return buff;
834 }
835 }
836
837 static char *
838 get_machine_flags (e_flags, e_machine)
839 unsigned e_flags;
840 unsigned e_machine;
841 {
842 static char buf [1024];
843
844 buf[0] = '\0';
845 if (e_flags)
846 {
847 switch (e_machine)
848 {
849 default:
850 break;
851
852 case EM_PPC:
853 if (e_flags & EF_PPC_EMB)
854 strcat (buf, ", emb");
855
856 if (e_flags & EF_PPC_RELOCATABLE)
857 strcat (buf, ", relocatable");
858
859 if (e_flags & EF_PPC_RELOCATABLE_LIB)
860 strcat (buf, ", relocatable-lib");
861 break;
862
863 case EM_CYGNUS_M32R:
864 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
865 strcat (buf, ", m32r");
866
867 /* start-sanitize-m32rx */
868 #ifdef E_M32RX_ARCH
869 if ((e_flags & EF_M32R_ARCH) == E_M32RX_ARCH)
870 strcat (buf, ", m32rx");
871 #endif
872 /* end-sanitize-m32rx */
873 break;
874
875 case EM_MIPS:
876 case EM_MIPS_RS4_BE:
877 if (e_flags & EF_MIPS_NOREORDER)
878 strcat (buf, ", noreorder");
879
880 if (e_flags & EF_MIPS_PIC)
881 strcat (buf, ", pic");
882
883 if (e_flags & EF_MIPS_CPIC)
884 strcat (buf, ", cpic");
885
886 if (e_flags & EF_MIPS_ABI2)
887 strcat (buf, ", abi2");
888
889 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
890 strcat (buf, ", mips1");
891
892 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
893 strcat (buf, ", mips2");
894
895 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
896 strcat (buf, ", mips3");
897
898 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
899 strcat (buf, ", mips4");
900 break;
901 }
902 }
903
904 return buf;
905 }
906
907 static char *
908 get_machine_data (e_data)
909 unsigned e_data;
910 {
911 static char buff [32];
912
913 switch (e_data)
914 {
915 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
916 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
917 default:
918 sprintf (buff, _("<unknown>: %x"), e_data);
919 return buff;
920 }
921 }
922
923 static char *
924 get_segment_type (p_type)
925 unsigned long p_type;
926 {
927 static char buff [32];
928
929 switch (p_type)
930 {
931 case PT_NULL: return _("Unused");
932 case PT_LOAD: return _("Loadable");
933 case PT_DYNAMIC: return _("Dynamic link info");
934 case PT_INTERP: return _("Interpreter");
935 case PT_NOTE: return _("Auxillary Info");
936 case PT_SHLIB: return _("Shared Library");
937 case PT_PHDR: return _("Program Headers");
938
939 default:
940 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
941 return _("processor specific");
942 else
943 {
944 sprintf (buff, _("<unknown>: %x"), p_type);
945 return buff;
946 }
947 }
948 }
949
950 static char *
951 get_section_type_name (sh_type)
952 unsigned int sh_type;
953 {
954 static char buff [32];
955
956 switch (sh_type)
957 {
958 case SHT_NULL: return _("Unused");
959 case SHT_PROGBITS: return _("Program data");
960 case SHT_SYMTAB: return _("Symbol table");
961 case SHT_STRTAB: return _("String table");
962 case SHT_RELA: return _("Relocs, addends");
963 case SHT_HASH: return _("Symbol hash table");
964 case SHT_DYNAMIC: return _("Dynamic linking info");
965 case SHT_NOTE: return _("Notes");
966 case SHT_NOBITS: return _("Space, no data");
967 case SHT_REL: return _("Relocs, no addends");
968 case SHT_SHLIB: return _("Shared Library info");
969 case SHT_DYNSYM: return _("Dynamic linker symbols");
970 case SHT_GNU_verdef: return _("Version definition");
971 case SHT_GNU_verneed: return _("Version needs");
972 case SHT_GNU_versym: return _("Version symbols");
973 case 0x6ffffff0: return "VERSYM";
974 case 0x6ffffffc: return "VERDEF";
975 case 0x7ffffffd: return "AUXILIARY";
976 case 0x7fffffff: return "FILTER";
977
978 default:
979 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
980 return _("processor specific");
981 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
982 return _("application specific");
983 else
984 {
985 sprintf (buff, _("<unknown>: %x"), sh_type);
986 return buff;
987 }
988 }
989 }
990
991 struct option options [] =
992 {
993 {"all", no_argument, 0, 'a'},
994 {"file-header", no_argument, 0, 'h'},
995 {"program-headers", no_argument, 0, 'l'},
996 {"segments", no_argument, 0, 'l'},
997 {"sections", no_argument, 0, 'S'},
998 {"symbols", no_argument, 0, 's'},
999 {"relocs", no_argument, 0, 'r'},
1000 {"dynamic", no_argument, 0, 'd'},
1001 {"version-info", no_argument, 0, 'V'},
1002 {"use-dynamic", no_argument, 0, 'D'},
1003
1004 {"hex-dump", required_argument, 0, 'x'},
1005 #ifdef SUPPORT_DISASSEMBLY
1006 {"instruction-dump", required_argument, 0, 'i'},
1007 #endif
1008
1009 {"version", no_argument, 0, 'v'},
1010 {"help", no_argument, 0, 'H'},
1011
1012 {0, no_argument, 0, 0}
1013 };
1014
1015 static void
1016 usage ()
1017 {
1018 fprintf (stderr, _("Usage: readelf {options} elf-file(s)\n"));
1019 fprintf (stderr, _(" Options are:\n"));
1020 fprintf (stderr, _(" -a or --all Display all the information\n"));
1021 fprintf (stderr, _(" -h or --file-header Display the ELF file header\n"));
1022 fprintf (stderr, _(" -l or --program-headers or --segments\n"));
1023 fprintf (stderr, _(" Display the program headers\n"));
1024 fprintf (stderr, _(" -S or --sections Display the sections' headers\n"));
1025 fprintf (stderr, _(" -s or --symbols Display the symbol table\n"));
1026 fprintf (stderr, _(" -r or --relocs Display the relocations (if present)\n"));
1027 fprintf (stderr, _(" -d or --dynamic Display the dynamic section (if present)\n"));
1028 fprintf (stderr, _(" -V or --version-info Display the version sections (if present)\n"));
1029 fprintf (stderr, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1030 fprintf (stderr, _(" -x <number> or --hex-dump=<number>\n"));
1031 fprintf (stderr, _(" Dump the contents of section <number>\n"));
1032 #ifdef SUPPORT_DISASSEMBLY
1033 fprintf (stderr, _(" -i <number> or --instruction-dump=<number>\n"));
1034 fprintf (stderr, _(" Disassemble the contents of section <number>\n"));
1035 #endif
1036 fprintf (stderr, _(" -v or --version Display the version number of readelf\n"));
1037 fprintf (stderr, _(" -H or --help Display this information\n"));
1038
1039 exit (0);
1040 }
1041
1042 static void
1043 parse_args (argc, argv)
1044 int argc;
1045 char ** argv;
1046 {
1047 char c;
1048
1049 if (argc < 2)
1050 usage ();
1051
1052 while ((c = getopt_long
1053 (argc, argv, "rsahldSDx:i:vV", options, NULL)) != EOF)
1054 {
1055 char * cp;
1056 int section;
1057
1058 switch (c)
1059 {
1060 case 'H':
1061 usage ();
1062 break;
1063
1064 case 'a':
1065 do_syms++;
1066 do_reloc++;
1067 do_dynamic++;
1068 do_header++;
1069 do_section++;
1070 do_load++;
1071 do_version++;
1072 break;
1073 case 'D':
1074 do_using_dynamic++;
1075 break;
1076 case 'r':
1077 do_reloc++;
1078 break;
1079 case 'h':
1080 do_header++;
1081 break;
1082 case 'l':
1083 do_load++;
1084 break;
1085 case 's':
1086 do_syms++;
1087 break;
1088 case 'S':
1089 do_section++;
1090 break;
1091 case 'd':
1092 do_dynamic++;
1093 break;
1094 case 'x':
1095 do_dump ++;
1096 section = strtoul (optarg, & cp, 0);
1097 if (! * cp && section >= 0 && section < NUM_DUMP_SECTS)
1098 {
1099 dump_sects [section] |= HEX_DUMP;
1100 break;
1101 }
1102 goto oops;
1103 #ifdef SUPPORT_DISASSEMBLY
1104 case 'i':
1105 do_dump ++;
1106 section = strtoul (optarg, & cp, 0);
1107 if (! * cp && section >= 0 && section < NUM_DUMP_SECTS)
1108 {
1109 dump_sects [section] |= DISASS_DUMP;
1110 break;
1111 }
1112 goto oops;
1113 #endif
1114 case 'v':
1115 print_version (program_name);
1116 break;
1117 case 'V':
1118 do_version ++;
1119 break;
1120 default:
1121 oops:
1122 /* xgettext:c-format */
1123 error (_("Invalid option '-%c'\n"), c);
1124 /* Drop through. */
1125 case '?':
1126 usage ();
1127 }
1128 }
1129
1130 if (!do_dynamic && !do_syms && !do_reloc && !do_section
1131 && !do_load && !do_header && !do_dump && !do_version)
1132 usage ();
1133 else if (argc < 3)
1134 warn (_("Nothing to do.\n"));
1135 }
1136
1137 static int
1138 process_elf_header ()
1139 {
1140 if ( epnt->e_ident [EI_MAG0] != ELFMAG0
1141 || epnt->e_ident [EI_MAG1] != ELFMAG1
1142 || epnt->e_ident [EI_MAG2] != ELFMAG2
1143 || epnt->e_ident [EI_MAG3] != ELFMAG3)
1144 {
1145 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1146 return 0;
1147 }
1148
1149 if (epnt->e_ident [EI_CLASS] != ELFCLASS32)
1150 {
1151 error (_("Not a 32 bit ELF file\n"));
1152 return 0;
1153 }
1154
1155 if (epnt->e_ident [EI_DATA] != expected_endian)
1156 must_swap = 1;
1157
1158 if (must_swap)
1159 {
1160 Elf_Ehdr * new_header = malloc (sizeof (* new_header));
1161
1162 if (new_header == NULL)
1163 {
1164 error (_("out of memory\n"));
1165 return 0;
1166 }
1167
1168 memcpy (new_header, epnt, sizeof (* new_header));
1169
1170 BYTE_SWAP (epnt, e_type);
1171 BYTE_SWAP (epnt, e_machine);
1172 BYTE_SWAP (epnt, e_version);
1173 BYTE_SWAP (epnt, e_entry);
1174 BYTE_SWAP (epnt, e_phoff);
1175 BYTE_SWAP (epnt, e_shoff);
1176 BYTE_SWAP (epnt, e_flags);
1177 BYTE_SWAP (epnt, e_ehsize);
1178 BYTE_SWAP (epnt, e_phentsize);
1179 BYTE_SWAP (epnt, e_phnum);
1180 BYTE_SWAP (epnt, e_shentsize);
1181 BYTE_SWAP (epnt, e_shnum);
1182 BYTE_SWAP (epnt, e_shstrndx);
1183
1184 epnt = new_header;
1185 }
1186
1187 if (do_header)
1188 {
1189 int i;
1190
1191 printf (_("ELF Header....\n"));
1192 printf (_(" Magic: "));
1193 for (i = 0; i < EI_NIDENT; i ++)
1194 printf ("%2.2x ", epnt->e_ident [i]);
1195 printf ("\n");
1196 printf (_(" Type: %s\n"), get_file_type (epnt->e_type));
1197 printf (_(" Machine: %s\n"), get_machine_name (epnt->e_machine));
1198 printf (_(" Version: 0x%lx\n"), (unsigned long)epnt->e_version);
1199 printf (_(" Data: %s\n"), get_machine_data (epnt->e_ident [EI_DATA]));
1200 printf (_(" Entry point address: 0x%lx\n"), (unsigned long)epnt->e_entry);
1201 printf (_(" Start of program headers: %ld (bytes into file)\n"), (long)epnt->e_phoff);
1202 printf (_(" Start of section headers: %ld (bytes into file)\n"), (long)epnt->e_shoff);
1203 printf (_(" Flags: 0x%lx%s\n"), (unsigned long)epnt->e_flags,
1204 get_machine_flags (epnt->e_flags, epnt->e_machine));
1205 printf (_(" Size of this header: %ld (bytes)\n"), (long)epnt->e_ehsize);
1206 printf (_(" Size of program headers: %ld (bytes)\n"), (long)epnt->e_phentsize);
1207 printf (_(" Number of program headers: %ld\n"), (long)epnt->e_phnum);
1208 printf (_(" Size of section headers: %ld (bytes)\n"), (long)epnt->e_shentsize);
1209 printf (_(" Number of section headers: %ld\n"), (long)epnt->e_shnum);
1210 printf (_(" Section header string table index: %ld\n"), (long)epnt->e_shstrndx);
1211 }
1212
1213 return 1;
1214 }
1215
1216
1217 static void
1218 process_program_headers ()
1219 {
1220 Elf_Phdr * elf_segments;
1221 Elf_Phdr * ppnt;
1222 int i;
1223
1224 if (epnt->e_phnum == 0)
1225 {
1226 if (do_load)
1227 printf (_("\nThere are no program headers in this file\n"));
1228 return;
1229 }
1230
1231 if (do_load && !do_header)
1232 {
1233 printf (_("\nElf file is %s\n"), get_file_type (epnt->e_type));
1234 printf (_("Entry point 0x%x\n"), epnt->e_entry);
1235 printf (_("There are %d program headers, starting at offset %x:\n"),
1236 epnt->e_phnum, epnt->e_phoff);
1237 }
1238
1239 if (must_swap)
1240 {
1241 Elf_Phdr * new_header = malloc (sizeof (* new_header) * epnt->e_phnum);
1242
1243 if (new_header == NULL)
1244 {
1245 error (_("out of memory\n"));
1246 return;
1247 }
1248
1249 memcpy (new_header, & header [epnt->e_phoff],
1250 sizeof (* new_header) * epnt->e_phnum);
1251
1252 elf_segments = ppnt = new_header;
1253
1254 for (i = 0; i < epnt->e_phnum; i++)
1255 {
1256 BYTE_SWAP (ppnt + i, p_type);
1257 BYTE_SWAP (ppnt + i, p_flags);
1258 BYTE_SWAP (ppnt + i, p_offset);
1259 BYTE_SWAP (ppnt + i, p_vaddr);
1260 BYTE_SWAP (ppnt + i, p_paddr);
1261 BYTE_SWAP (ppnt + i, p_filesz);
1262 BYTE_SWAP (ppnt + i, p_memsz);
1263 BYTE_SWAP (ppnt + i, p_align);
1264
1265 new_header ++;
1266 }
1267 }
1268 else
1269 {
1270 ppnt = (Elf_Phdr *) & header [epnt->e_phoff];
1271 elf_segments = NULL;
1272 }
1273
1274 if (do_load)
1275 {
1276 printf (_("\nProgram Header%s....\n"), epnt->e_phnum > 1 ? "s" : "");
1277 printf (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1278 }
1279
1280 loadaddr = -1;
1281 dynamic_addr = 0;
1282
1283 for (i = 0; i < epnt->e_phnum; i++)
1284 {
1285 if (loadaddr == -1 && ppnt->p_type == PT_LOAD)
1286 loadaddr = (ppnt->p_vaddr & 0xfffff000)
1287 - (ppnt->p_offset & 0xfffff000);
1288
1289 if (do_load)
1290 {
1291 printf (" %-10s ", get_segment_type (ppnt->p_type));
1292 printf ("0x%5.5lx ",ppnt->p_offset);
1293 printf ("0x%8.8lx ",ppnt->p_vaddr);
1294 printf ("0x%8.8lx ",ppnt->p_paddr);
1295 printf ("0x%5.5lx 0x%5.5lx ",ppnt->p_filesz, ppnt->p_memsz);
1296 printf ("%c%c%c ",
1297 (ppnt->p_flags & 4 ? 'R' : ' '),
1298 (ppnt->p_flags & 2 ? 'W' : ' '),
1299 (ppnt->p_flags & 1 ? 'E' : ' '));
1300 printf ("%#lx", ppnt->p_align);
1301 }
1302
1303 if (ppnt->p_type == PT_DYNAMIC)
1304 {
1305 if (dynamic_addr)
1306 error (_("more than one dynamic section\n"));
1307
1308 dynamic_addr = ppnt->p_offset;
1309 dynamic_size = ppnt->p_filesz;
1310 }
1311
1312 if (ppnt->p_type == PT_INTERP)
1313 {
1314 if (do_load)
1315 printf (_("\nRequesting program interpreter [%s]"),
1316 & header [ppnt->p_offset]);
1317 pint = strdup (& header [ppnt->p_offset]);
1318 }
1319
1320 if (do_load)
1321 putc ('\n', stdout);
1322
1323 ppnt ++;
1324 }
1325
1326 if (do_load)
1327 {
1328 printf (_("\n Section to Segment mapping:\n"));
1329 printf (_(" Segment Sections...\n"));
1330
1331 if (elf_segments)
1332 ppnt = elf_segments;
1333 else
1334 ppnt = (Elf_Phdr *) & header [epnt->e_phoff];
1335
1336 for (i = 0; i < epnt->e_phnum; i++, ppnt++)
1337 {
1338 int j;
1339 Elf_Shdr * spnt;
1340
1341 printf (" %2.2d ", i);
1342
1343 spnt = (Elf_Shdr *) & header [epnt->e_shoff];
1344
1345 if (must_swap)
1346 {
1347 lastmapped = SWAP4 (spnt[epnt->e_shstrndx].sh_offset);
1348
1349 for (j = 0; j < epnt->e_shnum; j++)
1350 {
1351 bfd_vma addr;
1352 bfd_size_type size;
1353 unsigned int name;
1354
1355 addr = SWAP4 (spnt[j].sh_addr);
1356 size = SWAP4 (spnt[j].sh_size);
1357 name = SWAP4 (spnt[j].sh_name);
1358
1359 if (size > 0
1360 && (addr >= ppnt->p_vaddr)
1361 && (addr + size) <= (ppnt->p_vaddr + ppnt->p_memsz))
1362 printf ("%s ", header + lastmapped + name);
1363 }
1364 }
1365 else
1366 {
1367 lastmapped = spnt[epnt->e_shstrndx].sh_offset;
1368
1369 for (j = 0; j < epnt->e_shnum; j++, spnt++)
1370 {
1371 if (spnt->sh_size > 0
1372 && (spnt->sh_addr >= ppnt->p_vaddr)
1373 && (spnt->sh_addr + spnt->sh_size)
1374 <= (ppnt->p_vaddr + ppnt->p_memsz))
1375 printf ("%s ", SECTION_NAME (spnt));
1376 }
1377 }
1378
1379 putc ('\n',stdout);
1380 }
1381 }
1382
1383 if (elf_segments)
1384 free (elf_segments);
1385 }
1386
1387
1388 static void
1389 process_section_headers ()
1390 {
1391 Elf_Shdr * spnt;
1392 int i;
1393
1394 if (must_swap)
1395 {
1396 Elf_Shdr * new_header = malloc (sizeof (* new_header) * epnt->e_shnum);
1397
1398 if (new_header == NULL)
1399 {
1400 error (_("out of memory\n"));
1401 return;
1402 }
1403
1404 memcpy (new_header, & header [epnt->e_shoff],
1405 sizeof (* new_header) * epnt->e_shnum);
1406
1407 elf_sections = spnt = new_header;
1408
1409 for (i = 0; i < epnt->e_shnum; i++)
1410 {
1411 BYTE_SWAP (spnt + i, sh_name);
1412 BYTE_SWAP (spnt + i, sh_type);
1413 BYTE_SWAP (spnt + i, sh_flags);
1414 BYTE_SWAP (spnt + i, sh_addr);
1415 BYTE_SWAP (spnt + i, sh_offset);
1416 BYTE_SWAP (spnt + i, sh_size);
1417 BYTE_SWAP (spnt + i, sh_link);
1418 BYTE_SWAP (spnt + i, sh_info);
1419 BYTE_SWAP (spnt + i, sh_addralign);
1420 BYTE_SWAP (spnt + i, sh_entsize);
1421
1422 new_header ++;
1423 }
1424 }
1425 else
1426 {
1427 elf_sections = spnt = (Elf_Shdr *) & header [epnt->e_shoff];
1428 }
1429
1430 spnt += epnt->e_shstrndx;
1431 lastmapped = spnt->sh_offset;
1432 spnt = elf_sections;
1433
1434 if (! do_section || (epnt->e_shnum == 0))
1435 return;
1436
1437 if (! do_header)
1438 printf (_("There are %d section headers, starting at offset %x:\n"),
1439 epnt->e_shnum, epnt->e_shoff);
1440
1441 printf (_("\nSection Header%s....\n"), epnt->e_shnum > 1 ? "s" : "");
1442 printf (_(" [Nr] Name Type Addr Off Size ES Flg Lk In Al\n"));
1443
1444 for (i = 0; i < epnt->e_shnum; i++)
1445 {
1446 printf (" [%2d] %-17s", i, SECTION_NAME (spnt));
1447
1448 printf (" %-15s ",get_section_type_name (spnt->sh_type));
1449 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1450 spnt->sh_addr,
1451 spnt->sh_offset,
1452 spnt->sh_size,
1453 spnt->sh_entsize);
1454
1455 printf (" %c%c%c %2ld %2lx %ld \n",
1456 (spnt->sh_flags & 1 ? 'W' : ' '),
1457 (spnt->sh_flags & 2 ? 'A' : ' '),
1458 (spnt->sh_flags & 4 ? 'X' : ' '),
1459 spnt->sh_link,
1460 spnt->sh_info,
1461 spnt->sh_addralign);
1462 spnt ++;
1463 }
1464 }
1465
1466 /* Parse the dynamic segment */
1467 static void
1468 process_dynamic_segment ()
1469 {
1470 Elf_Dyn * elf_dynamic;
1471 unsigned int i;
1472
1473 dynamic_size = dynamic_size / sizeof (Elf_Dyn);
1474
1475 if (must_swap)
1476 {
1477 Elf_Dyn * new_header = malloc (sizeof (* new_header) * dynamic_size);
1478
1479 if (new_header == NULL)
1480 {
1481 error (_("out of memory\n"));
1482 return;
1483 }
1484
1485 memcpy (new_header, & header [dynamic_addr],
1486 sizeof (* new_header) * dynamic_size);
1487
1488 elf_dynamic = dpnt = new_header;
1489
1490 for (i = 0; i < dynamic_size; i++)
1491 {
1492 BYTE_SWAP (dpnt + i, d_tag);
1493 BYTE_SWAP (dpnt + i, d_un.d_ptr);
1494
1495 new_header ++;
1496 }
1497 }
1498 else
1499 {
1500 dpnt = (Elf_Dyn *) & header [dynamic_addr];
1501 elf_dynamic = NULL;
1502 }
1503
1504 /* Find symtab. */
1505 for (i = 0; i < dynamic_size; ++i, ++dpnt)
1506 if (dpnt->d_tag == DT_SYMTAB)
1507 {
1508 dynamic_info [DT_SYMTAB] = dpnt->d_un.d_val;
1509 symtab = (Elf_Sym *) (header - loadaddr
1510 + dynamic_info[DT_SYMTAB]);
1511 }
1512 else if (dpnt->d_tag == DT_STRTAB)
1513 {
1514 dynamic_info [DT_STRTAB] = dpnt->d_un.d_val;
1515 strtab = (char *) (header - loadaddr + dynamic_info[DT_STRTAB]);
1516 }
1517
1518 if (do_dynamic && dynamic_addr)
1519 {
1520 printf (_("\n Dynamic section data: %x, %d entries\n"),
1521 dynamic_addr, dynamic_size );
1522 }
1523
1524 for (i = 0; i < dynamic_size; i++)
1525 {
1526 if (do_dynamic)
1527 printf (_(" Tag: %#10x: "), dpnt->d_tag);
1528
1529 switch (dpnt->d_tag)
1530 {
1531 case DT_AUXILIARY:
1532 case DT_FILTER:
1533 if (do_dynamic)
1534 {
1535 printf ("(%-11s)", filtertype [DT_FILTER - dpnt->d_tag]);
1536
1537 if (dynamic_info [DT_STRTAB])
1538 {
1539 if (dpnt->d_tag == DT_AUXILIARY)
1540 printf (_("Auxiliary library"));
1541 else
1542 printf (_("Filter library"));
1543
1544 printf (": [%s]\n", (dpnt->d_un.d_val + strtab));
1545 }
1546 else
1547 printf (_("Value %x\n"), dpnt->d_un.d_val);
1548 }
1549 break;
1550
1551 case DT_NULL :
1552 case DT_NEEDED :
1553 case DT_PLTRELSZ:
1554 case DT_PLTGOT :
1555 case DT_HASH :
1556 case DT_STRTAB :
1557 case DT_SYMTAB :
1558 case DT_RELA :
1559 case DT_RELASZ :
1560 case DT_RELAENT :
1561 case DT_STRSZ :
1562 case DT_SYMENT :
1563 case DT_INIT :
1564 case DT_FINI :
1565 case DT_SONAME :
1566 case DT_RPATH :
1567 case DT_SYMBOLIC:
1568 case DT_REL :
1569 case DT_RELSZ :
1570 case DT_RELENT :
1571 case DT_PLTREL :
1572 case DT_DEBUG :
1573 case DT_TEXTREL :
1574 case DT_JMPREL :
1575 dynamic_info [dpnt->d_tag] = dpnt->d_un.d_val;
1576
1577 if (do_dynamic)
1578 {
1579 printf ("(%-11s)", dyntype [dpnt->d_tag]);
1580
1581 if (dynamic_info [DT_STRTAB])
1582 {
1583 switch (dpnt->d_tag)
1584 {
1585 case DT_NEEDED:
1586 printf (_("Shared library: [%s]\n"),
1587 (dpnt->d_un.d_val + strtab));
1588
1589 if (strcmp (dpnt->d_un.d_val + strtab, pint))
1590 printf ("\n");
1591 else
1592 printf (_(" program interpreter\n"));
1593 break;
1594
1595 case DT_SONAME:
1596 printf (_("Library soname: [%s]\n"),
1597 (dpnt->d_un.d_val + strtab));
1598 break;
1599
1600 case DT_RPATH:
1601 printf (_("Library rpath: [%s]\n"),
1602 (dpnt->d_un.d_val + strtab));
1603 break;
1604
1605 default:
1606 printf (_("Value %x\n"), dpnt->d_un.d_val);
1607 }
1608 }
1609 else
1610 printf (_("Value %x\n"), dpnt->d_un.d_val);
1611 }
1612 break;
1613
1614 default:
1615 if ((dpnt->d_tag >= DT_VERSYM) && (dpnt->d_tag <= DT_VERNEEDNUM))
1616 {
1617 version_info [DT_VERSIONTAGIDX (dpnt->d_tag)] = dpnt->d_un.d_val;
1618
1619 if (do_dynamic)
1620 printf (_("(%-11s) Value %#x\n"),
1621 vertype [DT_VERSIONTAGIDX (dpnt->d_tag)],
1622 dpnt->d_un.d_ptr);
1623 }
1624 else
1625 warn (_("<Invalid> Value %#x\n"), dpnt->d_un.d_ptr);
1626 break;
1627 }
1628
1629 dpnt ++;
1630 }
1631
1632 if (do_reloc)
1633 {
1634 if (do_using_dynamic)
1635 {
1636 if (dynamic_info [DT_REL])
1637 {
1638 rpnt = (Elf_Rel *) (header + dynamic_info [DT_REL] - loadaddr);
1639 rel_size = dynamic_info [DT_RELSZ];
1640 if (rel_size)
1641 {
1642 printf (_("\nRelocation section data: %x %x\n"),
1643 dynamic_info[DT_REL], rel_size);
1644 dump_relocations (rpnt, rel_size);
1645 }
1646 else
1647 printf (_("\nNo Relocations in this file\n"));
1648 }
1649
1650 if (dynamic_info[DT_RELA])
1651 {
1652 rpnt = (Elf_Rel *) (header + dynamic_info[DT_RELA] - loadaddr);
1653 rel_size = dynamic_info[DT_RELASZ];
1654 if (rel_size)
1655 {
1656 printf (_("\nRelocation section data: %x %x\n"),
1657 dynamic_info[DT_RELA], rel_size);
1658 dump_relocations (rpnt, rel_size);
1659 }
1660 else
1661 printf (_("\nNo Relocations in this file\n"));
1662 }
1663
1664 if (dynamic_info[DT_JMPREL])
1665 {
1666 rpnt = (Elf_Rel *) (header + dynamic_info[DT_JMPREL]
1667 - loadaddr);
1668 rel_size = dynamic_info[DT_PLTRELSZ];
1669 if (rel_size)
1670 {
1671 printf (_("\nJumptable Relocation section data: %x %x\n"),
1672 dynamic_info[DT_JMPREL], rel_size);
1673 dump_relocations (rpnt, rel_size);
1674 }
1675 else
1676 printf (_("\nNo Relocations in this file\n"));
1677 }
1678 }
1679 else
1680 {
1681 Elf_Shdr * spnt;
1682
1683 spnt = elf_sections;
1684
1685 for (i = 0; i < epnt->e_shnum; i++, spnt++)
1686 {
1687 Elf_Shdr * symsec;
1688
1689
1690 if (spnt->sh_type != SHT_RELA && spnt->sh_type != SHT_REL)
1691 continue;
1692
1693 rpnt = (Elf_Rel *) (header + spnt->sh_offset);
1694
1695 rel_size = spnt->sh_size;
1696
1697 if (rel_size)
1698 {
1699 printf (_("\nRelocation section data: %s (%#x entries)\n"),
1700 SECTION_NAME (spnt), rel_size / spnt->sh_entsize);
1701
1702 symsec = & elf_sections [spnt->sh_link];
1703 symtab = (Elf_Sym *) (header + symsec->sh_offset);
1704 strtab = (char *) (header
1705 + elf_sections [symsec->sh_link].sh_offset);
1706
1707 dump_relocations (rpnt, rel_size);
1708 }
1709 else
1710 printf (_("\nNo Relocations in this file\n"));
1711 }
1712 }
1713 }
1714
1715 if (elf_dynamic)
1716 free (elf_dynamic);
1717 }
1718
1719 /* Dump the symbol table */
1720 static void
1721 process_symbol_table ()
1722 {
1723 char * pnt;
1724 int i;
1725 Elf_Shdr * spnt;
1726
1727 if (! do_syms)
1728 return;
1729
1730 if (dynamic_info [DT_HASH] && do_using_dynamic)
1731 {
1732 int nbucket;
1733 int nchain;
1734 int * elf_buckets;
1735 int * chains;
1736 int hn;
1737 int si;
1738 int * hash_addr;
1739
1740 hash_addr = (int *) (dynamic_info [DT_HASH] + header - loadaddr);
1741
1742 nbucket = *hash_addr++;
1743 nchain = *hash_addr++;
1744 elf_buckets = hash_addr;
1745 hash_addr += nbucket;
1746 chains = hash_addr;
1747
1748 printf (_("\n Symbol table for image\n"));
1749 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
1750
1751 for (hn = 0; hn < nbucket; hn++)
1752 {
1753 if (! elf_buckets [hn])
1754 continue;
1755
1756 for (si = elf_buckets[hn]; si; si = chains[si])
1757 {
1758 pnt = strtab + symtab[si].st_name;
1759
1760 printf ("%3d %3d: %8lx %5ld %6s %6s %2d ", si, hn,
1761 symtab[si].st_value,
1762 symtab[si].st_size,
1763 sttinfo [ELF_ST_TYPE (symtab[si].st_info)],
1764 stbinfo [ELF_ST_BIND (symtab[si].st_info)],
1765 symtab[si].st_other);
1766
1767 if (symtab[si].st_shndx == 0)
1768 printf ("UND");
1769 else if ((symtab[si].st_shndx & 0xffff) == 0xfff1)
1770 printf ("ABS");
1771 else if ((symtab[si].st_shndx & 0xffff) == 0xfff2)
1772 printf ("COM");
1773 else
1774 printf ("%3d", symtab[si].st_shndx);
1775 printf (" %s\n", pnt);
1776 }
1777 }
1778 }
1779 else if (!do_using_dynamic)
1780 {
1781 int i;
1782 unsigned short * vers_addr;
1783
1784 spnt = elf_sections;
1785 vers_addr = (short *) (version_info [DT_VERNEEDNUM - DT_VERSYM]
1786 + header - loadaddr);
1787
1788 for (i = 0; i < epnt->e_shnum; i++, spnt++)
1789 {
1790 unsigned int si;
1791
1792 if (spnt->sh_type != SHT_SYMTAB && spnt->sh_type != SHT_DYNSYM)
1793 continue;
1794
1795 printf (_("\nSymbol data for: %s\n"), SECTION_NAME (spnt));
1796 printf (_(" Num: Value Size Type Bind Ot Ndx Name\n"));
1797
1798 symtab = (Elf_Sym *) (header + spnt->sh_offset);
1799 strtab = (char *) (header + elf_sections [spnt->sh_link].sh_offset);
1800
1801 for (si = 0; si < spnt->sh_size / spnt->sh_entsize; si++)
1802 {
1803 Elf_Sym ssym;
1804 Elf_Sym * psym;
1805 Elf_Sym * new_header;
1806
1807 psym = symtab + si;
1808
1809 if (must_swap)
1810 {
1811 ssym = * psym;
1812
1813 new_header = & ssym;
1814
1815 BYTE_SWAP (psym, st_name);
1816 BYTE_SWAP (psym, st_value);
1817 BYTE_SWAP (psym, st_size);
1818 BYTE_SWAP (psym, st_shndx);
1819
1820 psym = new_header;
1821 }
1822
1823 pnt = strtab + psym->st_name;
1824
1825 printf (" %3d: %8lx %5ld %-7s %-6s %2d ", si,
1826 psym->st_value,
1827 psym->st_size,
1828 sttinfo [ELF_ST_TYPE (psym->st_info)],
1829 stbinfo [ELF_ST_BIND (psym->st_info)],
1830 psym->st_other);
1831
1832 if (psym->st_shndx == 0)
1833 printf ("UND");
1834 else if ((psym->st_shndx & 0xffff) == 0xfff1)
1835 printf ("ABS");
1836 else if ((psym->st_shndx & 0xffff) == 0xfff2)
1837 printf ("COM");
1838 else
1839 printf ("%3d", psym->st_shndx);
1840 printf (" %s", pnt);
1841
1842 if (spnt->sh_type == SHT_DYNSYM &&
1843 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0 &&
1844 ((vers_addr[si] & 0x8000) || vers_addr[si] > 1))
1845 {
1846 Elf_Vernaux * a;
1847
1848 if (elf_sections [psym->st_shndx].sh_type == SHT_NOBITS
1849 || psym->st_shndx == SHN_UNDEF)
1850 {
1851 Elf_Verneed * v;
1852
1853 /* We must test both. */
1854 v = (Elf_Verneed *)
1855 (version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
1856 + header - loadaddr);
1857
1858 for (;;)
1859 {
1860 a = (Elf_Vernaux *)((char *)v + v->vn_aux);
1861
1862 while (a->vna_other != vers_addr[si]
1863 && a->vna_next != 0)
1864 a = (Elf_Vernaux *)((char *)a + a->vna_next);
1865
1866 if (a->vna_other == vers_addr[si])
1867 break;
1868
1869 if (v->vn_next == 0)
1870 {
1871 if (elf_sections [psym->st_shndx].sh_type
1872 != SHT_NOBITS)
1873 error (_("bad dynamic symbol"));
1874
1875 a = NULL;
1876 break;
1877 }
1878
1879 v = (Elf_Verneed *)((char *)v + v->vn_next);
1880 }
1881
1882 if (a != NULL)
1883 printf ("@%s (%d)", strtab + a->vna_name, a->vna_other);
1884 }
1885 else if ((elf_sections [psym->st_shndx].sh_type
1886 == SHT_NOBITS && a == NULL)
1887 || psym->st_shndx != SHN_UNDEF)
1888 {
1889 Elf_Verdef * v;
1890 Elf_Verdaux * b;
1891
1892 v = (Elf_Verdef *)
1893 (version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
1894 + header - loadaddr);
1895
1896 if (vers_addr[si] == 0x8001)
1897 pnt = "";
1898 else
1899 {
1900 while (v->vd_ndx != (vers_addr [si] & 0x7fff))
1901 v = (Elf_Verdef *)((char *)v + v->vd_next);
1902
1903 b = (Elf_Verdaux *) ((char *)v + v->vd_aux);
1904
1905 if (psym->st_name != b->vda_name)
1906 pnt = strtab + b->vda_name;
1907 else
1908 pnt = NULL;
1909 }
1910
1911 if (pnt)
1912 printf ((vers_addr [si] & 0x8000)
1913 ? "@%s" : "@@%s", pnt);
1914 }
1915 }
1916
1917 puts ("");
1918 }
1919 }
1920 }
1921
1922 if (! do_version)
1923 return;
1924
1925 spnt = elf_sections;
1926
1927 for (i = 0; i < epnt->e_shnum; i++, spnt++)
1928 {
1929 if (spnt->sh_type == SHT_GNU_verdef)
1930 {
1931 Elf_Shdr * dspnt = &elf_sections[spnt->sh_link];
1932 unsigned int idx;
1933 unsigned int cnt;
1934
1935 strtab = (char *) (header - loadaddr + dynamic_info[DT_STRTAB]);
1936
1937 printf (_("\n Version definitions:%s (%#0x entries)\n"),
1938 SECTION_NAME(spnt), spnt->sh_info);
1939 printf (_("Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
1940 spnt->sh_addr, spnt->sh_offset, spnt->sh_link,
1941 SECTION_NAME(dspnt));
1942
1943 for (idx = cnt = 0; cnt < spnt->sh_info; ++cnt)
1944 {
1945 Elf_Verdef * ent = (Elf_Verdef *)
1946 ((char *) header + spnt->sh_offset + idx);
1947 Elf_Verdaux * aux = (Elf_Verdaux *)
1948 ((char *) ent + ent->vd_aux);
1949 int j, isum;
1950
1951 printf (_("%#06x: Rev: %d Flags: "), idx, ent->vd_version);
1952
1953 if (ent->vd_flags == 0)
1954 printf (_("none"));
1955 else
1956 {
1957 int f = 1;
1958 if (ent->vd_flags & 0x1)
1959 {
1960 printf (_("BASE"));
1961 f = 0;
1962 }
1963 if (ent->vd_flags & 0x2)
1964 {
1965 printf (_("%sWEAK"), f ? "" : "|");
1966 f = 0;
1967 }
1968 }
1969 printf (_(" Index: %d Cnt: %d Name: %s\n"),
1970 ent->vd_ndx, ent->vd_cnt, strtab + aux->vda_name);
1971 j = 1;
1972 isum = idx + ent->vd_aux;
1973 while (j < ent->vd_cnt)
1974 {
1975 isum += aux->vda_next;
1976 aux = (Elf_Verdaux *)((char *)aux + aux->vda_next);
1977 printf (_(" %#06x: Parent %d: %s\n"), isum, j,
1978 strtab + aux->vda_name);
1979 ++j;
1980 }
1981
1982 idx += ent->vd_next;
1983 }
1984 }
1985
1986 if (spnt->sh_type == SHT_GNU_verneed)
1987 {
1988 Elf_Shdr * dspnt = &elf_sections[spnt->sh_link];
1989 unsigned int idx;
1990 unsigned int cnt;
1991
1992 strtab = (char *) (header - loadaddr + dynamic_info[DT_STRTAB]);
1993 printf (_("\n Needed versions:%s (%#0x entries)\n"),
1994 SECTION_NAME (spnt), spnt->sh_info);
1995 printf (_("Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
1996 spnt->sh_addr, spnt->sh_offset, spnt->sh_link,
1997 SECTION_NAME (dspnt));
1998
1999 for (idx = cnt = 0; cnt < spnt->sh_info; ++cnt)
2000 {
2001 Elf_Verneed * ent = (Elf_Verneed *)
2002 ((char *) header + spnt->sh_offset + idx);
2003 Elf_Vernaux * aux = (Elf_Vernaux *)
2004 ((char *) ent + ent->vn_aux);
2005 int j, isum;
2006
2007 printf (_("%#06x: Version: %d File: %s Cnt: %d\n"),
2008 idx, ent->vn_version, strtab + ent->vn_file,ent->vn_cnt);
2009
2010 for (j = 0, isum = idx + ent->vn_aux; j < ent->vn_cnt; ++j)
2011 {
2012 printf (_(" %#06x: Name: %s Flags: %s Version: %d\n"),
2013 isum, strtab+aux->vna_name,
2014 aux->vna_flags & 0x2 ? "WEAK" : "none",
2015 aux->vna_other);
2016 isum += aux->vna_next;
2017 aux = (Elf_Vernaux *)((char *) aux + aux->vna_next);
2018 }
2019
2020 idx += ent->vn_next;
2021 }
2022 }
2023
2024 if (spnt->sh_type == SHT_GNU_versym)
2025 {
2026 Elf_Shdr * dspnt = &elf_sections[spnt->sh_link];
2027 int total = spnt->sh_size / spnt->sh_entsize;
2028 int cnt;
2029 unsigned short * p = (short *)
2030 (version_info[DT_VERNEEDNUM - DT_VERSYM] + header - loadaddr);
2031
2032 symtab = (Elf_Sym *) (header + dspnt->sh_offset);
2033 strtab = (char *) (header + elf_sections[dspnt->sh_link].sh_offset);
2034
2035 printf (_("\n Version symbols:%s (%#0x entries)\n"),
2036 SECTION_NAME (spnt), total);
2037 printf (_("Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2038 spnt->sh_addr, spnt->sh_offset, spnt->sh_link,
2039 SECTION_NAME (dspnt));
2040
2041 for (cnt = 0; cnt < total; cnt += 4)
2042 {
2043 int j, nn;
2044
2045 printf ("%#08x:", cnt);
2046
2047 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2048 switch (p[cnt + j])
2049 {
2050 case 0:
2051 printf (" 0 (*local*) ");
2052 break;
2053 case 1:
2054 printf (" 1 (*global*) ");
2055 break;
2056 default:
2057 nn = printf ("%4x%c", p[cnt + j] & 0x7fff,
2058 p[cnt + j] & 0x8000 ? 'h' : ' ');
2059 if (elf_sections[symtab[cnt + j].st_shndx].sh_type
2060 == SHT_NOBITS)
2061 {
2062 /* We must test both. */
2063 Elf_Verneed * v = (Elf_Verneed *)
2064 (version_info [DT_VERNEEDNUM - DT_VERNEED]
2065 + header - loadaddr);
2066 Elf_Vernaux * a = NULL;
2067
2068 for (;;)
2069 {
2070 a = (Elf_Vernaux *)((char *) v + v->vn_aux);
2071
2072 while (a->vna_other != p[cnt + j]
2073 && a->vna_next != 0)
2074 a = (Elf_Vernaux *)((char *) a + a->vna_next);
2075
2076 if (a->vna_other == p[cnt + j])
2077 break;
2078
2079 if (v->vn_next == 0)
2080 {
2081 a = NULL;
2082 break;
2083 }
2084
2085 v = (Elf_Verneed *)((char *)v + v->vn_next);
2086 }
2087
2088 if (a != NULL)
2089 nn += printf ("(%s)", strtab + a->vna_name);
2090 else
2091 {
2092 Elf_Verdef * v = (Elf_Verdef *)
2093 (version_info [DT_VERNEEDNUM - DT_VERDEF]
2094 + header - loadaddr);
2095 Elf_Verdaux * a;
2096
2097 if (p[cnt + j] == 0x8001)
2098 pnt = "";
2099 else
2100 {
2101 while (v->vd_ndx != (p[cnt + j]&0x7fff))
2102 v = (Elf_Verdef *)((char *)v + v->vd_next);
2103
2104 a = (Elf_Verdaux *) ((char *) v + v->vd_aux);
2105 pnt = strtab + a->vda_name;
2106 }
2107
2108 if (pnt)
2109 nn += printf ("(%s)", pnt);
2110 }
2111
2112 if (nn <16)
2113 printf ("%*c", 16 - nn, ' ');
2114 }
2115 else if (symtab[cnt + j].st_shndx ==SHN_UNDEF)
2116 {
2117 Elf_Verneed * v = (Elf_Verneed *)
2118 (version_info [DT_VERNEEDNUM - DT_VERNEED]
2119 + header - loadaddr);
2120 Elf_Vernaux * a;
2121
2122 for (;;)
2123 {
2124 a = (Elf_Vernaux *)((char *) v + v->vn_aux);
2125
2126 while (a->vna_other != p[cnt + j]
2127 && a->vna_next != 0)
2128 a = (Elf_Vernaux *)((char *)a + a->vna_next);
2129
2130 if (a->vna_other == p[cnt + j])
2131 break;
2132
2133 v = (Elf_Verneed *)((char *) v + v->vn_next);
2134 }
2135
2136 nn += printf ("(%s)", strtab + a->vna_name);
2137
2138 if (nn <16)
2139 printf ("%*c", 16 - nn, ' ');
2140 }
2141 else
2142 {
2143 Elf_Verdef * v = (Elf_Verdef *)
2144 (version_info [DT_VERNEEDNUM - DT_VERDEF]
2145 + header - loadaddr);
2146 Elf_Verdaux * a;
2147
2148 if (p[cnt + j] == 0x8001)
2149 pnt = "";
2150 else
2151 {
2152 while (v->vd_ndx != (p[cnt + j] & 0x7fff))
2153 v = (Elf_Verdef *)((char *) v + v->vd_next);
2154
2155 a = (Elf_Verdaux *) ((char *) v + v->vd_aux);
2156 pnt = strtab + a->vda_name;
2157 }
2158
2159 if (pnt)
2160 nn += printf ("(%s)", pnt);
2161
2162 if (nn <16)
2163 printf ("%*c", 16 - nn, ' ');
2164 }
2165 }
2166
2167 printf ("\n");
2168 }
2169 }
2170 }
2171 }
2172
2173 static void
2174 process_section_contents ()
2175 {
2176 Elf_Shdr * spnt;
2177 int i;
2178
2179 if (! do_dump)
2180 return;
2181
2182 spnt = elf_sections;
2183
2184 for (i = 0; i < epnt->e_shnum; i++, spnt++)
2185 {
2186 int bytes;
2187 int addr;
2188 int lbytes;
2189 unsigned char * my_addr;
2190
2191 #ifdef SUPPORT_DISASSEMBLY
2192 /* See if we need an assembly dump of this section */
2193
2194 if ((i < NUM_DUMP_SECTS) && (dump_sects[i] & DISASS_DUMP))
2195 {
2196 printf (_("\nAssembly dump of section %s\n"), SECTION_NAME (spnt));
2197
2198 bytes = spnt->sh_size;
2199 addr = spnt->sh_addr;
2200 my_addr = (unsigned char *) (header + spnt->sh_offset);
2201
2202 while (bytes > 0)
2203 {
2204 printf ("0x%8.8x ", addr);
2205
2206 switch (epnt->e_machine)
2207 {
2208 case EM_386:
2209 case EM_486:
2210 lbytes = db_disasm ((unsigned int) my_addr, 0, 0) -
2211 ((unsigned int) my_addr);
2212 break;
2213 case EM_68K:
2214 lbytes = (m68k_disass ((unsigned int) my_addr, addr)
2215 - (unsigned int) my_addr);
2216 break;
2217 default:
2218 warn (_("Unable to disassemble code for this platform\n"));
2219 return;
2220 }
2221
2222 addr += lbytes;
2223 my_addr += lbytes;
2224 bytes -= lbytes;
2225
2226 printf ("\n");
2227 }
2228 }
2229 #endif
2230
2231 /* OK, see if we need a hex dump of this section. */
2232 if ((i < NUM_DUMP_SECTS) && (dump_sects[i] & HEX_DUMP))
2233 {
2234 int j;
2235 int k;
2236
2237 printf (_("\nHex dump of section %s\n"), SECTION_NAME (spnt));
2238
2239 bytes = spnt->sh_size;
2240 addr = spnt->sh_addr;
2241 my_addr = (unsigned char *) (header + spnt->sh_offset);
2242
2243 while (bytes)
2244 {
2245 lbytes = (bytes > 16 ? 16 : bytes);
2246
2247 printf ("0x%8.8x ",addr);
2248
2249 switch (epnt->e_ident [EI_DATA])
2250 {
2251 case ELFDATA2LSB:
2252 for (j = 15; j >= 0; j --)
2253 {
2254 if (j < lbytes)
2255 printf ("%2.2x", my_addr[j]);
2256 else
2257 printf (" ");
2258
2259 if (!(j & 0x3))
2260 printf (" ");
2261 }
2262 break;
2263
2264 case ELFDATA2MSB:
2265 for (j = 0; j < 16; j++)
2266 {
2267 if (j < lbytes)
2268 printf ("%2.2x", my_addr[j]);
2269 else
2270 printf (" ");
2271
2272 if ((j & 3) == 3)
2273 printf (" ");
2274 }
2275 break;
2276 }
2277
2278 for (j = 0; j < lbytes; j++)
2279 {
2280 k = my_addr [j];
2281 if (k >= ' ' && k < 0x80)
2282 printf ("%c", k);
2283 else
2284 printf (".");
2285 }
2286
2287 printf ("\n");
2288
2289 my_addr += lbytes;
2290 addr += lbytes;
2291 bytes -= lbytes;
2292 }
2293 }
2294 }
2295 }
2296
2297 static void
2298 process_file (file_name)
2299 char * file_name;
2300 {
2301 int fd;
2302 struct stat statbuf;
2303
2304 must_swap = 0;
2305
2306 fd = open (file_name, O_RDONLY);
2307 if (fd == -1)
2308 {
2309 error (_("Input file %s not found.\n"), file_name);
2310 return;
2311 }
2312
2313 if (fstat (fd, & statbuf) < 0)
2314 {
2315 error (_("Cannot stat input file %s.\n"), file_name);
2316 close (fd);
2317 return;
2318 }
2319
2320 header = mmap (0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
2321
2322 if ((header == (char *) -1) || (header == NULL))
2323 {
2324 error (_("Cannot mmap %s: %s\n"), file_name, strerror (errno));
2325 close (fd);
2326 return;
2327 }
2328
2329 close (fd);
2330
2331 epnt = (Elf_Ehdr *) header;
2332
2333 if (show_name)
2334 printf (_("\nFile: %s\n"), file_name);
2335
2336 if (! process_elf_header ())
2337 {
2338 munmap (header, statbuf.st_size);
2339 return;
2340 }
2341
2342 process_program_headers ();
2343
2344 if (loadaddr == -1)
2345 {
2346 /* Very strange. */
2347 loadaddr = 0;
2348 }
2349
2350 process_section_headers ();
2351
2352 process_dynamic_segment ();
2353
2354 process_symbol_table ();
2355
2356 process_section_contents ();
2357
2358 munmap (header, statbuf.st_size);
2359
2360 if (must_swap)
2361 {
2362 if (epnt)
2363 {
2364 free (epnt);
2365 epnt = NULL;
2366 }
2367
2368 if (elf_sections)
2369 {
2370 free (elf_sections);
2371 elf_sections = NULL;
2372 }
2373 }
2374 }
2375
2376 #ifdef SUPPORT_DISASSEMBLY
2377 /* Needed by the i386 disassembler. For extra credit, someone could
2378 fix this so that we insert symbolic addresses here, esp for GOT/PLT
2379 symbols */
2380
2381 void
2382 print_address (unsigned int addr, FILE * outfile)
2383 {
2384 fprintf (outfile,"0x%8.8x", addr);
2385 }
2386
2387 /* Needed by the i386 disassembler. */
2388 void
2389 db_task_printsym (unsigned int addr)
2390 {
2391 print_address (addr, stderr);
2392 }
2393 #endif
2394
2395 int
2396 main (argc, argv)
2397 int argc;
2398 char ** argv;
2399 {
2400 parse_args (argc, argv);
2401
2402 expected_endian = 0x12345678;
2403
2404 if (* ((char *) & expected_endian) == 0x12)
2405 expected_endian = ELFDATA2MSB;
2406 else
2407 expected_endian = ELFDATA2LSB;
2408
2409 if (optind < (argc - 1))
2410 show_name = 1;
2411
2412 while (optind < argc)
2413 process_file (argv [optind ++]);
2414
2415 return 0;
2416 }
This page took 0.081629 seconds and 5 git commands to generate.