*** empty log message ***
[binutils.git] / binutils / readelf.c
blobb0d3d5505b7719deb35bd32e09277e5c0c59cc64
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@cygnus.com>
7 This file is part of GNU Binutils.
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.
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.
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. */
25 #include <assert.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <time.h>
30 #include "bfd.h"
32 #include "elf/common.h"
33 #include "elf/external.h"
34 #include "elf/internal.h"
35 #include "elf/dwarf2.h"
37 /* The following headers use the elf/reloc-macros.h file to
38 automatically generate relocation recognition functions
39 such as elf_mips_reloc_type() */
41 #define RELOC_MACROS_GEN_FUNC
43 #include "elf/i386.h"
44 #include "elf/v850.h"
45 #include "elf/ppc.h"
46 #include "elf/mips.h"
47 #include "elf/alpha.h"
48 #include "elf/arm.h"
49 #include "elf/m68k.h"
50 #include "elf/sparc.h"
51 #include "elf/m32r.h"
52 #include "elf/d10v.h"
53 #include "elf/d30v.h"
54 #include "elf/sh.h"
55 #include "elf/mn10200.h"
56 #include "elf/mn10300.h"
57 #include "elf/hppa.h"
58 #include "elf/arc.h"
59 #include "elf/fr30.h"
60 #include "elf/mcore.h"
62 #include "bucomm.h"
63 #include "getopt.h"
65 #ifdef ANSI_PROTOTYPES
66 #include <stdarg.h>
67 #else
68 #include <varargs.h>
69 #endif
71 char * program_name = "readelf";
72 unsigned int dynamic_addr;
73 unsigned int dynamic_size;
74 unsigned int rela_addr;
75 unsigned int rela_size;
76 char * dynamic_strings;
77 char * string_table;
78 Elf_Internal_Sym * dynamic_symbols;
79 Elf_Internal_Syminfo * dynamic_syminfo;
80 unsigned long dynamic_syminfo_offset;
81 unsigned int dynamic_syminfo_nent;
82 char program_interpreter [64];
83 int dynamic_info[DT_JMPREL + 1];
84 int version_info[16];
85 int loadaddr = 0;
86 Elf_Internal_Ehdr elf_header;
87 Elf_Internal_Shdr * section_headers;
88 Elf_Internal_Dyn * dynamic_segment;
89 int show_name;
90 int do_dynamic;
91 int do_syms;
92 int do_reloc;
93 int do_sections;
94 int do_segments;
95 int do_using_dynamic;
96 int do_header;
97 int do_dump;
98 int do_version;
99 int do_histogram;
100 int do_debugging;
101 int do_debug_info;
102 int do_debug_abbrevs;
103 int do_debug_lines;
104 int do_debug_pubnames;
105 int do_debug_aranges;
106 int binary_class;
108 /* A dynamic array of flags indicating which sections require dumping. */
109 char * dump_sects = NULL;
110 unsigned int num_dump_sects = 0;
112 #define HEX_DUMP (1 << 0)
113 #define DISASS_DUMP (1 << 1)
114 #define DEBUG_DUMP (1 << 2)
116 /* Forward declarations for dumb compilers. */
117 static unsigned long (* byte_get) PARAMS ((unsigned char *, int));
118 static const char * get_mips_dynamic_type PARAMS ((unsigned long type));
119 static const char * get_dynamic_type PARAMS ((unsigned long type));
120 static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *));
121 static char * get_file_type PARAMS ((unsigned e_type));
122 static char * get_machine_name PARAMS ((unsigned e_machine));
123 static char * get_machine_data PARAMS ((unsigned e_data));
124 static char * get_machine_flags PARAMS ((unsigned, unsigned e_machine));
125 static const char * get_mips_segment_type PARAMS ((unsigned long type));
126 static const char * get_segment_type PARAMS ((unsigned long p_type));
127 static const char * get_mips_section_type_name PARAMS ((unsigned int sh_type));
128 static const char * get_section_type_name PARAMS ((unsigned int sh_type));
129 static char * get_symbol_binding PARAMS ((unsigned int binding));
130 static char * get_symbol_type PARAMS ((unsigned int type));
131 static void usage PARAMS ((void));
132 static void parse_args PARAMS ((int argc, char ** argv));
133 static int process_file_header PARAMS ((void));
134 static int process_program_headers PARAMS ((FILE *));
135 static int process_section_headers PARAMS ((FILE *));
136 static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *entry));
137 static int process_dynamic_segment PARAMS ((FILE *));
138 static int process_symbol_table PARAMS ((FILE *));
139 static int process_section_contents PARAMS ((FILE *));
140 static void process_file PARAMS ((char * file_name));
141 static int process_relocs PARAMS ((FILE *));
142 static int process_version_sections PARAMS ((FILE *));
143 static char * get_ver_flags PARAMS ((unsigned int flags));
144 static char * get_symbol_index_type PARAMS ((unsigned int type));
145 static int get_section_headers PARAMS ((FILE * file));
146 static int get_file_header PARAMS ((FILE * file));
147 static Elf_Internal_Sym * get_elf_symbols PARAMS ((FILE * file, unsigned long offset, unsigned long number));
148 static int * get_dynamic_data PARAMS ((FILE * file, unsigned int number));
149 #ifdef SUPPORT_DISASSEMBLY
150 static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
151 #endif
152 static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
153 static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
154 static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
155 static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
156 static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
157 static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
158 static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
159 static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
160 static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
161 static int process_extended_line_op PARAMS ((unsigned char *, int));
162 static void reset_state_machine PARAMS ((int));
163 static char * get_TAG_name PARAMS ((unsigned long));
164 static char * get_AT_name PARAMS ((unsigned long));
165 static char * get_FORM_name PARAMS ((unsigned long));
166 static void free_abbrevs PARAMS ((void));
167 static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
168 static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
169 static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
170 static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
171 static void decode_location_expression PARAMS ((unsigned char *, unsigned int));
172 static void request_dump PARAMS ((unsigned int, char));
173 static const char * get_elf_class PARAMS ((unsigned char));
174 static const char * get_data_encoding PARAMS ((unsigned char));
175 static const char * get_osabi_name PARAMS ((unsigned char));
177 typedef int Elf32_Word;
179 #define SECTION_NAME(X) (string_table + (X)->sh_name)
181 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
183 #define BYTE_GET(field) byte_get (field, sizeof (field))
185 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
187 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
188 if (fseek (file, offset, SEEK_SET)) \
190 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
191 return 0; \
194 var = (type) malloc (size); \
196 if (var == NULL) \
198 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
199 return 0; \
202 if (fread (var, size, 1, file) != 1) \
204 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
205 free (var); \
206 var = NULL; \
207 return 0; \
211 #define GET_DATA(offset, var, reason) \
212 if (fseek (file, offset, SEEK_SET)) \
214 error (_("Unable to seek to %x for %s\n"), offset, reason); \
215 return 0; \
217 else if (fread (& var, sizeof (var), 1, file) != 1) \
219 error (_("Unable to read data at %x for %s\n"), offset, reason); \
220 return 0; \
223 #ifdef ANSI_PROTOTYPES
224 static void
225 error (const char * message, ...)
227 va_list args;
229 fprintf (stderr, _("%s: Error: "), program_name);
230 va_start (args, message);
231 vfprintf (stderr, message, args);
232 va_end (args);
233 return;
236 static void
237 warn (const char * message, ...)
239 va_list args;
241 fprintf (stderr, _("%s: Warning: "), program_name);
242 va_start (args, message);
243 vfprintf (stderr, message, args);
244 va_end (args);
245 return;
247 #else
248 static void
249 error (va_alist)
250 va_dcl
252 char * message;
253 va_list args;
255 fprintf (stderr, _("%s: Error: "), program_name);
256 va_start (args);
257 message = va_arg (args, char *);
258 vfprintf (stderr, message, args);
259 va_end (args);
260 return;
263 static void
264 warn (va_alist)
265 va_dcl
267 char * message;
268 va_list args;
270 fprintf (stderr, _("%s: Warning: "), program_name);
271 va_start (args);
272 message = va_arg (args, char *);
273 vfprintf (stderr, message, args);
274 va_end (args);
275 return;
277 #endif
279 static unsigned long int
280 byte_get_little_endian (field, size)
281 unsigned char * field;
282 int size;
284 switch (size)
286 case 1:
287 return * field;
289 case 2:
290 return ((unsigned int) (field [0]))
291 | (((unsigned int) (field [1])) << 8);
293 case 4:
294 return ((unsigned long) (field [0]))
295 | (((unsigned long) (field [1])) << 8)
296 | (((unsigned long) (field [2])) << 16)
297 | (((unsigned long) (field [3])) << 24);
299 default:
300 error (_("Unhandled data length: %d\n"), size);
301 abort();
305 static unsigned long int
306 byte_get_big_endian (field, size)
307 unsigned char * field;
308 int size;
310 switch (size)
312 case 1:
313 return * field;
315 case 2:
316 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
318 case 4:
319 return ((unsigned long) (field [3]))
320 | (((unsigned long) (field [2])) << 8)
321 | (((unsigned long) (field [1])) << 16)
322 | (((unsigned long) (field [0])) << 24);
324 default:
325 error (_("Unhandled data length: %d\n"), size);
326 abort();
331 /* Display the contents of the relocation data
332 found at the specified offset. */
333 static int
334 dump_relocations (file, rel_offset, rel_size, symtab, strtab)
335 FILE * file;
336 unsigned long rel_offset;
337 unsigned long rel_size;
338 Elf_Internal_Sym * symtab;
339 char * strtab;
341 unsigned int i;
342 int is_rela;
343 Elf_Internal_Rel * rels;
344 Elf_Internal_Rela * relas;
347 /* Compute number of relocations and read them in. */
348 switch (elf_header.e_machine)
350 /* Targets that use REL relocations. */
351 case EM_ARM:
352 case EM_386:
353 case EM_486:
354 case EM_CYGNUS_M32R:
355 case EM_CYGNUS_D10V:
356 case EM_MIPS:
357 case EM_MIPS_RS4_BE:
359 Elf32_External_Rel * erels;
361 GET_DATA_ALLOC (rel_offset, rel_size, erels,
362 Elf32_External_Rel *, "relocs");
364 rel_size = rel_size / sizeof (Elf32_External_Rel);
366 rels = (Elf_Internal_Rel *) malloc (rel_size *
367 sizeof (Elf_Internal_Rel));
369 for (i = 0; i < rel_size; i++)
371 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
372 rels[i].r_info = BYTE_GET (erels[i].r_info);
375 free (erels);
377 is_rela = 0;
378 relas = (Elf_Internal_Rela *) rels;
380 break;
382 /* Targets that use RELA relocations. */
383 case EM_68K:
384 case EM_SPARC:
385 case EM_PPC:
386 case EM_CYGNUS_V850:
387 case EM_CYGNUS_D30V:
388 case EM_CYGNUS_MN10200:
389 case EM_CYGNUS_MN10300:
390 case EM_CYGNUS_FR30:
391 case EM_SH:
392 case EM_ALPHA:
393 case EM_MCORE:
395 Elf32_External_Rela * erelas;
397 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
398 Elf32_External_Rela *, "relocs");
400 rel_size = rel_size / sizeof (Elf32_External_Rela);
402 relas = (Elf_Internal_Rela *) malloc (rel_size *
403 sizeof (Elf_Internal_Rela));
405 for (i = 0; i < rel_size; i++)
407 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
408 relas[i].r_info = BYTE_GET (erelas[i].r_info);
409 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
412 free (erelas);
414 is_rela = 1;
415 rels = (Elf_Internal_Rel *) relas;
417 break;
419 default:
420 warn (_("Don't know about relocations on this machine architecture\n"));
421 return 0;
424 if (is_rela)
425 printf
426 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
427 else
428 printf
429 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
431 for (i = 0; i < rel_size; i++)
433 const char * rtype;
434 unsigned long offset;
435 unsigned long info;
436 int symtab_index;
438 if (is_rela)
440 offset = relas [i].r_offset;
441 info = relas [i].r_info;
443 else
445 offset = rels [i].r_offset;
446 info = rels [i].r_info;
449 printf (" %8.8lx %5.5lx ", offset, info);
451 switch (elf_header.e_machine)
453 default:
454 rtype = NULL;
455 break;
457 case EM_CYGNUS_M32R:
458 rtype = elf_m32r_reloc_type (ELF32_R_TYPE (info));
459 break;
461 case EM_386:
462 case EM_486:
463 rtype = elf_i386_reloc_type (ELF32_R_TYPE (info));
464 break;
466 case EM_68K:
467 rtype = elf_m68k_reloc_type (ELF32_R_TYPE (info));
468 break;
470 case EM_SPARC:
471 rtype = elf_sparc_reloc_type (ELF32_R_TYPE (info));
472 break;
474 case EM_CYGNUS_V850:
475 rtype = v850_reloc_type (ELF32_R_TYPE (info));
476 break;
478 case EM_CYGNUS_D10V:
479 rtype = elf_d10v_reloc_type (ELF32_R_TYPE (info));
480 break;
482 case EM_CYGNUS_D30V:
483 rtype = elf_d30v_reloc_type (ELF32_R_TYPE (info));
484 break;
486 case EM_SH:
487 rtype = elf_sh_reloc_type (ELF32_R_TYPE (info));
488 break;
490 case EM_CYGNUS_MN10300:
491 rtype = elf_mn10300_reloc_type (ELF32_R_TYPE (info));
492 break;
494 case EM_CYGNUS_MN10200:
495 rtype = elf_mn10200_reloc_type (ELF32_R_TYPE (info));
496 break;
498 case EM_CYGNUS_FR30:
499 rtype = elf_fr30_reloc_type (ELF32_R_TYPE (info));
500 break;
502 case EM_MCORE:
503 rtype = elf_mcore_reloc_type (ELF32_R_TYPE (info));
504 break;
506 case EM_PPC:
507 rtype = elf_ppc_reloc_type (ELF32_R_TYPE (info));
508 break;
510 case EM_MIPS:
511 case EM_MIPS_RS4_BE:
512 rtype = elf_mips_reloc_type (ELF32_R_TYPE (info));
513 break;
515 case EM_ALPHA:
516 rtype = elf_alpha_reloc_type (ELF32_R_TYPE (info));
517 break;
519 case EM_ARM:
520 rtype = elf_arm_reloc_type (ELF32_R_TYPE (info));
521 break;
523 case EM_CYGNUS_ARC:
524 rtype = elf_arc_reloc_type (ELF32_R_TYPE (info));
525 break;
527 case EM_PARISC:
528 rtype = elf32_hppa_reloc_type (ELF32_R_TYPE (info));
529 break;
532 if (rtype == NULL)
533 printf (_("unrecognised: %-7lx"), ELF32_R_TYPE (info));
534 else
535 printf ("%-21.21s", rtype);
537 symtab_index = ELF32_R_SYM (info);
539 if (symtab_index && symtab != NULL)
541 Elf_Internal_Sym * psym;
543 psym = symtab + symtab_index;
545 printf (" %08lx ", (unsigned long) psym->st_value);
547 if (psym->st_name == 0)
548 printf ("%-25.25s",
549 SECTION_NAME (section_headers + psym->st_shndx));
550 else if (strtab == NULL)
551 printf (_("<string table index %3ld>"), psym->st_name);
552 else
553 printf ("%-25.25s", strtab + psym->st_name);
555 if (is_rela)
556 printf (" + %lx", (unsigned long) relas [i].r_addend);
559 putchar ('\n');
562 free (relas);
564 return 1;
567 static const char *
568 get_mips_dynamic_type (type)
569 unsigned long type;
571 switch (type)
573 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
574 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
575 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
576 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
577 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
578 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
579 case DT_MIPS_MSYM: return "MIPS_MSYM";
580 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
581 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
582 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
583 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
584 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
585 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
586 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
587 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
588 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
589 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
590 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
591 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
592 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
593 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
594 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
595 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
596 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
597 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
598 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
599 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
600 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
601 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
602 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
603 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
604 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
605 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
606 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
607 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
608 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
609 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
610 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
611 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
612 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
613 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
614 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
615 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
616 default:
617 return NULL;
621 static const char *
622 get_dynamic_type (type)
623 unsigned long type;
625 static char buff [32];
627 switch (type)
629 case DT_NULL: return "NULL";
630 case DT_NEEDED: return "NEEDED";
631 case DT_PLTRELSZ: return "PLTRELSZ";
632 case DT_PLTGOT: return "PLTGOT";
633 case DT_HASH: return "HASH";
634 case DT_STRTAB: return "STRTAB";
635 case DT_SYMTAB: return "SYMTAB";
636 case DT_RELA: return "RELA";
637 case DT_RELASZ: return "RELASZ";
638 case DT_RELAENT: return "RELAENT";
639 case DT_STRSZ: return "STRSZ";
640 case DT_SYMENT: return "SYMENT";
641 case DT_INIT: return "INIT";
642 case DT_FINI: return "FINI";
643 case DT_SONAME: return "SONAME";
644 case DT_RPATH: return "RPATH";
645 case DT_SYMBOLIC: return "SYMBOLIC";
646 case DT_REL: return "REL";
647 case DT_RELSZ: return "RELSZ";
648 case DT_RELENT: return "RELENT";
649 case DT_PLTREL: return "PLTREL";
650 case DT_DEBUG: return "DEBUG";
651 case DT_TEXTREL: return "TEXTREL";
652 case DT_JMPREL: return "JMPREL";
653 case DT_BIND_NOW: return "BIND_NOW";
654 case DT_INIT_ARRAY: return "INIT_ARRAY";
655 case DT_FINI_ARRAY: return "FINI_ARRAY";
656 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
657 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
659 case DT_PLTPADSZ: return "PLTPADSZ";
660 case DT_MOVEENT: return "MOVEENT";
661 case DT_MOVESZ: return "MOVESZ";
662 case DT_FEATURE_1: return "FEATURE_1";
663 case DT_POSFLAG_1: return "POSFLAG_1";
664 case DT_SYMINSZ: return "SYMINSZ";
665 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
667 case DT_ADDRRNGLO: return "ADDRRNGLO";
668 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
670 case DT_VERSYM: return "VERSYM";
672 case DT_RELACOUNT: return "RELACOUNT";
673 case DT_RELCOUNT: return "RELCOUNT";
674 case DT_FLAGS_1: return "FLAGS_1";
675 case DT_VERDEF: return "VERDEF";
676 case DT_VERDEFNUM: return "VERDEFNUM";
677 case DT_VERNEED: return "VERNEED";
678 case DT_VERNEEDNUM: return "VERNEEDNUM";
680 case DT_AUXILIARY: return "AUXILARY";
681 case DT_USED: return "USED";
682 case DT_FILTER: return "FILTER";
684 default:
685 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
687 const char * result;
689 switch (elf_header.e_machine)
691 case EM_MIPS:
692 case EM_MIPS_RS4_BE:
693 result = get_mips_dynamic_type (type);
694 break;
695 default:
696 result = NULL;
697 break;
700 if (result != NULL)
701 return result;
703 sprintf (buff, _("Processor Specific: %lx"), type);
705 else if ((type >= DT_LOOS) && (type <= DT_HIOS))
706 sprintf (buff, _("Operating System specific: %lx"), type);
707 else
708 sprintf (buff, _("<unknown>: %lx"), type);
710 return buff;
714 static char *
715 get_file_type (e_type)
716 unsigned e_type;
718 static char buff [32];
720 switch (e_type)
722 case ET_NONE: return _("NONE (None)");
723 case ET_REL: return _("REL (Relocatable file)");
724 case ET_EXEC: return _("EXEC (Executable file)");
725 case ET_DYN: return _("DYN (Shared object file)");
726 case ET_CORE: return _("CORE (Core file)");
728 default:
729 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
730 sprintf (buff, _("Processor Specific: (%x)"), e_type);
731 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
732 sprintf (buff, _("OS Specific: (%x)"), e_type);
733 else
734 sprintf (buff, _("<unknown>: %x"), e_type);
735 return buff;
739 static char *
740 get_machine_name (e_machine)
741 unsigned e_machine;
743 static char buff [32];
745 switch (e_machine)
747 case EM_NONE: return _("None");
748 case EM_M32: return "WE32100";
749 case EM_SPARC: return "Sparc";
750 case EM_386: return "Intel 80386";
751 case EM_68K: return "MC68000";
752 case EM_88K: return "MC88000";
753 case EM_486: return "Intel 80486";
754 case EM_860: return "Intel 80860";
755 case EM_MIPS: return "MIPS R3000 big-endian";
756 case EM_S370: return "Amdahl";
757 case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
758 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
759 case EM_PARISC: return "HPPA";
760 case EM_PPC_OLD: return "Power PC (old)";
761 case EM_SPARC32PLUS: return "Sparc v8+" ;
762 case EM_960: return "Intel 90860";
763 case EM_PPC: return "PowerPC";
764 case EM_V800: return "NEC V800";
765 case EM_FR20: return "Fujitsu FR20";
766 case EM_RH32: return "TRW RH32";
767 case EM_MCORE: return "MCORE";
768 case EM_ARM: return "ARM";
769 case EM_OLD_ALPHA: return "Digital Alpha (old)";
770 case EM_SH: return "Hitachi SH";
771 case EM_SPARCV9: return "Sparc v9";
772 case EM_TRICORE: return "Siemens Tricore";
773 case EM_ARC: return "Argonaut RISC Core";
774 case EM_H8_300: return "Hitachi H8/300";
775 case EM_H8_300H: return "Hitachi H8/300H";
776 case EM_H8S: return "Hitachi H8S";
777 case EM_H8_500: return "Hitachi H8/500";
778 case EM_IA_64: return "Intel Merced";
779 case EM_MIPS_X: return "Stanford MIPS-X";
780 case EM_COLDFIRE: return "Motorola Coldfire";
781 case EM_68HC12: return "Motorola M68HC12";
782 case EM_ALPHA: return "Alpha";
783 case EM_CYGNUS_D10V: return "d10v";
784 case EM_CYGNUS_D30V: return "d30v";
785 case EM_CYGNUS_ARC: return "Arc";
786 case EM_CYGNUS_M32R: return "Mitsubishi M32r";
787 case EM_CYGNUS_V850: return "NEC v850";
788 case EM_CYGNUS_MN10300: return "mn10300";
789 case EM_CYGNUS_MN10200: return "mn10200";
790 case EM_CYGNUS_FR30: return "Fujitsu FR30";
792 default:
793 sprintf (buff, _("<unknown>: %x"), e_machine);
794 return buff;
798 static char *
799 get_machine_flags (e_flags, e_machine)
800 unsigned e_flags;
801 unsigned e_machine;
803 static char buf [1024];
805 buf[0] = '\0';
806 if (e_flags)
808 switch (e_machine)
810 default:
811 break;
813 case EM_68K:
814 if (e_flags & EF_CPU32)
815 strcat (buf, ", cpu32");
816 break;
818 case EM_PPC:
819 if (e_flags & EF_PPC_EMB)
820 strcat (buf, ", emb");
822 if (e_flags & EF_PPC_RELOCATABLE)
823 strcat (buf, ", relocatable");
825 if (e_flags & EF_PPC_RELOCATABLE_LIB)
826 strcat (buf, ", relocatable-lib");
827 break;
829 case EM_CYGNUS_V850:
830 switch (e_flags & EF_V850_ARCH)
832 case E_V850E_ARCH:
833 strcat (buf, ", v850e");
834 break;
835 case E_V850EA_ARCH:
836 strcat (buf, ", v850ea");
837 break;
838 case E_V850_ARCH:
839 strcat (buf, ", v850");
840 break;
841 default:
842 strcat (buf, ", unknown v850 architecture variant");
843 break;
845 break;
847 case EM_CYGNUS_M32R:
848 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
849 strcat (buf, ", m32r");
851 break;
853 case EM_MIPS:
854 case EM_MIPS_RS4_BE:
855 if (e_flags & EF_MIPS_NOREORDER)
856 strcat (buf, ", noreorder");
858 if (e_flags & EF_MIPS_PIC)
859 strcat (buf, ", pic");
861 if (e_flags & EF_MIPS_CPIC)
862 strcat (buf, ", cpic");
864 if (e_flags & EF_MIPS_ABI2)
865 strcat (buf, ", abi2");
867 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
868 strcat (buf, ", mips1");
870 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
871 strcat (buf, ", mips2");
873 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
874 strcat (buf, ", mips3");
876 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
877 strcat (buf, ", mips4");
878 break;
882 return buf;
885 static char *
886 get_machine_data (e_data)
887 unsigned e_data;
889 static char buff [32];
891 switch (e_data)
893 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
894 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
895 default:
896 sprintf (buff, _("<unknown>: %x"), e_data);
897 return buff;
901 static const char *
902 get_mips_segment_type (type)
903 unsigned long type;
905 switch (type)
907 case PT_MIPS_REGINFO:
908 return "REGINFO";
909 case PT_MIPS_RTPROC:
910 return "RTPROC";
911 case PT_MIPS_OPTIONS:
912 return "OPTIONS";
913 default:
914 break;
917 return NULL;
920 static const char *
921 get_segment_type (p_type)
922 unsigned long p_type;
924 static char buff [32];
926 switch (p_type)
928 case PT_NULL: return "NULL";
929 case PT_LOAD: return "LOAD";
930 case PT_DYNAMIC: return "DYNAMIC";
931 case PT_INTERP: return "INTERP";
932 case PT_NOTE: return "NOTE";
933 case PT_SHLIB: return "SHLIB";
934 case PT_PHDR: return "PHDR";
936 default:
937 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
939 const char * result;
941 switch (elf_header.e_machine)
943 case EM_MIPS:
944 case EM_MIPS_RS4_BE:
945 result = get_mips_segment_type (p_type);
946 break;
947 default:
948 result = NULL;
949 break;
952 if (result != NULL)
953 return result;
955 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
957 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
958 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
959 else
960 sprintf (buff, _("<unknown>: %lx"), p_type);
962 return buff;
966 static const char *
967 get_mips_section_type_name (sh_type)
968 unsigned int sh_type;
970 switch (sh_type)
972 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
973 case SHT_MIPS_MSYM: return "MIPS_MSYM";
974 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
975 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
976 case SHT_MIPS_UCODE: return "MIPS_UCODE";
977 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
978 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
979 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
980 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
981 case SHT_MIPS_RELD: return "MIPS_RELD";
982 case SHT_MIPS_IFACE: return "MIPS_IFACE";
983 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
984 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
985 case SHT_MIPS_SHDR: return "MIPS_SHDR";
986 case SHT_MIPS_FDESC: return "MIPS_FDESC";
987 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
988 case SHT_MIPS_DENSE: return "MIPS_DENSE";
989 case SHT_MIPS_PDESC: return "MIPS_PDESC";
990 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
991 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
992 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
993 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
994 case SHT_MIPS_LINE: return "MIPS_LINE";
995 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
996 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
997 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
998 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
999 case SHT_MIPS_DWARF: return "MIPS_DWARF";
1000 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
1001 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1002 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
1003 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
1004 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
1005 case SHT_MIPS_XLATE: return "MIPS_XLATE";
1006 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
1007 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
1008 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
1009 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
1010 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1011 default:
1012 break;
1014 return NULL;
1017 static const char *
1018 get_section_type_name (sh_type)
1019 unsigned int sh_type;
1021 static char buff [32];
1023 switch (sh_type)
1025 case SHT_NULL: return "NULL";
1026 case SHT_PROGBITS: return "PROGBITS";
1027 case SHT_SYMTAB: return "SYMTAB";
1028 case SHT_STRTAB: return "STRTAB";
1029 case SHT_RELA: return "RELA";
1030 case SHT_HASH: return "HASH";
1031 case SHT_DYNAMIC: return "DYNAMIC";
1032 case SHT_NOTE: return "NOTE";
1033 case SHT_NOBITS: return "NOBITS";
1034 case SHT_REL: return "REL";
1035 case SHT_SHLIB: return "SHLIB";
1036 case SHT_DYNSYM: return "DYNSYM";
1037 case SHT_GNU_verdef: return "VERDEF";
1038 case SHT_GNU_verneed: return "VERNEED";
1039 case SHT_GNU_versym: return "VERSYM";
1040 case 0x6ffffff0: return "VERSYM";
1041 case 0x6ffffffc: return "VERDEF";
1042 case 0x7ffffffd: return "AUXILIARY";
1043 case 0x7fffffff: return "FILTER";
1045 default:
1046 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1048 const char * result;
1050 switch (elf_header.e_machine)
1052 case EM_MIPS:
1053 case EM_MIPS_RS4_BE:
1054 result = get_mips_section_type_name (sh_type);
1055 break;
1056 default:
1057 result = NULL;
1058 break;
1061 if (result != NULL)
1062 return result;
1064 sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1066 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1067 sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1068 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1069 sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1070 else
1071 sprintf (buff, _("<unknown>: %x"), sh_type);
1073 return buff;
1077 struct option options [] =
1079 {"all", no_argument, 0, 'a'},
1080 {"file-header", no_argument, 0, 'h'},
1081 {"program-headers", no_argument, 0, 'l'},
1082 {"headers", no_argument, 0, 'e'},
1083 {"histogram", no_argument, & do_histogram, 1},
1084 {"segments", no_argument, 0, 'l'},
1085 {"sections", no_argument, 0, 'S'},
1086 {"section-headers", no_argument, 0, 'S'},
1087 {"symbols", no_argument, 0, 's'},
1088 {"syms", no_argument, 0, 's'},
1089 {"relocs", no_argument, 0, 'r'},
1090 {"dynamic", no_argument, 0, 'd'},
1091 {"version-info", no_argument, 0, 'V'},
1092 {"use-dynamic", no_argument, 0, 'D'},
1093 {"hex-dump", required_argument, 0, 'x'},
1094 {"debug-dump", optional_argument, 0, 'w'},
1095 #ifdef SUPPORT_DISASSEMBLY
1096 {"instruction-dump", required_argument, 0, 'i'},
1097 #endif
1099 {"version", no_argument, 0, 'v'},
1100 {"help", no_argument, 0, 'H'},
1101 {0, no_argument, 0, 0}
1104 static void
1105 usage ()
1107 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1108 fprintf (stdout, _(" Options are:\n"));
1109 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1110 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1111 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1112 fprintf (stdout, _(" Display the program headers\n"));
1113 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1114 fprintf (stdout, _(" Display the sections' header\n"));
1115 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1116 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1117 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1118 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1119 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1120 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1121 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1122 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1123 fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1124 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1125 #ifdef SUPPORT_DISASSEMBLY
1126 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1127 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1128 #endif
1129 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1130 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1131 fprintf (stdout, _(" -H or --help Display this information\n"));
1132 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1134 exit (0);
1137 static void
1138 request_dump (section, type)
1139 unsigned int section;
1140 char type;
1142 if (section >= num_dump_sects)
1144 char * new_dump_sects;
1146 new_dump_sects = (char *) calloc (section + 1, 1);
1148 if (new_dump_sects == NULL)
1149 error (_("Out of memory allocating dump request table."));
1150 else
1152 /* Copy current flag settings. */
1153 memcpy (new_dump_sects, dump_sects, num_dump_sects);
1155 free (dump_sects);
1157 dump_sects = new_dump_sects;
1158 num_dump_sects = section + 1;
1162 if (dump_sects)
1163 dump_sects [section] |= type;
1165 return;
1168 static void
1169 parse_args (argc, argv)
1170 int argc;
1171 char ** argv;
1173 int c;
1175 if (argc < 2)
1176 usage ();
1178 while ((c = getopt_long
1179 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1181 char * cp;
1182 int section;
1184 switch (c)
1186 case 0:
1187 /* Long options. */
1188 break;
1189 case 'H':
1190 usage ();
1191 break;
1193 case 'a':
1194 do_syms ++;
1195 do_reloc ++;
1196 do_dynamic ++;
1197 do_header ++;
1198 do_sections ++;
1199 do_segments ++;
1200 do_version ++;
1201 do_histogram ++;
1202 break;
1203 case 'e':
1204 do_header ++;
1205 do_sections ++;
1206 do_segments ++;
1207 break;
1208 case 'D':
1209 do_using_dynamic ++;
1210 break;
1211 case 'r':
1212 do_reloc ++;
1213 break;
1214 case 'h':
1215 do_header ++;
1216 break;
1217 case 'l':
1218 do_segments ++;
1219 break;
1220 case 's':
1221 do_syms ++;
1222 break;
1223 case 'S':
1224 do_sections ++;
1225 break;
1226 case 'd':
1227 do_dynamic ++;
1228 break;
1229 case 'x':
1230 do_dump ++;
1231 section = strtoul (optarg, & cp, 0);
1232 if (! * cp && section >= 0)
1234 request_dump (section, HEX_DUMP);
1235 break;
1237 goto oops;
1238 case 'w':
1239 do_dump ++;
1240 if (optarg == 0)
1241 do_debugging = 1;
1242 else
1244 do_debugging = 0;
1245 switch (optarg[0])
1247 case 'i':
1248 case 'I':
1249 do_debug_info = 1;
1250 break;
1252 case 'a':
1253 case 'A':
1254 do_debug_abbrevs = 1;
1255 break;
1257 case 'l':
1258 case 'L':
1259 do_debug_lines = 1;
1260 break;
1262 case 'p':
1263 case 'P':
1264 do_debug_pubnames = 1;
1265 break;
1267 case 'r':
1268 case 'R':
1269 do_debug_aranges = 1;
1270 break;
1272 default:
1273 warn (_("Unrecognised debug option '%s'\n"), optarg);
1274 break;
1277 break;
1278 #ifdef SUPPORT_DISASSEMBLY
1279 case 'i':
1280 do_dump ++;
1281 section = strtoul (optarg, & cp, 0);
1282 if (! * cp && section >= 0)
1284 request_dump (section, DISASS_DUMP);
1285 break;
1287 goto oops;
1288 #endif
1289 case 'v':
1290 print_version (program_name);
1291 break;
1292 case 'V':
1293 do_version ++;
1294 break;
1295 default:
1296 oops:
1297 /* xgettext:c-format */
1298 error (_("Invalid option '-%c'\n"), c);
1299 /* Drop through. */
1300 case '?':
1301 usage ();
1305 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1306 && !do_segments && !do_header && !do_dump && !do_version
1307 && !do_histogram && !do_debugging)
1308 usage ();
1309 else if (argc < 3)
1311 warn (_("Nothing to do.\n"));
1312 usage();
1316 static const char *
1317 get_elf_class (elf_class)
1318 unsigned char elf_class;
1320 switch (elf_class)
1322 case ELFCLASSNONE: return _("none");
1323 case ELFCLASS32: return _("ELF32");
1324 case ELFCLASS64: return _("ELF64");
1325 default: return _("<unknown>");
1329 static const char *
1330 get_data_encoding (encoding)
1331 unsigned char encoding;
1333 switch (encoding)
1335 case ELFDATANONE: return _("none");
1336 case ELFDATA2LSB: return _("2's complement, little endian");
1337 case ELFDATA2MSB: return _("2's complement, big endian");
1338 default: return _("<unknown>");
1342 static const char *
1343 get_osabi_name (osabi)
1344 unsigned char osabi;
1346 switch (osabi)
1348 case ELFOSABI_SYSV: return _("UNIX - System V");
1349 case ELFOSABI_HPUX: return _("UNIX - HP-UX");
1350 case ELFOSABI_STANDALONE: return _("Standalone App");
1351 default: return _("<unknown>");
1355 /* Decode the data held in 'elf_header'. */
1356 static int
1357 process_file_header ()
1359 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1360 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1361 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1362 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1364 error
1365 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1366 return 0;
1369 if (do_header)
1371 int i;
1373 printf (_("ELF Header:\n"));
1374 printf (_(" Magic: "));
1375 for (i = 0; i < EI_NIDENT; i ++)
1376 printf ("%2.2x ", elf_header.e_ident [i]);
1377 printf ("\n");
1378 printf (_(" Class: %s\n"),
1379 get_elf_class (elf_header.e_ident [EI_CLASS]));
1380 printf (_(" Data: %s\n"),
1381 get_data_encoding (elf_header.e_ident [EI_DATA]));
1382 printf (_(" Version: %d %s\n"),
1383 elf_header.e_ident [EI_VERSION],
1384 elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
1385 elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown>" : "");
1386 printf (_(" OS/ABI: %s\n"),
1387 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1388 printf (_(" ABI Version: %d\n"),
1389 elf_header.e_ident [EI_ABIVERSION]);
1390 printf (_(" Type: %s\n"),
1391 get_file_type (elf_header.e_type));
1392 printf (_(" Machine: %s\n"),
1393 get_machine_name (elf_header.e_machine));
1394 printf (_(" Version: 0x%lx\n"),
1395 (unsigned long) elf_header.e_version);
1396 printf (_(" Data: %s\n"),
1397 get_machine_data (elf_header.e_ident [EI_DATA]));
1398 printf (_(" Entry point address: 0x%lx\n"),
1399 (unsigned long) elf_header.e_entry);
1400 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1401 (long) elf_header.e_phoff);
1402 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1403 (long) elf_header.e_shoff);
1404 printf (_(" Flags: 0x%lx%s\n"),
1405 (unsigned long) elf_header.e_flags,
1406 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1407 printf (_(" Size of this header: %ld (bytes)\n"),
1408 (long) elf_header.e_ehsize);
1409 printf (_(" Size of program headers: %ld (bytes)\n"),
1410 (long) elf_header.e_phentsize);
1411 printf (_(" Number of program headers: %ld\n"),
1412 (long) elf_header.e_phnum);
1413 printf (_(" Size of section headers: %ld (bytes)\n"),
1414 (long) elf_header.e_shentsize);
1415 printf (_(" Number of section headers: %ld\n"),
1416 (long) elf_header.e_shnum);
1417 printf (_(" Section header string table index: %ld\n"),
1418 (long) elf_header.e_shstrndx);
1421 /* Test class after dumping header so that at least the header can be
1422 display on 64 bit binaries. */
1424 binary_class = elf_header.e_ident [EI_CLASS];
1425 if (binary_class != ELFCLASS32)
1427 error (_("Not a 32 bit ELF file\n"));
1428 return 0;
1431 return 1;
1435 static int
1436 process_program_headers (file)
1437 FILE * file;
1439 Elf32_External_Phdr * phdrs;
1440 Elf32_Internal_Phdr * program_headers;
1441 Elf32_Internal_Phdr * segment;
1442 unsigned int i;
1444 if (elf_header.e_phnum == 0)
1446 if (do_segments)
1447 printf (_("\nThere are no program headers in this file.\n"));
1448 return 1;
1451 if (do_segments && !do_header)
1453 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1454 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1455 printf (_("There are %d program headers, starting at offset %lx:\n"),
1456 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1459 GET_DATA_ALLOC (elf_header.e_phoff,
1460 elf_header.e_phentsize * elf_header.e_phnum,
1461 phdrs, Elf32_External_Phdr *, "program headers");
1463 program_headers = (Elf32_Internal_Phdr *) malloc
1464 (elf_header.e_phnum * sizeof (Elf32_Internal_Phdr));
1466 if (program_headers == NULL)
1468 error (_("Out of memory\n"));
1469 return 0;
1472 for (i = 0, segment = program_headers;
1473 i < elf_header.e_phnum;
1474 i ++, segment ++)
1476 segment->p_type = BYTE_GET (phdrs[i].p_type);
1477 segment->p_offset = BYTE_GET (phdrs[i].p_offset);
1478 segment->p_vaddr = BYTE_GET (phdrs[i].p_vaddr);
1479 segment->p_paddr = BYTE_GET (phdrs[i].p_paddr);
1480 segment->p_filesz = BYTE_GET (phdrs[i].p_filesz);
1481 segment->p_memsz = BYTE_GET (phdrs[i].p_memsz);
1482 segment->p_flags = BYTE_GET (phdrs[i].p_flags);
1483 segment->p_align = BYTE_GET (phdrs[i].p_align);
1486 free (phdrs);
1488 if (do_segments)
1490 printf
1491 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1492 printf
1493 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1496 loadaddr = -1;
1497 dynamic_addr = 0;
1499 for (i = 0, segment = program_headers;
1500 i < elf_header.e_phnum;
1501 i ++, segment ++)
1503 if (do_segments)
1505 printf (" %-11.11s ", get_segment_type (segment->p_type));
1506 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1507 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1508 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1509 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1510 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1511 printf ("%c%c%c ",
1512 (segment->p_flags & PF_R ? 'R' : ' '),
1513 (segment->p_flags & PF_W ? 'W' : ' '),
1514 (segment->p_flags & PF_X ? 'E' : ' '));
1515 printf ("%#lx", (unsigned long) segment->p_align);
1518 switch (segment->p_type)
1520 case PT_LOAD:
1521 if (loadaddr == -1)
1522 loadaddr = (segment->p_vaddr & 0xfffff000)
1523 - (segment->p_offset & 0xfffff000);
1524 break;
1526 case PT_DYNAMIC:
1527 if (dynamic_addr)
1528 error (_("more than one dynamic segment\n"));
1530 dynamic_addr = segment->p_offset;
1531 dynamic_size = segment->p_filesz;
1532 break;
1534 case PT_INTERP:
1535 if (fseek (file, segment->p_offset, SEEK_SET))
1536 error (_("Unable to find program interpreter name\n"));
1537 else
1539 program_interpreter[0] = 0;
1540 fscanf (file, "%63s", program_interpreter);
1542 if (do_segments)
1543 printf (_("\n [Requesting program interpreter: %s]"),
1544 program_interpreter);
1546 break;
1549 if (do_segments)
1550 putc ('\n', stdout);
1553 if (loadaddr == -1)
1555 /* Very strange. */
1556 loadaddr = 0;
1559 if (do_segments && section_headers != NULL)
1561 printf (_("\n Section to Segment mapping:\n"));
1562 printf (_(" Segment Sections...\n"));
1564 assert (string_table != NULL);
1566 for (i = 0; i < elf_header.e_phnum; i++)
1568 int j;
1569 Elf32_Internal_Shdr * section;
1571 segment = program_headers + i;
1572 section = section_headers;
1574 printf (" %2.2d ", i);
1576 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1578 if (section->sh_size > 0
1579 /* Compare allocated sections by VMA, unallocated
1580 sections by file offset. */
1581 && (section->sh_flags & SHF_ALLOC
1582 ? (section->sh_addr >= segment->p_vaddr
1583 && section->sh_addr + section->sh_size
1584 <= segment->p_vaddr + segment->p_memsz)
1585 : (section->sh_offset >= segment->p_offset
1586 && (section->sh_offset + section->sh_size
1587 <= segment->p_offset + segment->p_filesz))))
1588 printf ("%s ", SECTION_NAME (section));
1591 putc ('\n',stdout);
1595 free (program_headers);
1597 return 1;
1601 static int
1602 get_section_headers (file)
1603 FILE * file;
1605 Elf32_External_Shdr * shdrs;
1606 Elf32_Internal_Shdr * internal;
1607 unsigned int i;
1609 GET_DATA_ALLOC (elf_header.e_shoff,
1610 elf_header.e_shentsize * elf_header.e_shnum,
1611 shdrs, Elf32_External_Shdr *, "section headers");
1613 section_headers = (Elf32_Internal_Shdr *) malloc
1614 (elf_header.e_shnum * sizeof (Elf32_Internal_Shdr));
1616 if (section_headers == NULL)
1618 error (_("Out of memory\n"));
1619 return 0;
1622 for (i = 0, internal = section_headers;
1623 i < elf_header.e_shnum;
1624 i ++, internal ++)
1626 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1627 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1628 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1629 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1630 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1631 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1632 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1633 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1634 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1635 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1638 free (shdrs);
1640 return 1;
1643 static Elf_Internal_Sym *
1644 get_elf_symbols (file, offset, number)
1645 FILE * file;
1646 unsigned long offset;
1647 unsigned long number;
1649 Elf32_External_Sym * esyms;
1650 Elf_Internal_Sym * isyms;
1651 Elf_Internal_Sym * psym;
1652 unsigned int j;
1654 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1655 esyms, Elf32_External_Sym *, "symbols");
1657 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1659 if (isyms == NULL)
1661 error (_("Out of memory\n"));
1662 free (esyms);
1664 return NULL;
1667 for (j = 0, psym = isyms;
1668 j < number;
1669 j ++, psym ++)
1671 psym->st_name = BYTE_GET (esyms[j].st_name);
1672 psym->st_value = BYTE_GET (esyms[j].st_value);
1673 psym->st_size = BYTE_GET (esyms[j].st_size);
1674 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1675 psym->st_info = BYTE_GET (esyms[j].st_info);
1676 psym->st_other = BYTE_GET (esyms[j].st_other);
1679 free (esyms);
1681 return isyms;
1684 static int
1685 process_section_headers (file)
1686 FILE * file;
1688 Elf32_Internal_Shdr * section;
1689 int i;
1691 section_headers = NULL;
1693 if (elf_header.e_shnum == 0)
1695 if (do_sections)
1696 printf (_("\nThere are no sections in this file.\n"));
1698 return 1;
1701 if (do_sections && !do_header)
1702 printf (_("There are %d section headers, starting at offset %lx:\n"),
1703 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
1705 if (! get_section_headers (file))
1706 return 0;
1708 /* Read in the string table, so that we have names to display. */
1709 section = section_headers + elf_header.e_shstrndx;
1711 if (section->sh_size != 0)
1713 unsigned long string_table_offset;
1715 string_table_offset = section->sh_offset;
1717 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1718 string_table, char *, "string table");
1721 /* Scan the sections for the dynamic symbol table
1722 and dynamic string table and debug sections. */
1723 dynamic_symbols = NULL;
1724 dynamic_strings = NULL;
1725 dynamic_syminfo = NULL;
1726 for (i = 0, section = section_headers;
1727 i < elf_header.e_shnum;
1728 i ++, section ++)
1730 char * name = SECTION_NAME (section);
1732 if (section->sh_type == SHT_DYNSYM)
1734 if (dynamic_symbols != NULL)
1736 error (_("File contains multiple dynamic symbol tables\n"));
1737 continue;
1740 dynamic_symbols = get_elf_symbols
1741 (file, section->sh_offset,
1742 section->sh_size / section->sh_entsize);
1744 else if (section->sh_type == SHT_STRTAB
1745 && strcmp (name, ".dynstr") == 0)
1747 if (dynamic_strings != NULL)
1749 error (_("File contains multiple dynamic string tables\n"));
1750 continue;
1753 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1754 dynamic_strings, char *, "dynamic strings");
1756 else if ((do_debugging || do_debug_info || do_debug_abbrevs
1757 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
1758 && strncmp (name, ".debug_", 7) == 0)
1760 name += 7;
1762 if (do_debugging
1763 || (do_debug_info && (strcmp (name, "info") == 0))
1764 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
1765 || (do_debug_lines && (strcmp (name, "line") == 0))
1766 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
1767 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
1769 request_dump (i, DEBUG_DUMP);
1773 if (! do_sections)
1774 return 1;
1776 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
1777 printf
1778 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1780 for (i = 0, section = section_headers;
1781 i < elf_header.e_shnum;
1782 i ++, section ++)
1784 printf (" [%2d] %-17.17s %-15.15s ",
1786 SECTION_NAME (section),
1787 get_section_type_name (section->sh_type));
1789 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1790 (unsigned long) section->sh_addr,
1791 (unsigned long) section->sh_offset,
1792 (unsigned long) section->sh_size,
1793 (unsigned long) section->sh_entsize);
1795 printf (" %c%c%c %2ld %3lx %ld\n",
1796 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
1797 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
1798 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
1799 (unsigned long) section->sh_link,
1800 (unsigned long) section->sh_info,
1801 (unsigned long) section->sh_addralign);
1804 return 1;
1807 /* Process the reloc section. */
1808 static int
1809 process_relocs (file)
1810 FILE * file;
1812 unsigned long rel_size;
1813 unsigned long rel_offset;
1816 if (!do_reloc)
1817 return 1;
1819 if (do_using_dynamic)
1821 rel_size = 0;
1822 rel_offset = 0;
1824 if (dynamic_info[DT_REL])
1826 rel_offset = dynamic_info[DT_REL];
1827 rel_size = dynamic_info[DT_RELSZ];
1829 else if (dynamic_info [DT_RELA])
1831 rel_offset = dynamic_info[DT_RELA];
1832 rel_size = dynamic_info[DT_RELASZ];
1834 else if (dynamic_info[DT_JMPREL])
1836 rel_offset = dynamic_info[DT_JMPREL];
1837 rel_size = dynamic_info[DT_PLTRELSZ];
1840 if (rel_size)
1842 printf
1843 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
1844 rel_offset, rel_size);
1846 dump_relocations (file, rel_offset - loadaddr, rel_size,
1847 dynamic_symbols, dynamic_strings);
1849 else
1850 printf (_("\nThere are no dynamic relocations in this file.\n"));
1852 else
1854 Elf32_Internal_Shdr * section;
1855 unsigned long i;
1856 int found = 0;
1858 for (i = 0, section = section_headers;
1859 i < elf_header.e_shnum;
1860 i++, section ++)
1862 if ( section->sh_type != SHT_RELA
1863 && section->sh_type != SHT_REL)
1864 continue;
1866 rel_offset = section->sh_offset;
1867 rel_size = section->sh_size;
1869 if (rel_size)
1871 Elf32_Internal_Shdr * strsec;
1872 Elf32_Internal_Shdr * symsec;
1873 Elf_Internal_Sym * symtab;
1874 char * strtab;
1876 printf (_("\nRelocation section "));
1878 if (string_table == NULL)
1879 printf ("%d", section->sh_name);
1880 else
1881 printf ("'%s'", SECTION_NAME (section));
1883 printf (_(" at offset 0x%lx contains %lu entries:\n"),
1884 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
1886 symsec = section_headers + section->sh_link;
1888 symtab = get_elf_symbols (file, symsec->sh_offset,
1889 symsec->sh_size / symsec->sh_entsize);
1891 if (symtab == NULL)
1892 continue;
1894 strsec = section_headers + symsec->sh_link;
1896 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
1897 char *, "string table");
1899 dump_relocations (file, rel_offset, rel_size, symtab, strtab);
1901 free (strtab);
1902 free (symtab);
1904 found = 1;
1908 if (! found)
1909 printf (_("\nThere are no relocations in this file.\n"));
1912 return 1;
1916 static void
1917 dynamic_segment_mips_val (entry)
1918 Elf_Internal_Dyn * entry;
1920 switch (entry->d_tag)
1922 case DT_MIPS_FLAGS:
1923 if (entry->d_un.d_val == 0)
1924 printf ("NONE\n");
1925 else
1927 static const char * opts[] =
1929 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
1930 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
1931 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
1932 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
1933 "RLD_ORDER_SAFE"
1935 unsigned int cnt;
1936 int first = 1;
1937 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
1938 if (entry->d_un.d_val & (1 << cnt))
1940 printf ("%s%s", first ? "" : " ", opts[cnt]);
1941 first = 0;
1943 puts ("");
1945 break;
1947 case DT_MIPS_IVERSION:
1948 if (dynamic_strings != NULL)
1949 printf ("Interface Version: %s\n",
1950 dynamic_strings + entry->d_un.d_val);
1951 else
1952 printf ("%ld\n", (long) entry->d_un.d_ptr);
1953 break;
1955 case DT_MIPS_TIME_STAMP:
1957 char timebuf[20];
1958 time_t time = entry->d_un.d_val;
1959 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
1960 printf ("Time Stamp: %s\n", timebuf);
1962 break;
1964 case DT_MIPS_RLD_VERSION:
1965 case DT_MIPS_LOCAL_GOTNO:
1966 case DT_MIPS_CONFLICTNO:
1967 case DT_MIPS_LIBLISTNO:
1968 case DT_MIPS_SYMTABNO:
1969 case DT_MIPS_UNREFEXTNO:
1970 case DT_MIPS_HIPAGENO:
1971 case DT_MIPS_DELTA_CLASS_NO:
1972 case DT_MIPS_DELTA_INSTANCE_NO:
1973 case DT_MIPS_DELTA_RELOC_NO:
1974 case DT_MIPS_DELTA_SYM_NO:
1975 case DT_MIPS_DELTA_CLASSSYM_NO:
1976 case DT_MIPS_COMPACT_SIZE:
1977 printf ("%ld\n", (long) entry->d_un.d_ptr);
1978 break;
1980 default:
1981 printf ("%#lx\n", (long) entry->d_un.d_ptr);
1985 /* Parse the dynamic segment */
1986 static int
1987 process_dynamic_segment (file)
1988 FILE * file;
1990 Elf_Internal_Dyn * entry;
1991 Elf32_External_Dyn * edyn;
1992 unsigned int i;
1994 if (dynamic_size == 0)
1996 if (do_dynamic)
1997 printf (_("\nThere is no dynamic segment in this file.\n"));
1999 return 1;
2002 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2003 edyn, Elf32_External_Dyn *, "dynamic segment");
2005 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2006 how large .dynamic is now. We can do this even before the byte
2007 swapping since the DT_NULL tag is recognizable. */
2008 dynamic_size = 0;
2009 while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
2012 dynamic_segment = (Elf_Internal_Dyn *)
2013 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2015 if (dynamic_segment == NULL)
2017 error (_("Out of memory\n"));
2018 free (edyn);
2019 return 0;
2022 for (i = 0, entry = dynamic_segment;
2023 i < dynamic_size;
2024 i ++, entry ++)
2026 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2027 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2030 free (edyn);
2032 /* Find the appropriate symbol table. */
2033 if (dynamic_symbols == NULL)
2035 for (i = 0, entry = dynamic_segment;
2036 i < dynamic_size;
2037 ++i, ++ entry)
2039 unsigned long offset;
2040 long num_syms;
2042 if (entry->d_tag != DT_SYMTAB)
2043 continue;
2045 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2047 /* Since we do not know how big the symbol table is,
2048 we default to reading in the entire file (!) and
2049 processing that. This is overkill, I know, but it
2050 should work. */
2052 offset = entry->d_un.d_val - loadaddr;
2054 if (fseek (file, 0, SEEK_END))
2055 error (_("Unable to seek to end of file!"));
2057 num_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2059 if (num_syms < 1)
2061 error (_("Unable to determine the number of symbols to load\n"));
2062 continue;
2065 dynamic_symbols = get_elf_symbols (file, offset, num_syms);
2069 /* Similarly find a string table. */
2070 if (dynamic_strings == NULL)
2072 for (i = 0, entry = dynamic_segment;
2073 i < dynamic_size;
2074 ++i, ++ entry)
2076 unsigned long offset;
2077 long str_tab_len;
2079 if (entry->d_tag != DT_STRTAB)
2080 continue;
2082 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2084 /* Since we do not know how big the string table is,
2085 we default to reading in the entire file (!) and
2086 processing that. This is overkill, I know, but it
2087 should work. */
2089 offset = entry->d_un.d_val - loadaddr;
2090 if (fseek (file, 0, SEEK_END))
2091 error (_("Unable to seek to end of file\n"));
2092 str_tab_len = ftell (file) - offset;
2094 if (str_tab_len < 1)
2096 error
2097 (_("Unable to determine the length of the dynamic string table\n"));
2098 continue;
2101 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2102 "dynamic string table");
2104 break;
2108 /* And find the syminfo section if available. */
2109 if (dynamic_syminfo == NULL)
2111 unsigned int syminsz = 0;
2113 for (i = 0, entry = dynamic_segment;
2114 i < dynamic_size;
2115 ++i, ++ entry)
2117 if (entry->d_tag == DT_SYMINENT)
2119 /* Note: these braces are necessary to avoid a syntax
2120 error from the SunOS4 C compiler. */
2121 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2123 else if (entry->d_tag == DT_SYMINSZ)
2124 syminsz = entry->d_un.d_val;
2125 else if (entry->d_tag == DT_SYMINFO)
2126 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2129 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2131 Elf_External_Syminfo *extsyminfo;
2132 Elf_Internal_Syminfo *syminfo;
2134 /* There is a syminfo section. Read the data. */
2135 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2136 Elf_External_Syminfo *, "symbol information");
2138 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2139 if (dynamic_syminfo == NULL)
2141 error (_("Out of memory\n"));
2142 return 0;
2145 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2146 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2147 ++i, ++syminfo)
2149 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2150 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2153 free (extsyminfo);
2157 if (do_dynamic && dynamic_addr)
2158 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
2159 dynamic_addr, dynamic_size);
2160 if (do_dynamic)
2161 printf (_(" Tag Type Name/Value\n"));
2163 for (i = 0, entry = dynamic_segment;
2164 i < dynamic_size;
2165 i++, entry ++)
2167 if (do_dynamic)
2168 printf (_(" 0x%-8.8lx (%s)%*s"),
2169 (unsigned long) entry->d_tag,
2170 get_dynamic_type (entry->d_tag),
2171 27 - strlen (get_dynamic_type (entry->d_tag)),
2172 " ");
2174 switch (entry->d_tag)
2176 case DT_AUXILIARY:
2177 case DT_FILTER:
2178 if (do_dynamic)
2180 if (entry->d_tag == DT_AUXILIARY)
2181 printf (_("Auxiliary library"));
2182 else
2183 printf (_("Filter library"));
2185 if (dynamic_strings)
2186 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2187 else
2188 printf (": %#lx\n", (long) entry->d_un.d_val);
2190 break;
2192 case DT_FEATURE_1:
2193 if (do_dynamic)
2195 printf (_("Flags:"));
2196 if (entry->d_un.d_val == 0)
2197 printf (_(" None\n"));
2198 else
2200 unsigned long int val = entry->d_un.d_val;
2201 if (val & DTF_1_PARINIT)
2203 printf (" PARINIT");
2204 val ^= DTF_1_PARINIT;
2206 if (val != 0)
2207 printf (" %lx", val);
2208 puts ("");
2211 break;
2213 case DT_POSFLAG_1:
2214 if (do_dynamic)
2216 printf (_("Flags:"));
2217 if (entry->d_un.d_val == 0)
2218 printf (_(" None\n"));
2219 else
2221 unsigned long int val = entry->d_un.d_val;
2222 if (val & DF_P1_LAZYLOAD)
2224 printf (" LAZYLOAD");
2225 val ^= DF_P1_LAZYLOAD;
2227 if (val & DF_P1_GROUPPERM)
2229 printf (" GROUPPERM");
2230 val ^= DF_P1_GROUPPERM;
2232 if (val != 0)
2233 printf (" %lx", val);
2234 puts ("");
2237 break;
2239 case DT_FLAGS_1:
2240 if (do_dynamic)
2242 printf (_("Flags:"));
2243 if (entry->d_un.d_val == 0)
2244 printf (_(" None\n"));
2245 else
2247 unsigned long int val = entry->d_un.d_val;
2248 if (val & DF_1_NOW)
2250 printf (" NOW");
2251 val ^= DF_1_NOW;
2253 if (val & DF_1_GLOBAL)
2255 printf (" GLOBAL");
2256 val ^= DF_1_GLOBAL;
2258 if (val & DF_1_GROUP)
2260 printf (" GROUP");
2261 val ^= DF_1_GROUP;
2263 if (val & DF_1_NODELETE)
2265 printf (" NODELETE");
2266 val ^= DF_1_NODELETE;
2268 if (val & DF_1_LOADFLTR)
2270 printf (" LOADFLTR");
2271 val ^= DF_1_LOADFLTR;
2273 if (val & DF_1_INITFIRST)
2275 printf (" INITFIRST");
2276 val ^= DF_1_INITFIRST;
2278 if (val & DF_1_NOOPEN)
2280 printf (" NOOPEN");
2281 val ^= DF_1_NOOPEN;
2283 if (val & DF_1_ORIGIN)
2285 printf (" ORIGIN");
2286 val ^= DF_1_ORIGIN;
2288 if (val & DF_1_DIRECT)
2290 printf (" DIRECT");
2291 val ^= DF_1_DIRECT;
2293 if (val & DF_1_TRANS)
2295 printf (" TRANS");
2296 val ^= DF_1_TRANS;
2298 if (val & DF_1_INTERPOSE)
2300 printf (" INTERPOSE");
2301 val ^= DF_1_INTERPOSE;
2303 if (val != 0)
2304 printf (" %lx", val);
2305 puts ("");
2308 break;
2310 case DT_PLTREL:
2311 if (do_dynamic)
2312 puts (get_dynamic_type (entry->d_un.d_val));
2313 break;
2315 case DT_NULL :
2316 case DT_NEEDED :
2317 case DT_PLTGOT :
2318 case DT_HASH :
2319 case DT_STRTAB :
2320 case DT_SYMTAB :
2321 case DT_RELA :
2322 case DT_INIT :
2323 case DT_FINI :
2324 case DT_SONAME :
2325 case DT_RPATH :
2326 case DT_SYMBOLIC:
2327 case DT_REL :
2328 case DT_DEBUG :
2329 case DT_TEXTREL :
2330 case DT_JMPREL :
2331 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2333 if (do_dynamic)
2335 char * name;
2337 if (dynamic_strings == NULL)
2338 name = NULL;
2339 else
2340 name = dynamic_strings + entry->d_un.d_val;
2342 if (name)
2344 switch (entry->d_tag)
2346 case DT_NEEDED:
2347 printf (_("Shared library: [%s]"), name);
2349 if (strcmp (name, program_interpreter))
2350 printf ("\n");
2351 else
2352 printf (_(" program interpreter\n"));
2353 break;
2355 case DT_SONAME:
2356 printf (_("Library soname: [%s]\n"), name);
2357 break;
2359 case DT_RPATH:
2360 printf (_("Library rpath: [%s]\n"), name);
2361 break;
2363 default:
2364 printf ("%#lx\n", (long) entry->d_un.d_val);
2367 else
2368 printf ("%#lx\n", (long) entry->d_un.d_val);
2370 break;
2372 case DT_PLTRELSZ:
2373 case DT_RELASZ :
2374 case DT_STRSZ :
2375 case DT_RELSZ :
2376 case DT_RELAENT :
2377 case DT_SYMENT :
2378 case DT_RELENT :
2379 case DT_PLTPADSZ:
2380 case DT_MOVEENT :
2381 case DT_MOVESZ :
2382 case DT_INIT_ARRAYSZ:
2383 case DT_FINI_ARRAYSZ:
2384 if (do_dynamic)
2385 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2386 break;
2388 case DT_VERDEFNUM:
2389 case DT_VERNEEDNUM:
2390 case DT_RELACOUNT:
2391 case DT_RELCOUNT:
2392 if (do_dynamic)
2393 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2394 break;
2396 case DT_SYMINSZ:
2397 case DT_SYMINENT:
2398 case DT_SYMINFO:
2399 case DT_USED:
2400 case DT_INIT_ARRAY:
2401 case DT_FINI_ARRAY:
2402 if (do_dynamic)
2404 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2406 char * name;
2408 name = dynamic_strings + entry->d_un.d_val;
2410 if (* name)
2412 printf (_("Not needed object: [%s]\n"), name);
2413 break;
2417 printf ("%#lx\n", (long) entry->d_un.d_val);
2419 break;
2421 case DT_BIND_NOW:
2422 /* The value of this entry is ignored. */
2423 break;
2425 default:
2426 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2427 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2428 entry->d_un.d_val;
2430 if (do_dynamic)
2432 switch (elf_header.e_machine)
2434 case EM_MIPS:
2435 case EM_MIPS_RS4_BE:
2436 dynamic_segment_mips_val (entry);
2437 break;
2438 default:
2439 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2442 break;
2446 return 1;
2449 static char *
2450 get_ver_flags (flags)
2451 unsigned int flags;
2453 static char buff [32];
2455 buff[0] = 0;
2457 if (flags == 0)
2458 return _("none");
2460 if (flags & VER_FLG_BASE)
2461 strcat (buff, "BASE ");
2463 if (flags & VER_FLG_WEAK)
2465 if (flags & VER_FLG_BASE)
2466 strcat (buff, "| ");
2468 strcat (buff, "WEAK ");
2471 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2472 strcat (buff, "| <unknown>");
2474 return buff;
2477 /* Display the contents of the version sections. */
2478 static int
2479 process_version_sections (file)
2480 FILE * file;
2482 Elf32_Internal_Shdr * section;
2483 unsigned i;
2484 int found = 0;
2486 if (! do_version)
2487 return 1;
2489 for (i = 0, section = section_headers;
2490 i < elf_header.e_shnum;
2491 i++, section ++)
2493 switch (section->sh_type)
2495 case SHT_GNU_verdef:
2497 Elf_External_Verdef * edefs;
2498 unsigned int idx;
2499 unsigned int cnt;
2501 found = 1;
2503 printf
2504 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2505 SECTION_NAME (section), section->sh_info);
2507 printf (_(" Addr: 0x"));
2508 printf_vma (section->sh_addr);
2509 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2510 section->sh_offset, section->sh_link,
2511 SECTION_NAME (section_headers + section->sh_link));
2513 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2514 edefs, Elf_External_Verdef *,
2515 "version definition section");
2517 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2519 char * vstart;
2520 Elf_External_Verdef * edef;
2521 Elf_Internal_Verdef ent;
2522 Elf_External_Verdaux * eaux;
2523 Elf_Internal_Verdaux aux;
2524 int j;
2525 int isum;
2527 vstart = ((char *) edefs) + idx;
2529 edef = (Elf_External_Verdef *) vstart;
2531 ent.vd_version = BYTE_GET (edef->vd_version);
2532 ent.vd_flags = BYTE_GET (edef->vd_flags);
2533 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2534 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2535 ent.vd_hash = BYTE_GET (edef->vd_hash);
2536 ent.vd_aux = BYTE_GET (edef->vd_aux);
2537 ent.vd_next = BYTE_GET (edef->vd_next);
2539 printf (_(" %#06x: Rev: %d Flags: %s"),
2540 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2542 printf (_(" Index: %d Cnt: %d "),
2543 ent.vd_ndx, ent.vd_cnt);
2545 vstart += ent.vd_aux;
2547 eaux = (Elf_External_Verdaux *) vstart;
2549 aux.vda_name = BYTE_GET (eaux->vda_name);
2550 aux.vda_next = BYTE_GET (eaux->vda_next);
2552 if (dynamic_strings)
2553 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2554 else
2555 printf (_("Name index: %ld\n"), aux.vda_name);
2557 isum = idx + ent.vd_aux;
2559 for (j = 1; j < ent.vd_cnt; j ++)
2561 isum += aux.vda_next;
2562 vstart += aux.vda_next;
2564 eaux = (Elf_External_Verdaux *) vstart;
2566 aux.vda_name = BYTE_GET (eaux->vda_name);
2567 aux.vda_next = BYTE_GET (eaux->vda_next);
2569 if (dynamic_strings)
2570 printf (_(" %#06x: Parent %d: %s\n"),
2571 isum, j, dynamic_strings + aux.vda_name);
2572 else
2573 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2574 isum, j, aux.vda_name);
2577 idx += ent.vd_next;
2580 free (edefs);
2582 break;
2584 case SHT_GNU_verneed:
2586 Elf_External_Verneed * eneed;
2587 unsigned int idx;
2588 unsigned int cnt;
2590 found = 1;
2592 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2593 SECTION_NAME (section), section->sh_info);
2595 printf (_(" Addr: 0x"));
2596 printf_vma (section->sh_addr);
2597 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
2598 section->sh_offset, section->sh_link,
2599 SECTION_NAME (section_headers + section->sh_link));
2601 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2602 eneed, Elf_External_Verneed *,
2603 "version need section");
2605 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
2607 Elf_External_Verneed * entry;
2608 Elf_Internal_Verneed ent;
2609 int j;
2610 int isum;
2611 char * vstart;
2613 vstart = ((char *) eneed) + idx;
2615 entry = (Elf_External_Verneed *) vstart;
2617 ent.vn_version = BYTE_GET (entry->vn_version);
2618 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
2619 ent.vn_file = BYTE_GET (entry->vn_file);
2620 ent.vn_aux = BYTE_GET (entry->vn_aux);
2621 ent.vn_next = BYTE_GET (entry->vn_next);
2623 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
2625 if (dynamic_strings)
2626 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
2627 else
2628 printf (_(" File: %lx"), ent.vn_file);
2630 printf (_(" Cnt: %d\n"), ent.vn_cnt);
2632 vstart += ent.vn_aux;
2634 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
2636 Elf_External_Vernaux * eaux;
2637 Elf_Internal_Vernaux aux;
2639 eaux = (Elf_External_Vernaux *) vstart;
2641 aux.vna_hash = BYTE_GET (eaux->vna_hash);
2642 aux.vna_flags = BYTE_GET (eaux->vna_flags);
2643 aux.vna_other = BYTE_GET (eaux->vna_other);
2644 aux.vna_name = BYTE_GET (eaux->vna_name);
2645 aux.vna_next = BYTE_GET (eaux->vna_next);
2647 if (dynamic_strings)
2648 printf (_(" %#06x: Name: %s"),
2649 isum, dynamic_strings + aux.vna_name);
2650 else
2651 printf (_(" %#06x: Name index: %lx"),
2652 isum, aux.vna_name);
2654 printf (_(" Flags: %s Version: %d\n"),
2655 get_ver_flags (aux.vna_flags), aux.vna_other);
2657 isum += aux.vna_next;
2658 vstart += aux.vna_next;
2661 idx += ent.vn_next;
2664 free (eneed);
2666 break;
2668 case SHT_GNU_versym:
2670 Elf32_Internal_Shdr * link_section;
2671 int total;
2672 int cnt;
2673 unsigned char * edata;
2674 unsigned short * data;
2675 char * strtab;
2676 Elf_Internal_Sym * symbols;
2677 Elf32_Internal_Shdr * string_sec;
2679 link_section = section_headers + section->sh_link;
2680 total = section->sh_size / section->sh_entsize;
2682 found = 1;
2684 symbols = get_elf_symbols
2685 (file, link_section->sh_offset,
2686 link_section->sh_size / link_section->sh_entsize);
2688 string_sec = section_headers + link_section->sh_link;
2690 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2691 strtab, char *, "version string table");
2693 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2694 SECTION_NAME (section), total);
2696 printf (_(" Addr: "));
2697 printf_vma (section->sh_addr);
2698 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2699 section->sh_offset, section->sh_link,
2700 SECTION_NAME (link_section));
2702 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2703 - loadaddr,
2704 total * sizeof (short), edata,
2705 unsigned char *, "version symbol data");
2707 data = (unsigned short *) malloc (total * sizeof (short));
2709 for (cnt = total; cnt --;)
2710 data [cnt] = byte_get (edata + cnt * sizeof (short),
2711 sizeof (short));
2713 free (edata);
2715 for (cnt = 0; cnt < total; cnt += 4)
2717 int j, nn;
2719 printf (" %03x:", cnt);
2721 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2722 switch (data [cnt + j])
2724 case 0:
2725 fputs (_(" 0 (*local*) "), stdout);
2726 break;
2728 case 1:
2729 fputs (_(" 1 (*global*) "), stdout);
2730 break;
2732 default:
2733 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
2734 data [cnt + j] & 0x8000 ? 'h' : ' ');
2736 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
2737 && section_headers[symbols [cnt + j].st_shndx].sh_type
2738 == SHT_NOBITS)
2740 /* We must test both. */
2741 Elf_Internal_Verneed ivn;
2742 unsigned long offset;
2744 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2745 - loadaddr;
2749 Elf_External_Verneed evn;
2750 Elf_External_Vernaux evna;
2751 Elf_Internal_Vernaux ivna;
2752 unsigned long vna_off;
2754 GET_DATA (offset, evn, "version need");
2756 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2757 ivn.vn_next = BYTE_GET (evn.vn_next);
2759 vna_off = offset + ivn.vn_aux;
2763 GET_DATA (vna_off, evna,
2764 "version need aux (1)");
2766 ivna.vna_next = BYTE_GET (evna.vna_next);
2767 ivna.vna_other = BYTE_GET (evna.vna_other);
2769 vna_off += ivna.vna_next;
2771 while (ivna.vna_other != data [cnt + j]
2772 && ivna.vna_next != 0);
2774 if (ivna.vna_other == data [cnt + j])
2776 ivna.vna_name = BYTE_GET (evna.vna_name);
2778 nn += printf ("(%s%-*s",
2779 strtab + ivna.vna_name,
2780 12 - strlen (strtab
2781 + ivna.vna_name),
2782 ")");
2783 break;
2785 else if (ivn.vn_next == 0)
2787 if (data [cnt + j] != 0x8001)
2789 Elf_Internal_Verdef ivd;
2790 Elf_External_Verdef evd;
2792 offset = version_info
2793 [DT_VERSIONTAGIDX (DT_VERDEF)]
2794 - loadaddr;
2798 GET_DATA (offset, evd,
2799 "version definition");
2801 ivd.vd_next = BYTE_GET (evd.vd_next);
2802 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2804 offset += ivd.vd_next;
2806 while (ivd.vd_ndx
2807 != (data [cnt + j] & 0x7fff)
2808 && ivd.vd_next != 0);
2810 if (ivd.vd_ndx
2811 == (data [cnt + j] & 0x7fff))
2813 Elf_External_Verdaux evda;
2814 Elf_Internal_Verdaux ivda;
2816 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2818 GET_DATA (offset + ivd.vd_aux, evda,
2819 "version definition aux");
2821 ivda.vda_name =
2822 BYTE_GET (evda.vda_name);
2824 nn +=
2825 printf ("(%s%-*s",
2826 strtab + ivda.vda_name,
2828 - strlen (strtab
2829 + ivda.vda_name),
2830 ")");
2834 break;
2836 else
2837 offset += ivn.vn_next;
2839 while (ivn.vn_next);
2841 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
2843 Elf_Internal_Verneed ivn;
2844 unsigned long offset;
2846 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2847 - loadaddr;
2851 Elf_Internal_Vernaux ivna;
2852 Elf_External_Verneed evn;
2853 Elf_External_Vernaux evna;
2854 unsigned long a_off;
2856 GET_DATA (offset, evn, "version need");
2858 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2859 ivn.vn_next = BYTE_GET (evn.vn_next);
2861 a_off = offset + ivn.vn_aux;
2865 GET_DATA (a_off, evna,
2866 "version need aux (2)");
2868 ivna.vna_next = BYTE_GET (evna.vna_next);
2869 ivna.vna_other = BYTE_GET (evna.vna_other);
2871 a_off += ivna.vna_next;
2873 while (ivna.vna_other != data [cnt + j]
2874 && ivna.vna_next != 0);
2876 if (ivna.vna_other == data [cnt + j])
2878 ivna.vna_name = BYTE_GET (evna.vna_name);
2880 nn += printf ("(%s%-*s",
2881 strtab + ivna.vna_name,
2882 12 - strlen (strtab
2883 + ivna.vna_name),
2884 ")");
2885 break;
2888 offset += ivn.vn_next;
2890 while (ivn.vn_next);
2892 else if (data [cnt + j] != 0x8001)
2894 Elf_Internal_Verdef ivd;
2895 Elf_External_Verdef evd;
2896 unsigned long offset;
2898 offset = version_info
2899 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
2903 GET_DATA (offset, evd, "version def");
2905 ivd.vd_next = BYTE_GET (evd.vd_next);
2906 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2908 offset += ivd.vd_next;
2910 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
2911 && ivd.vd_next != 0);
2913 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
2915 Elf_External_Verdaux evda;
2916 Elf_Internal_Verdaux ivda;
2918 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2920 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
2921 evda, "version def aux");
2923 ivda.vda_name = BYTE_GET (evda.vda_name);
2925 nn += printf ("(%s%-*s",
2926 strtab + ivda.vda_name,
2927 12 - strlen (strtab
2928 + ivda.vda_name),
2929 ")");
2933 if (nn < 18)
2934 printf ("%*c", 18 - nn, ' ');
2937 putchar ('\n');
2940 free (data);
2941 free (strtab);
2942 free (symbols);
2944 break;
2946 default:
2947 break;
2951 if (! found)
2952 printf (_("\nNo version information found in this file.\n"));
2954 return 1;
2957 static char *
2958 get_symbol_binding (binding)
2959 unsigned int binding;
2961 static char buff [32];
2963 switch (binding)
2965 case STB_LOCAL: return _("LOCAL");
2966 case STB_GLOBAL: return _("GLOBAL");
2967 case STB_WEAK: return _("WEAK");
2968 default:
2969 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
2970 sprintf (buff, _("<processor specific>: %d"), binding);
2971 else if (binding >= STB_LOOS && binding <= STB_HIOS)
2972 sprintf (buff, _("<OS specific>: %d"), binding);
2973 else
2974 sprintf (buff, _("<unknown>: %d"), binding);
2975 return buff;
2979 static char *
2980 get_symbol_type (type)
2981 unsigned int type;
2983 static char buff [32];
2985 switch (type)
2987 case STT_NOTYPE: return _("NOTYPE");
2988 case STT_OBJECT: return _("OBJECT");
2989 case STT_FUNC: return _("FUNC");
2990 case STT_SECTION: return _("SECTION");
2991 case STT_FILE: return _("FILE");
2992 default:
2993 if (type >= STT_LOPROC && type <= STT_HIPROC)
2994 sprintf (buff, _("<processor specific>: %d"), type);
2995 else if (type >= STT_LOOS && type <= STT_HIOS)
2996 sprintf (buff, _("<OS specific>: %d"), type);
2997 else
2998 sprintf (buff, _("<unknown>: %d"), type);
2999 return buff;
3003 static char *
3004 get_symbol_index_type (type)
3005 unsigned int type;
3007 switch (type)
3009 case SHN_UNDEF: return "UND";
3010 case SHN_ABS: return "ABS";
3011 case SHN_COMMON: return "COM";
3012 default:
3013 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3014 return "PRC";
3015 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3016 return "RSV";
3017 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3018 return "OS ";
3019 else
3021 static char buff [32];
3023 sprintf (buff, "%3d", type);
3024 return buff;
3030 static int *
3031 get_dynamic_data (file, number)
3032 FILE * file;
3033 unsigned int number;
3035 char * e_data;
3036 int * i_data;
3038 e_data = (char *) malloc (number * 4);
3040 if (e_data == NULL)
3042 error (_("Out of memory\n"));
3043 return NULL;
3046 if (fread (e_data, 4, number, file) != number)
3048 error (_("Unable to read in dynamic data\n"));
3049 return NULL;
3052 i_data = (int *) malloc (number * sizeof (* i_data));
3054 if (i_data == NULL)
3056 error (_("Out of memory\n"));
3057 free (e_data);
3058 return NULL;
3061 while (number--)
3062 i_data [number] = byte_get (e_data + number * 4, 4);
3064 free (e_data);
3066 return i_data;
3069 /* Dump the symbol table */
3070 static int
3071 process_symbol_table (file)
3072 FILE * file;
3074 Elf32_Internal_Shdr * section;
3075 char nb [4];
3076 char nc [4];
3077 int nbuckets;
3078 int nchains;
3079 int * buckets = NULL;
3080 int * chains = NULL;
3082 if (! do_syms && !do_histogram)
3083 return 1;
3085 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3086 || do_histogram))
3088 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3090 error (_("Unable to seek to start of dynamic information"));
3091 return 0;
3094 if (fread (nb, sizeof (nb), 1, file) != 1)
3096 error (_("Failed to read in number of buckets\n"));
3097 return 0;
3100 if (fread (nc, sizeof (nc), 1, file) != 1)
3102 error (_("Failed to read in number of chains\n"));
3103 return 0;
3106 nbuckets = byte_get (nb, 4);
3107 nchains = byte_get (nc, 4);
3109 buckets = get_dynamic_data (file, nbuckets);
3110 chains = get_dynamic_data (file, nchains);
3112 if (buckets == NULL || chains == NULL)
3113 return 0;
3116 if (do_syms
3117 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3119 int hn;
3120 int si;
3122 printf (_("\nSymbol table for image:\n"));
3123 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3125 for (hn = 0; hn < nbuckets; hn++)
3127 if (! buckets [hn])
3128 continue;
3130 for (si = buckets [hn]; si; si = chains [si])
3132 Elf_Internal_Sym * psym;
3134 psym = dynamic_symbols + si;
3136 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3137 si, hn,
3138 (unsigned long) psym->st_value,
3139 (unsigned long) psym->st_size,
3140 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3141 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3142 psym->st_other);
3144 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3146 printf (" %s\n", dynamic_strings + psym->st_name);
3150 else if (do_syms && !do_using_dynamic)
3152 unsigned int i;
3154 for (i = 0, section = section_headers;
3155 i < elf_header.e_shnum;
3156 i++, section++)
3158 unsigned int si;
3159 char * strtab;
3160 Elf_Internal_Sym * symtab;
3161 Elf_Internal_Sym * psym;
3164 if ( section->sh_type != SHT_SYMTAB
3165 && section->sh_type != SHT_DYNSYM)
3166 continue;
3168 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3169 SECTION_NAME (section),
3170 (unsigned long) (section->sh_size / section->sh_entsize));
3171 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3172 stdout);
3174 symtab = get_elf_symbols (file, section->sh_offset,
3175 section->sh_size / section->sh_entsize);
3176 if (symtab == NULL)
3177 continue;
3179 if (section->sh_link == elf_header.e_shstrndx)
3180 strtab = string_table;
3181 else
3183 Elf32_Internal_Shdr * string_sec;
3185 string_sec = section_headers + section->sh_link;
3187 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3188 strtab, char *, "string table");
3191 for (si = 0, psym = symtab;
3192 si < section->sh_size / section->sh_entsize;
3193 si ++, psym ++)
3195 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3197 (unsigned long) psym->st_value,
3198 (unsigned long) psym->st_size,
3199 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3200 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3201 psym->st_other);
3203 if (psym->st_shndx == 0)
3204 fputs (" UND", stdout);
3205 else if ((psym->st_shndx & 0xffff) == 0xfff1)
3206 fputs (" ABS", stdout);
3207 else if ((psym->st_shndx & 0xffff) == 0xfff2)
3208 fputs (" COM", stdout);
3209 else
3210 printf ("%4x", psym->st_shndx);
3212 printf (" %s", strtab + psym->st_name);
3214 if (section->sh_type == SHT_DYNSYM &&
3215 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3217 unsigned char data[2];
3218 unsigned short vers_data;
3219 unsigned long offset;
3220 int is_nobits;
3221 int check_def;
3223 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3224 - loadaddr;
3226 GET_DATA (offset + si * sizeof (vers_data), data,
3227 "version data");
3229 vers_data = byte_get (data, 2);
3231 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3232 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3233 : 0;
3235 check_def = (psym->st_shndx != SHN_UNDEF);
3237 if ((vers_data & 0x8000) || vers_data > 1)
3239 if (is_nobits || ! check_def)
3241 Elf_External_Verneed evn;
3242 Elf_Internal_Verneed ivn;
3243 Elf_Internal_Vernaux ivna;
3245 /* We must test both. */
3246 offset = version_info
3247 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3249 GET_DATA (offset, evn, "version need");
3251 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3252 ivn.vn_next = BYTE_GET (evn.vn_next);
3256 unsigned long vna_off;
3258 vna_off = offset + ivn.vn_aux;
3262 Elf_External_Vernaux evna;
3264 GET_DATA (vna_off, evna,
3265 "version need aux (3)");
3267 ivna.vna_other = BYTE_GET (evna.vna_other);
3268 ivna.vna_next = BYTE_GET (evna.vna_next);
3269 ivna.vna_name = BYTE_GET (evna.vna_name);
3271 vna_off += ivna.vna_next;
3273 while (ivna.vna_other != vers_data
3274 && ivna.vna_next != 0);
3276 if (ivna.vna_other == vers_data)
3277 break;
3279 offset += ivn.vn_next;
3281 while (ivn.vn_next != 0);
3283 if (ivna.vna_other == vers_data)
3285 printf ("@%s (%d)",
3286 strtab + ivna.vna_name, ivna.vna_other);
3287 check_def = 0;
3289 else if (! is_nobits)
3290 error (_("bad dynamic symbol"));
3291 else
3292 check_def = 1;
3295 if (check_def)
3297 if (vers_data != 0x8001)
3299 Elf_Internal_Verdef ivd;
3300 Elf_Internal_Verdaux ivda;
3301 Elf_External_Verdaux evda;
3302 unsigned long offset;
3304 offset =
3305 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3306 - loadaddr;
3310 Elf_External_Verdef evd;
3312 GET_DATA (offset, evd, "version def");
3314 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3315 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3316 ivd.vd_next = BYTE_GET (evd.vd_next);
3318 offset += ivd.vd_next;
3320 while (ivd.vd_ndx != (vers_data & 0x7fff)
3321 && ivd.vd_next != 0);
3323 offset -= ivd.vd_next;
3324 offset += ivd.vd_aux;
3326 GET_DATA (offset, evda, "version def aux");
3328 ivda.vda_name = BYTE_GET (evda.vda_name);
3330 if (psym->st_name != ivda.vda_name)
3331 printf ((vers_data & 0x8000)
3332 ? "@%s" : "@@%s",
3333 strtab + ivda.vda_name);
3339 putchar ('\n');
3342 free (symtab);
3343 if (strtab != string_table)
3344 free (strtab);
3347 else if (do_syms)
3348 printf
3349 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3351 if (do_histogram && buckets != NULL)
3353 int *lengths;
3354 int *counts;
3355 int hn;
3356 int si;
3357 int maxlength = 0;
3358 int nzero_counts = 0;
3359 int nsyms = 0;
3361 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3362 nbuckets);
3363 printf (_(" Length Number %% of total Coverage\n"));
3365 lengths = (int *) calloc (nbuckets, sizeof (int));
3366 if (lengths == NULL)
3368 error (_("Out of memory"));
3369 return 0;
3371 for (hn = 0; hn < nbuckets; ++hn)
3373 if (! buckets [hn])
3374 continue;
3376 for (si = buckets[hn]; si; si = chains[si])
3378 ++nsyms;
3379 if (maxlength < ++lengths[hn])
3380 ++maxlength;
3384 counts = (int *) calloc (maxlength + 1, sizeof (int));
3385 if (counts == NULL)
3387 error (_("Out of memory"));
3388 return 0;
3391 for (hn = 0; hn < nbuckets; ++hn)
3392 ++ counts [lengths [hn]];
3394 printf (" 0 %-10d (%5.1f%%)\n",
3395 counts[0], (counts[0] * 100.0) / nbuckets);
3396 for (si = 1; si <= maxlength; ++si)
3398 nzero_counts += counts[si] * si;
3399 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3400 si, counts[si], (counts[si] * 100.0) / nbuckets,
3401 (nzero_counts * 100.0) / nsyms);
3404 free (counts);
3405 free (lengths);
3408 if (buckets != NULL)
3410 free (buckets);
3411 free (chains);
3414 return 1;
3417 static int
3418 process_syminfo (file)
3419 FILE * file;
3421 int i;
3423 if (dynamic_syminfo == NULL
3424 || !do_dynamic)
3425 /* No syminfo, this is ok. */
3426 return 1;
3428 /* There better should be a dynamic symbol section. */
3429 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3430 return 0;
3432 if (dynamic_addr)
3433 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3434 dynamic_syminfo_offset, dynamic_syminfo_nent);
3436 printf (_(" Num: Name BoundTo Flags\n"));
3437 for (i = 0; i < dynamic_syminfo_nent; ++i)
3439 unsigned short int flags = dynamic_syminfo[i].si_flags;
3441 printf ("%4d: %-30s ", i,
3442 dynamic_strings + dynamic_symbols[i].st_name);
3444 switch (dynamic_syminfo[i].si_boundto)
3446 case SYMINFO_BT_SELF:
3447 fputs ("SELF ", stdout);
3448 break;
3449 case SYMINFO_BT_PARENT:
3450 fputs ("PARENT ", stdout);
3451 break;
3452 default:
3453 if (dynamic_syminfo[i].si_boundto > 0
3454 && dynamic_syminfo[i].si_boundto < dynamic_size)
3455 printf ("%-10s ",
3456 dynamic_strings
3457 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3458 else
3459 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3460 break;
3463 if (flags & SYMINFO_FLG_DIRECT)
3464 printf (" DIRECT");
3465 if (flags & SYMINFO_FLG_PASSTHRU)
3466 printf (" PASSTHRU");
3467 if (flags & SYMINFO_FLG_COPY)
3468 printf (" COPY");
3469 if (flags & SYMINFO_FLG_LAZYLOAD)
3470 printf (" LAZYLOAD");
3472 puts ("");
3475 return 1;
3478 #ifdef SUPPORT_DISASSEMBLY
3479 static void
3480 disassemble_section (section, file)
3481 Elf32_Internal_Shdr * section;
3482 FILE * file;
3484 printf (_("\nAssembly dump of section %s\n"),
3485 SECTION_NAME (section));
3487 /* XXX -- to be done --- XXX */
3489 return 1;
3491 #endif
3493 static int
3494 dump_section (section, file)
3495 Elf32_Internal_Shdr * section;
3496 FILE * file;
3498 int bytes;
3499 int addr;
3500 unsigned char * data;
3501 unsigned char * start;
3503 bytes = section->sh_size;
3505 if (bytes == 0)
3507 printf (_("\nSection '%s' has no data to dump.\n"),
3508 SECTION_NAME (section));
3509 return 0;
3511 else
3512 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3514 addr = section->sh_addr;
3516 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3517 "section data");
3519 data = start;
3521 while (bytes)
3523 int j;
3524 int k;
3525 int lbytes;
3527 lbytes = (bytes > 16 ? 16 : bytes);
3529 printf (" 0x%8.8x ", addr);
3531 switch (elf_header.e_ident [EI_DATA])
3533 case ELFDATA2LSB:
3534 for (j = 15; j >= 0; j --)
3536 if (j < lbytes)
3537 printf ("%2.2x", data [j]);
3538 else
3539 printf (" ");
3541 if (!(j & 0x3))
3542 printf (" ");
3544 break;
3546 case ELFDATA2MSB:
3547 for (j = 0; j < 16; j++)
3549 if (j < lbytes)
3550 printf ("%2.2x", data [j]);
3551 else
3552 printf (" ");
3554 if ((j & 3) == 3)
3555 printf (" ");
3557 break;
3560 for (j = 0; j < lbytes; j++)
3562 k = data [j];
3563 if (k >= ' ' && k < 0x80)
3564 printf ("%c", k);
3565 else
3566 printf (".");
3569 putchar ('\n');
3571 data += lbytes;
3572 addr += lbytes;
3573 bytes -= lbytes;
3576 free (start);
3578 return 1;
3582 static unsigned long int
3583 read_leb128 (data, length_return, sign)
3584 unsigned char * data;
3585 int * length_return;
3586 int sign;
3588 unsigned long int result = 0;
3589 unsigned int num_read = 0;
3590 int shift = 0;
3591 unsigned char byte;
3595 byte = * data ++;
3596 num_read ++;
3598 result |= (byte & 0x7f) << shift;
3600 shift += 7;
3603 while (byte & 0x80);
3605 if (length_return != NULL)
3606 * length_return = num_read;
3608 if (sign && (shift < 32) && (byte & 0x40))
3609 result |= -1 << shift;
3611 return result;
3614 typedef struct State_Machine_Registers
3616 unsigned long address;
3617 unsigned int file;
3618 unsigned int line;
3619 unsigned int column;
3620 int is_stmt;
3621 int basic_block;
3622 int end_sequence;
3623 /* This variable hold the number of the last entry seen
3624 in the File Table. */
3625 unsigned int last_file_entry;
3626 } SMR;
3628 static SMR state_machine_regs;
3630 static void
3631 reset_state_machine (is_stmt)
3632 int is_stmt;
3634 state_machine_regs.address = 0;
3635 state_machine_regs.file = 1;
3636 state_machine_regs.line = 1;
3637 state_machine_regs.column = 0;
3638 state_machine_regs.is_stmt = is_stmt;
3639 state_machine_regs.basic_block = 0;
3640 state_machine_regs.end_sequence = 0;
3641 state_machine_regs.last_file_entry = 0;
3644 /* Handled an extend line op. Returns true if this is the end
3645 of sequence. */
3646 static int
3647 process_extended_line_op (data, is_stmt)
3648 unsigned char * data;
3649 int is_stmt;
3651 unsigned char op_code;
3652 int bytes_read;
3653 unsigned int len;
3654 unsigned char * name;
3655 unsigned long adr;
3657 len = read_leb128 (data, & bytes_read, 0);
3658 data += bytes_read;
3660 if (len == 0)
3662 warn (_("badly formed extended line op encountered!"));
3663 return bytes_read;
3666 len += bytes_read;
3667 op_code = * data ++;
3669 printf (_(" Extended opcode %d: "), op_code);
3671 switch (op_code)
3673 case DW_LNE_end_sequence:
3674 printf (_("End of Sequence\n\n"));
3675 reset_state_machine (is_stmt);
3676 break;
3678 case DW_LNE_set_address:
3679 /* XXX - assumption here that address size is 4! */
3680 adr = byte_get (data, 4);
3681 printf (_("set Address to 0x%lx\n"), adr);
3682 state_machine_regs.address = adr;
3683 break;
3685 case DW_LNE_define_file:
3686 printf (_(" define new File Table entry\n"));
3687 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3689 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3690 name = data;
3691 data += strlen (data) + 1;
3692 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3693 data += bytes_read;
3694 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3695 data += bytes_read;
3696 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3697 printf (_("%s\n\n"), name);
3698 break;
3700 default:
3701 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
3702 break;
3705 return len;
3709 static int
3710 display_debug_lines (section, start, file)
3711 Elf32_Internal_Shdr * section;
3712 unsigned char * start;
3713 FILE * file;
3715 DWARF2_External_LineInfo * external;
3716 DWARF2_Internal_LineInfo info;
3717 unsigned char * standard_opcodes;
3718 unsigned char * data = start;
3719 unsigned char * end = start + section->sh_size;
3720 unsigned char * end_of_sequence;
3721 int i;
3723 printf (_("\nDump of debug contents of section %s:\n\n"),
3724 SECTION_NAME (section));
3726 while (data < end)
3728 external = (DWARF2_External_LineInfo *) data;
3730 /* Check the length of the block. */
3731 info.li_length = BYTE_GET (external->li_length);
3732 if (info.li_length > section->sh_size)
3734 warn
3735 (_("The line info appears to be corrupt - the section is too small\n"));
3736 return 0;
3739 /* Check its version number. */
3740 info.li_version = BYTE_GET (external->li_version);
3741 if (info.li_version != 2)
3743 warn (_("Only DWARF version 2 line info is currently supported.\n"));
3744 return 0;
3747 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
3748 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
3749 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
3750 info.li_line_base = BYTE_GET (external->li_line_base);
3751 info.li_line_range = BYTE_GET (external->li_line_range);
3752 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
3754 /* Sign extend the line base field. */
3755 info.li_line_base <<= 24;
3756 info.li_line_base >>= 24;
3758 printf (_(" Length: %ld\n"), info.li_length);
3759 printf (_(" DWARF Version: %d\n"), info.li_version);
3760 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
3761 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
3762 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
3763 printf (_(" Line Base: %d\n"), info.li_line_base);
3764 printf (_(" Line Range: %d\n"), info.li_line_range);
3765 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
3767 end_of_sequence = data + info.li_length + sizeof (info.li_length);
3769 reset_state_machine (info.li_default_is_stmt);
3771 /* Display the contents of the Opcodes table. */
3772 standard_opcodes = data + sizeof (* external);
3774 printf (_("\n Opcodes:\n"));
3776 for (i = 1; i < info.li_opcode_base; i++)
3777 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
3779 /* Display the contents of the Directory table. */
3780 data = standard_opcodes + info.li_opcode_base - 1;
3782 if (* data == 0)
3783 printf (_("\n The Directory Table is empty.\n"));
3784 else
3786 printf (_("\n The Directory Table:\n"));
3788 while (* data != 0)
3790 printf (_(" %s\n"), data);
3792 data += strlen (data) + 1;
3796 /* Skip the NUL at the end of the table. */
3797 data ++;
3799 /* Display the contents of the File Name table. */
3800 if (* data == 0)
3801 printf (_("\n The File Name Table is empty.\n"));
3802 else
3804 printf (_("\n The File Name Table:\n"));
3805 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3807 while (* data != 0)
3809 char * name;
3810 int bytes_read;
3812 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3813 name = data;
3815 data += strlen (data) + 1;
3817 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3818 data += bytes_read;
3819 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3820 data += bytes_read;
3821 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3822 data += bytes_read;
3823 printf (_("%s\n"), name);
3827 /* Skip the NUL at the end of the table. */
3828 data ++;
3830 /* Now display the statements. */
3831 printf (_("\n Line Number Statements:\n"));
3834 while (data < end_of_sequence)
3836 unsigned char op_code;
3837 int adv;
3838 int bytes_read;
3840 op_code = * data ++;
3842 switch (op_code)
3844 case DW_LNS_extended_op:
3845 data += process_extended_line_op (data, info.li_default_is_stmt);
3846 break;
3848 case DW_LNS_copy:
3849 printf (_(" Copy\n"));
3850 break;
3852 case DW_LNS_advance_pc:
3853 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
3854 data += bytes_read;
3855 state_machine_regs.address += adv;
3856 printf (_(" Advance PC by %d to %lx\n"), adv,
3857 state_machine_regs.address);
3858 break;
3860 case DW_LNS_advance_line:
3861 adv = read_leb128 (data, & bytes_read, 1);
3862 data += bytes_read;
3863 state_machine_regs.line += adv;
3864 printf (_(" Advance Line by %d to %d\n"), adv,
3865 state_machine_regs.line);
3866 break;
3868 case DW_LNS_set_file:
3869 adv = read_leb128 (data, & bytes_read, 0);
3870 data += bytes_read;
3871 printf (_(" Set File Name to entry %d in the File Name Table\n"),
3872 adv);
3873 state_machine_regs.file = adv;
3874 break;
3876 case DW_LNS_set_column:
3877 adv = read_leb128 (data, & bytes_read, 0);
3878 data += bytes_read;
3879 printf (_(" Set column to %d\n"), adv);
3880 state_machine_regs.column = adv;
3881 break;
3883 case DW_LNS_negate_stmt:
3884 adv = state_machine_regs.is_stmt;
3885 adv = ! adv;
3886 printf (_(" Set is_stmt to %d\n"), adv);
3887 state_machine_regs.is_stmt = adv;
3888 break;
3890 case DW_LNS_set_basic_block:
3891 printf (_(" Set basic block\n"));
3892 state_machine_regs.basic_block = 1;
3893 break;
3895 case DW_LNS_const_add_pc:
3896 adv = (255 - info.li_opcode_base) / info.li_line_range;
3897 state_machine_regs.address += adv;
3898 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
3899 state_machine_regs.address);
3900 break;
3902 case DW_LNS_fixed_advance_pc:
3903 adv = byte_get (data, 2);
3904 data += 2;
3905 state_machine_regs.address += adv;
3906 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
3907 adv, state_machine_regs.address);
3908 break;
3910 default:
3911 op_code -= info.li_opcode_base;
3912 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
3913 state_machine_regs.address += adv;
3914 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
3915 op_code, adv, state_machine_regs.address);
3916 adv += (op_code % info.li_line_range) + info.li_line_base;
3917 state_machine_regs.line += adv;
3918 printf (_(" and Line by %d to %d\n"),
3919 adv, state_machine_regs.line);
3920 break;
3923 printf ("\n");
3926 return 1;
3929 static int
3930 display_debug_pubnames (section, start, file)
3931 Elf32_Internal_Shdr * section;
3932 unsigned char * start;
3933 FILE * file;
3935 DWARF2_External_PubNames * external;
3936 DWARF2_Internal_PubNames pubnames;
3937 unsigned char * end;
3939 end = start + section->sh_size;
3941 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
3943 while (start < end)
3945 unsigned char * data;
3946 unsigned long offset;
3948 external = (DWARF2_External_PubNames *) start;
3950 pubnames.pn_length = BYTE_GET (external->pn_length);
3951 pubnames.pn_version = BYTE_GET (external->pn_version);
3952 pubnames.pn_offset = BYTE_GET (external->pn_offset);
3953 pubnames.pn_size = BYTE_GET (external->pn_size);
3955 data = start + sizeof (* external);
3956 start += pubnames.pn_length + sizeof (external->pn_length);
3958 if (pubnames.pn_version != 2)
3960 warn (_("Only DWARF 2 pubnames are currently supported"));
3961 continue;
3964 printf (_(" Length: %ld\n"),
3965 pubnames.pn_length);
3966 printf (_(" Version: %d\n"),
3967 pubnames.pn_version);
3968 printf (_(" Offset into .debug_info section: %ld\n"),
3969 pubnames.pn_offset);
3970 printf (_(" Size of area in .debug_info section: %ld\n"),
3971 pubnames.pn_size);
3973 printf (_("\n Offset\tName\n"));
3977 offset = byte_get (data, 4);
3979 if (offset != 0)
3981 data += 4;
3982 printf (" %ld\t\t%s\n", offset, data);
3983 data += strlen (data) + 1;
3986 while (offset != 0);
3989 printf ("\n");
3990 return 1;
3993 static char *
3994 get_TAG_name (tag)
3995 unsigned long tag;
3997 switch (tag)
3999 case DW_TAG_padding: return "DW_TAG_padding";
4000 case DW_TAG_array_type: return "DW_TAG_array_type";
4001 case DW_TAG_class_type: return "DW_TAG_class_type";
4002 case DW_TAG_entry_point: return "DW_TAG_entry_point";
4003 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4004 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4005 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4006 case DW_TAG_label: return "DW_TAG_label";
4007 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4008 case DW_TAG_member: return "DW_TAG_member";
4009 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4010 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4011 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4012 case DW_TAG_string_type: return "DW_TAG_string_type";
4013 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4014 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4015 case DW_TAG_typedef: return "DW_TAG_typedef";
4016 case DW_TAG_union_type: return "DW_TAG_union_type";
4017 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4018 case DW_TAG_variant: return "DW_TAG_variant";
4019 case DW_TAG_common_block: return "DW_TAG_common_block";
4020 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4021 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4022 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4023 case DW_TAG_module: return "DW_TAG_module";
4024 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4025 case DW_TAG_set_type: return "DW_TAG_set_type";
4026 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4027 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4028 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4029 case DW_TAG_base_type: return "DW_TAG_base_type";
4030 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4031 case DW_TAG_const_type: return "DW_TAG_const_type";
4032 case DW_TAG_constant: return "DW_TAG_constant";
4033 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4034 case DW_TAG_file_type: return "DW_TAG_file_type";
4035 case DW_TAG_friend: return "DW_TAG_friend";
4036 case DW_TAG_namelist: return "DW_TAG_namelist";
4037 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4038 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4039 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4040 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4041 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4042 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4043 case DW_TAG_try_block: return "DW_TAG_try_block";
4044 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4045 case DW_TAG_variable: return "DW_TAG_variable";
4046 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4047 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4048 case DW_TAG_format_label: return "DW_TAG_format_label";
4049 case DW_TAG_function_template: return "DW_TAG_function_template";
4050 case DW_TAG_class_template: return "DW_TAG_class_template";
4051 default:
4053 static char buffer [100];
4055 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4056 return buffer;
4061 static char *
4062 get_AT_name (attribute)
4063 unsigned long attribute;
4065 switch (attribute)
4067 case DW_AT_sibling: return "DW_AT_sibling";
4068 case DW_AT_location: return "DW_AT_location";
4069 case DW_AT_name: return "DW_AT_name";
4070 case DW_AT_ordering: return "DW_AT_ordering";
4071 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4072 case DW_AT_byte_size: return "DW_AT_byte_size";
4073 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4074 case DW_AT_bit_size: return "DW_AT_bit_size";
4075 case DW_AT_element_list: return "DW_AT_element_list";
4076 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4077 case DW_AT_low_pc: return "DW_AT_low_pc";
4078 case DW_AT_high_pc: return "DW_AT_high_pc";
4079 case DW_AT_language: return "DW_AT_language";
4080 case DW_AT_member: return "DW_AT_member";
4081 case DW_AT_discr: return "DW_AT_discr";
4082 case DW_AT_discr_value: return "DW_AT_discr_value";
4083 case DW_AT_visibility: return "DW_AT_visibility";
4084 case DW_AT_import: return "DW_AT_import";
4085 case DW_AT_string_length: return "DW_AT_string_length";
4086 case DW_AT_common_reference: return "DW_AT_common_reference";
4087 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4088 case DW_AT_const_value: return "DW_AT_const_value";
4089 case DW_AT_containing_type: return "DW_AT_containing_type";
4090 case DW_AT_default_value: return "DW_AT_default_value";
4091 case DW_AT_inline: return "DW_AT_inline";
4092 case DW_AT_is_optional: return "DW_AT_is_optional";
4093 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4094 case DW_AT_producer: return "DW_AT_producer";
4095 case DW_AT_prototyped: return "DW_AT_prototyped";
4096 case DW_AT_return_addr: return "DW_AT_return_addr";
4097 case DW_AT_start_scope: return "DW_AT_start_scope";
4098 case DW_AT_stride_size: return "DW_AT_stride_size";
4099 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4100 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4101 case DW_AT_accessibility: return "DW_AT_accessibility";
4102 case DW_AT_address_class: return "DW_AT_address_class";
4103 case DW_AT_artificial: return "DW_AT_artificial";
4104 case DW_AT_base_types: return "DW_AT_base_types";
4105 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4106 case DW_AT_count: return "DW_AT_count";
4107 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4108 case DW_AT_decl_column: return "DW_AT_decl_column";
4109 case DW_AT_decl_file: return "DW_AT_decl_file";
4110 case DW_AT_decl_line: return "DW_AT_decl_line";
4111 case DW_AT_declaration: return "DW_AT_declaration";
4112 case DW_AT_discr_list: return "DW_AT_discr_list";
4113 case DW_AT_encoding: return "DW_AT_encoding";
4114 case DW_AT_external: return "DW_AT_external";
4115 case DW_AT_frame_base: return "DW_AT_frame_base";
4116 case DW_AT_friend: return "DW_AT_friend";
4117 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4118 case DW_AT_macro_info: return "DW_AT_macro_info";
4119 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4120 case DW_AT_priority: return "DW_AT_priority";
4121 case DW_AT_segment: return "DW_AT_segment";
4122 case DW_AT_specification: return "DW_AT_specification";
4123 case DW_AT_static_link: return "DW_AT_static_link";
4124 case DW_AT_type: return "DW_AT_type";
4125 case DW_AT_use_location: return "DW_AT_use_location";
4126 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4127 case DW_AT_virtuality: return "DW_AT_virtuality";
4128 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4129 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4130 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4131 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4132 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4133 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4134 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4135 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4136 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4137 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4138 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4139 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4140 case DW_AT_sf_names: return "DW_AT_sf_names";
4141 case DW_AT_src_info: return "DW_AT_src_info";
4142 case DW_AT_mac_info: return "DW_AT_mac_info";
4143 case DW_AT_src_coords: return "DW_AT_src_coords";
4144 case DW_AT_body_begin: return "DW_AT_body_begin";
4145 case DW_AT_body_end: return "DW_AT_body_end";
4146 default:
4148 static char buffer [100];
4150 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4151 return buffer;
4156 static char *
4157 get_FORM_name (form)
4158 unsigned long form;
4160 switch (form)
4162 case DW_FORM_addr: return "DW_FORM_addr";
4163 case DW_FORM_block2: return "DW_FORM_block2";
4164 case DW_FORM_block4: return "DW_FORM_block4";
4165 case DW_FORM_data2: return "DW_FORM_data2";
4166 case DW_FORM_data4: return "DW_FORM_data4";
4167 case DW_FORM_data8: return "DW_FORM_data8";
4168 case DW_FORM_string: return "DW_FORM_string";
4169 case DW_FORM_block: return "DW_FORM_block";
4170 case DW_FORM_block1: return "DW_FORM_block1";
4171 case DW_FORM_data1: return "DW_FORM_data1";
4172 case DW_FORM_flag: return "DW_FORM_flag";
4173 case DW_FORM_sdata: return "DW_FORM_sdata";
4174 case DW_FORM_strp: return "DW_FORM_strp";
4175 case DW_FORM_udata: return "DW_FORM_udata";
4176 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4177 case DW_FORM_ref1: return "DW_FORM_ref1";
4178 case DW_FORM_ref2: return "DW_FORM_ref2";
4179 case DW_FORM_ref4: return "DW_FORM_ref4";
4180 case DW_FORM_ref8: return "DW_FORM_ref8";
4181 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4182 case DW_FORM_indirect: return "DW_FORM_indirect";
4183 default:
4185 static char buffer [100];
4187 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4188 return buffer;
4193 /* FIXME: There are better and more effiecint ways to handle
4194 these structures. For now though, I just want something that
4195 is simple to implement. */
4196 typedef struct abbrev_attr
4198 unsigned long attribute;
4199 unsigned long form;
4200 struct abbrev_attr * next;
4202 abbrev_attr;
4204 typedef struct abbrev_entry
4206 unsigned long entry;
4207 unsigned long tag;
4208 int children;
4209 struct abbrev_attr * first_attr;
4210 struct abbrev_attr * last_attr;
4211 struct abbrev_entry * next;
4213 abbrev_entry;
4215 static abbrev_entry * first_abbrev = NULL;
4216 static abbrev_entry * last_abbrev = NULL;
4218 static void
4219 free_abbrevs PARAMS ((void))
4221 abbrev_entry * abbrev;
4223 for (abbrev = first_abbrev; abbrev;)
4225 abbrev_entry * next = abbrev->next;
4226 abbrev_attr * attr;
4228 for (attr = abbrev->first_attr; attr;)
4230 abbrev_attr * next = attr->next;
4232 free (attr);
4233 attr = next;
4236 free (abbrev);
4237 abbrev = next;
4240 last_abbrev = first_abbrev = NULL;
4243 static void
4244 add_abbrev (number, tag, children)
4245 unsigned long number;
4246 unsigned long tag;
4247 int children;
4249 abbrev_entry * entry;
4251 entry = (abbrev_entry *) malloc (sizeof (* entry));
4253 if (entry == NULL)
4254 /* ugg */
4255 return;
4257 entry->entry = number;
4258 entry->tag = tag;
4259 entry->children = children;
4260 entry->first_attr = NULL;
4261 entry->last_attr = NULL;
4262 entry->next = NULL;
4264 if (first_abbrev == NULL)
4265 first_abbrev = entry;
4266 else
4267 last_abbrev->next = entry;
4269 last_abbrev = entry;
4272 static void
4273 add_abbrev_attr (attribute, form)
4274 unsigned long attribute;
4275 unsigned long form;
4277 abbrev_attr * attr;
4279 attr = (abbrev_attr *) malloc (sizeof (* attr));
4281 if (attr == NULL)
4282 /* ugg */
4283 return;
4285 attr->attribute = attribute;
4286 attr->form = form;
4287 attr->next = NULL;
4289 if (last_abbrev->first_attr == NULL)
4290 last_abbrev->first_attr = attr;
4291 else
4292 last_abbrev->last_attr->next = attr;
4294 last_abbrev->last_attr = attr;
4297 /* Processes the (partial) contents of a .debug_abbrev section.
4298 Returns NULL if the end of the section was encountered.
4299 Returns the address after the last byte read if the end of
4300 an abbreviation set was found. */
4302 static unsigned char *
4303 process_abbrev_section (start, end)
4304 unsigned char * start;
4305 unsigned char * end;
4307 if (first_abbrev != NULL)
4308 return NULL;
4310 while (start < end)
4312 int bytes_read;
4313 unsigned long entry;
4314 unsigned long tag;
4315 unsigned long attribute;
4316 int children;
4318 entry = read_leb128 (start, & bytes_read, 0);
4319 start += bytes_read;
4321 if (entry == 0)
4322 return start;
4324 tag = read_leb128 (start, & bytes_read, 0);
4325 start += bytes_read;
4327 children = * start ++;
4329 add_abbrev (entry, tag, children);
4333 unsigned long form;
4335 attribute = read_leb128 (start, & bytes_read, 0);
4336 start += bytes_read;
4338 form = read_leb128 (start, & bytes_read, 0);
4339 start += bytes_read;
4341 if (attribute != 0)
4342 add_abbrev_attr (attribute, form);
4344 while (attribute != 0);
4347 return NULL;
4351 static int
4352 display_debug_abbrev (section, start, file)
4353 Elf32_Internal_Shdr * section;
4354 unsigned char * start;
4355 FILE * file;
4357 abbrev_entry * entry;
4358 unsigned char * end = start + section->sh_size;
4360 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4364 start = process_abbrev_section (start, end);
4366 printf (_(" Number TAG\n"));
4368 for (entry = first_abbrev; entry; entry = entry->next)
4370 abbrev_attr * attr;
4372 printf (_(" %ld %s [%s]\n"),
4373 entry->entry,
4374 get_TAG_name (entry->tag),
4375 entry->children ? _("has children") : _("no children"));
4377 for (attr = entry->first_attr; attr; attr = attr->next)
4379 printf (_(" %-18s %s\n"),
4380 get_AT_name (attr->attribute),
4381 get_FORM_name (attr->form));
4385 while (start);
4387 printf ("\n");
4389 return 1;
4393 static unsigned char *
4394 display_block (data, length)
4395 unsigned char * data;
4396 unsigned long length;
4398 printf (_(" %lu byte block: "), length);
4400 while (length --)
4401 printf ("%lx ", byte_get (data ++, 1));
4403 return data;
4406 static void
4407 decode_location_expression (data, pointer_size)
4408 unsigned char * data;
4409 unsigned int pointer_size;
4411 unsigned char op;
4412 int bytes_read;
4414 op = * data ++;
4416 switch (op)
4418 case DW_OP_addr: printf ("DW_OP_addr: %lx", byte_get (data, pointer_size)); break;
4419 case DW_OP_deref: printf ("DW_OP_deref"); break;
4420 case DW_OP_const1u: printf ("DW_OP_const1u: %lu", byte_get (data, 1)); break;
4421 case DW_OP_const1s: printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1)); break;
4422 case DW_OP_const2u: printf ("DW_OP_const2u: %lu", byte_get (data, 2)); break;
4423 case DW_OP_const2s: printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2)); break;
4424 case DW_OP_const4u: printf ("DW_OP_const4u: %lu", byte_get (data, 4)); break;
4425 case DW_OP_const4s: printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4)); break;
4426 case DW_OP_const8u: printf ("DW_OP_const8u: %lu %lu", byte_get (data, 4), byte_get (data + 4, 4)); break;
4427 case DW_OP_const8s: printf ("DW_OP_const8s: %ld %ld", byte_get (data, 4), byte_get (data + 4, 4)); break;
4428 case DW_OP_constu: printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0)); break;
4429 case DW_OP_consts: printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1)); break;
4430 case DW_OP_dup: printf ("DW_OP_dup"); break;
4431 case DW_OP_drop: printf ("DW_OP_drop"); break;
4432 case DW_OP_over: printf ("DW_OP_over"); break;
4433 case DW_OP_pick: printf ("DW_OP_pick: %ld", byte_get (data, 1)); break;
4434 case DW_OP_swap: printf ("DW_OP_swap"); break;
4435 case DW_OP_rot: printf ("DW_OP_rot"); break;
4436 case DW_OP_xderef: printf ("DW_OP_xderef"); break;
4437 case DW_OP_abs: printf ("DW_OP_abs"); break;
4438 case DW_OP_and: printf ("DW_OP_and"); break;
4439 case DW_OP_div: printf ("DW_OP_div"); break;
4440 case DW_OP_minus: printf ("DW_OP_minus"); break;
4441 case DW_OP_mod: printf ("DW_OP_mod"); break;
4442 case DW_OP_mul: printf ("DW_OP_mul"); break;
4443 case DW_OP_neg: printf ("DW_OP_neg"); break;
4444 case DW_OP_not: printf ("DW_OP_not"); break;
4445 case DW_OP_or: printf ("DW_OP_or"); break;
4446 case DW_OP_plus: printf ("DW_OP_plus"); break;
4447 case DW_OP_plus_uconst: printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0)); break;
4448 case DW_OP_shl: printf ("DW_OP_shl"); break;
4449 case DW_OP_shr: printf ("DW_OP_shr"); break;
4450 case DW_OP_shra: printf ("DW_OP_shra"); break;
4451 case DW_OP_xor: printf ("DW_OP_xor"); break;
4452 case DW_OP_bra: printf ("DW_OP_bra: %ld", byte_get (data, 2)); break;
4453 case DW_OP_eq: printf ("DW_OP_eq"); break;
4454 case DW_OP_ge: printf ("DW_OP_ge"); break;
4455 case DW_OP_gt: printf ("DW_OP_gt"); break;
4456 case DW_OP_le: printf ("DW_OP_le"); break;
4457 case DW_OP_lt: printf ("DW_OP_lt"); break;
4458 case DW_OP_ne: printf ("DW_OP_ne"); break;
4459 case DW_OP_skip: printf ("DW_OP_skip: %ld", byte_get (data, 2)); break;
4460 case DW_OP_lit0: printf ("DW_OP_lit0"); break;
4461 case DW_OP_lit1: printf ("DW_OP_lit1"); break;
4462 case DW_OP_lit2: printf ("DW_OP_lit2"); break;
4463 case DW_OP_lit3: printf ("DW_OP_lit3"); break;
4464 case DW_OP_lit4: printf ("DW_OP_lit4"); break;
4465 case DW_OP_lit5: printf ("DW_OP_lit5"); break;
4466 case DW_OP_lit6: printf ("DW_OP_lit6"); break;
4467 case DW_OP_lit7: printf ("DW_OP_lit7"); break;
4468 case DW_OP_lit8: printf ("DW_OP_lit8"); break;
4469 case DW_OP_lit9: printf ("DW_OP_lit9"); break;
4470 case DW_OP_lit10: printf ("DW_OP_lit10"); break;
4471 case DW_OP_lit11: printf ("DW_OP_lit11"); break;
4472 case DW_OP_lit12: printf ("DW_OP_lit12"); break;
4473 case DW_OP_lit13: printf ("DW_OP_lit13"); break;
4474 case DW_OP_lit14: printf ("DW_OP_lit14"); break;
4475 case DW_OP_lit15: printf ("DW_OP_lit15"); break;
4476 case DW_OP_lit16: printf ("DW_OP_lit16"); break;
4477 case DW_OP_lit17: printf ("DW_OP_lit17"); break;
4478 case DW_OP_lit18: printf ("DW_OP_lit18"); break;
4479 case DW_OP_lit19: printf ("DW_OP_lit19"); break;
4480 case DW_OP_lit20: printf ("DW_OP_lit20"); break;
4481 case DW_OP_lit21: printf ("DW_OP_lit21"); break;
4482 case DW_OP_lit22: printf ("DW_OP_lit22"); break;
4483 case DW_OP_lit23: printf ("DW_OP_lit23"); break;
4484 case DW_OP_lit24: printf ("DW_OP_lit24"); break;
4485 case DW_OP_lit25: printf ("DW_OP_lit25"); break;
4486 case DW_OP_lit26: printf ("DW_OP_lit26"); break;
4487 case DW_OP_lit27: printf ("DW_OP_lit27"); break;
4488 case DW_OP_lit28: printf ("DW_OP_lit28"); break;
4489 case DW_OP_lit29: printf ("DW_OP_lit29"); break;
4490 case DW_OP_lit30: printf ("DW_OP_lit30"); break;
4491 case DW_OP_lit31: printf ("DW_OP_lit31"); break;
4492 case DW_OP_reg0: printf ("DW_OP_reg0"); break;
4493 case DW_OP_reg1: printf ("DW_OP_reg1"); break;
4494 case DW_OP_reg2: printf ("DW_OP_reg2"); break;
4495 case DW_OP_reg3: printf ("DW_OP_reg3"); break;
4496 case DW_OP_reg4: printf ("DW_OP_reg4"); break;
4497 case DW_OP_reg5: printf ("DW_OP_reg5"); break;
4498 case DW_OP_reg6: printf ("DW_OP_reg6"); break;
4499 case DW_OP_reg7: printf ("DW_OP_reg7"); break;
4500 case DW_OP_reg8: printf ("DW_OP_reg8"); break;
4501 case DW_OP_reg9: printf ("DW_OP_reg9"); break;
4502 case DW_OP_reg10: printf ("DW_OP_reg10"); break;
4503 case DW_OP_reg11: printf ("DW_OP_reg11"); break;
4504 case DW_OP_reg12: printf ("DW_OP_reg12"); break;
4505 case DW_OP_reg13: printf ("DW_OP_reg13"); break;
4506 case DW_OP_reg14: printf ("DW_OP_reg14"); break;
4507 case DW_OP_reg15: printf ("DW_OP_reg15"); break;
4508 case DW_OP_reg16: printf ("DW_OP_reg16"); break;
4509 case DW_OP_reg17: printf ("DW_OP_reg17"); break;
4510 case DW_OP_reg18: printf ("DW_OP_reg18"); break;
4511 case DW_OP_reg19: printf ("DW_OP_reg19"); break;
4512 case DW_OP_reg20: printf ("DW_OP_reg20"); break;
4513 case DW_OP_reg21: printf ("DW_OP_reg21"); break;
4514 case DW_OP_reg22: printf ("DW_OP_reg22"); break;
4515 case DW_OP_reg23: printf ("DW_OP_reg23"); break;
4516 case DW_OP_reg24: printf ("DW_OP_reg24"); break;
4517 case DW_OP_reg25: printf ("DW_OP_reg25"); break;
4518 case DW_OP_reg26: printf ("DW_OP_reg26"); break;
4519 case DW_OP_reg27: printf ("DW_OP_reg27"); break;
4520 case DW_OP_reg28: printf ("DW_OP_reg28"); break;
4521 case DW_OP_reg29: printf ("DW_OP_reg29"); break;
4522 case DW_OP_reg30: printf ("DW_OP_reg30"); break;
4523 case DW_OP_reg31: printf ("DW_OP_reg31"); break;
4524 case DW_OP_breg0: printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1)); break;
4525 case DW_OP_breg1: printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1)); break;
4526 case DW_OP_breg2: printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1)); break;
4527 case DW_OP_breg3: printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1)); break;
4528 case DW_OP_breg4: printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1)); break;
4529 case DW_OP_breg5: printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1)); break;
4530 case DW_OP_breg6: printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1)); break;
4531 case DW_OP_breg7: printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1)); break;
4532 case DW_OP_breg8: printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1)); break;
4533 case DW_OP_breg9: printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1)); break;
4534 case DW_OP_breg10: printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1)); break;
4535 case DW_OP_breg11: printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1)); break;
4536 case DW_OP_breg12: printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1)); break;
4537 case DW_OP_breg13: printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1)); break;
4538 case DW_OP_breg14: printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1)); break;
4539 case DW_OP_breg15: printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1)); break;
4540 case DW_OP_breg16: printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1)); break;
4541 case DW_OP_breg17: printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1)); break;
4542 case DW_OP_breg18: printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1)); break;
4543 case DW_OP_breg19: printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1)); break;
4544 case DW_OP_breg20: printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1)); break;
4545 case DW_OP_breg21: printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1)); break;
4546 case DW_OP_breg22: printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1)); break;
4547 case DW_OP_breg23: printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1)); break;
4548 case DW_OP_breg24: printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1)); break;
4549 case DW_OP_breg25: printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1)); break;
4550 case DW_OP_breg26: printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1)); break;
4551 case DW_OP_breg27: printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1)); break;
4552 case DW_OP_breg28: printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1)); break;
4553 case DW_OP_breg29: printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1)); break;
4554 case DW_OP_breg30: printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1)); break;
4555 case DW_OP_breg31: printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1)); break;
4556 case DW_OP_regx: printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0)); break;
4557 case DW_OP_fbreg: printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1)); break;
4558 case DW_OP_bregx: printf ("DW_OP_bregx: %lu %ld", read_leb128 (data, & bytes_read, 0), read_leb128 (data + bytes_read, NULL, 1)); break;
4559 case DW_OP_piece: printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0)); break;
4560 case DW_OP_deref_size: printf ("DW_OP_deref_size: %ld", byte_get (data, 1)); break;
4561 case DW_OP_xderef_size: printf ("DW_OP_xderef_size: %ld", byte_get (data, 1)); break;
4562 case DW_OP_nop: printf ("DW_OP_nop"); break;
4564 default:
4565 if (op >= DW_OP_lo_user
4566 && op <= DW_OP_hi_user)
4567 printf (_("(User defined location op)"));
4568 else
4569 printf (_("(Unknown location op)"));
4570 break;
4575 static unsigned char *
4576 read_and_display_attr (attribute, form, data, pointer_size)
4577 unsigned long attribute;
4578 unsigned long form;
4579 unsigned char * data;
4580 unsigned long pointer_size;
4582 unsigned long uvalue;
4583 unsigned char * block_start;
4584 int bytes_read;
4585 int is_ref = 0;
4587 printf (" %-18s:", get_AT_name (attribute));
4589 switch (form)
4591 case DW_FORM_ref_addr:
4592 case DW_FORM_ref1:
4593 case DW_FORM_ref2:
4594 case DW_FORM_ref4:
4595 case DW_FORM_ref8:
4596 case DW_FORM_ref_udata:
4597 is_ref = 1;
4600 switch (form)
4602 case DW_FORM_ref_addr:
4603 case DW_FORM_addr:
4604 uvalue = byte_get (data, pointer_size);
4605 printf (is_ref ? " <%x>" : " %#x", uvalue);
4606 data += pointer_size;
4607 break;
4609 case DW_FORM_ref1:
4610 case DW_FORM_flag:
4611 case DW_FORM_data1:
4612 uvalue = byte_get (data ++, 1);
4613 printf (is_ref ? " <%x>" : " %d", uvalue);
4614 break;
4616 case DW_FORM_ref2:
4617 case DW_FORM_data2:
4618 uvalue = byte_get (data, 2);
4619 data += 2;
4620 printf (is_ref ? " <%x>" : " %d", uvalue);
4621 break;
4623 case DW_FORM_ref4:
4624 case DW_FORM_data4:
4625 uvalue = byte_get (data, 4);
4626 data += 4;
4627 printf (is_ref ? " <%x>" : " %d", uvalue);
4628 break;
4630 case DW_FORM_ref8:
4631 case DW_FORM_data8:
4632 uvalue = byte_get (data, 4);
4633 printf (" %lx", uvalue);
4634 printf (" %lx", byte_get (data + 4, 4));
4635 data += 8;
4636 break;
4638 case DW_FORM_string:
4639 printf (" %s", data);
4640 data += strlen (data) + 1;
4641 break;
4643 case DW_FORM_sdata:
4644 uvalue = read_leb128 (data, & bytes_read, 1);
4645 data += bytes_read;
4646 printf (" %ld", (long) uvalue);
4647 break;
4649 case DW_FORM_ref_udata:
4650 case DW_FORM_udata:
4651 uvalue = read_leb128 (data, & bytes_read, 0);
4652 data += bytes_read;
4653 printf (is_ref ? " <%lx>" : " %ld", uvalue);
4654 break;
4656 case DW_FORM_block:
4657 uvalue = read_leb128 (data, & bytes_read, 0);
4658 block_start = data + bytes_read;
4659 data = display_block (block_start, uvalue);
4660 uvalue = * block_start;
4661 break;
4663 case DW_FORM_block1:
4664 uvalue = byte_get (data, 1);
4665 block_start = data + 1;
4666 data = display_block (block_start, uvalue);
4667 uvalue = * block_start;
4668 break;
4670 case DW_FORM_block2:
4671 uvalue = byte_get (data, 2);
4672 block_start = data + 2;
4673 data = display_block (block_start, uvalue);
4674 uvalue = * block_start;
4675 break;
4677 case DW_FORM_block4:
4678 uvalue = byte_get (data, 4);
4679 block_start = data + 4;
4680 data = display_block (block_start, uvalue);
4681 uvalue = * block_start;
4682 break;
4684 case DW_FORM_strp:
4685 case DW_FORM_indirect:
4686 warn (_("Unable to handle FORM: %d"), form);
4687 break;
4689 default:
4690 warn (_("Unrecognised form: %d"), form);
4691 break;
4694 /* For some attributes we can display futher information. */
4696 printf ("\t");
4698 switch (attribute)
4700 case DW_AT_inline:
4701 switch (uvalue)
4703 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
4704 case DW_INL_inlined: printf (_("(inlined)")); break;
4705 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
4706 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
4707 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
4709 break;
4711 case DW_AT_frame_base:
4712 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
4713 printf ("(reg %ld)", uvalue - DW_OP_reg0);
4714 break;
4716 case DW_AT_language:
4717 switch (uvalue)
4719 case DW_LANG_C: printf ("(non-ANSI C)"); break;
4720 case DW_LANG_C89: printf ("(ANSI C)"); break;
4721 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
4722 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
4723 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
4724 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
4725 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
4726 case DW_LANG_Ada83: printf ("(Ada)"); break;
4727 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
4728 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
4729 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
4730 default: printf ("(Unknown: %lx)", uvalue); break;
4732 break;
4734 case DW_AT_encoding:
4735 switch (uvalue)
4737 case DW_ATE_void: printf ("(void)"); break;
4738 case DW_ATE_address: printf ("(machine address)"); break;
4739 case DW_ATE_boolean: printf ("(boolean)"); break;
4740 case DW_ATE_complex_float: printf ("(complex float)"); break;
4741 case DW_ATE_float: printf ("(float)"); break;
4742 case DW_ATE_signed: printf ("(signed)"); break;
4743 case DW_ATE_signed_char: printf ("(signed char)"); break;
4744 case DW_ATE_unsigned: printf ("(unsigned)"); break;
4745 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
4746 default:
4747 if (uvalue >= DW_ATE_lo_user
4748 && uvalue <= DW_ATE_hi_user)
4749 printf ("(user defined type)");
4750 else
4751 printf ("(unknown type)");
4752 break;
4754 break;
4756 case DW_AT_accessibility:
4757 switch (uvalue)
4759 case DW_ACCESS_public: printf ("(public)"); break;
4760 case DW_ACCESS_protected: printf ("(protected)"); break;
4761 case DW_ACCESS_private: printf ("(private)"); break;
4762 default: printf ("(unknown accessibility)"); break;
4764 break;
4766 case DW_AT_visibility:
4767 switch (uvalue)
4769 case DW_VIS_local: printf ("(local)"); break;
4770 case DW_VIS_exported: printf ("(exported)"); break;
4771 case DW_VIS_qualified: printf ("(qualified)"); break;
4772 default: printf ("(unknown visibility)"); break;
4774 break;
4776 case DW_AT_virtuality:
4777 switch (uvalue)
4779 case DW_VIRTUALITY_none: printf ("(none)"); break;
4780 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
4781 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
4782 default: printf ("(unknown virtuality)"); break;
4784 break;
4786 case DW_AT_identifier_case:
4787 switch (uvalue)
4789 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
4790 case DW_ID_up_case: printf ("(up_case)"); break;
4791 case DW_ID_down_case: printf ("(down_case)"); break;
4792 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
4793 default: printf ("(unknown case)"); break;
4795 break;
4797 case DW_AT_calling_convention:
4798 switch (uvalue)
4800 case DW_CC_normal: printf ("(normal)"); break;
4801 case DW_CC_program: printf ("(program)"); break;
4802 case DW_CC_nocall: printf ("(nocall)"); break;
4803 default:
4804 if (uvalue >= DW_CC_lo_user
4805 && uvalue <= DW_CC_hi_user)
4806 printf ("(user defined)");
4807 else
4808 printf ("(unknown convention)");
4810 break;
4812 case DW_AT_location:
4813 case DW_AT_data_member_location:
4814 case DW_AT_vtable_elem_location:
4815 printf ("(");
4816 decode_location_expression (block_start, pointer_size);
4817 printf (")");
4818 break;
4820 default:
4821 break;
4824 printf ("\n");
4825 return data;
4828 static int
4829 display_debug_info (section, start, file)
4830 Elf32_Internal_Shdr * section;
4831 unsigned char * start;
4832 FILE * file;
4834 unsigned char * end = start + section->sh_size;
4835 unsigned char * section_begin = start;
4837 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4839 while (start < end)
4841 DWARF2_External_CompUnit * external;
4842 DWARF2_Internal_CompUnit compunit;
4843 unsigned char * tags;
4844 int i;
4845 int level;
4847 external = (DWARF2_External_CompUnit *) start;
4849 compunit.cu_length = BYTE_GET (external->cu_length);
4850 compunit.cu_version = BYTE_GET (external->cu_version);
4851 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
4852 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
4854 tags = start + sizeof (* external);
4855 start += compunit.cu_length + sizeof (external->cu_length);
4857 if (compunit.cu_version != 2)
4859 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
4860 continue;
4863 printf (_(" Compilation Unit:\n"));
4864 printf (_(" Length: %ld\n"), compunit.cu_length);
4865 printf (_(" Version: %d\n"), compunit.cu_version);
4866 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
4867 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
4869 if (first_abbrev != NULL)
4870 free_abbrevs ();
4872 /* Read in the abbrevs used by this compilation unit. */
4875 Elf32_Internal_Shdr * sec;
4876 unsigned char * begin;
4878 /* Locate the .debug_abbrev section and process it. */
4879 for (i = 0, sec = section_headers;
4880 i < elf_header.e_shnum;
4881 i ++, sec ++)
4882 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
4883 break;
4885 if (i == -1 || sec->sh_size == 0)
4887 warn (_("Unable to locate .debug_abbrev section!\n"));
4888 return 0;
4891 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
4892 "debug_abbrev section data");
4894 process_abbrev_section (begin + compunit.cu_abbrev_offset,
4895 begin + sec->sh_size);
4897 free (begin);
4900 level = 0;
4901 while (tags < start)
4903 int bytes_read;
4904 int abbrev_number;
4905 abbrev_entry * entry;
4906 abbrev_attr * attr;
4908 abbrev_number = read_leb128 (tags, & bytes_read, 0);
4909 tags += bytes_read;
4911 /* A null DIE marks the end of a list of children. */
4912 if (abbrev_number == 0)
4914 --level;
4915 continue;
4918 /* Scan through the abbreviation list until we reach the
4919 correct entry. */
4920 for (entry = first_abbrev;
4921 entry && entry->entry != abbrev_number;
4922 entry = entry->next)
4923 continue;
4925 if (entry == NULL)
4927 warn (_("Unable to locate entry %d in the abbreviation table\n"),
4928 abbrev_number);
4929 return 0;
4932 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
4933 level, tags - section_begin - bytes_read,
4934 abbrev_number,
4935 get_TAG_name (entry->tag));
4937 for (attr = entry->first_attr; attr; attr = attr->next)
4938 tags = read_and_display_attr (attr->attribute,
4939 attr->form,
4940 tags,
4941 compunit.cu_pointer_size);
4943 if (entry->children)
4944 ++level;
4948 printf ("\n");
4950 return 1;
4953 static int
4954 display_debug_aranges (section, start, file)
4955 Elf32_Internal_Shdr * section;
4956 unsigned char * start;
4957 FILE * file;
4959 unsigned char * end = start + section->sh_size;
4961 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4963 while (start < end)
4965 DWARF2_External_ARange * external;
4966 DWARF2_Internal_ARange arange;
4967 unsigned char * ranges;
4968 unsigned long length;
4969 unsigned long address;
4971 external = (DWARF2_External_ARange *) start;
4973 arange.ar_length = BYTE_GET (external->ar_length);
4974 arange.ar_version = BYTE_GET (external->ar_version);
4975 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
4976 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
4977 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
4979 printf (_(" Length: %ld\n"), arange.ar_length);
4980 printf (_(" Version: %d\n"), arange.ar_version);
4981 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
4982 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
4983 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
4985 printf (_("\n Address Length\n"));
4987 ranges = start + sizeof (* external);
4989 for (;;)
4991 address = byte_get (ranges, arange.ar_pointer_size);
4993 if (address == 0)
4994 break;
4996 ranges += arange.ar_pointer_size;
4998 length = byte_get (ranges, arange.ar_pointer_size);
5000 ranges += arange.ar_pointer_size;
5002 printf (" %8.8lx %lu\n", address, length);
5005 start += arange.ar_length + sizeof (external->ar_length);
5008 printf ("\n");
5010 return 1;
5014 static int
5015 display_debug_not_supported (section, start, file)
5016 Elf32_Internal_Shdr * section;
5017 unsigned char * start;
5018 FILE * file;
5020 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5021 SECTION_NAME (section));
5023 return 1;
5026 /* A structure containing the name of a debug section and a pointer
5027 to a function that can decode it. */
5028 struct
5030 char * name;
5031 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5033 debug_displays[] =
5035 { ".debug_info", display_debug_info },
5036 { ".debug_abbrev", display_debug_abbrev },
5037 { ".debug_line", display_debug_lines },
5038 { ".debug_aranges", display_debug_aranges },
5039 { ".debug_pubnames", display_debug_pubnames },
5040 { ".debug_macinfo", display_debug_not_supported },
5041 { ".debug_frame", display_debug_not_supported },
5042 { ".debug_str", display_debug_not_supported },
5043 { ".debug_static_func", display_debug_not_supported },
5044 { ".debug_static_vars", display_debug_not_supported },
5045 { ".debug_types", display_debug_not_supported },
5046 { ".debug_weaknames", display_debug_not_supported }
5049 static int
5050 display_debug_section (section, file)
5051 Elf32_Internal_Shdr * section;
5052 FILE * file;
5054 char * name = SECTION_NAME (section);
5055 bfd_size_type length;
5056 unsigned char * start;
5057 int i;
5059 length = section->sh_size;
5060 if (length == 0)
5062 printf (_("\nSection '%s' has no debugging data.\n"), name);
5063 return 0;
5066 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5067 "debug section data");
5069 /* See if we know how to display the contents of this section. */
5070 for (i = NUM_ELEM (debug_displays); i--;)
5071 if (strcmp (debug_displays[i].name, name) == 0)
5073 debug_displays[i].display (section, start, file);
5074 break;
5077 if (i == -1)
5078 printf (_("Unrecognised debug section: %s\n"), name);
5080 free (start);
5082 /* If we loaded in the abbrev section at some point,
5083 we must release it here. */
5084 if (first_abbrev != NULL)
5085 free_abbrevs ();
5087 return 1;
5090 static int
5091 process_section_contents (file)
5092 FILE * file;
5094 Elf32_Internal_Shdr * section;
5095 unsigned int i;
5097 if (! do_dump)
5098 return 1;
5100 for (i = 0, section = section_headers;
5101 i < elf_header.e_shnum
5102 && i < num_dump_sects;
5103 i ++, section ++)
5105 #ifdef SUPPORT_DISASSEMBLY
5106 if (dump_sects[i] & DISASS_DUMP)
5107 disassemble_section (section, file);
5108 #endif
5109 if (dump_sects[i] & HEX_DUMP)
5110 dump_section (section, file);
5112 if (dump_sects[i] & DEBUG_DUMP)
5113 display_debug_section (section, file);
5116 if (i < num_dump_sects)
5117 warn (_("Some sections were not dumped because they do not exist!\n"));
5119 return 1;
5122 static void
5123 process_mips_fpe_exception (mask)
5124 int mask;
5126 if (mask)
5128 int first = 1;
5129 if (mask & OEX_FPU_INEX)
5130 fputs ("INEX", stdout), first = 0;
5131 if (mask & OEX_FPU_UFLO)
5132 printf ("%sUFLO", first ? "" : "|"), first = 0;
5133 if (mask & OEX_FPU_OFLO)
5134 printf ("%sOFLO", first ? "" : "|"), first = 0;
5135 if (mask & OEX_FPU_DIV0)
5136 printf ("%sDIV0", first ? "" : "|"), first = 0;
5137 if (mask & OEX_FPU_INVAL)
5138 printf ("%sINVAL", first ? "" : "|");
5140 else
5141 fputs ("0", stdout);
5144 static int
5145 process_mips_specific (file)
5146 FILE *file;
5148 Elf_Internal_Dyn *entry;
5149 size_t liblist_offset = 0;
5150 size_t liblistno = 0;
5151 size_t conflictsno = 0;
5152 size_t options_offset = 0;
5153 size_t conflicts_offset = 0;
5155 /* We have a lot of special sections. Thanks SGI! */
5156 if (dynamic_segment == NULL)
5157 /* No information available. */
5158 return 0;
5160 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5161 switch (entry->d_tag)
5163 case DT_MIPS_LIBLIST:
5164 liblist_offset = entry->d_un.d_val - loadaddr;
5165 break;
5166 case DT_MIPS_LIBLISTNO:
5167 liblistno = entry->d_un.d_val;
5168 break;
5169 case DT_MIPS_OPTIONS:
5170 options_offset = entry->d_un.d_val - loadaddr;
5171 break;
5172 case DT_MIPS_CONFLICT:
5173 conflicts_offset = entry->d_un.d_val - loadaddr;
5174 break;
5175 case DT_MIPS_CONFLICTNO:
5176 conflictsno = entry->d_un.d_val;
5177 break;
5178 default:
5179 break;
5182 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5184 Elf32_External_Lib *elib;
5185 size_t cnt;
5187 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5188 elib, Elf32_External_Lib *, "liblist");
5190 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5191 fputs (" Library Time Stamp Checksum Version Flags\n",
5192 stdout);
5194 for (cnt = 0; cnt < liblistno; ++cnt)
5196 Elf32_Lib liblist;
5197 time_t time;
5198 char timebuf[20];
5200 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5201 time = BYTE_GET (elib[cnt].l_time_stamp);
5202 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5203 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5204 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5206 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5208 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5209 dynamic_strings + liblist.l_name, timebuf,
5210 liblist.l_checksum, liblist.l_version);
5212 if (liblist.l_flags == 0)
5213 puts (" NONE");
5214 else
5216 static const struct
5218 const char *name;
5219 int bit;
5220 } l_flags_vals[] =
5222 { " EXACT_MATCH", LL_EXACT_MATCH },
5223 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5224 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5225 { " EXPORTS", LL_EXPORTS },
5226 { " DELAY_LOAD", LL_DELAY_LOAD },
5227 { " DELTA", LL_DELTA }
5229 int flags = liblist.l_flags;
5230 int fcnt;
5232 for (fcnt = 0;
5233 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5234 ++fcnt)
5235 if ((flags & l_flags_vals[fcnt].bit) != 0)
5237 fputs (l_flags_vals[fcnt].name, stdout);
5238 flags ^= l_flags_vals[fcnt].bit;
5240 if (flags != 0)
5241 printf (" %#x", (unsigned int) flags);
5243 puts ("");
5247 free (elib);
5250 if (options_offset != 0)
5252 Elf_External_Options *eopt;
5253 Elf_Internal_Shdr *sect = section_headers;
5254 Elf_Internal_Options *iopt;
5255 Elf_Internal_Options *option;
5256 size_t offset;
5257 int cnt;
5259 /* Find the section header so that we get the size. */
5260 while (sect->sh_type != SHT_MIPS_OPTIONS)
5261 ++sect;
5263 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5264 Elf_External_Options *, "options");
5266 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5267 * sizeof (*iopt));
5268 if (iopt == NULL)
5270 error (_("Out of memory"));
5271 return 0;
5274 offset = cnt = 0;
5275 option = iopt;
5276 while (offset < sect->sh_size)
5278 Elf_External_Options *eoption;
5280 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5282 option->kind = BYTE_GET (eoption->kind);
5283 option->size = BYTE_GET (eoption->size);
5284 option->section = BYTE_GET (eoption->section);
5285 option->info = BYTE_GET (eoption->info);
5287 offset += option->size;
5288 ++option;
5289 ++cnt;
5292 printf (_("\nSection '%s' contains %d entries:\n"),
5293 string_table + sect->sh_name, cnt);
5295 option = iopt;
5296 while (cnt-- > 0)
5298 size_t len;
5300 switch (option->kind)
5302 case ODK_NULL:
5303 /* This shouldn't happen. */
5304 printf (" NULL %d %lx", option->section, option->info);
5305 break;
5306 case ODK_REGINFO:
5307 printf (" REGINFO ");
5308 if (elf_header.e_machine == EM_MIPS)
5310 /* 32bit form. */
5311 Elf32_External_RegInfo *ereg;
5312 Elf32_RegInfo reginfo;
5314 ereg = (Elf32_External_RegInfo *) (option + 1);
5315 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5316 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5317 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5318 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5319 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5320 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5322 printf ("GPR %08lx GP 0x%lx\n",
5323 reginfo.ri_gprmask,
5324 (unsigned long) reginfo.ri_gp_value);
5325 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5326 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5327 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5329 else
5331 /* 64 bit form. */
5332 Elf64_External_RegInfo *ereg;
5333 Elf64_Internal_RegInfo reginfo;
5335 ereg = (Elf64_External_RegInfo *) (option + 1);
5336 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5337 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5338 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5339 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5340 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5341 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5343 printf ("GPR %08lx GP 0x",
5344 reginfo.ri_gprmask);
5345 printf_vma (reginfo.ri_gp_value);
5346 printf ("\n");
5348 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5349 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5350 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5352 ++option;
5353 continue;
5354 case ODK_EXCEPTIONS:
5355 fputs (" EXCEPTIONS fpe_min(", stdout);
5356 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
5357 fputs (") fpe_max(", stdout);
5358 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
5359 fputs (")", stdout);
5361 if (option->info & OEX_PAGE0)
5362 fputs (" PAGE0", stdout);
5363 if (option->info & OEX_SMM)
5364 fputs (" SMM", stdout);
5365 if (option->info & OEX_FPDBUG)
5366 fputs (" FPDBUG", stdout);
5367 if (option->info & OEX_DISMISS)
5368 fputs (" DISMISS", stdout);
5369 break;
5370 case ODK_PAD:
5371 fputs (" PAD ", stdout);
5372 if (option->info & OPAD_PREFIX)
5373 fputs (" PREFIX", stdout);
5374 if (option->info & OPAD_POSTFIX)
5375 fputs (" POSTFIX", stdout);
5376 if (option->info & OPAD_SYMBOL)
5377 fputs (" SYMBOL", stdout);
5378 break;
5379 case ODK_HWPATCH:
5380 fputs (" HWPATCH ", stdout);
5381 if (option->info & OHW_R4KEOP)
5382 fputs (" R4KEOP", stdout);
5383 if (option->info & OHW_R8KPFETCH)
5384 fputs (" R8KPFETCH", stdout);
5385 if (option->info & OHW_R5KEOP)
5386 fputs (" R5KEOP", stdout);
5387 if (option->info & OHW_R5KCVTL)
5388 fputs (" R5KCVTL", stdout);
5389 break;
5390 case ODK_FILL:
5391 fputs (" FILL ", stdout);
5392 /* XXX Print content of info word? */
5393 break;
5394 case ODK_TAGS:
5395 fputs (" TAGS ", stdout);
5396 /* XXX Print content of info word? */
5397 break;
5398 case ODK_HWAND:
5399 fputs (" HWAND ", stdout);
5400 if (option->info & OHWA0_R4KEOP_CHECKED)
5401 fputs (" R4KEOP_CHECKED", stdout);
5402 if (option->info & OHWA0_R4KEOP_CLEAN)
5403 fputs (" R4KEOP_CLEAN", stdout);
5404 break;
5405 case ODK_HWOR:
5406 fputs (" HWOR ", stdout);
5407 if (option->info & OHWA0_R4KEOP_CHECKED)
5408 fputs (" R4KEOP_CHECKED", stdout);
5409 if (option->info & OHWA0_R4KEOP_CLEAN)
5410 fputs (" R4KEOP_CLEAN", stdout);
5411 break;
5412 case ODK_GP_GROUP:
5413 printf (" GP_GROUP %#06lx self-contained %#06lx",
5414 option->info & OGP_GROUP,
5415 (option->info & OGP_SELF) >> 16);
5416 break;
5417 case ODK_IDENT:
5418 printf (" IDENT %#06lx self-contained %#06lx",
5419 option->info & OGP_GROUP,
5420 (option->info & OGP_SELF) >> 16);
5421 break;
5422 default:
5423 /* This shouldn't happen. */
5424 printf (" %3d ??? %d %lx",
5425 option->kind, option->section, option->info);
5426 break;
5429 len = sizeof (*eopt);
5430 while (len < option->size)
5431 if (((char *) option)[len] >= ' '
5432 && ((char *) option)[len] < 0x7f)
5433 printf ("%c", ((char *) option)[len++]);
5434 else
5435 printf ("\\%03o", ((char *) option)[len++]);
5437 fputs ("\n", stdout);
5438 ++option;
5441 free (eopt);
5444 if (conflicts_offset != 0 && conflictsno != 0)
5446 Elf32_External_Conflict *econf32;
5447 Elf64_External_Conflict *econf64;
5448 Elf32_Conflict *iconf;
5449 size_t cnt;
5451 if (dynamic_symbols == NULL)
5453 error (_("conflict list with without table"));
5454 return 0;
5457 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
5458 if (iconf == NULL)
5460 error (_("Out of memory"));
5461 return 0;
5464 if (binary_class == ELFCLASS32)
5466 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
5467 econf32, Elf32_External_Conflict *, "conflict");
5469 for (cnt = 0; cnt < conflictsno; ++cnt)
5470 iconf[cnt] = BYTE_GET (econf32[cnt]);
5472 else
5474 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
5475 econf64, Elf64_External_Conflict *, "conflict");
5477 for (cnt = 0; cnt < conflictsno; ++cnt)
5478 iconf[cnt] = BYTE_GET (econf64[cnt]);
5481 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
5482 puts (_(" Num: Index Value Name"));
5484 for (cnt = 0; cnt < conflictsno; ++cnt)
5486 Elf_Internal_Sym *psym = &dynamic_symbols[iconf[cnt]];
5488 printf ("%5u: %8lu %#10lx %s\n",
5489 cnt, iconf[cnt], (unsigned long) psym->st_value,
5490 dynamic_strings + psym->st_name);
5494 free (iconf);
5497 return 1;
5500 static int
5501 process_arch_specific (file)
5502 FILE *file;
5504 switch (elf_header.e_machine)
5506 case EM_MIPS:
5507 case EM_MIPS_RS4_BE:
5508 return process_mips_specific (file);
5509 break;
5510 default:
5511 break;
5513 return 1;
5516 static int
5517 get_file_header (file)
5518 FILE * file;
5520 Elf32_External_Ehdr ehdr;
5522 if (fread (& ehdr, sizeof (ehdr), 1, file) != 1)
5523 return 0;
5525 memcpy (elf_header.e_ident, ehdr.e_ident, EI_NIDENT);
5527 if (elf_header.e_ident [EI_DATA] == ELFDATA2LSB)
5528 byte_get = byte_get_little_endian;
5529 else
5530 byte_get = byte_get_big_endian;
5532 elf_header.e_entry = BYTE_GET (ehdr.e_entry);
5533 elf_header.e_phoff = BYTE_GET (ehdr.e_phoff);
5534 elf_header.e_shoff = BYTE_GET (ehdr.e_shoff);
5535 elf_header.e_version = BYTE_GET (ehdr.e_version);
5536 elf_header.e_flags = BYTE_GET (ehdr.e_flags);
5537 elf_header.e_type = BYTE_GET (ehdr.e_type);
5538 elf_header.e_machine = BYTE_GET (ehdr.e_machine);
5539 elf_header.e_ehsize = BYTE_GET (ehdr.e_ehsize);
5540 elf_header.e_phentsize = BYTE_GET (ehdr.e_phentsize);
5541 elf_header.e_phnum = BYTE_GET (ehdr.e_phnum);
5542 elf_header.e_shentsize = BYTE_GET (ehdr.e_shentsize);
5543 elf_header.e_shnum = BYTE_GET (ehdr.e_shnum);
5544 elf_header.e_shstrndx = BYTE_GET (ehdr.e_shstrndx);
5546 return 1;
5549 static void
5550 process_file (file_name)
5551 char * file_name;
5553 FILE * file;
5554 struct stat statbuf;
5555 unsigned int i;
5557 if (stat (file_name, & statbuf) < 0)
5559 error (_("Cannot stat input file %s.\n"), file_name);
5560 return;
5563 file = fopen (file_name, "rb");
5564 if (file == NULL)
5566 error (_("Input file %s not found.\n"), file_name);
5567 return;
5570 if (! get_file_header (file))
5572 error (_("%s: Failed to read file header\n"), file_name);
5573 fclose (file);
5574 return;
5577 /* Initialise per file variables. */
5578 for (i = NUM_ELEM (version_info); i--;)
5579 version_info[i] = 0;
5581 for (i = NUM_ELEM (dynamic_info); i--;)
5582 dynamic_info[i] = 0;
5584 /* Process the file. */
5585 if (show_name)
5586 printf (_("\nFile: %s\n"), file_name);
5588 if (! process_file_header ())
5590 fclose (file);
5591 return;
5594 process_section_headers (file);
5596 process_program_headers (file);
5598 process_dynamic_segment (file);
5600 process_relocs (file);
5602 process_symbol_table (file);
5604 process_syminfo (file);
5606 process_version_sections (file);
5608 process_section_contents (file);
5610 process_arch_specific (file);
5612 fclose (file);
5614 if (section_headers)
5616 free (section_headers);
5617 section_headers = NULL;
5620 if (string_table)
5622 free (string_table);
5623 string_table = NULL;
5626 if (dynamic_strings)
5628 free (dynamic_strings);
5629 dynamic_strings = NULL;
5632 if (dynamic_symbols)
5634 free (dynamic_symbols);
5635 dynamic_symbols = NULL;
5638 if (dynamic_syminfo)
5640 free (dynamic_syminfo);
5641 dynamic_syminfo = NULL;
5645 #ifdef SUPPORT_DISASSEMBLY
5646 /* Needed by the i386 disassembler. For extra credit, someone could
5647 fix this so that we insert symbolic addresses here, esp for GOT/PLT
5648 symbols */
5650 void
5651 print_address (unsigned int addr, FILE * outfile)
5653 fprintf (outfile,"0x%8.8x", addr);
5656 /* Needed by the i386 disassembler. */
5657 void
5658 db_task_printsym (unsigned int addr)
5660 print_address (addr, stderr);
5662 #endif
5665 main (argc, argv)
5666 int argc;
5667 char ** argv;
5669 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
5670 setlocale (LC_MESSAGES, "");
5671 #endif
5672 bindtextdomain (PACKAGE, LOCALEDIR);
5673 textdomain (PACKAGE);
5675 parse_args (argc, argv);
5677 if (optind < (argc - 1))
5678 show_name = 1;
5680 while (optind < argc)
5681 process_file (argv [optind ++]);
5683 if (dump_sects != NULL)
5684 free (dump_sects);
5686 return 0;