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