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