]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - binutils/readelf.c
Rewrite of readelf to use fopen/fread rather than mmap.
[thirdparty/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/stat.h>
27 #include <stdio.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 * dynamic_strings;
42 Elf_Sym * dynamic_symbols;
43 char program_interpreter [64];
44 char * program_name = "readelf";
45 int dynamic_info [DT_JMPREL + 1];
46 int version_info [16];
47 int must_swap = 0;
48 int loadaddr = 0;
49 unsigned int rela_addr;
50 unsigned int rela_size;
51 Elf_Ehdr elf_header;
52 Elf_Shdr * section_headers;
53 char * string_table;
54 Elf_Dyn * dpnt;
55 Elf_Rel * rpnt;
56 int show_name;
57 int do_dynamic;
58 int do_syms;
59 int do_reloc;
60 int do_sections;
61 int do_segments;
62 int do_using_dynamic;
63 int do_header;
64 int do_dump;
65 int do_version;
66 long int expected_endian;
67
68
69 #define SECTION_NAME(X) (string_table + (X)->sh_name)
70
71 #define NUM_DUMP_SECTS 100
72 char dump_sects [NUM_DUMP_SECTS];
73 #define HEX_DUMP 1
74 #define DISASS_DUMP 2
75
76 /* Forward declarations for dumb compilers. */
77 static char * get_dynamic_type PARAMS ((unsigned long));
78 static char * get_i386_rel_type PARAMS ((bfd_vma rtype));
79 static char * get_m68k_rel_type PARAMS ((bfd_vma rtype));
80 static char * get_sparc_rel_type PARAMS ((bfd_vma rtype));
81 static char * get_m32r_rel_type PARAMS ((bfd_vma rtype));
82 static char * get_v850_rel_type PARAMS ((bfd_vma rtype));
83 static char * get_d10v_rel_type PARAMS ((bfd_vma rtype));
84 /* start-sanitize-d30v */
85 static char * get_d30v_rel_type PARAMS ((bfd_vma rtype));
86 /* end-sanitize-d30v */
87 static char * get_sh_rel_type PARAMS ((bfd_vma rtype));
88 static char * get_mn10300_rel_type PARAMS ((bfd_vma rtype));
89 static char * get_mn10200_rel_type PARAMS ((bfd_vma rtype));
90 static char * get_ppc_rel_type PARAMS ((bfd_vma rtype));
91 static void dump_relocations
92 PARAMS ((FILE *, unsigned long, unsigned long, Elf_Sym *, char *));
93 static char * get_file_type PARAMS ((unsigned e_type));
94 static char * get_machine_name PARAMS ((unsigned e_machine));
95 static char * get_machine_data PARAMS ((unsigned e_data));
96 static char * get_machine_flags PARAMS ((unsigned, unsigned e_machine));
97 static char * get_segment_type PARAMS ((unsigned long p_type));
98 static char * get_section_type_name PARAMS ((unsigned int sh_type));
99 static char * get_symbol_binding PARAMS ((unsigned int binding));
100 static char * get_symbol_type PARAMS ((unsigned int type));
101 static void usage PARAMS ((void));
102 static void parse_args PARAMS ((int argc, char ** argv));
103 static int process_file_header PARAMS ((void));
104 static void process_program_headers PARAMS ((FILE *));
105 static void process_section_headers PARAMS ((FILE *));
106 static void process_dynamic_segment PARAMS ((FILE *));
107 static void process_symbol_table PARAMS ((FILE *));
108 static void process_section_contents PARAMS ((FILE *));
109 static void process_file PARAMS ((char * file_name));
110 static void process_relocs PARAMS ((FILE *));
111 static void process_version_sections PARAMS ((FILE *));
112 static char * get_ver_flags PARAMS ((unsigned short flags));
113 static char * get_symbol_index_type PARAMS ((unsigned short type));
114
115 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
116
117 #define SWAP2(val) ( (((val) << 8) & (0xff << 8)) \
118 | (((val) >> 8) & (0xff << 0)))
119
120 #define SWAP4(val) ( (((val) << 24) & (0xff << 24)) \
121 | (((val) << 8) & (0xff << 16)) \
122 | (((val) >> 8) & (0xff << 8)) \
123 | (((val) >> 24) & (0xff << 0)))
124
125 /* Warning: This macro assumes 8 bits in a char,
126 and at least 16 bits in a short,
127 and at least 32 bits in a long. */
128 #define BYTE_SWAP(structure, field) \
129 if (sizeof ((structure).field) == 2) \
130 { \
131 unsigned short val = (structure).field; \
132 (structure).field = SWAP2 (val); \
133 } \
134 else if (sizeof ((structure).field) != 4) \
135 abort (); \
136 else \
137 { \
138 unsigned long val = (structure).field; \
139 (structure).field = SWAP4 (val); \
140 }
141
142 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
143 if (fseek (file, offset, SEEK_SET)) \
144 { \
145 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
146 return; \
147 } \
148 \
149 var = (type) malloc (size); \
150 \
151 if (var == NULL) \
152 { \
153 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
154 return; \
155 } \
156 \
157 if (fread (var, size, 1, file) != 1) \
158 { \
159 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
160 free (var); \
161 var = NULL; \
162 return; \
163 }
164
165
166 #define GET_DATA(offset, var, reason) \
167 if (fseek (file, offset, SEEK_SET)) \
168 { \
169 error (_("Unable to seek to %x for %s\n"), offset, reason); \
170 return; \
171 } \
172 else if (fread (& var, sizeof (var), 1, file) != 1) \
173 { \
174 error (_("Unable to read data at %x for %s\n"), offset, reason); \
175 return; \
176 }
177
178 #ifdef ANSI_PROTOTYPES
179 static void
180 error (const char * message, ...)
181 {
182 va_list args;
183
184 fprintf (stderr, _("%s: Error: "), program_name);
185 va_start (args, message);
186 vfprintf (stderr, message, args);
187 va_end (args);
188 return;
189 }
190
191 static void
192 warn (const char * message, ...)
193 {
194 va_list args;
195
196 fprintf (stderr, _("%s: Warning: "), program_name);
197 va_start (args, message);
198 vfprintf (stderr, message, args);
199 va_end (args);
200 return;
201 }
202 #else
203 static void
204 error (va_alist)
205 {
206 char * message;
207 va_list args;
208
209 fprintf (stderr, _("%s: Error: "), program_name);
210 va_start (args);
211 message = va_arg (args, char *);
212 vfprintf (stderr, message, args);
213 va_end (args);
214 return;
215 }
216
217 static void
218 warn (va_alist)
219 va_dcl;
220 {
221 char * message;
222 va_list args;
223
224 fprintf (stderr, _("%s: Warning: "), program_name);
225 va_start (args);
226 message = va_arg (args, char *);
227 vfprintf (stderr, message, args);
228 va_end (args);
229 return;
230 }
231 #endif
232
233
234 static char *
235 get_i386_rel_type (rtype)
236 bfd_vma rtype;
237 {
238 switch (rtype)
239 {
240 case 0: return "R_386_NONE";
241 case 1: return "R_386_32";
242 case 2: return "R_386_PC32";
243 case 3: return "R_386_GOT32";
244 case 4: return "R_386_PLT32";
245 case 5: return "R_386_COPY";
246 case 6: return "R_386_GLOB_DAT";
247 case 7: return "R_386_JMP_SLOT";
248 case 8: return "R_386_RELATIVE";
249 case 9: return "R_386_GOTOFF";
250 case 10: return "R_386_GOTPC";
251 case 20: return "R_386_16";
252 case 21: return "R_386_PC16";
253 case 22: return "R_386_PC8";
254 case 23: return "R_386_max";
255 default: return _("*INVALID*");
256 }
257 }
258
259 static char *
260 get_m68k_rel_type (rtype)
261 bfd_vma rtype;
262 {
263 switch (rtype)
264 {
265 case 0: return "R_68K_NONE";
266 case 1: return "R_68K_32";
267 case 2: return "R_68K_16";
268 case 3: return "R_68K_8";
269 case 4: return "R_68K_PC32";
270 case 5: return "R_68K_PC16";
271 case 6: return "R_68K_PC8";
272 case 7: return "R_68K_GOT32";
273 case 8: return "R_68K_GOT16";
274 case 9: return "R_68K_GOT8";
275 case 10: return "R_68K_GOT32O";
276 case 11: return "R_68K_GOT16O";
277 case 12: return "R_68K_GOT8O";
278 case 13: return "R_68K_PLT32";
279 case 14: return "R_68K_PLT16";
280 case 15: return "R_68K_PLT8";
281 case 16: return "R_68K_PLT32O";
282 case 17: return "R_68K_PLT16O";
283 case 18: return "R_68K_PLT8O";
284 case 19: return "R_68K_COPY";
285 case 20: return "R_68K_GLOB_DAT";
286 case 21: return "R_68K_JMP_SLOT";
287 case 22: return "R_68K_RELATIVE";
288 default: return _("*INVALID*");
289 }
290 }
291
292
293 static char *
294 get_sparc_rel_type (rtype)
295 bfd_vma rtype;
296 {
297 switch (rtype)
298 {
299 case 0: return "R_SPARC_NONE";
300 case 1: return "R_SPARC_8";
301 case 2: return "R_SPARC_16";
302 case 3: return "R_SPARC_32";
303 case 4: return "R_SPARC_DISP8";
304 case 5: return "R_SPARC_DISP16";
305 case 6: return "R_SPARC_DISP32";
306 case 7: return "R_SPARC_WDISP30";
307 case 8: return "R_SPARC_WDISP22";
308 case 9: return "R_SPARC_HI22";
309 case 10: return "R_SPARC_22";
310 case 11: return "R_SPARC_13";
311 case 12: return "R_SPARC_LO10";
312 case 13: return "R_SPARC_GOT10";
313 case 14: return "R_SPARC_GOT13";
314 case 15: return "R_SPARC_GOT22";
315 case 16: return "R_SPARC_PC10";
316 case 17: return "R_SPARC_PC22";
317 case 18: return "R_SPARC_WPLT30";
318 case 19: return "R_SPARC_COPY";
319 case 20: return "R_SPARC_GLOB_DAT";
320 case 21: return "R_SPARC_JMP_SLOT";
321 case 22: return "R_SPARC_RELATIVE";
322 case 23: return "R_SPARC_UA32";
323 case 24: return "R_SPARC_10";
324 case 25: return "R_SPARC_11";
325 case 26: return "R_SPARC_64";
326 case 27: return "R_SPARC_OLO10";
327 case 28: return "R_SPARC_HH22";
328 case 29: return "R_SPARC_HM10";
329 case 30: return "R_SPARC_LM22";
330 case 31: return "R_SPARC_PC_HH22";
331 case 32: return "R_SPARC_PC_HM10";
332 case 33: return "R_SPARC_PC_LM22";
333 case 34: return "R_SPARC_WDISP16";
334 case 35: return "R_SPARC_WDISP19";
335 case 36: return "R_SPARC_UNUSED_42";
336 case 37: return "R_SPARC_7";
337 case 38: return "R_SPARC_5";
338 case 39: return "R_SPARC_6";
339 case 40: return "R_SPARC_DISP64";
340 case 41: return "R_SPARC_PLT64";
341 case 42: return "R_SPARC_HIX22";
342 case 43: return "R_SPARC_LOX10";
343 case 44: return "R_SPARC_H44";
344 case 45: return "R_SPARC_M44";
345 case 46: return "R_SPARC_L44";
346 case 47: return "R_SPARC_REGISTER";
347 case 48: return "R_SPARC_UA64";
348 case 49: return "R_SPARC_UA16";
349 case 50: return "R_SPARC_32LE";
350 default: return _("*INVALID*");
351 }
352 }
353
354
355 static char *
356 get_m32r_rel_type (rtype)
357 bfd_vma rtype;
358 {
359 switch (rtype)
360 {
361 case 0: return "R_M32R_NONE";
362 case 1: return "R_M32R_16";
363 case 2: return "R_M32R_32";
364 case 3: return "R_M32R_24";
365 case 4: return "R_M32R_10_PCREL";
366 case 5: return "R_M32R_18_PCREL";
367 case 6: return "R_M32R_26_PCREL";
368 case 7: return "R_M32R_HI16_ULO";
369 case 8: return "R_M32R_HI16_SLO";
370 case 9: return "R_M32R_LO16";
371 case 10: return "R_M32R_SDA16";
372 default: return _("*INVALID*");
373 }
374 }
375
376
377 static char *
378 get_v850_rel_type (rtype)
379 bfd_vma rtype;
380 {
381 switch (rtype)
382 {
383 case 0: return "R_V850_NONE";
384 case 1: return "R_V850_9_PCREL";
385 case 2: return "R_V850_22_PCREL";
386 case 3: return "R_V850_HI16_S";
387 case 4: return "R_V850_HI16";
388 case 5: return "R_V850_LO16";
389 case 6: return "R_V850_32";
390 case 7: return "R_V850_16";
391 case 8: return "R_V850_8";
392 case 9: return "R_V850_SDA_16_16_OFFSET";
393 case 10: return "R_V850_SDA_15_16_OFFSET";
394 case 11: return "R_V850_ZDA_16_16_OFFSET";
395 case 12: return "R_V850_ZDA_15_16_OFFSET";
396 case 13: return "R_V850_TDA_6_8_OFFSET";
397 case 14: return "R_V850_TDA_7_8_OFFSET";
398 case 15: return "R_V850_TDA_7_7_OFFSET";
399 case 16: return "R_V850_TDA_16_16_OFFSET";
400 /* start-sanitize-v850e */
401 case 17: return "R_V850_TDA_4_5_OFFSET";
402 case 18: return "R_V850_TDA_4_4_OFFSET";
403 case 19: return "R_V850_SDA_16_16_SPLIT_OFFSET";
404 case 20: return "R_V850_ZDA_16_16_SPLIT_OFFSET";
405 case 21: return "R_V850_CALLT_6_7_OFFSET";
406 case 22: return "R_V850_CALLT_16_16_OFFSET";
407 /* end-sanitize-v850e */
408 default: return _("*INVALID*");
409 }
410 }
411
412
413 static char *
414 get_d10v_rel_type (rtype)
415 bfd_vma rtype;
416 {
417 switch (rtype)
418 {
419 case 0: return "R_D10V_NONE";
420 case 1: return "R_D10V_10_PCREL_R";
421 case 2: return "R_D10V_10_PCREL_L";
422 case 3: return "R_D10V_16";
423 case 4: return "R_D10V_18";
424 case 5: return "R_D10V_18_PCREL";
425 case 6: return "R_D10V_32";
426 default: return _("*INVALID*");
427 }
428 }
429
430 /* start-sanitize-d30v */
431 static char *
432 get_d30v_rel_type (rtype)
433 bfd_vma rtype;
434 {
435 switch (rtype)
436 {
437 case 0: return "R_D30V_NONE";
438 case 1: return "R_D30V_6";
439 case 2: return "R_D30V_9_PCREL";
440 case 3: return "R_D30V_9_PCREL_R";
441 case 4: return "R_D30V_15";
442 case 5: return "R_D30V_15_PCREL";
443 case 6: return "R_D30V_15_PCREL_R";
444 case 7: return "R_D30V_21";
445 case 8: return "R_D30V_21_PCREL";
446 case 9: return "R_D30V_21_PCREL_R";
447 case 10: return "R_D30V_32";
448 case 11: return "R_D30V_32_PCREL";
449 case 12: return "R_D30V_32_NORMAL";
450 default: return _("*INVALID*");
451 }
452 }
453
454 /* end-sanitize-d30v */
455 static char *
456 get_sh_rel_type (rtype)
457 bfd_vma rtype;
458 {
459 switch (rtype)
460 {
461 case 0: return "R_SH_NONE";
462 case 1: return "R_SH_DIR32";
463 case 2: return "R_SH_REL32";
464 case 3: return "R_SH_DIR8WPN";
465 case 4: return "R_SH_IND12W";
466 case 5: return "R_SH_DIR8WPL";
467 case 6: return "R_SH_DIR8WPZ";
468 case 7: return "R_SH_DIR8BP";
469 case 8: return "R_SH_DIR8W";
470 case 9: return "R_SH_DIR8L";
471 case 25: return "R_SH_SWITCH16";
472 case 26: return "R_SH_SWITCH32";
473 case 27: return "R_SH_USES";
474 case 28: return "R_SH_COUNT";
475 case 29: return "R_SH_ALIGN";
476 case 30: return "R_SH_CODE";
477 case 31: return "R_SH_DATA";
478 case 32: return "R_SH_LABEL";
479 default: return _("*INVALID*");
480 }
481 }
482
483
484 static char *
485 get_mn10300_rel_type (rtype)
486 bfd_vma rtype;
487 {
488 switch (rtype)
489 {
490 case 0: return "R_MN10300_NONE";
491 case 1: return "R_MN10300_32";
492 case 2: return "R_MN10300_16";
493 case 3: return "R_MN10300_8";
494 case 4: return "R_MN10300_PCREL32";
495 case 5: return "R_MN10300_PCREL16";
496 case 6: return "R_MN10300_PCREL8";
497 default: return _("*INVALID*");
498 }
499 }
500
501
502 static char *
503 get_mn10200_rel_type (rtype)
504 bfd_vma rtype;
505 {
506 switch (rtype)
507 {
508 case 0: return "R_MN10200_NONE";
509 case 1: return "R_MN10200_32";
510 case 2: return "R_MN10200_16";
511 case 3: return "R_MN10200_8";
512 case 4: return "R_MN10200_24";
513 case 5: return "R_MN10200_PCREL8";
514 case 6: return "R_MN10200_PCREL16";
515 case 7: return "R_MN10200_PCREL24";
516 default: return _("*INVALID*");
517 }
518 }
519
520
521 static char *
522 get_ppc_rel_type (rtype)
523 bfd_vma rtype;
524 {
525 switch (rtype)
526 {
527 case 0: return "R_PPC_NONE,";
528 case 1: return "R_PPC_ADDR32,";
529 case 2: return "R_PPC_ADDR24,";
530 case 3: return "R_PPC_ADDR16,";
531 case 4: return "R_PPC_ADDR16_LO,";
532 case 5: return "R_PPC_ADDR16_HI,";
533 case 6: return "R_PPC_ADDR16_HA,";
534 case 7: return "R_PPC_ADDR14,";
535 case 8: return "R_PPC_ADDR14_BRTAKEN,";
536 case 9: return "R_PPC_ADDR14_BRNTAKEN,";
537 case 10: return "R_PPC_REL24,";
538 case 11: return "R_PPC_REL14,";
539 case 12: return "R_PPC_REL14_BRTAKEN,";
540 case 13: return "R_PPC_REL14_BRNTAKEN,";
541 case 14: return "R_PPC_GOT16,";
542 case 15: return "R_PPC_GOT16_LO,";
543 case 16: return "R_PPC_GOT16_HI,";
544 case 17: return "R_PPC_GOT16_HA,";
545 case 18: return "R_PPC_PLT24,";
546 case 19: return "R_PPC_COPY,";
547 case 21: return "R_PPC_JMP_SLOT,";
548 case 22: return "R_PPC_RELATIVE,";
549 case 23: return "R_PPC_LOCAL24PC,";
550 case 24: return "R_PPC_UADDR32,";
551 case 25: return "R_PPC_UADDR16,";
552 case 26: return "R_PPC_REL32,";
553 case 27: return "R_PPC_PLT32,";
554 case 28: return "R_PPC_PLTREL32,";
555 case 29: return "R_PPC_PLT16_LO,";
556 case 30: return "R_PPC_PLT16_HI,";
557 case 31: return "R_PPC_PLT16_HA,";
558 case 32: return "R_PPC_SDAREL,";
559 case 33: return "R_PPC_SECTOFF,";
560 case 34: return "R_PPC_SECTOFF_LO,";
561 case 35: return "R_PPC_SECTOFF_HI,";
562 case 36: return "R_PPC_SECTOFF_HA,";
563 case 101: return "R_PPC_EMB_NADDR32,";
564 case 102: return "R_PPC_EMB_NADDR16,";
565 case 103: return "R_PPC_EMB_NADDR16_LO,";
566 case 104: return "R_PPC_EMB_NADDR16_HI,";
567 case 105: return "R_PPC_EMB_NADDR16_HA,";
568 case 106: return "R_PPC_EMB_SDAI16,";
569 case 107: return "R_PPC_EMB_SDA2I16,";
570 case 108: return "R_PPC_EMB_SDA2REL,";
571 case 109: return "R_PPC_EMB_SDA21,";
572 case 110: return "R_PPC_EMB_MRKREF,";
573 case 111: return "R_PPC_EMB_RELSEC16,";
574 case 112: return "R_PPC_EMB_RELST_LO,";
575 case 113: return "R_PPC_EMB_RELST_HI,";
576 case 114: return "R_PPC_EMB_RELST_HA,";
577 case 115: return "R_PPC_EMB_BIT_FLD,";
578 case 116: return "R_PPC_EMB_RELSDA,";
579 default: return _("*INVALID*");
580 }
581 }
582
583
584 /* Display the contents of the relocation data
585 found at the specified offset. */
586 static void
587 dump_relocations (file, rel_offset, rel_size, symtab, strtab)
588 FILE * file;
589 unsigned long rel_offset;
590 unsigned long rel_size;
591 Elf_Sym * symtab;
592 char * strtab;
593 {
594 unsigned i;
595 int is_rela;
596 Elf_Rel * rels;
597 Elf_Rela * relas;
598
599
600 /* Compute number of relocations and read them in. */
601 switch (elf_header.e_machine)
602 {
603 case EM_386:
604 case EM_486:
605 case EM_CYGNUS_M32R:
606 case EM_CYGNUS_D10V:
607 GET_DATA_ALLOC (rel_offset, rel_size, rels, Elf_Rel *, "relocs");
608
609 rel_size = rel_size / sizeof (Elf_Rel);
610
611 if (must_swap)
612 {
613 for (i = 0; i < rel_size; i++)
614 {
615 BYTE_SWAP (rels[i], r_offset);
616 BYTE_SWAP (rels[i], r_info);
617 }
618 }
619
620 is_rela = 0;
621 relas = (Elf_Rela *) rels;
622 break;
623
624 case EM_68K:
625 case EM_SPARC:
626 case EM_PPC:
627 case EM_CYGNUS_V850:
628 /* start-sanitize-d30v */
629 case EM_CYGNUS_D30V:
630 /* end-sanitize-d30v */
631 case EM_CYGNUS_MN10200:
632 case EM_CYGNUS_MN10300:
633 case EM_SH:
634 GET_DATA_ALLOC (rel_offset, rel_size, relas, Elf_Rela *, "relocs");
635
636 rel_size = rel_size / sizeof (Elf_Rela);
637
638 if (must_swap)
639 {
640 for (i = 0; i < rel_size; i++)
641 {
642 BYTE_SWAP (relas [i], r_offset);
643 BYTE_SWAP (relas [i], r_info);
644 BYTE_SWAP (relas [i], r_addend);
645 }
646 }
647
648 is_rela = 1;
649 rels = (Elf_Rel *) relas;
650 break;
651
652 default:
653 warn (_("Don't know about relocations on this machine architecture\n"));
654 return;
655 }
656
657 if (is_rela)
658 printf
659 (_(" Offset Value Type Symbol's Value Symbol's Name Addend\n"));
660 else
661 printf
662 (_(" Offset Value Type Symbol's Value Symbol's Name\n"));
663
664 for (i = 0; i < rel_size; i++)
665 {
666 char * rtype;
667 bfd_vma offset;
668 bfd_vma info;
669 int symtab_index;
670
671 if (is_rela)
672 {
673 offset = relas [i].r_offset;
674 info = relas [i].r_info;
675 }
676 else
677 {
678 offset = rels [i].r_offset;
679 info = rels [i].r_info;
680 }
681
682 printf (" %8.8lx %5.5lx ", offset, info);
683
684 switch (elf_header.e_machine)
685 {
686 default:
687 rtype = "<unknown>";
688 break;
689
690 case EM_CYGNUS_M32R:
691 rtype = get_m32r_rel_type (ELF32_R_TYPE (info));
692 break;
693
694 case EM_386:
695 case EM_486:
696 rtype = get_i386_rel_type (ELF32_R_TYPE (info));
697 break;
698
699 case EM_68K:
700 rtype = get_m68k_rel_type (ELF32_R_TYPE (info));
701 break;
702
703 case EM_SPARC:
704 rtype = get_sparc_rel_type (ELF32_R_TYPE (info));
705 break;
706
707 case EM_CYGNUS_V850:
708 rtype = get_v850_rel_type (ELF32_R_TYPE (info));
709 break;
710
711 case EM_CYGNUS_D10V:
712 rtype = get_d10v_rel_type (ELF32_R_TYPE (info));
713 break;
714
715 /* start-sanitize-d30v */
716 case EM_CYGNUS_D30V:
717 rtype = get_d30v_rel_type (ELF32_R_TYPE (info));
718 break;
719
720 /* end-sanitize-d30v */
721 case EM_SH:
722 rtype = get_sh_rel_type (ELF32_R_TYPE (info));
723 break;
724
725 case EM_CYGNUS_MN10300:
726 rtype = get_mn10300_rel_type (ELF32_R_TYPE (info));
727 break;
728
729 case EM_CYGNUS_MN10200:
730 rtype = get_mn10200_rel_type (ELF32_R_TYPE (info));
731 break;
732
733 case EM_PPC:
734 rtype = get_ppc_rel_type (ELF32_R_TYPE (info));
735 break;
736 }
737
738 printf ("%-21.21s", rtype);
739
740 symtab_index = ELF32_R_SYM (info);
741
742 if (symtab_index && symtab != NULL)
743 {
744 Elf_Sym * psym;
745
746 psym = symtab + symtab_index;
747
748 printf (" %08lx ", psym->st_value);
749
750 if (psym->st_name == 0)
751 printf ("%-17.17s",
752 SECTION_NAME (section_headers + psym->st_shndx));
753 else if (strtab == NULL)
754 printf (_("<string table index %d>"), psym->st_name);
755 else
756 printf ("%-17.17s", strtab + psym->st_name);
757
758 if (is_rela)
759 printf (" + %lx", relas [i].r_addend);
760 }
761
762 putchar ('\n');
763 }
764
765 free (relas);
766 }
767
768 static char *
769 get_dynamic_type (type)
770 unsigned long type;
771 {
772 static char buff [32];
773
774 switch (type)
775 {
776 case DT_NULL: return _("NULL");
777 case DT_NEEDED: return _("NEEDED");
778 case DT_PLTRELSZ: return _("PLTRELSZ");
779 case DT_PLTGOT: return _("PLTGOT");
780 case DT_HASH: return _("HASH");
781 case DT_STRTAB: return _("STRTAB");
782 case DT_SYMTAB: return _("SYMTAB");
783 case DT_RELA: return _("RELA");
784 case DT_RELASZ: return _("RELASZ");
785 case DT_RELAENT: return _("RELAENT");
786 case DT_STRSZ: return _("STRSZ");
787 case DT_SYMENT: return _("SYMENT");
788 case DT_INIT: return _("INIT");
789 case DT_FINI: return _("FINI");
790 case DT_SONAME: return _("SONAME");
791 case DT_RPATH: return _("RPATH");
792 case DT_SYMBOLIC: return _("SYMBOLIC");
793 case DT_REL: return _("REL");
794 case DT_RELSZ: return _("RELSZ");
795 case DT_RELENT: return _("RELENT");
796 case DT_PLTREL: return _("PLTREL");
797 case DT_DEBUG: return _("DEBUG");
798 case DT_TEXTREL: return _("TEXTREL");
799 case DT_JMPREL: return _("JMPREL");
800 case DT_VERDEF: return _("VERDEF");
801 case DT_VERDEFNUM: return _("VERDEFNUM");
802 case DT_VERNEED: return _("VERNEED");
803 case DT_VERNEEDNUM: return _("VERNEEDNUM");
804 case DT_VERSYM: return _("VERSYN");
805 case DT_AUXILIARY: return _("AUXILARY");
806 case DT_FILTER: return _("FILTER");
807
808 default:
809 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
810 sprintf (buff, _("Processor Specific: (%x)"), type);
811 else
812 sprintf (buff, _("<unknown>: %x"), type);
813 return buff;
814 }
815 }
816
817 static char *
818 get_file_type (e_type)
819 unsigned e_type;
820 {
821 static char buff [32];
822
823 switch (e_type)
824 {
825 case ET_NONE: return _("None");
826 case ET_REL: return _("Relocatable file");
827 case ET_EXEC: return _("Executable file");
828 case ET_DYN: return _("Shared object file");
829 case ET_CORE: return _("Core file");
830
831 default:
832 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
833 sprintf (buff, _("Processor Specific: (%x)"), e_type);
834 else
835 sprintf (buff, _("<unknown>: %x"), e_type);
836 return buff;
837 }
838 }
839
840 static char *
841 get_machine_name (e_machine)
842 unsigned e_machine;
843 {
844 static char buff [32];
845
846 switch (e_machine)
847 {
848 case EM_NONE: return _("None");
849 case EM_M32: return "WE32100";
850 case EM_SPARC: return "Sparc";
851 case EM_386: return "80386";
852 case EM_68K: return "MC68000";
853 case EM_88K: return "MC88000";
854 case EM_486: return "Intel 80486";
855 case EM_860: return "Intel 80860";
856 case EM_MIPS: return "MIPS R3000 big-endian";
857 case EM_S370: return "Amdahl";
858 case EM_MIPS_RS4_BE: return "MIPS R400 big-endian";
859 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
860 case EM_PARISC: return "HPPA";
861 case EM_PPC_OLD: return "Power PC (old)";
862 case EM_SPARC32PLUS: return "Sparc v8+" ;
863 case EM_960: return "Intel 90860";
864 case EM_PPC: return "PowerPC";
865 case EM_V800: return "NEC V800";
866 case EM_FR20: return "Fujitsu FR20";
867 case EM_RH32: return "TRW RH32";
868 case EM_MMA: return "Fujitsu MMA";
869 case EM_ARM: return "ARM";
870 case EM_OLD_ALPHA: return "Digital Alpha (old)";
871 case EM_SH: return "Hitachi SH";
872 case EM_SPARCV9: return "Sparc v9";
873 case EM_ALPHA: return "Alpha";
874 case EM_CYGNUS_D10V: return "d10v";
875 /* start-sanitize-d30v */
876 case EM_CYGNUS_D30V: return "d30v";
877 /* end-sanitize-d30v */
878 case EM_CYGNUS_M32R: return "M32r";
879 case EM_CYGNUS_V850: return "v850";
880 case EM_CYGNUS_MN10300: return "mn10300";
881 case EM_CYGNUS_MN10200: return "mn10200";
882
883 default:
884 sprintf (buff, _("<unknown>: %x"), e_machine);
885 return buff;
886 }
887 }
888
889 static char *
890 get_machine_flags (e_flags, e_machine)
891 unsigned e_flags;
892 unsigned e_machine;
893 {
894 static char buf [1024];
895
896 buf[0] = '\0';
897 if (e_flags)
898 {
899 switch (e_machine)
900 {
901 default:
902 break;
903
904 case EM_PPC:
905 if (e_flags & EF_PPC_EMB)
906 strcat (buf, ", emb");
907
908 if (e_flags & EF_PPC_RELOCATABLE)
909 strcat (buf, ", relocatable");
910
911 if (e_flags & EF_PPC_RELOCATABLE_LIB)
912 strcat (buf, ", relocatable-lib");
913 break;
914
915 case EM_CYGNUS_M32R:
916 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
917 strcat (buf, ", m32r");
918
919 /* start-sanitize-m32rx */
920 #ifdef E_M32RX_ARCH
921 if ((e_flags & EF_M32R_ARCH) == E_M32RX_ARCH)
922 strcat (buf, ", m32rx");
923 #endif
924 /* end-sanitize-m32rx */
925 break;
926
927 case EM_MIPS:
928 case EM_MIPS_RS4_BE:
929 if (e_flags & EF_MIPS_NOREORDER)
930 strcat (buf, ", noreorder");
931
932 if (e_flags & EF_MIPS_PIC)
933 strcat (buf, ", pic");
934
935 if (e_flags & EF_MIPS_CPIC)
936 strcat (buf, ", cpic");
937
938 if (e_flags & EF_MIPS_ABI2)
939 strcat (buf, ", abi2");
940
941 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
942 strcat (buf, ", mips1");
943
944 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
945 strcat (buf, ", mips2");
946
947 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
948 strcat (buf, ", mips3");
949
950 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
951 strcat (buf, ", mips4");
952 break;
953 }
954 }
955
956 return buf;
957 }
958
959 static char *
960 get_machine_data (e_data)
961 unsigned e_data;
962 {
963 static char buff [32];
964
965 switch (e_data)
966 {
967 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
968 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
969 default:
970 sprintf (buff, _("<unknown>: %x"), e_data);
971 return buff;
972 }
973 }
974
975 static char *
976 get_segment_type (p_type)
977 unsigned long p_type;
978 {
979 static char buff [32];
980
981 switch (p_type)
982 {
983 case PT_NULL: return _("Unused");
984 case PT_LOAD: return _("Loadable");
985 case PT_DYNAMIC: return _("Dynamic link info");
986 case PT_INTERP: return _("Interpreter");
987 case PT_NOTE: return _("Auxillary Info");
988 case PT_SHLIB: return _("Shared Library");
989 case PT_PHDR: return _("Program Header");
990
991 default:
992 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
993 return _("processor specific");
994 else
995 {
996 sprintf (buff, _("<unknown>: %x"), p_type);
997 return buff;
998 }
999 }
1000 }
1001
1002 static char *
1003 get_section_type_name (sh_type)
1004 unsigned int sh_type;
1005 {
1006 static char buff [32];
1007
1008 switch (sh_type)
1009 {
1010 case SHT_NULL: return _("Unused");
1011 case SHT_PROGBITS: return _("Program data");
1012 case SHT_SYMTAB: return _("Symbol table");
1013 case SHT_STRTAB: return _("String table");
1014 case SHT_RELA: return _("Relocations");
1015 case SHT_HASH: return _("Symbol hashes");
1016 case SHT_DYNAMIC: return _("Dynamic info");
1017 case SHT_NOTE: return _("Notes");
1018 case SHT_NOBITS: return _("Space, no data");
1019 case SHT_REL: return _("Relocations");
1020 case SHT_SHLIB: return _("Shared lib info");
1021 case SHT_DYNSYM: return _("Dynamic symbols");
1022 case SHT_GNU_verdef: return _("Version definition");
1023 case SHT_GNU_verneed: return _("Version needs");
1024 case SHT_GNU_versym: return _("Version symbols");
1025 case 0x6ffffff0: return "VERSYM";
1026 case 0x6ffffffc: return "VERDEF";
1027 case 0x7ffffffd: return "AUXILIARY";
1028 case 0x7fffffff: return "FILTER";
1029
1030 default:
1031 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1032 sprintf (buff, _("cpu defined (%d)"), sh_type - SHT_LOPROC);
1033 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1034 sprintf (buff, _("app defined (%d)"), sh_type - SHT_LOUSER);
1035 else
1036 sprintf (buff, _("<unknown>: %x"), sh_type);
1037 return buff;
1038 }
1039 }
1040
1041 struct option options [] =
1042 {
1043 {"all", no_argument, 0, 'a'},
1044 {"file-header", no_argument, 0, 'h'},
1045 {"program-headers", no_argument, 0, 'l'},
1046 {"headers", no_argument, 0, 'e'},
1047 {"segments", no_argument, 0, 'l'},
1048 {"sections", no_argument, 0, 'S'},
1049 {"section-headers", no_argument, 0, 'S'},
1050 {"symbols", no_argument, 0, 's'},
1051 {"relocs", no_argument, 0, 'r'},
1052 {"dynamic", no_argument, 0, 'd'},
1053 {"version-info", no_argument, 0, 'V'},
1054 {"use-dynamic", no_argument, 0, 'D'},
1055
1056 {"hex-dump", required_argument, 0, 'x'},
1057 #ifdef SUPPORT_DISASSEMBLY
1058 {"instruction-dump", required_argument, 0, 'i'},
1059 #endif
1060
1061 {"version", no_argument, 0, 'v'},
1062 {"help", no_argument, 0, 'H'},
1063
1064 {0, no_argument, 0, 0}
1065 };
1066
1067 static void
1068 usage ()
1069 {
1070 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1071 fprintf (stdout, _(" Options are:\n"));
1072 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V\n"));
1073 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1074 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1075 fprintf (stdout, _(" Display the program headers\n"));
1076 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1077 fprintf (stdout, _(" Display the sections' header\n"));
1078 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1079 fprintf (stdout, _(" -s or --symbols Display the symbol table\n"));
1080 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1081 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1082 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1083 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1084 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1085 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1086 #ifdef SUPPORT_DISASSEMBLY
1087 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1088 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1089 #endif
1090 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1091 fprintf (stdout, _(" -H or --help Display this information\n"));
1092 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1093
1094 exit (0);
1095 }
1096
1097 static void
1098 parse_args (argc, argv)
1099 int argc;
1100 char ** argv;
1101 {
1102 int c;
1103
1104 if (argc < 2)
1105 usage ();
1106
1107 while ((c = getopt_long
1108 (argc, argv, "ersahldSDx:i:vV", options, NULL)) != EOF)
1109 {
1110 char * cp;
1111 int section;
1112
1113 switch (c)
1114 {
1115 case 'H':
1116 usage ();
1117 break;
1118
1119 case 'a':
1120 do_syms ++;
1121 do_reloc ++;
1122 do_dynamic ++;
1123 do_header ++;
1124 do_sections ++;
1125 do_segments ++;
1126 do_version ++;
1127 break;
1128 case 'e':
1129 do_header ++;
1130 do_sections ++;
1131 do_segments ++;
1132 break;
1133 case 'D':
1134 do_using_dynamic ++;
1135 break;
1136 case 'r':
1137 do_reloc ++;
1138 break;
1139 case 'h':
1140 do_header ++;
1141 break;
1142 case 'l':
1143 do_segments ++;
1144 break;
1145 case 's':
1146 do_syms ++;
1147 break;
1148 case 'S':
1149 do_sections ++;
1150 break;
1151 case 'd':
1152 do_dynamic ++;
1153 break;
1154 case 'x':
1155 do_dump ++;
1156 section = strtoul (optarg, & cp, 0);
1157 if (! * cp && section >= 0 && section < NUM_DUMP_SECTS)
1158 {
1159 dump_sects [section] |= HEX_DUMP;
1160 break;
1161 }
1162 goto oops;
1163 #ifdef SUPPORT_DISASSEMBLY
1164 case 'i':
1165 do_dump ++;
1166 section = strtoul (optarg, & cp, 0);
1167 if (! * cp && section >= 0 && section < NUM_DUMP_SECTS)
1168 {
1169 dump_sects [section] |= DISASS_DUMP;
1170 break;
1171 }
1172 goto oops;
1173 #endif
1174 case 'v':
1175 print_version (program_name);
1176 break;
1177 case 'V':
1178 do_version ++;
1179 break;
1180 default:
1181 oops:
1182 /* xgettext:c-format */
1183 error (_("Invalid option '-%c'\n"), c);
1184 /* Drop through. */
1185 case '?':
1186 usage ();
1187 }
1188 }
1189
1190 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1191 && !do_segments && !do_header && !do_dump && !do_version)
1192 usage ();
1193 else if (argc < 3)
1194 {
1195 warn (_("Nothing to do.\n"));
1196 usage();
1197 }
1198 }
1199
1200 /* Decode the data held in 'elf_header'. */
1201 static int
1202 process_file_header ()
1203 {
1204 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1205 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1206 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1207 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1208 {
1209 error
1210 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1211 return 0;
1212 }
1213
1214 if (elf_header.e_ident [EI_CLASS] != ELFCLASS32)
1215 {
1216 error (_("Not a 32 bit ELF file\n"));
1217 return 0;
1218 }
1219
1220 if (elf_header.e_ident [EI_DATA] != expected_endian)
1221 {
1222 must_swap = 1;
1223
1224 BYTE_SWAP (elf_header, e_type);
1225 BYTE_SWAP (elf_header, e_machine);
1226 BYTE_SWAP (elf_header, e_version);
1227 BYTE_SWAP (elf_header, e_entry);
1228 BYTE_SWAP (elf_header, e_phoff);
1229 BYTE_SWAP (elf_header, e_shoff);
1230 BYTE_SWAP (elf_header, e_flags);
1231 BYTE_SWAP (elf_header, e_ehsize);
1232 BYTE_SWAP (elf_header, e_phentsize);
1233 BYTE_SWAP (elf_header, e_phnum);
1234 BYTE_SWAP (elf_header, e_shentsize);
1235 BYTE_SWAP (elf_header, e_shnum);
1236 BYTE_SWAP (elf_header, e_shstrndx);
1237 }
1238
1239 if (do_header)
1240 {
1241 int i;
1242
1243 printf (_("ELF Header:\n"));
1244 printf (_(" Magic: "));
1245 for (i = 0; i < EI_NIDENT; i ++)
1246 printf ("%2.2x ", elf_header.e_ident [i]);
1247 printf ("\n");
1248 printf (_(" Type: %s\n"),
1249 get_file_type (elf_header.e_type));
1250 printf (_(" Machine: %s\n"),
1251 get_machine_name (elf_header.e_machine));
1252 printf (_(" Version: 0x%lx\n"),
1253 (unsigned long) elf_header.e_version);
1254
1255 printf (_(" Data: %s"),
1256 get_machine_data (elf_header.e_ident [EI_DATA]));
1257 if (must_swap)
1258 printf (_(" [byte swapping]"));
1259 putchar ('\n');
1260
1261 printf (_(" Entry point address: 0x%lx\n"),
1262 (unsigned long) elf_header.e_entry);
1263 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1264 (long) elf_header.e_phoff);
1265 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1266 (long) elf_header.e_shoff);
1267 printf (_(" Flags: 0x%lx%s\n"),
1268 (unsigned long) elf_header.e_flags,
1269 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1270 printf (_(" Size of this header: %ld (bytes)\n"),
1271 (long) elf_header.e_ehsize);
1272 printf (_(" Size of program headers: %ld (bytes)\n"),
1273 (long) elf_header.e_phentsize);
1274 printf (_(" Number of program headers: %ld\n"),
1275 (long) elf_header.e_phnum);
1276 printf (_(" Size of section headers: %ld (bytes)\n"),
1277 (long) elf_header.e_shentsize);
1278 printf (_(" Number of section headers: %ld\n"),
1279 (long) elf_header.e_shnum);
1280 printf (_(" Section header string table index: %ld\n"),
1281 (long) elf_header.e_shstrndx);
1282 }
1283
1284 return 1;
1285 }
1286
1287
1288 static void
1289 process_program_headers (file)
1290 FILE * file;
1291 {
1292 Elf_Phdr * program_headers;
1293 Elf_Phdr * segment;
1294 int i;
1295
1296 if (elf_header.e_phnum == 0)
1297 {
1298 if (do_segments)
1299 printf (_("\nThere are no program headers in this file.\n"));
1300 return;
1301 }
1302
1303 if (do_segments && !do_header)
1304 {
1305 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1306 printf (_("Entry point 0x%x\n"), elf_header.e_entry);
1307 printf (_("There are %d program headers, starting at offset %x:\n"),
1308 elf_header.e_phnum, elf_header.e_phoff);
1309 }
1310
1311 GET_DATA_ALLOC (elf_header.e_phoff, elf_header.e_phentsize * elf_header.e_phnum,
1312 program_headers, Elf_Phdr *, "program headers");
1313
1314 if (must_swap)
1315 {
1316 for (i = 0; i < elf_header.e_phnum; i++)
1317 {
1318 BYTE_SWAP (program_headers [i], p_type);
1319 BYTE_SWAP (program_headers [i], p_flags);
1320 BYTE_SWAP (program_headers [i], p_offset);
1321 BYTE_SWAP (program_headers [i], p_vaddr);
1322 BYTE_SWAP (program_headers [i], p_paddr);
1323 BYTE_SWAP (program_headers [i], p_filesz);
1324 BYTE_SWAP (program_headers [i], p_memsz);
1325 BYTE_SWAP (program_headers [i], p_align);
1326 }
1327 }
1328
1329 if (do_segments)
1330 {
1331 printf
1332 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1333 printf
1334 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1335 }
1336
1337 loadaddr = -1;
1338 dynamic_addr = 0;
1339
1340 for (i = 0; i < elf_header.e_phnum; i++)
1341 {
1342 segment = program_headers + i;
1343
1344 if (do_segments)
1345 {
1346 printf (" %-16.16s ", get_segment_type (segment->p_type));
1347 printf ("0x%5.5lx ", segment->p_offset);
1348 printf ("0x%8.8lx ", segment->p_vaddr);
1349 printf ("0x%8.8lx ", segment->p_paddr);
1350 printf ("0x%5.5lx 0x%5.5lx ", segment->p_filesz, segment->p_memsz);
1351 printf ("%c%c%c ",
1352 (segment->p_flags & PF_R ? 'R' : ' '),
1353 (segment->p_flags & PF_W ? 'W' : ' '),
1354 (segment->p_flags & PF_X ? 'E' : ' '));
1355 printf ("%#lx", segment->p_align);
1356 }
1357
1358 switch (segment->p_type)
1359 {
1360 case PT_LOAD:
1361 if (loadaddr == -1)
1362 loadaddr = (segment->p_vaddr & 0xfffff000)
1363 - (segment->p_offset & 0xfffff000);
1364 break;
1365
1366 case PT_DYNAMIC:
1367 if (dynamic_addr)
1368 error (_("more than one dynamic segment\n"));
1369
1370 dynamic_addr = segment->p_offset;
1371 dynamic_size = segment->p_filesz;
1372 break;
1373
1374 case PT_INTERP:
1375 if (fseek (file, segment->p_offset, SEEK_SET))
1376 error (_("Unable to find program interpreter name\n"));
1377 else
1378 {
1379 program_interpreter[0] = 0;
1380 fscanf (file, "%63s", program_interpreter);
1381
1382 if (do_segments)
1383 printf (_("\n [Requesting program interpreter: %s]"),
1384 program_interpreter);
1385 }
1386 break;
1387 }
1388
1389 if (do_segments)
1390 putc ('\n', stdout);
1391 }
1392
1393 if (loadaddr == -1)
1394 {
1395 /* Very strange. */
1396 loadaddr = 0;
1397 }
1398
1399 if (do_segments && section_headers != NULL)
1400 {
1401 printf (_("\n Section to Segment mapping:\n"));
1402 printf (_(" Segment Sections...\n"));
1403
1404 assert (string_table != NULL);
1405
1406 for (i = 0; i < elf_header.e_phnum; i++)
1407 {
1408 int j;
1409 Elf_Shdr * section;
1410
1411 segment = program_headers + i;
1412 section = section_headers;
1413
1414 printf (" %2.2d ", i);
1415
1416 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1417 {
1418 if (section->sh_size > 0
1419 /* Compare allocated sections by VMA, unallocated
1420 sections by file offset. */
1421 && (section->sh_flags & SHF_ALLOC
1422 ? (section->sh_addr >= segment->p_vaddr
1423 && section->sh_addr + section->sh_size
1424 <= segment->p_vaddr + segment->p_memsz)
1425 : (section->sh_offset >= segment->p_offset
1426 && (section->sh_offset + section->sh_size
1427 <= segment->p_offset + segment->p_filesz))))
1428 printf ("%s ", SECTION_NAME (section));
1429 }
1430
1431 putc ('\n',stdout);
1432 }
1433 }
1434
1435 free (program_headers);
1436 }
1437
1438
1439 static void
1440 process_section_headers (file)
1441 FILE * file;
1442 {
1443 Elf_Shdr * section;
1444 int i;
1445
1446 if (elf_header.e_shnum == 0)
1447 {
1448 if (do_sections)
1449 printf (_("\nThere are no sections in this file.\n"));
1450
1451 section_headers = NULL;
1452 return;
1453 }
1454
1455 if (do_sections && !do_header)
1456 printf (_("There are %d section headers, starting at offset %x:\n"),
1457 elf_header.e_shnum, elf_header.e_shoff);
1458
1459 GET_DATA_ALLOC (elf_header.e_shoff,
1460 elf_header.e_shentsize * elf_header.e_shnum,
1461 section_headers, Elf_Shdr *, "section headers");
1462
1463 if (must_swap)
1464 {
1465 for (i = 0; i < elf_header.e_shnum; i++)
1466 {
1467 BYTE_SWAP (section_headers [i], sh_name);
1468 BYTE_SWAP (section_headers [i], sh_type);
1469 BYTE_SWAP (section_headers [i], sh_flags);
1470 BYTE_SWAP (section_headers [i], sh_addr);
1471 BYTE_SWAP (section_headers [i], sh_offset);
1472 BYTE_SWAP (section_headers [i], sh_size);
1473 BYTE_SWAP (section_headers [i], sh_link);
1474 BYTE_SWAP (section_headers [i], sh_info);
1475 BYTE_SWAP (section_headers [i], sh_addralign);
1476 BYTE_SWAP (section_headers [i], sh_entsize);
1477 }
1478 }
1479
1480 /* Read in the string table, so that we have names to display. */
1481 section = section_headers + elf_header.e_shstrndx;
1482
1483 if (section->sh_size != 0)
1484 {
1485 unsigned long string_table_offset;
1486
1487 string_table_offset = section->sh_offset;
1488
1489 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1490 string_table, char *, "string table");
1491 }
1492
1493 /* Scan the sections for the dynamic symbol table
1494 and dynamic string table. */
1495 dynamic_symbols = NULL;
1496 dynamic_strings = NULL;
1497 for (i = 0, section = section_headers;
1498 i < elf_header.e_shnum;
1499 i ++, section ++)
1500 {
1501 if (section->sh_type == SHT_DYNSYM)
1502 {
1503 if (dynamic_symbols != NULL)
1504 {
1505 error (_("File contains multiple dynamic symbol tables\n"));
1506 continue;
1507 }
1508
1509 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1510 dynamic_symbols, Elf_Sym *, "dynamic symbols");
1511
1512 if (must_swap)
1513 {
1514 Elf_Sym * psym;
1515
1516 for (i = 0, psym = dynamic_symbols;
1517 i < section->sh_size / section->sh_entsize;
1518 i ++, psym ++)
1519 {
1520 BYTE_SWAP (* psym, st_name);
1521 BYTE_SWAP (* psym, st_value);
1522 BYTE_SWAP (* psym, st_size);
1523 BYTE_SWAP (* psym, st_shndx);
1524 }
1525 }
1526 }
1527 else if (section->sh_type == SHT_STRTAB
1528 && strcmp (SECTION_NAME (section), ".dynstr") == 0)
1529 {
1530 if (dynamic_strings != NULL)
1531 {
1532 error (_("File contains multiple dynamic string tables\n"));
1533 continue;
1534 }
1535
1536 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1537 dynamic_strings, char *, "dynamic strings");
1538 }
1539 }
1540
1541 if (! do_sections)
1542 return;
1543
1544 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
1545 printf
1546 (_(" [Nr] Name Type Addr Off Size ES Flg Lk In Al\n"));
1547
1548 for (i = 0, section = section_headers;
1549 i < elf_header.e_shnum;
1550 i ++, section ++)
1551 {
1552 printf (" [%2d] %-17.17s", i, SECTION_NAME (section));
1553
1554 printf (" %-15.15s ",get_section_type_name (section->sh_type));
1555 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1556 section->sh_addr,
1557 section->sh_offset,
1558 section->sh_size,
1559 section->sh_entsize);
1560
1561 printf (" %c%c%c %2ld %2lx %ld \n",
1562 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
1563 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
1564 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
1565 section->sh_link,
1566 section->sh_info,
1567 section->sh_addralign);
1568 }
1569 }
1570
1571 /* Process the reloc section. */
1572 static void
1573 process_relocs (file)
1574 FILE * file;
1575 {
1576 unsigned long rel_size;
1577 unsigned long rel_offset;
1578
1579
1580 if (!do_reloc)
1581 return;
1582
1583 if (do_using_dynamic)
1584 {
1585 rel_size = 0;
1586 rel_offset = 0;
1587
1588 if (dynamic_info [DT_REL])
1589 {
1590 rel_offset = dynamic_info [DT_REL];
1591 rel_size = dynamic_info [DT_RELSZ];
1592 }
1593 else if (dynamic_info [DT_RELA])
1594 {
1595 rel_offset = dynamic_info [DT_RELA];
1596 rel_size = dynamic_info [DT_RELASZ];
1597 }
1598 else if (dynamic_info [DT_JMPREL])
1599 {
1600 rel_offset = dynamic_info [DT_JMPREL];
1601 rel_size = dynamic_info [DT_PLTRELSZ];
1602 }
1603
1604 if (rel_size)
1605 {
1606 printf (_("\nRelocation section at offset 0x%x contains %d bytes:\n"),
1607 rel_offset, rel_size);
1608
1609 dump_relocations (file, rel_offset - loadaddr, rel_size,
1610 dynamic_symbols, dynamic_strings);
1611 }
1612 else
1613 printf (_("\nThere are no dynamic relocations in this file.\n"));
1614 }
1615 else
1616 {
1617 Elf_Shdr * section;
1618 unsigned long i;
1619 int found = 0;
1620
1621 assert (string_table != NULL);
1622
1623 for (i = 0, section = section_headers;
1624 i < elf_header.e_shnum;
1625 i++, section ++)
1626 {
1627 if ( section->sh_type != SHT_RELA
1628 && section->sh_type != SHT_REL)
1629 continue;
1630
1631 rel_offset = section->sh_offset;
1632 rel_size = section->sh_size;
1633
1634 if (rel_size)
1635 {
1636 Elf_Shdr * strsec;
1637 Elf_Shdr * symsec;
1638 Elf_Sym * symtab;
1639 char * strtab;
1640
1641 printf (_("\nRelocation section '%s' at offset 0x%x contains %d entries:\n"),
1642 SECTION_NAME (section), rel_offset,
1643 rel_size / section->sh_entsize);
1644
1645 symsec = section_headers + section->sh_link;
1646
1647 GET_DATA_ALLOC (symsec->sh_offset, symsec->sh_size, symtab,
1648 Elf_Sym *, "symbols");
1649
1650 if (must_swap)
1651 {
1652 unsigned int si;
1653
1654 for (si = 0;
1655 si < symsec->sh_size / symsec->sh_entsize;
1656 si ++)
1657 {
1658 BYTE_SWAP (symtab [si], st_name);
1659 BYTE_SWAP (symtab [si], st_value);
1660 BYTE_SWAP (symtab [si], st_size);
1661 BYTE_SWAP (symtab [si], st_shndx);
1662 }
1663 }
1664
1665 strsec = section_headers + symsec->sh_link;
1666
1667 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
1668 char *, "string table");
1669
1670 dump_relocations (file, rel_offset, rel_size, symtab, strtab);
1671
1672 free (strtab);
1673 free (symtab);
1674
1675 found = 1;
1676 }
1677 }
1678
1679 if (! found)
1680 printf (_("\nThere are no relocations in this file.\n"));
1681 }
1682 }
1683
1684
1685 /* Parse the dynamic segment */
1686 static void
1687 process_dynamic_segment (file)
1688 FILE * file;
1689 {
1690 Elf_Dyn * dynamic_segment;
1691 Elf_Dyn * entry;
1692 unsigned int i;
1693
1694 if (dynamic_size == 0)
1695 {
1696 if (do_dynamic)
1697 printf (_("\nThere is no dynamic segment in this file.\n"));
1698
1699 return;
1700 }
1701
1702 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
1703 dynamic_segment, Elf_Dyn *, "dynamic segment");
1704
1705 dynamic_size = dynamic_size / sizeof (Elf_Dyn);
1706
1707 if (must_swap)
1708 {
1709 for (i = 0; i < dynamic_size; i++)
1710 {
1711 BYTE_SWAP (dynamic_segment [i], d_tag);
1712 BYTE_SWAP (dynamic_segment [i], d_un.d_val);
1713 }
1714 }
1715
1716 /* Find the appropriate symbol table. */
1717 if (dynamic_symbols == NULL)
1718 {
1719 for (i = 0, entry = dynamic_segment;
1720 i < dynamic_size;
1721 ++i, ++ entry)
1722 {
1723 unsigned long offset;
1724 long num_syms;
1725
1726 if (entry->d_tag != DT_SYMTAB)
1727 continue;
1728
1729 dynamic_info [DT_SYMTAB] = entry->d_un.d_val;
1730
1731 /* Since we do not know how big the symbol table is,
1732 we default to reading in the entire file (!) and
1733 processing that. This is overkill, I know, but it
1734 should work. */
1735
1736 offset = entry->d_un.d_val - loadaddr;
1737 if (fseek (file, 0, SEEK_END))
1738 error (_("Unable to seek to end of file!"));
1739
1740 num_syms = (ftell (file) - offset) / sizeof (Elf_Sym);
1741
1742 if (num_syms < 1)
1743 {
1744 error (_("Unable to determine the number of symbols to load\n"));
1745 continue;
1746 }
1747
1748 GET_DATA_ALLOC (offset, num_syms * sizeof (Elf_Sym),
1749 dynamic_symbols, Elf_Sym *, "dynamic symbols");
1750
1751 if (must_swap)
1752 {
1753 Elf_Sym * psym;
1754
1755 for (i = 0, psym = dynamic_symbols;
1756 i < num_syms;
1757 i ++, psym ++)
1758 {
1759 BYTE_SWAP (* psym, st_name);
1760 BYTE_SWAP (* psym, st_value);
1761 BYTE_SWAP (* psym, st_size);
1762 BYTE_SWAP (* psym, st_shndx);
1763 }
1764 }
1765
1766 break;
1767 }
1768 }
1769
1770 /* Similarly find a string table. */
1771 if (dynamic_strings == NULL)
1772 {
1773 for (i = 0, entry = dynamic_segment;
1774 i < dynamic_size;
1775 ++i, ++ entry)
1776 {
1777 unsigned long offset;
1778 long str_tab_len;
1779
1780 if (entry->d_tag != DT_STRTAB)
1781 continue;
1782
1783 dynamic_info [DT_STRTAB] = entry->d_un.d_val;
1784
1785 /* Since we do not know how big the string table is,
1786 we default to reading in the entire file (!) and
1787 processing that. This is overkill, I know, but it
1788 should work. */
1789
1790 offset = entry->d_un.d_val - loadaddr;
1791 if (fseek (file, 0, SEEK_END))
1792 error (_("Unable to seek to end of file\n"));
1793 str_tab_len = ftell (file) - offset;
1794
1795 if (str_tab_len < 1)
1796 {
1797 error (_("Unable to determine the length of the dynamic string table\n"));
1798 continue;
1799 }
1800
1801 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
1802 "dynamic string table");
1803
1804 break;
1805 }
1806 }
1807
1808 if (do_dynamic && dynamic_addr)
1809 printf (_("\nDynamic segement at offset 0x%x contains %d entries:\n"),
1810 dynamic_addr, dynamic_size);
1811 if (do_dynamic)
1812 printf (_(" Tag Type Name/Value\n"));
1813
1814 for (i = 0, entry = dynamic_segment;
1815 i < dynamic_size;
1816 i++, entry ++)
1817 {
1818 if (do_dynamic)
1819 printf (_(" 0x%-6.6x (%-11.11s) "),
1820 entry->d_tag,
1821 get_dynamic_type (entry->d_tag));
1822
1823 switch (entry->d_tag)
1824 {
1825 case DT_AUXILIARY:
1826 case DT_FILTER:
1827 if (do_dynamic)
1828 {
1829 if (entry->d_tag == DT_AUXILIARY)
1830 printf (_("Auxiliary library"));
1831 else
1832 printf (_("Filter library"));
1833
1834 if (dynamic_strings)
1835 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
1836 else
1837 printf (": %#lx\n", entry->d_un.d_val);
1838 }
1839 break;
1840
1841 case DT_NULL :
1842 case DT_NEEDED :
1843 case DT_PLTRELSZ:
1844 case DT_PLTGOT :
1845 case DT_HASH :
1846 case DT_STRTAB :
1847 case DT_SYMTAB :
1848 case DT_RELA :
1849 case DT_RELASZ :
1850 case DT_RELAENT :
1851 case DT_STRSZ :
1852 case DT_SYMENT :
1853 case DT_INIT :
1854 case DT_FINI :
1855 case DT_SONAME :
1856 case DT_RPATH :
1857 case DT_SYMBOLIC:
1858 case DT_REL :
1859 case DT_RELSZ :
1860 case DT_RELENT :
1861 case DT_PLTREL :
1862 case DT_DEBUG :
1863 case DT_TEXTREL :
1864 case DT_JMPREL :
1865 dynamic_info [entry->d_tag] = entry->d_un.d_val;
1866
1867 if (do_dynamic)
1868 {
1869 char * name;
1870
1871 if (dynamic_strings == NULL)
1872 name = NULL;
1873 else
1874 name = dynamic_strings + entry->d_un.d_val;
1875
1876 if (name)
1877 {
1878 switch (entry->d_tag)
1879 {
1880 case DT_NEEDED:
1881 printf (_("Shared library: [%s]"), name);
1882
1883 if (strcmp (name, program_interpreter))
1884 printf ("\n");
1885 else
1886 printf (_(" program interpreter\n"));
1887 break;
1888
1889 case DT_SONAME:
1890 printf (_("Library soname: [%s]\n"), name);
1891 break;
1892
1893 case DT_RPATH:
1894 printf (_("Library rpath: [%s]\n"), name);
1895 break;
1896
1897 default:
1898 printf ("%#lx\n", entry->d_un.d_val);
1899 }
1900 }
1901 else
1902 printf ("%#lx\n", entry->d_un.d_val);
1903 }
1904 break;
1905
1906 default:
1907 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
1908 {
1909 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
1910 entry->d_un.d_val;
1911
1912 if (do_dynamic)
1913 printf ("%#lx\n", entry->d_un.d_ptr);
1914 }
1915 break;
1916 }
1917 }
1918
1919 free (dynamic_segment);
1920 }
1921
1922 static char *
1923 get_ver_flags (unsigned short flags)
1924 {
1925 static char buff [32];
1926
1927 buff[0] = 0;
1928
1929 if (flags == 0)
1930 return _("none");
1931
1932 if (flags & VER_FLG_BASE)
1933 strcat (buff, "BASE ");
1934
1935 if (flags & VER_FLG_WEAK)
1936 {
1937 if (flags & VER_FLG_BASE)
1938 strcat (buff, "| ");
1939
1940 strcat (buff, "WEAK ");
1941 }
1942
1943 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
1944 strcat (buff, "| <unknown>");
1945
1946 return buff;
1947 }
1948
1949 /* Display the contents of the version sections. */
1950 static void
1951 process_version_sections (file)
1952 FILE * file;
1953 {
1954 Elf_Shdr * section;
1955 unsigned i;
1956 int found = 0;
1957
1958 if (! do_version)
1959 return;
1960
1961 for (i = 0, section = section_headers;
1962 i < elf_header.e_shnum;
1963 i++, section ++)
1964 {
1965 switch (section->sh_type)
1966 {
1967 case SHT_GNU_verdef:
1968 {
1969 Elf_Verdef * verdef_section;
1970 unsigned int idx;
1971 unsigned int cnt;
1972
1973 found = 1;
1974
1975 printf (_("\nVersion definition section '%s' contains %d entries:\n"),
1976 SECTION_NAME (section), section->sh_info);
1977
1978 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
1979 section->sh_addr, section->sh_offset, section->sh_link,
1980 SECTION_NAME (section_headers + section->sh_link));
1981
1982 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1983 verdef_section, Elf_Verdef *,
1984 "version definition section");
1985
1986 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
1987 {
1988 Elf_Verdef * ent;
1989 Elf_Verdaux * aux;
1990 int j;
1991 int isum;
1992
1993 ent = (Elf_Verdef *) (((char *) verdef_section) + idx);
1994
1995 if (must_swap)
1996 {
1997 BYTE_SWAP (* ent, vd_version);
1998 BYTE_SWAP (* ent, vd_flags);
1999 BYTE_SWAP (* ent, vd_ndx);
2000 BYTE_SWAP (* ent, vd_cnt);
2001 BYTE_SWAP (* ent, vd_hash);
2002 BYTE_SWAP (* ent, vd_aux);
2003 BYTE_SWAP (* ent, vd_next);
2004 }
2005
2006 printf (_(" %#06x: Rev: %d Flags: %s"),
2007 idx, ent->vd_version, get_ver_flags (ent->vd_flags));
2008
2009 printf (_(" Index: %d Cnt: %d "), ent->vd_ndx, ent->vd_cnt);
2010
2011 aux = (Elf_Verdaux *) ((char *) ent + ent->vd_aux);
2012
2013 if (must_swap)
2014 {
2015 BYTE_SWAP (* aux, vda_name);
2016 BYTE_SWAP (* aux, vda_next);
2017 }
2018
2019 if (dynamic_strings)
2020 printf (_("Name: %s\n"), dynamic_strings + aux->vda_name);
2021 else
2022 printf (_("Name index: %d\n"), aux->vda_name);
2023
2024 j = 1;
2025 isum = idx + ent->vd_aux;
2026
2027 while (j < ent->vd_cnt)
2028 {
2029 isum += aux->vda_next;
2030
2031 aux = (Elf_Verdaux *)((char *) aux + aux->vda_next);
2032
2033 if (must_swap)
2034 {
2035 BYTE_SWAP (* aux, vda_name);
2036 BYTE_SWAP (* aux, vda_next);
2037 }
2038
2039 if (dynamic_strings)
2040 printf (_(" %#06x: Parent %d: %s\n"),
2041 isum, j, dynamic_strings + aux->vda_name);
2042 else
2043 printf (_(" %#06x: Parent %d, name index: %d\n"),
2044 isum, j, aux->vda_name);
2045
2046 ++j;
2047 }
2048
2049 idx += ent->vd_next;
2050 }
2051
2052 free (verdef_section);
2053 }
2054 break;
2055
2056 case SHT_GNU_verneed:
2057 {
2058 Elf_Verneed * verneed_section;
2059 unsigned int idx;
2060 unsigned int cnt;
2061
2062 found = 1;
2063
2064 printf (_("\nVersion needs section '%s' contains %d entries:\n"),
2065 SECTION_NAME (section), section->sh_info);
2066
2067 printf (_(" Addr: %#08x Offset: %#08x Link to section: %d (%s)\n"),
2068 section->sh_addr, section->sh_offset, section->sh_link,
2069 SECTION_NAME (section_headers + section->sh_link));
2070
2071 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2072 verneed_section, Elf_Verneed *,
2073 "version need section");
2074
2075 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
2076 {
2077 Elf_Verneed * ent;
2078 Elf_Vernaux * aux;
2079 int j;
2080 int isum;
2081
2082 ent = verneed_section + idx / sizeof (Elf_Verneed);
2083
2084 if (must_swap)
2085 {
2086 BYTE_SWAP (* ent, vn_version);
2087 BYTE_SWAP (* ent, vn_cnt);
2088 BYTE_SWAP (* ent, vn_file);
2089 BYTE_SWAP (* ent, vn_aux);
2090 BYTE_SWAP (* ent, vn_next);
2091 }
2092
2093 printf (_(" %#06x: Version: %d"), idx, ent->vn_version);
2094
2095 if (dynamic_strings)
2096 printf (_(" File: %s"), dynamic_strings + ent->vn_file);
2097 else
2098 printf (_(" File: %x"), ent->vn_file);
2099
2100 printf (_(" Cnt: %d\n"), ent->vn_cnt);
2101
2102 aux = (Elf_Vernaux *)((char *) ent + ent->vn_aux);
2103
2104 for (j = 0, isum = idx + ent->vn_aux; j < ent->vn_cnt; ++j)
2105 {
2106 if (must_swap)
2107 {
2108 BYTE_SWAP (* aux, vna_hash);
2109 BYTE_SWAP (* aux, vna_flags);
2110 BYTE_SWAP (* aux, vna_other);
2111 BYTE_SWAP (* aux, vna_name);
2112 BYTE_SWAP (* aux, vna_next);
2113 }
2114
2115 if (dynamic_strings)
2116 printf (_(" %#06x: Name: %s"),
2117 isum, dynamic_strings + aux->vna_name);
2118 else
2119 printf (_(" %#06x: Name index: %x"),
2120 isum, aux->vna_name);
2121
2122 printf (_(" Flags: %s Version: %d\n"),
2123 get_ver_flags (aux->vna_flags), aux->vna_other);
2124
2125 isum += aux->vna_next;
2126 aux = (Elf_Vernaux *)((char *) aux + aux->vna_next);
2127 }
2128
2129 idx += ent->vn_next;
2130 }
2131 }
2132 break;
2133
2134 case SHT_GNU_versym:
2135 {
2136 Elf_Shdr * link_section = section_headers + section->sh_link;
2137 int total = section->sh_size / section->sh_entsize;
2138 int cnt;
2139 unsigned short * p;
2140 char * strtab;
2141 Elf_Sym * symbols;
2142 Elf_Shdr * string_sec;
2143
2144 found = 1;
2145
2146 GET_DATA_ALLOC (link_section->sh_offset, link_section->sh_size,
2147 symbols, Elf_Sym *, "version symbols section");
2148
2149 if (must_swap)
2150 {
2151 int k;
2152
2153 for (k = link_section->sh_size / link_section->sh_entsize;
2154 k --;)
2155 {
2156 BYTE_SWAP (symbols [k], st_name);
2157 BYTE_SWAP (symbols [k], st_value);
2158 BYTE_SWAP (symbols [k], st_size);
2159 BYTE_SWAP (symbols [k], st_shndx);
2160 }
2161 }
2162
2163 string_sec = section_headers + link_section->sh_link;
2164
2165 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2166 strtab, char *, "version string table");
2167
2168 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2169 SECTION_NAME (section), total);
2170
2171 printf (_(" Addr: %#08x Offset: %#08x Link: %x (%s)\n"),
2172 section->sh_addr, section->sh_offset, section->sh_link,
2173 SECTION_NAME (link_section));
2174
2175 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)] - loadaddr,
2176 total * sizeof (unsigned short), p,
2177 unsigned short *, "version symbol data");
2178
2179 if (must_swap)
2180 {
2181 int k;
2182 for (k = total; k--;)
2183 p [k] = SWAP2 (p [k]);
2184 }
2185
2186 for (cnt = 0; cnt < total; cnt += 4)
2187 {
2188 int j, nn;
2189
2190 printf (" %03x:", cnt);
2191
2192 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2193 switch (p[cnt + j])
2194 {
2195 case 0:
2196 printf (" 0 (*local*) ");
2197 break;
2198
2199 case 1:
2200 printf (" 1 (*global*) ");
2201 break;
2202
2203 default:
2204 nn = printf ("%4x%c", p[cnt + j] & 0x7fff,
2205 p[cnt + j] & 0x8000 ? 'h' : ' ');
2206
2207 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
2208 && section_headers[symbols [cnt + j].st_shndx].sh_type
2209 == SHT_NOBITS)
2210 {
2211 /* We must test both. */
2212 Elf_Verneed vn;
2213 Elf_Vernaux vna;
2214 unsigned long offset;
2215
2216 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2217 - loadaddr;
2218
2219 do
2220 {
2221 unsigned long vna_off;
2222
2223 GET_DATA (offset, vn, "version need");
2224
2225 if (must_swap)
2226 {
2227 BYTE_SWAP (vn, vn_aux);
2228 BYTE_SWAP (vn, vn_next);
2229 }
2230
2231 vna_off = offset + vn.vn_aux;
2232
2233 do
2234 {
2235 GET_DATA (vna_off, vna,
2236 "version need aux (1)");
2237
2238 if (must_swap)
2239 {
2240 BYTE_SWAP (vna, vna_next);
2241 BYTE_SWAP (vna, vna_other);
2242 }
2243
2244 vna_off += vna.vna_next;
2245 }
2246 while (vna.vna_other != p[cnt + j]
2247 && vna.vna_next != 0);
2248
2249 if (vna.vna_other == p[cnt + j])
2250 {
2251 if (must_swap)
2252 BYTE_SWAP (vna, vna_name);
2253
2254 nn += printf ("(%11.11s)",
2255 strtab + vna.vna_name);
2256 break;
2257 }
2258 else if (vn.vn_next == 0)
2259 {
2260 if (p[cnt + j] != 0x8001)
2261 {
2262 Elf_Verdef vd;
2263 Elf_Verdaux vda;
2264
2265 offset = version_info
2266 [DT_VERSIONTAGIDX (DT_VERDEF)]
2267 - loadaddr;
2268
2269 do
2270 {
2271 GET_DATA (offset, vd,
2272 "version definition");
2273
2274 if (must_swap)
2275 {
2276 BYTE_SWAP (vd, vd_next);
2277 BYTE_SWAP (vd, vd_ndx);
2278 }
2279
2280 offset += vd.vd_next;
2281 }
2282 while (vd.vd_ndx != (p[cnt + j] & 0x7fff)
2283 && vd.vd_next != 0);
2284
2285 if (vd.vd_ndx == (p[cnt + j] & 0x7fff))
2286 {
2287 if (must_swap)
2288 BYTE_SWAP (vd, vd_aux);
2289
2290 GET_DATA (offset + vd.vd_aux, vda,
2291 "version definition aux");
2292
2293 if (must_swap)
2294 BYTE_SWAP (vda, vda_name);
2295
2296 nn += printf ("(%11.11s)",
2297 strtab + vda.vda_name);
2298 }
2299 }
2300
2301 break;
2302 }
2303 else
2304 offset += vn.vn_next;
2305 }
2306 while (vn.vn_next);
2307 }
2308 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
2309 {
2310 Elf_Vernaux a;
2311 Elf_Verneed v;
2312 unsigned long offset;
2313
2314 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2315 - loadaddr;
2316
2317 do
2318 {
2319 unsigned long a_off;
2320
2321 GET_DATA (offset, v, "version need");
2322
2323 if (must_swap)
2324 {
2325 BYTE_SWAP (v, vn_aux);
2326 BYTE_SWAP (v, vn_next);
2327 }
2328
2329 a_off = offset + v.vn_aux;
2330
2331 do
2332 {
2333 GET_DATA (a_off, a, "version need aux (2)");
2334
2335 if (must_swap)
2336 {
2337 BYTE_SWAP (a, vna_next);
2338 BYTE_SWAP (a, vna_other);
2339 }
2340
2341 a_off += a.vna_next;
2342 }
2343 while (a.vna_other != p[cnt + j]
2344 && a.vna_next != 0);
2345
2346 if (a.vna_other == p[cnt + j])
2347 {
2348 if (must_swap)
2349 BYTE_SWAP (a, vna_name);
2350
2351 nn += printf ("(%11.11s)",
2352 strtab + a.vna_name);
2353
2354 break;
2355 }
2356
2357 offset += v.vn_next;
2358 }
2359 while (v.vn_next);
2360 }
2361 else
2362 {
2363 if (p[cnt + j] != 0x8001)
2364 {
2365 Elf_Verdaux a;
2366 Elf_Verdef v;
2367 unsigned long offset;
2368
2369 offset = version_info
2370 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
2371
2372 do
2373 {
2374 GET_DATA (offset, v, "version def");
2375
2376 if (must_swap)
2377 {
2378 BYTE_SWAP (v, vd_next);
2379 BYTE_SWAP (v, vd_ndx);
2380 }
2381
2382 offset += v.vd_next;
2383 }
2384 while (v.vd_ndx != (p[cnt + j] & 0x7fff)
2385 && v.vd_next != 0);
2386
2387 if (v.vd_ndx == (p[cnt + j] & 0x7fff))
2388 {
2389 if (must_swap)
2390 BYTE_SWAP (v, vd_aux);
2391
2392 GET_DATA (offset - v.vd_next + v.vd_aux, a,
2393 "version def aux");
2394
2395 if (must_swap)
2396 BYTE_SWAP (a, vda_name);
2397
2398 nn += printf ("(%11.11s)",
2399 strtab + a.vda_name);
2400 }
2401 }
2402 }
2403
2404 if (nn < 18)
2405 printf ("%*c", 18 - nn, ' ');
2406 }
2407
2408 putchar ('\n');
2409 }
2410
2411 free (p);
2412 free (strtab);
2413 free (symbols);
2414 }
2415 break;
2416
2417 default:
2418 }
2419 }
2420
2421 if (! found)
2422 printf (_("\nNo version information found in this file.\n"));
2423 }
2424
2425 static char *
2426 get_symbol_binding (binding)
2427 unsigned int binding;
2428 {
2429 static char buff [32];
2430
2431 switch (binding)
2432 {
2433 case STB_LOCAL: return _("LOCAL");
2434 case STB_GLOBAL: return _("GLOBAL");
2435 case STB_WEAK: return _("WEAK");
2436 default:
2437 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
2438 sprintf (buff, _("<processor specific>: %d"), binding);
2439 else
2440 sprintf (buff, _("<unknown>: %d"), binding);
2441 return buff;
2442 }
2443 }
2444
2445 static char *
2446 get_symbol_type (type)
2447 unsigned int type;
2448 {
2449 static char buff [32];
2450
2451 switch (type)
2452 {
2453 case STT_NOTYPE: return _("NOTYPE");
2454 case STT_OBJECT: return _("OBJECT");
2455 case STT_FUNC: return _("FUNC");
2456 case STT_SECTION: return _("SECTION");
2457 case STT_FILE: return _("FILE");
2458 default:
2459 if (type >= STT_LOPROC && type <= STT_HIPROC)
2460 sprintf (buff, _("<processor specific>: %d"), type);
2461 else
2462 sprintf (buff, _("<unknown>: %d"), type);
2463 return buff;
2464 }
2465 }
2466
2467 static char *
2468 get_symbol_index_type (type)
2469 unsigned short type;
2470 {
2471 switch (type)
2472 {
2473 case SHN_UNDEF: return "UND";
2474 case SHN_ABS: return "ABS";
2475 case SHN_COMMON: return "COM";
2476 default:
2477 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
2478 return "PRC";
2479 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
2480 return "RSV";
2481 else
2482 {
2483 static char buff [32];
2484
2485 sprintf (buff, "%3d", type);
2486 return buff;
2487 }
2488 }
2489 }
2490
2491
2492 /* Dump the symbol table */
2493 static void
2494 process_symbol_table (file)
2495 FILE * file;
2496 {
2497 Elf_Shdr * section;
2498
2499 if (! do_syms)
2500 return;
2501
2502 if (dynamic_info [DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
2503 {
2504 int nbuckets;
2505 int nchains;
2506 int * buckets;
2507 int * chains;
2508 int hn;
2509 int si;
2510
2511 if (fseek (file, dynamic_info [DT_HASH] - loadaddr, SEEK_SET))
2512 {
2513 error (_("Unable to seek to start of dynamic information"));
2514 return;
2515 }
2516
2517 if (fread (& nbuckets, sizeof (nbuckets), 1, file) != 1)
2518 {
2519 error (_("Failed to read in number of buckets\n"));
2520 return;
2521 }
2522
2523 if (fread (& nchains, sizeof (nchains), 1, file) != 1)
2524 {
2525 error (_("Failed to read in number of chains\n"));
2526 return;
2527 }
2528
2529 if (must_swap)
2530 {
2531 nbuckets = SWAP4 (nbuckets);
2532 nchains = SWAP4 (nchains);
2533 }
2534
2535 buckets = (int *) malloc (nbuckets * sizeof (* buckets));
2536 if (buckets == NULL)
2537 {
2538 error (_("Failed to allocate space for buckets\n"));
2539 return;
2540 }
2541
2542 if (fread (buckets, sizeof (* buckets), nbuckets, file) != nbuckets)
2543 {
2544 error (_("Unable to read in buckets\n"));
2545 return;
2546 }
2547
2548 chains = (int *) malloc (nchains * sizeof (* chains));
2549 if (chains == NULL)
2550 {
2551 error (_("Failed to allocate space for chains\n"));
2552 free (buckets);
2553 return;
2554 }
2555
2556 if (fread (chains, sizeof (* chains), nchains, file) != nchains)
2557 {
2558 error (_("Unable to read in chains!\n"));
2559 free (buckets);
2560 return;
2561 }
2562
2563 if (must_swap)
2564 {
2565 for (si = nbuckets; si--;)
2566 buckets [si] = SWAP4 (buckets [si]);
2567
2568 for (si = nchains; si--;)
2569 chains [si] = SWAP4 (chains [si]);
2570 }
2571
2572 printf (_("\nSymbol table for image:\n"));
2573 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
2574
2575 for (hn = 0; hn < nbuckets; hn++)
2576 {
2577 if (! buckets [hn])
2578 continue;
2579
2580 for (si = buckets [hn]; si; si = chains [si])
2581 {
2582 Elf_Sym * psym;
2583
2584 psym = dynamic_symbols + si;
2585
2586 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ", si, hn,
2587 psym->st_value,
2588 psym->st_size,
2589 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
2590 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
2591 psym->st_other);
2592
2593 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
2594
2595 printf (" %s\n", dynamic_strings + psym->st_name);
2596 }
2597 }
2598
2599 free (buckets);
2600 free (chains);
2601 }
2602 else if (!do_using_dynamic)
2603 {
2604 unsigned int i;
2605
2606 for (i = 0, section = section_headers;
2607 i < elf_header.e_shnum;
2608 i++, section++)
2609 {
2610 unsigned int si;
2611 char * strtab;
2612 Elf_Sym * symtab;
2613 Elf_Sym * psym;
2614
2615
2616 if ( section->sh_type != SHT_SYMTAB
2617 && section->sh_type != SHT_DYNSYM)
2618 continue;
2619
2620 printf (_("\nSymbol table '%s' contains %d entries:\n"),
2621 SECTION_NAME (section),
2622 section->sh_size / section->sh_entsize);
2623 printf (_(" Num: Value Size Type Bind Ot Ndx Name\n"));
2624
2625 GET_DATA_ALLOC (section->sh_offset, section->sh_size, symtab,
2626 Elf_Sym *, "symbol section");
2627
2628 if (must_swap)
2629 {
2630 for (si = 0; si < section->sh_size / section->sh_entsize; si ++)
2631 {
2632 BYTE_SWAP (symtab [si], st_name);
2633 BYTE_SWAP (symtab [si], st_value);
2634 BYTE_SWAP (symtab [si], st_size);
2635 BYTE_SWAP (symtab [si], st_shndx);
2636 }
2637 }
2638
2639 if (section->sh_link == elf_header.e_shstrndx)
2640 strtab = string_table;
2641 else
2642 {
2643 Elf_Shdr * string_sec = section_headers + section->sh_link;
2644
2645 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2646 strtab, char *, "string table");
2647 }
2648
2649 for (si = 0, psym = symtab;
2650 si < section->sh_size / section->sh_entsize;
2651 si ++, psym ++)
2652 {
2653 printf (" %3d: %8lx %5ld %-7s %-6s %2d ", si,
2654 psym->st_value,
2655 psym->st_size,
2656 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
2657 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
2658 psym->st_other);
2659
2660 if (psym->st_shndx == 0)
2661 printf ("UND");
2662 else if ((psym->st_shndx & 0xffff) == 0xfff1)
2663 printf ("ABS");
2664 else if ((psym->st_shndx & 0xffff) == 0xfff2)
2665 printf ("COM");
2666 else
2667 printf ("%3d", psym->st_shndx);
2668
2669 printf (" %s", strtab + psym->st_name);
2670
2671 if (section->sh_type == SHT_DYNSYM &&
2672 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
2673 {
2674 unsigned short vers_data;
2675 unsigned long offset;
2676 int is_nobits;
2677 int check_def;
2678
2679 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2680 - loadaddr;
2681
2682 GET_DATA (offset + si * sizeof (vers_data), vers_data,
2683 "version data");
2684
2685 if (must_swap)
2686 vers_data = SWAP2 (vers_data);
2687
2688 is_nobits = psym->st_shndx < SHN_LORESERVE ?
2689 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
2690 : 0;
2691
2692 check_def = (psym->st_shndx != SHN_UNDEF);
2693
2694 if ((vers_data & 0x8000) || vers_data > 1)
2695 {
2696 if (is_nobits || ! check_def)
2697 {
2698 Elf_Verneed vn;
2699 Elf_Vernaux vna;
2700
2701 /* We must test both. */
2702 offset = version_info
2703 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
2704
2705 GET_DATA (offset, vn, "version need");
2706
2707 if (must_swap)
2708 {
2709 BYTE_SWAP (vn, vn_aux);
2710 BYTE_SWAP (vn, vn_next);
2711 }
2712
2713 do
2714 {
2715 unsigned long vna_off;
2716
2717 vna_off = offset + vn.vn_aux;
2718
2719 do
2720 {
2721 GET_DATA (vna_off, vna,
2722 "version need aux (3)");
2723
2724 if (must_swap)
2725 {
2726 BYTE_SWAP (vna, vna_other);
2727 BYTE_SWAP (vna, vna_next);
2728 }
2729
2730 vna_off += vna.vna_next;
2731 }
2732 while (vna.vna_other != vers_data
2733 && vna.vna_next != 0);
2734
2735 if (vna.vna_other == vers_data)
2736 break;
2737
2738 offset += vn.vn_next;
2739 }
2740 while (vn.vn_next != 0);
2741
2742 if (vna.vna_other == vers_data)
2743 printf ("@%s (%d)",
2744 strtab + vna.vna_name, vna.vna_other);
2745 else if (! is_nobits)
2746 error (_("bad dynamic symbol"));
2747 else
2748 check_def = 1;
2749 }
2750
2751 if (check_def)
2752 {
2753 if (vers_data != 0x8001)
2754 {
2755 Elf_Verdef vd;
2756 Elf_Verdaux vda;
2757 unsigned long offset;
2758
2759 offset =
2760 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
2761 - loadaddr;
2762
2763 do
2764 {
2765 GET_DATA (offset, vd, "version def");
2766
2767 if (must_swap)
2768 {
2769 BYTE_SWAP (vd, vd_ndx);
2770 BYTE_SWAP (vd, vd_aux);
2771 BYTE_SWAP (vd, vd_next);
2772 }
2773
2774 offset += vd.vd_next;
2775 }
2776 while (vd.vd_ndx != (vers_data & 0x7fff)
2777 && vd.vd_next != 0);
2778
2779 offset -= vd.vd_next;
2780 offset += vd.vd_aux;
2781
2782 GET_DATA (offset, vda, "version def aux");
2783
2784 if (must_swap)
2785 BYTE_SWAP (vda, vda_name);
2786
2787 if (psym->st_name != vda.vda_name)
2788 printf ((vers_data & 0x8000)
2789 ? "@%s" : "@@%s",
2790 strtab + vda.vda_name);
2791 }
2792 }
2793 }
2794 }
2795
2796 putchar ('\n');
2797 }
2798
2799 free (symtab);
2800 if (strtab != string_table)
2801 free (strtab);
2802 }
2803 }
2804 else
2805 printf
2806 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
2807 }
2808
2809 static void
2810 process_section_contents (file)
2811 FILE * file;
2812 {
2813 Elf_Shdr * section;
2814 unsigned int i;
2815
2816 if (! do_dump)
2817 return;
2818
2819 for (i = 0, section = section_headers;
2820 i < elf_header.e_shnum;
2821 i ++, section ++)
2822 {
2823 #ifdef SUPPORT_DISASSEMBLY
2824 /* See if we need an assembly dump of this section */
2825
2826 if ((i < NUM_DUMP_SECTS) && (dump_sects[i] & DISASS_DUMP))
2827 {
2828 printf (_("\nAssembly dump of section %s\n"),
2829 SECTION_NAME (section));
2830
2831 /* XXX -- to be done --- XXX */
2832 }
2833 #endif
2834 /* See if we need a hex dump of this section. */
2835 if ((i < NUM_DUMP_SECTS) && (dump_sects[i] & HEX_DUMP))
2836 {
2837 int bytes;
2838 int addr;
2839 unsigned char * data;
2840 char * start;
2841
2842 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
2843
2844 bytes = section->sh_size;
2845 addr = section->sh_addr;
2846
2847 GET_DATA_ALLOC (section->sh_offset, bytes, start, char *,
2848 "section data");
2849
2850 data = start;
2851
2852 while (bytes)
2853 {
2854 int j;
2855 int k;
2856 int lbytes;
2857
2858 lbytes = (bytes > 16 ? 16 : bytes);
2859
2860 printf (" 0x%8.8x ", addr);
2861
2862 switch (elf_header.e_ident [EI_DATA])
2863 {
2864 case ELFDATA2LSB:
2865 for (j = 15; j >= 0; j --)
2866 {
2867 if (j < lbytes)
2868 printf ("%2.2x", data [j]);
2869 else
2870 printf (" ");
2871
2872 if (!(j & 0x3))
2873 printf (" ");
2874 }
2875 break;
2876
2877 case ELFDATA2MSB:
2878 for (j = 0; j < 16; j++)
2879 {
2880 if (j < lbytes)
2881 printf ("%2.2x", data [j]);
2882 else
2883 printf (" ");
2884
2885 if ((j & 3) == 3)
2886 printf (" ");
2887 }
2888 break;
2889 }
2890
2891 for (j = 0; j < lbytes; j++)
2892 {
2893 k = data [j];
2894 if (k >= ' ' && k < 0x80)
2895 printf ("%c", k);
2896 else
2897 printf (".");
2898 }
2899
2900 putchar ('\n');
2901
2902 data += lbytes;
2903 addr += lbytes;
2904 bytes -= lbytes;
2905 }
2906
2907 free (start);
2908 }
2909 }
2910 }
2911
2912 static void
2913 process_file (file_name)
2914 char * file_name;
2915 {
2916 FILE * file;
2917 struct stat statbuf;
2918 unsigned int i;
2919
2920 if (stat (file_name, & statbuf) < 0)
2921 {
2922 error (_("Cannot stat input file %s.\n"), file_name);
2923 return;
2924 }
2925
2926 file = fopen (file_name, "rb");
2927 if (file == NULL)
2928 {
2929 error (_("Input file %s not found.\n"), file_name);
2930 return;
2931 }
2932
2933 if (fread (& elf_header, sizeof (elf_header), 1, file) != 1)
2934 {
2935 error (_("%s: Failed to read file header\n"), file_name);
2936 fclose (file);
2937 return;
2938 }
2939
2940 /* Initialise per file variables. */
2941 must_swap = 0;
2942
2943 for (i = NUM_ELEM (version_info); i--;)
2944 version_info [i] = 0;
2945
2946 for (i = NUM_ELEM (dynamic_info); i--;)
2947 dynamic_info [i] = 0;
2948
2949
2950 /* Process the file. */
2951 if (show_name)
2952 printf (_("\nFile: %s\n"), file_name);
2953
2954 if (! process_file_header ())
2955 {
2956 fclose (file);
2957 return;
2958 }
2959
2960 process_section_headers (file);
2961
2962 process_program_headers (file);
2963
2964 process_dynamic_segment (file);
2965
2966 process_relocs (file);
2967
2968 process_symbol_table (file);
2969
2970 process_version_sections (file);
2971
2972 process_section_contents (file);
2973
2974 fclose (file);
2975
2976 if (section_headers)
2977 {
2978 free (section_headers);
2979 section_headers = NULL;
2980 }
2981
2982 if (string_table)
2983 {
2984 free (string_table);
2985 string_table = NULL;
2986 }
2987
2988 if (dynamic_strings)
2989 {
2990 free (dynamic_strings);
2991 dynamic_strings = NULL;
2992 }
2993
2994 if (dynamic_symbols)
2995 {
2996 free (dynamic_symbols);
2997 dynamic_symbols = NULL;
2998 }
2999 }
3000
3001 #ifdef SUPPORT_DISASSEMBLY
3002 /* Needed by the i386 disassembler. For extra credit, someone could
3003 fix this so that we insert symbolic addresses here, esp for GOT/PLT
3004 symbols */
3005
3006 void
3007 print_address (unsigned int addr, FILE * outfile)
3008 {
3009 fprintf (outfile,"0x%8.8x", addr);
3010 }
3011
3012 /* Needed by the i386 disassembler. */
3013 void
3014 db_task_printsym (unsigned int addr)
3015 {
3016 print_address (addr, stderr);
3017 }
3018 #endif
3019
3020 int
3021 main (argc, argv)
3022 int argc;
3023 char ** argv;
3024 {
3025 parse_args (argc, argv);
3026
3027 expected_endian = 0x12345678;
3028
3029 if (* ((char *) & expected_endian) == 0x12)
3030 expected_endian = ELFDATA2MSB;
3031 else
3032 expected_endian = ELFDATA2LSB;
3033
3034 if (optind < (argc - 1))
3035 show_name = 1;
3036
3037 while (optind < argc)
3038 process_file (argv [optind ++]);
3039
3040 return 0;
3041 }