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