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