Initial revision
[binutils.git] / binutils / readelf.c
blob549bf1a68b61cf070ea3d15ad145099ccc840ec4
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_PPC:
814 if (e_flags & EF_PPC_EMB)
815 strcat (buf, ", emb");
817 if (e_flags & EF_PPC_RELOCATABLE)
818 strcat (buf, ", relocatable");
820 if (e_flags & EF_PPC_RELOCATABLE_LIB)
821 strcat (buf, ", relocatable-lib");
822 break;
824 case EM_CYGNUS_V850:
825 switch (e_flags & EF_V850_ARCH)
827 case E_V850E_ARCH:
828 strcat (buf, ", v850e");
829 break;
830 case E_V850EA_ARCH:
831 strcat (buf, ", v850ea");
832 break;
833 case E_V850_ARCH:
834 strcat (buf, ", v850");
835 break;
836 default:
837 strcat (buf, ", unknown v850 architecture variant");
838 break;
840 break;
842 case EM_CYGNUS_M32R:
843 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
844 strcat (buf, ", m32r");
846 break;
848 case EM_MIPS:
849 case EM_MIPS_RS4_BE:
850 if (e_flags & EF_MIPS_NOREORDER)
851 strcat (buf, ", noreorder");
853 if (e_flags & EF_MIPS_PIC)
854 strcat (buf, ", pic");
856 if (e_flags & EF_MIPS_CPIC)
857 strcat (buf, ", cpic");
859 if (e_flags & EF_MIPS_ABI2)
860 strcat (buf, ", abi2");
862 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
863 strcat (buf, ", mips1");
865 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
866 strcat (buf, ", mips2");
868 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
869 strcat (buf, ", mips3");
871 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
872 strcat (buf, ", mips4");
873 break;
877 return buf;
880 static char *
881 get_machine_data (e_data)
882 unsigned e_data;
884 static char buff [32];
886 switch (e_data)
888 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
889 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
890 default:
891 sprintf (buff, _("<unknown>: %x"), e_data);
892 return buff;
896 static const char *
897 get_mips_segment_type (type)
898 unsigned long type;
900 switch (type)
902 case PT_MIPS_REGINFO:
903 return "REGINFO";
904 case PT_MIPS_RTPROC:
905 return "RTPROC";
906 case PT_MIPS_OPTIONS:
907 return "OPTIONS";
908 default:
909 break;
912 return NULL;
915 static const char *
916 get_segment_type (p_type)
917 unsigned long p_type;
919 static char buff [32];
921 switch (p_type)
923 case PT_NULL: return "NULL";
924 case PT_LOAD: return "LOAD";
925 case PT_DYNAMIC: return "DYNAMIC";
926 case PT_INTERP: return "INTERP";
927 case PT_NOTE: return "NOTE";
928 case PT_SHLIB: return "SHLIB";
929 case PT_PHDR: return "PHDR";
931 default:
932 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
934 const char * result;
936 switch (elf_header.e_machine)
938 case EM_MIPS:
939 case EM_MIPS_RS4_BE:
940 result = get_mips_segment_type (p_type);
941 break;
942 default:
943 result = NULL;
944 break;
947 if (result != NULL)
948 return result;
950 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
952 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
953 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
954 else
955 sprintf (buff, _("<unknown>: %lx"), p_type);
957 return buff;
961 static const char *
962 get_mips_section_type_name (sh_type)
963 unsigned int sh_type;
965 switch (sh_type)
967 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
968 case SHT_MIPS_MSYM: return "MIPS_MSYM";
969 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
970 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
971 case SHT_MIPS_UCODE: return "MIPS_UCODE";
972 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
973 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
974 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
975 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
976 case SHT_MIPS_RELD: return "MIPS_RELD";
977 case SHT_MIPS_IFACE: return "MIPS_IFACE";
978 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
979 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
980 case SHT_MIPS_SHDR: return "MIPS_SHDR";
981 case SHT_MIPS_FDESC: return "MIPS_FDESC";
982 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
983 case SHT_MIPS_DENSE: return "MIPS_DENSE";
984 case SHT_MIPS_PDESC: return "MIPS_PDESC";
985 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
986 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
987 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
988 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
989 case SHT_MIPS_LINE: return "MIPS_LINE";
990 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
991 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
992 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
993 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
994 case SHT_MIPS_DWARF: return "MIPS_DWARF";
995 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
996 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
997 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
998 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
999 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
1000 case SHT_MIPS_XLATE: return "MIPS_XLATE";
1001 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
1002 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
1003 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
1004 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
1005 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1006 default:
1007 break;
1009 return NULL;
1012 static const char *
1013 get_section_type_name (sh_type)
1014 unsigned int sh_type;
1016 static char buff [32];
1018 switch (sh_type)
1020 case SHT_NULL: return "NULL";
1021 case SHT_PROGBITS: return "PROGBITS";
1022 case SHT_SYMTAB: return "SYMTAB";
1023 case SHT_STRTAB: return "STRTAB";
1024 case SHT_RELA: return "RELA";
1025 case SHT_HASH: return "HASH";
1026 case SHT_DYNAMIC: return "DYNAMIC";
1027 case SHT_NOTE: return "NOTE";
1028 case SHT_NOBITS: return "NOBITS";
1029 case SHT_REL: return "REL";
1030 case SHT_SHLIB: return "SHLIB";
1031 case SHT_DYNSYM: return "DYNSYM";
1032 case SHT_GNU_verdef: return "VERDEF";
1033 case SHT_GNU_verneed: return "VERNEED";
1034 case SHT_GNU_versym: return "VERSYM";
1035 case 0x6ffffff0: return "VERSYM";
1036 case 0x6ffffffc: return "VERDEF";
1037 case 0x7ffffffd: return "AUXILIARY";
1038 case 0x7fffffff: return "FILTER";
1040 default:
1041 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1043 const char * result;
1045 switch (elf_header.e_machine)
1047 case EM_MIPS:
1048 case EM_MIPS_RS4_BE:
1049 result = get_mips_section_type_name (sh_type);
1050 break;
1051 default:
1052 result = NULL;
1053 break;
1056 if (result != NULL)
1057 return result;
1059 sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1061 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1062 sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1063 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1064 sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1065 else
1066 sprintf (buff, _("<unknown>: %x"), sh_type);
1068 return buff;
1072 struct option options [] =
1074 {"all", no_argument, 0, 'a'},
1075 {"file-header", no_argument, 0, 'h'},
1076 {"program-headers", no_argument, 0, 'l'},
1077 {"headers", no_argument, 0, 'e'},
1078 {"histogram", no_argument, & do_histogram, 1},
1079 {"segments", no_argument, 0, 'l'},
1080 {"sections", no_argument, 0, 'S'},
1081 {"section-headers", no_argument, 0, 'S'},
1082 {"symbols", no_argument, 0, 's'},
1083 {"syms", no_argument, 0, 's'},
1084 {"relocs", no_argument, 0, 'r'},
1085 {"dynamic", no_argument, 0, 'd'},
1086 {"version-info", no_argument, 0, 'V'},
1087 {"use-dynamic", no_argument, 0, 'D'},
1088 {"hex-dump", required_argument, 0, 'x'},
1089 {"debug-dump", optional_argument, 0, 'w'},
1090 #ifdef SUPPORT_DISASSEMBLY
1091 {"instruction-dump", required_argument, 0, 'i'},
1092 #endif
1094 {"version", no_argument, 0, 'v'},
1095 {"help", no_argument, 0, 'H'},
1096 {0, no_argument, 0, 0}
1099 static void
1100 usage ()
1102 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1103 fprintf (stdout, _(" Options are:\n"));
1104 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1105 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1106 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1107 fprintf (stdout, _(" Display the program headers\n"));
1108 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1109 fprintf (stdout, _(" Display the sections' header\n"));
1110 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1111 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1112 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1113 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1114 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1115 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1116 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1117 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1118 fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1119 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1120 #ifdef SUPPORT_DISASSEMBLY
1121 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1122 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1123 #endif
1124 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1125 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1126 fprintf (stdout, _(" -H or --help Display this information\n"));
1127 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1129 exit (0);
1132 static void
1133 request_dump (section, type)
1134 unsigned int section;
1135 char type;
1137 if (section >= num_dump_sects)
1139 char * new_dump_sects;
1141 new_dump_sects = (char *) calloc (section + 1, 1);
1143 if (new_dump_sects == NULL)
1144 error (_("Out of memory allocating dump request table."));
1145 else
1147 /* Copy current flag settings. */
1148 memcpy (new_dump_sects, dump_sects, num_dump_sects);
1150 free (dump_sects);
1152 dump_sects = new_dump_sects;
1153 num_dump_sects = section + 1;
1157 if (dump_sects)
1158 dump_sects [section] |= type;
1160 return;
1163 static void
1164 parse_args (argc, argv)
1165 int argc;
1166 char ** argv;
1168 int c;
1170 if (argc < 2)
1171 usage ();
1173 while ((c = getopt_long
1174 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1176 char * cp;
1177 int section;
1179 switch (c)
1181 case 0:
1182 /* Long options. */
1183 break;
1184 case 'H':
1185 usage ();
1186 break;
1188 case 'a':
1189 do_syms ++;
1190 do_reloc ++;
1191 do_dynamic ++;
1192 do_header ++;
1193 do_sections ++;
1194 do_segments ++;
1195 do_version ++;
1196 do_histogram ++;
1197 break;
1198 case 'e':
1199 do_header ++;
1200 do_sections ++;
1201 do_segments ++;
1202 break;
1203 case 'D':
1204 do_using_dynamic ++;
1205 break;
1206 case 'r':
1207 do_reloc ++;
1208 break;
1209 case 'h':
1210 do_header ++;
1211 break;
1212 case 'l':
1213 do_segments ++;
1214 break;
1215 case 's':
1216 do_syms ++;
1217 break;
1218 case 'S':
1219 do_sections ++;
1220 break;
1221 case 'd':
1222 do_dynamic ++;
1223 break;
1224 case 'x':
1225 do_dump ++;
1226 section = strtoul (optarg, & cp, 0);
1227 if (! * cp && section >= 0)
1229 request_dump (section, HEX_DUMP);
1230 break;
1232 goto oops;
1233 case 'w':
1234 do_dump ++;
1235 if (optarg == 0)
1236 do_debugging = 1;
1237 else
1239 do_debugging = 0;
1240 switch (optarg[0])
1242 case 'i':
1243 case 'I':
1244 do_debug_info = 1;
1245 break;
1247 case 'a':
1248 case 'A':
1249 do_debug_abbrevs = 1;
1250 break;
1252 case 'l':
1253 case 'L':
1254 do_debug_lines = 1;
1255 break;
1257 case 'p':
1258 case 'P':
1259 do_debug_pubnames = 1;
1260 break;
1262 case 'r':
1263 case 'R':
1264 do_debug_aranges = 1;
1265 break;
1267 default:
1268 warn (_("Unrecognised debug option '%s'\n"), optarg);
1269 break;
1272 break;
1273 #ifdef SUPPORT_DISASSEMBLY
1274 case 'i':
1275 do_dump ++;
1276 section = strtoul (optarg, & cp, 0);
1277 if (! * cp && section >= 0)
1279 request_dump (section, DISASS_DUMP);
1280 break;
1282 goto oops;
1283 #endif
1284 case 'v':
1285 print_version (program_name);
1286 break;
1287 case 'V':
1288 do_version ++;
1289 break;
1290 default:
1291 oops:
1292 /* xgettext:c-format */
1293 error (_("Invalid option '-%c'\n"), c);
1294 /* Drop through. */
1295 case '?':
1296 usage ();
1300 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1301 && !do_segments && !do_header && !do_dump && !do_version
1302 && !do_histogram && !do_debugging)
1303 usage ();
1304 else if (argc < 3)
1306 warn (_("Nothing to do.\n"));
1307 usage();
1311 static const char *
1312 get_elf_class (elf_class)
1313 unsigned char elf_class;
1315 switch (elf_class)
1317 case ELFCLASSNONE: return _("none");
1318 case ELFCLASS32: return _("ELF32");
1319 case ELFCLASS64: return _("ELF64");
1320 default: return _("<unknown>");
1324 static const char *
1325 get_data_encoding (encoding)
1326 unsigned char encoding;
1328 switch (encoding)
1330 case ELFDATANONE: return _("none");
1331 case ELFDATA2LSB: return _("2's compilment, little endian");
1332 case ELFDATA2MSB: return _("2's compilment, big endian");
1333 default: return _("<unknown>");
1337 static const char *
1338 get_osabi_name (osabi)
1339 unsigned char osabi;
1341 switch (osabi)
1343 case ELFOSABI_SYSV: return _("UNIX - System V");
1344 case ELFOSABI_HPUX: return _("UNIX - HP-UX");
1345 case ELFOSABI_STANDALONE: return _("Standalone App");
1346 default: return _("<unknown>");
1350 /* Decode the data held in 'elf_header'. */
1351 static int
1352 process_file_header ()
1354 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1355 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1356 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1357 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1359 error
1360 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1361 return 0;
1364 if (do_header)
1366 int i;
1368 printf (_("ELF Header:\n"));
1369 printf (_(" Magic: "));
1370 for (i = 0; i < EI_NIDENT; i ++)
1371 printf ("%2.2x ", elf_header.e_ident [i]);
1372 printf ("\n");
1373 printf (_(" Class: %s\n"),
1374 get_elf_class (elf_header.e_ident [EI_CLASS]));
1375 printf (_(" Data: %s\n"),
1376 get_data_encoding (elf_header.e_ident [EI_DATA]));
1377 printf (_(" Version: %d %s\n"),
1378 elf_header.e_ident [EI_VERSION],
1379 elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
1380 elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown>" : "");
1381 printf (_(" OS/ABI: %s\n"),
1382 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1383 printf (_(" ABI Version: %d\n"),
1384 elf_header.e_ident [EI_ABIVERSION]);
1385 printf (_(" Type: %s\n"),
1386 get_file_type (elf_header.e_type));
1387 printf (_(" Machine: %s\n"),
1388 get_machine_name (elf_header.e_machine));
1389 printf (_(" Version: 0x%lx\n"),
1390 (unsigned long) elf_header.e_version);
1391 printf (_(" Data: %s\n"),
1392 get_machine_data (elf_header.e_ident [EI_DATA]));
1393 printf (_(" Entry point address: 0x%lx\n"),
1394 (unsigned long) elf_header.e_entry);
1395 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1396 (long) elf_header.e_phoff);
1397 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1398 (long) elf_header.e_shoff);
1399 printf (_(" Flags: 0x%lx%s\n"),
1400 (unsigned long) elf_header.e_flags,
1401 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1402 printf (_(" Size of this header: %ld (bytes)\n"),
1403 (long) elf_header.e_ehsize);
1404 printf (_(" Size of program headers: %ld (bytes)\n"),
1405 (long) elf_header.e_phentsize);
1406 printf (_(" Number of program headers: %ld\n"),
1407 (long) elf_header.e_phnum);
1408 printf (_(" Size of section headers: %ld (bytes)\n"),
1409 (long) elf_header.e_shentsize);
1410 printf (_(" Number of section headers: %ld\n"),
1411 (long) elf_header.e_shnum);
1412 printf (_(" Section header string table index: %ld\n"),
1413 (long) elf_header.e_shstrndx);
1416 /* Test class after dumping header so that at least the header can be
1417 display on 64 bit binaries. */
1419 binary_class = elf_header.e_ident [EI_CLASS];
1420 if (binary_class != ELFCLASS32)
1422 error (_("Not a 32 bit ELF file\n"));
1423 return 0;
1426 return 1;
1430 static int
1431 process_program_headers (file)
1432 FILE * file;
1434 Elf32_External_Phdr * phdrs;
1435 Elf32_Internal_Phdr * program_headers;
1436 Elf32_Internal_Phdr * segment;
1437 unsigned int i;
1439 if (elf_header.e_phnum == 0)
1441 if (do_segments)
1442 printf (_("\nThere are no program headers in this file.\n"));
1443 return 1;
1446 if (do_segments && !do_header)
1448 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1449 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1450 printf (_("There are %d program headers, starting at offset %lx:\n"),
1451 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1454 GET_DATA_ALLOC (elf_header.e_phoff,
1455 elf_header.e_phentsize * elf_header.e_phnum,
1456 phdrs, Elf32_External_Phdr *, "program headers");
1458 program_headers = (Elf32_Internal_Phdr *) malloc
1459 (elf_header.e_phnum * sizeof (Elf32_Internal_Phdr));
1461 if (program_headers == NULL)
1463 error (_("Out of memory\n"));
1464 return 0;
1467 for (i = 0, segment = program_headers;
1468 i < elf_header.e_phnum;
1469 i ++, segment ++)
1471 segment->p_type = BYTE_GET (phdrs[i].p_type);
1472 segment->p_offset = BYTE_GET (phdrs[i].p_offset);
1473 segment->p_vaddr = BYTE_GET (phdrs[i].p_vaddr);
1474 segment->p_paddr = BYTE_GET (phdrs[i].p_paddr);
1475 segment->p_filesz = BYTE_GET (phdrs[i].p_filesz);
1476 segment->p_memsz = BYTE_GET (phdrs[i].p_memsz);
1477 segment->p_flags = BYTE_GET (phdrs[i].p_flags);
1478 segment->p_align = BYTE_GET (phdrs[i].p_align);
1481 free (phdrs);
1483 if (do_segments)
1485 printf
1486 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1487 printf
1488 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1491 loadaddr = -1;
1492 dynamic_addr = 0;
1494 for (i = 0, segment = program_headers;
1495 i < elf_header.e_phnum;
1496 i ++, segment ++)
1498 if (do_segments)
1500 printf (" %-11.11s ", get_segment_type (segment->p_type));
1501 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1502 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1503 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1504 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1505 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1506 printf ("%c%c%c ",
1507 (segment->p_flags & PF_R ? 'R' : ' '),
1508 (segment->p_flags & PF_W ? 'W' : ' '),
1509 (segment->p_flags & PF_X ? 'E' : ' '));
1510 printf ("%#lx", (unsigned long) segment->p_align);
1513 switch (segment->p_type)
1515 case PT_LOAD:
1516 if (loadaddr == -1)
1517 loadaddr = (segment->p_vaddr & 0xfffff000)
1518 - (segment->p_offset & 0xfffff000);
1519 break;
1521 case PT_DYNAMIC:
1522 if (dynamic_addr)
1523 error (_("more than one dynamic segment\n"));
1525 dynamic_addr = segment->p_offset;
1526 dynamic_size = segment->p_filesz;
1527 break;
1529 case PT_INTERP:
1530 if (fseek (file, segment->p_offset, SEEK_SET))
1531 error (_("Unable to find program interpreter name\n"));
1532 else
1534 program_interpreter[0] = 0;
1535 fscanf (file, "%63s", program_interpreter);
1537 if (do_segments)
1538 printf (_("\n [Requesting program interpreter: %s]"),
1539 program_interpreter);
1541 break;
1544 if (do_segments)
1545 putc ('\n', stdout);
1548 if (loadaddr == -1)
1550 /* Very strange. */
1551 loadaddr = 0;
1554 if (do_segments && section_headers != NULL)
1556 printf (_("\n Section to Segment mapping:\n"));
1557 printf (_(" Segment Sections...\n"));
1559 assert (string_table != NULL);
1561 for (i = 0; i < elf_header.e_phnum; i++)
1563 int j;
1564 Elf32_Internal_Shdr * section;
1566 segment = program_headers + i;
1567 section = section_headers;
1569 printf (" %2.2d ", i);
1571 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1573 if (section->sh_size > 0
1574 /* Compare allocated sections by VMA, unallocated
1575 sections by file offset. */
1576 && (section->sh_flags & SHF_ALLOC
1577 ? (section->sh_addr >= segment->p_vaddr
1578 && section->sh_addr + section->sh_size
1579 <= segment->p_vaddr + segment->p_memsz)
1580 : (section->sh_offset >= segment->p_offset
1581 && (section->sh_offset + section->sh_size
1582 <= segment->p_offset + segment->p_filesz))))
1583 printf ("%s ", SECTION_NAME (section));
1586 putc ('\n',stdout);
1590 free (program_headers);
1592 return 1;
1596 static int
1597 get_section_headers (file)
1598 FILE * file;
1600 Elf32_External_Shdr * shdrs;
1601 Elf32_Internal_Shdr * internal;
1602 unsigned int i;
1604 GET_DATA_ALLOC (elf_header.e_shoff,
1605 elf_header.e_shentsize * elf_header.e_shnum,
1606 shdrs, Elf32_External_Shdr *, "section headers");
1608 section_headers = (Elf32_Internal_Shdr *) malloc
1609 (elf_header.e_shnum * sizeof (Elf32_Internal_Shdr));
1611 if (section_headers == NULL)
1613 error (_("Out of memory\n"));
1614 return 0;
1617 for (i = 0, internal = section_headers;
1618 i < elf_header.e_shnum;
1619 i ++, internal ++)
1621 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1622 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1623 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1624 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1625 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1626 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1627 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1628 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1629 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1630 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1633 free (shdrs);
1635 return 1;
1638 static Elf_Internal_Sym *
1639 get_elf_symbols (file, offset, number)
1640 FILE * file;
1641 unsigned long offset;
1642 unsigned long number;
1644 Elf32_External_Sym * esyms;
1645 Elf_Internal_Sym * isyms;
1646 Elf_Internal_Sym * psym;
1647 unsigned int j;
1649 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1650 esyms, Elf32_External_Sym *, "symbols");
1652 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1654 if (isyms == NULL)
1656 error (_("Out of memory\n"));
1657 free (esyms);
1659 return NULL;
1662 for (j = 0, psym = isyms;
1663 j < number;
1664 j ++, psym ++)
1666 psym->st_name = BYTE_GET (esyms[j].st_name);
1667 psym->st_value = BYTE_GET (esyms[j].st_value);
1668 psym->st_size = BYTE_GET (esyms[j].st_size);
1669 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1670 psym->st_info = BYTE_GET (esyms[j].st_info);
1671 psym->st_other = BYTE_GET (esyms[j].st_other);
1674 free (esyms);
1676 return isyms;
1679 static int
1680 process_section_headers (file)
1681 FILE * file;
1683 Elf32_Internal_Shdr * section;
1684 int i;
1686 section_headers = NULL;
1688 if (elf_header.e_shnum == 0)
1690 if (do_sections)
1691 printf (_("\nThere are no sections in this file.\n"));
1693 return 1;
1696 if (do_sections && !do_header)
1697 printf (_("There are %d section headers, starting at offset %lx:\n"),
1698 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
1700 if (! get_section_headers (file))
1701 return 0;
1703 /* Read in the string table, so that we have names to display. */
1704 section = section_headers + elf_header.e_shstrndx;
1706 if (section->sh_size != 0)
1708 unsigned long string_table_offset;
1710 string_table_offset = section->sh_offset;
1712 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1713 string_table, char *, "string table");
1716 /* Scan the sections for the dynamic symbol table
1717 and dynamic string table and debug sections. */
1718 dynamic_symbols = NULL;
1719 dynamic_strings = NULL;
1720 dynamic_syminfo = NULL;
1721 for (i = 0, section = section_headers;
1722 i < elf_header.e_shnum;
1723 i ++, section ++)
1725 char * name = SECTION_NAME (section);
1727 if (section->sh_type == SHT_DYNSYM)
1729 if (dynamic_symbols != NULL)
1731 error (_("File contains multiple dynamic symbol tables\n"));
1732 continue;
1735 dynamic_symbols = get_elf_symbols
1736 (file, section->sh_offset,
1737 section->sh_size / section->sh_entsize);
1739 else if (section->sh_type == SHT_STRTAB
1740 && strcmp (name, ".dynstr") == 0)
1742 if (dynamic_strings != NULL)
1744 error (_("File contains multiple dynamic string tables\n"));
1745 continue;
1748 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1749 dynamic_strings, char *, "dynamic strings");
1751 else if ((do_debugging || do_debug_info || do_debug_abbrevs
1752 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
1753 && strncmp (name, ".debug_", 7) == 0)
1755 name += 7;
1757 if (do_debugging
1758 || (do_debug_info && (strcmp (name, "info") == 0))
1759 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
1760 || (do_debug_lines && (strcmp (name, "line") == 0))
1761 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
1762 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
1764 request_dump (i, DEBUG_DUMP);
1768 if (! do_sections)
1769 return 1;
1771 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
1772 printf
1773 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1775 for (i = 0, section = section_headers;
1776 i < elf_header.e_shnum;
1777 i ++, section ++)
1779 printf (" [%2d] %-17.17s %-15.15s ",
1781 SECTION_NAME (section),
1782 get_section_type_name (section->sh_type));
1784 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1785 (unsigned long) section->sh_addr,
1786 (unsigned long) section->sh_offset,
1787 (unsigned long) section->sh_size,
1788 (unsigned long) section->sh_entsize);
1790 printf (" %c%c%c %2ld %3lx %ld\n",
1791 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
1792 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
1793 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
1794 (unsigned long) section->sh_link,
1795 (unsigned long) section->sh_info,
1796 (unsigned long) section->sh_addralign);
1799 return 1;
1802 /* Process the reloc section. */
1803 static int
1804 process_relocs (file)
1805 FILE * file;
1807 unsigned long rel_size;
1808 unsigned long rel_offset;
1811 if (!do_reloc)
1812 return 1;
1814 if (do_using_dynamic)
1816 rel_size = 0;
1817 rel_offset = 0;
1819 if (dynamic_info[DT_REL])
1821 rel_offset = dynamic_info[DT_REL];
1822 rel_size = dynamic_info[DT_RELSZ];
1824 else if (dynamic_info [DT_RELA])
1826 rel_offset = dynamic_info[DT_RELA];
1827 rel_size = dynamic_info[DT_RELASZ];
1829 else if (dynamic_info[DT_JMPREL])
1831 rel_offset = dynamic_info[DT_JMPREL];
1832 rel_size = dynamic_info[DT_PLTRELSZ];
1835 if (rel_size)
1837 printf
1838 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
1839 rel_offset, rel_size);
1841 dump_relocations (file, rel_offset - loadaddr, rel_size,
1842 dynamic_symbols, dynamic_strings);
1844 else
1845 printf (_("\nThere are no dynamic relocations in this file.\n"));
1847 else
1849 Elf32_Internal_Shdr * section;
1850 unsigned long i;
1851 int found = 0;
1853 for (i = 0, section = section_headers;
1854 i < elf_header.e_shnum;
1855 i++, section ++)
1857 if ( section->sh_type != SHT_RELA
1858 && section->sh_type != SHT_REL)
1859 continue;
1861 rel_offset = section->sh_offset;
1862 rel_size = section->sh_size;
1864 if (rel_size)
1866 Elf32_Internal_Shdr * strsec;
1867 Elf32_Internal_Shdr * symsec;
1868 Elf_Internal_Sym * symtab;
1869 char * strtab;
1871 printf (_("\nRelocation section "));
1873 if (string_table == NULL)
1874 printf ("%d", section->sh_name);
1875 else
1876 printf ("'%s'", SECTION_NAME (section));
1878 printf (_(" at offset 0x%lx contains %lu entries:\n"),
1879 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
1881 symsec = section_headers + section->sh_link;
1883 symtab = get_elf_symbols (file, symsec->sh_offset,
1884 symsec->sh_size / symsec->sh_entsize);
1886 if (symtab == NULL)
1887 continue;
1889 strsec = section_headers + symsec->sh_link;
1891 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
1892 char *, "string table");
1894 dump_relocations (file, rel_offset, rel_size, symtab, strtab);
1896 free (strtab);
1897 free (symtab);
1899 found = 1;
1903 if (! found)
1904 printf (_("\nThere are no relocations in this file.\n"));
1907 return 1;
1911 static void
1912 dynamic_segment_mips_val (entry)
1913 Elf_Internal_Dyn * entry;
1915 switch (entry->d_tag)
1917 case DT_MIPS_FLAGS:
1918 if (entry->d_un.d_val == 0)
1919 printf ("NONE\n");
1920 else
1922 static const char * opts[] =
1924 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
1925 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
1926 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
1927 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
1928 "RLD_ORDER_SAFE"
1930 unsigned int cnt;
1931 int first = 1;
1932 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
1933 if (entry->d_un.d_val & (1 << cnt))
1935 printf ("%s%s", first ? "" : " ", opts[cnt]);
1936 first = 0;
1938 puts ("");
1940 break;
1942 case DT_MIPS_IVERSION:
1943 if (dynamic_strings != NULL)
1944 printf ("Interface Version: %s\n",
1945 dynamic_strings + entry->d_un.d_val);
1946 else
1947 printf ("%ld\n", (long) entry->d_un.d_ptr);
1948 break;
1950 case DT_MIPS_TIME_STAMP:
1952 char timebuf[20];
1953 time_t time = entry->d_un.d_val;
1954 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
1955 printf ("Time Stamp: %s\n", timebuf);
1957 break;
1959 case DT_MIPS_RLD_VERSION:
1960 case DT_MIPS_LOCAL_GOTNO:
1961 case DT_MIPS_CONFLICTNO:
1962 case DT_MIPS_LIBLISTNO:
1963 case DT_MIPS_SYMTABNO:
1964 case DT_MIPS_UNREFEXTNO:
1965 case DT_MIPS_HIPAGENO:
1966 case DT_MIPS_DELTA_CLASS_NO:
1967 case DT_MIPS_DELTA_INSTANCE_NO:
1968 case DT_MIPS_DELTA_RELOC_NO:
1969 case DT_MIPS_DELTA_SYM_NO:
1970 case DT_MIPS_DELTA_CLASSSYM_NO:
1971 case DT_MIPS_COMPACT_SIZE:
1972 printf ("%ld\n", (long) entry->d_un.d_ptr);
1973 break;
1975 default:
1976 printf ("%#lx\n", (long) entry->d_un.d_ptr);
1980 /* Parse the dynamic segment */
1981 static int
1982 process_dynamic_segment (file)
1983 FILE * file;
1985 Elf_Internal_Dyn * entry;
1986 Elf32_External_Dyn * edyn;
1987 unsigned int i;
1989 if (dynamic_size == 0)
1991 if (do_dynamic)
1992 printf (_("\nThere is no dynamic segment in this file.\n"));
1994 return 1;
1997 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
1998 edyn, Elf32_External_Dyn *, "dynamic segment");
2000 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2001 how large .dynamic is now. We can do this even before the byte
2002 swapping since the DT_NULL tag is recognizable. */
2003 dynamic_size = 0;
2004 while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
2007 dynamic_segment = (Elf_Internal_Dyn *)
2008 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2010 if (dynamic_segment == NULL)
2012 error (_("Out of memory\n"));
2013 free (edyn);
2014 return 0;
2017 for (i = 0, entry = dynamic_segment;
2018 i < dynamic_size;
2019 i ++, entry ++)
2021 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2022 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2025 free (edyn);
2027 /* Find the appropriate symbol table. */
2028 if (dynamic_symbols == NULL)
2030 for (i = 0, entry = dynamic_segment;
2031 i < dynamic_size;
2032 ++i, ++ entry)
2034 unsigned long offset;
2035 long num_syms;
2037 if (entry->d_tag != DT_SYMTAB)
2038 continue;
2040 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2042 /* Since we do not know how big the symbol table is,
2043 we default to reading in the entire file (!) and
2044 processing that. This is overkill, I know, but it
2045 should work. */
2047 offset = entry->d_un.d_val - loadaddr;
2049 if (fseek (file, 0, SEEK_END))
2050 error (_("Unable to seek to end of file!"));
2052 num_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2054 if (num_syms < 1)
2056 error (_("Unable to determine the number of symbols to load\n"));
2057 continue;
2060 dynamic_symbols = get_elf_symbols (file, offset, num_syms);
2064 /* Similarly find a string table. */
2065 if (dynamic_strings == NULL)
2067 for (i = 0, entry = dynamic_segment;
2068 i < dynamic_size;
2069 ++i, ++ entry)
2071 unsigned long offset;
2072 long str_tab_len;
2074 if (entry->d_tag != DT_STRTAB)
2075 continue;
2077 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2079 /* Since we do not know how big the string table is,
2080 we default to reading in the entire file (!) and
2081 processing that. This is overkill, I know, but it
2082 should work. */
2084 offset = entry->d_un.d_val - loadaddr;
2085 if (fseek (file, 0, SEEK_END))
2086 error (_("Unable to seek to end of file\n"));
2087 str_tab_len = ftell (file) - offset;
2089 if (str_tab_len < 1)
2091 error
2092 (_("Unable to determine the length of the dynamic string table\n"));
2093 continue;
2096 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2097 "dynamic string table");
2099 break;
2103 /* And find the syminfo section if available. */
2104 if (dynamic_syminfo == NULL)
2106 unsigned int syminsz = 0;
2108 for (i = 0, entry = dynamic_segment;
2109 i < dynamic_size;
2110 ++i, ++ entry)
2112 if (entry->d_tag == DT_SYMINENT)
2114 /* Note: these braces are necessary to avoid a syntax
2115 error from the SunOS4 C compiler. */
2116 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2118 else if (entry->d_tag == DT_SYMINSZ)
2119 syminsz = entry->d_un.d_val;
2120 else if (entry->d_tag == DT_SYMINFO)
2121 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2124 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2126 Elf_External_Syminfo *extsyminfo;
2127 Elf_Internal_Syminfo *syminfo;
2129 /* There is a syminfo section. Read the data. */
2130 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2131 Elf_External_Syminfo *, "symbol information");
2133 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2134 if (dynamic_syminfo == NULL)
2136 error (_("Out of memory\n"));
2137 return 0;
2140 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2141 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2142 ++i, ++syminfo)
2144 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2145 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2148 free (extsyminfo);
2152 if (do_dynamic && dynamic_addr)
2153 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
2154 dynamic_addr, dynamic_size);
2155 if (do_dynamic)
2156 printf (_(" Tag Type Name/Value\n"));
2158 for (i = 0, entry = dynamic_segment;
2159 i < dynamic_size;
2160 i++, entry ++)
2162 if (do_dynamic)
2163 printf (_(" 0x%-8.8lx (%s)%*s"),
2164 (unsigned long) entry->d_tag,
2165 get_dynamic_type (entry->d_tag),
2166 27 - strlen (get_dynamic_type (entry->d_tag)),
2167 " ");
2169 switch (entry->d_tag)
2171 case DT_AUXILIARY:
2172 case DT_FILTER:
2173 if (do_dynamic)
2175 if (entry->d_tag == DT_AUXILIARY)
2176 printf (_("Auxiliary library"));
2177 else
2178 printf (_("Filter library"));
2180 if (dynamic_strings)
2181 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2182 else
2183 printf (": %#lx\n", (long) entry->d_un.d_val);
2185 break;
2187 case DT_FEATURE_1:
2188 if (do_dynamic)
2190 printf (_("Flags:"));
2191 if (entry->d_un.d_val == 0)
2192 printf (_(" None\n"));
2193 else
2195 unsigned long int val = entry->d_un.d_val;
2196 if (val & DTF_1_PARINIT)
2198 printf (" PARINIT");
2199 val ^= DTF_1_PARINIT;
2201 if (val != 0)
2202 printf (" %lx", val);
2203 puts ("");
2206 break;
2208 case DT_POSFLAG_1:
2209 if (do_dynamic)
2211 printf (_("Flags:"));
2212 if (entry->d_un.d_val == 0)
2213 printf (_(" None\n"));
2214 else
2216 unsigned long int val = entry->d_un.d_val;
2217 if (val & DF_P1_LAZYLOAD)
2219 printf (" LAZYLOAD");
2220 val ^= DF_P1_LAZYLOAD;
2222 if (val & DF_P1_GROUPPERM)
2224 printf (" GROUPPERM");
2225 val ^= DF_P1_GROUPPERM;
2227 if (val != 0)
2228 printf (" %lx", val);
2229 puts ("");
2232 break;
2234 case DT_FLAGS_1:
2235 if (do_dynamic)
2237 printf (_("Flags:"));
2238 if (entry->d_un.d_val == 0)
2239 printf (_(" None\n"));
2240 else
2242 unsigned long int val = entry->d_un.d_val;
2243 if (val & DF_1_NOW)
2245 printf (" NOW");
2246 val ^= DF_1_NOW;
2248 if (val & DF_1_GLOBAL)
2250 printf (" GLOBAL");
2251 val ^= DF_1_GLOBAL;
2253 if (val & DF_1_GROUP)
2255 printf (" GROUP");
2256 val ^= DF_1_GROUP;
2258 if (val & DF_1_NODELETE)
2260 printf (" NODELETE");
2261 val ^= DF_1_NODELETE;
2263 if (val & DF_1_LOADFLTR)
2265 printf (" LOADFLTR");
2266 val ^= DF_1_LOADFLTR;
2268 if (val & DF_1_INITFIRST)
2270 printf (" INITFIRST");
2271 val ^= DF_1_INITFIRST;
2273 if (val & DF_1_NOOPEN)
2275 printf (" NOOPEN");
2276 val ^= DF_1_NOOPEN;
2278 if (val & DF_1_ORIGIN)
2280 printf (" ORIGIN");
2281 val ^= DF_1_ORIGIN;
2283 if (val & DF_1_DIRECT)
2285 printf (" DIRECT");
2286 val ^= DF_1_DIRECT;
2288 if (val & DF_1_TRANS)
2290 printf (" TRANS");
2291 val ^= DF_1_TRANS;
2293 if (val & DF_1_INTERPOSE)
2295 printf (" INTERPOSE");
2296 val ^= DF_1_INTERPOSE;
2298 if (val != 0)
2299 printf (" %lx", val);
2300 puts ("");
2303 break;
2305 case DT_PLTREL:
2306 if (do_dynamic)
2307 puts (get_dynamic_type (entry->d_un.d_val));
2308 break;
2310 case DT_NULL :
2311 case DT_NEEDED :
2312 case DT_PLTGOT :
2313 case DT_HASH :
2314 case DT_STRTAB :
2315 case DT_SYMTAB :
2316 case DT_RELA :
2317 case DT_INIT :
2318 case DT_FINI :
2319 case DT_SONAME :
2320 case DT_RPATH :
2321 case DT_SYMBOLIC:
2322 case DT_REL :
2323 case DT_DEBUG :
2324 case DT_TEXTREL :
2325 case DT_JMPREL :
2326 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2328 if (do_dynamic)
2330 char * name;
2332 if (dynamic_strings == NULL)
2333 name = NULL;
2334 else
2335 name = dynamic_strings + entry->d_un.d_val;
2337 if (name)
2339 switch (entry->d_tag)
2341 case DT_NEEDED:
2342 printf (_("Shared library: [%s]"), name);
2344 if (strcmp (name, program_interpreter))
2345 printf ("\n");
2346 else
2347 printf (_(" program interpreter\n"));
2348 break;
2350 case DT_SONAME:
2351 printf (_("Library soname: [%s]\n"), name);
2352 break;
2354 case DT_RPATH:
2355 printf (_("Library rpath: [%s]\n"), name);
2356 break;
2358 default:
2359 printf ("%#lx\n", (long) entry->d_un.d_val);
2362 else
2363 printf ("%#lx\n", (long) entry->d_un.d_val);
2365 break;
2367 case DT_PLTRELSZ:
2368 case DT_RELASZ :
2369 case DT_STRSZ :
2370 case DT_RELSZ :
2371 case DT_RELAENT :
2372 case DT_SYMENT :
2373 case DT_RELENT :
2374 case DT_PLTPADSZ:
2375 case DT_MOVEENT :
2376 case DT_MOVESZ :
2377 case DT_INIT_ARRAYSZ:
2378 case DT_FINI_ARRAYSZ:
2379 if (do_dynamic)
2380 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2381 break;
2383 case DT_VERDEFNUM:
2384 case DT_VERNEEDNUM:
2385 case DT_RELACOUNT:
2386 case DT_RELCOUNT:
2387 if (do_dynamic)
2388 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2389 break;
2391 case DT_SYMINSZ:
2392 case DT_SYMINENT:
2393 case DT_SYMINFO:
2394 case DT_USED:
2395 case DT_INIT_ARRAY:
2396 case DT_FINI_ARRAY:
2397 if (do_dynamic)
2399 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2401 char * name;
2403 name = dynamic_strings + entry->d_un.d_val;
2405 if (* name)
2407 printf (_("Not needed object: [%s]\n"), name);
2408 break;
2412 printf ("%#lx\n", (long) entry->d_un.d_val);
2414 break;
2416 case DT_BIND_NOW:
2417 /* The value of this entry is ignored. */
2418 break;
2420 default:
2421 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2422 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2423 entry->d_un.d_val;
2425 if (do_dynamic)
2427 switch (elf_header.e_machine)
2429 case EM_MIPS:
2430 case EM_MIPS_RS4_BE:
2431 dynamic_segment_mips_val (entry);
2432 break;
2433 default:
2434 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2437 break;
2441 return 1;
2444 static char *
2445 get_ver_flags (flags)
2446 unsigned int flags;
2448 static char buff [32];
2450 buff[0] = 0;
2452 if (flags == 0)
2453 return _("none");
2455 if (flags & VER_FLG_BASE)
2456 strcat (buff, "BASE ");
2458 if (flags & VER_FLG_WEAK)
2460 if (flags & VER_FLG_BASE)
2461 strcat (buff, "| ");
2463 strcat (buff, "WEAK ");
2466 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2467 strcat (buff, "| <unknown>");
2469 return buff;
2472 /* Display the contents of the version sections. */
2473 static int
2474 process_version_sections (file)
2475 FILE * file;
2477 Elf32_Internal_Shdr * section;
2478 unsigned i;
2479 int found = 0;
2481 if (! do_version)
2482 return 1;
2484 for (i = 0, section = section_headers;
2485 i < elf_header.e_shnum;
2486 i++, section ++)
2488 switch (section->sh_type)
2490 case SHT_GNU_verdef:
2492 Elf_External_Verdef * edefs;
2493 unsigned int idx;
2494 unsigned int cnt;
2496 found = 1;
2498 printf
2499 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2500 SECTION_NAME (section), section->sh_info);
2502 printf (_(" Addr: 0x"));
2503 printf_vma (section->sh_addr);
2504 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2505 section->sh_offset, section->sh_link,
2506 SECTION_NAME (section_headers + section->sh_link));
2508 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2509 edefs, Elf_External_Verdef *,
2510 "version definition section");
2512 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2514 char * vstart;
2515 Elf_External_Verdef * edef;
2516 Elf_Internal_Verdef ent;
2517 Elf_External_Verdaux * eaux;
2518 Elf_Internal_Verdaux aux;
2519 int j;
2520 int isum;
2522 vstart = ((char *) edefs) + idx;
2524 edef = (Elf_External_Verdef *) vstart;
2526 ent.vd_version = BYTE_GET (edef->vd_version);
2527 ent.vd_flags = BYTE_GET (edef->vd_flags);
2528 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2529 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2530 ent.vd_hash = BYTE_GET (edef->vd_hash);
2531 ent.vd_aux = BYTE_GET (edef->vd_aux);
2532 ent.vd_next = BYTE_GET (edef->vd_next);
2534 printf (_(" %#06x: Rev: %d Flags: %s"),
2535 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2537 printf (_(" Index: %d Cnt: %d "),
2538 ent.vd_ndx, ent.vd_cnt);
2540 vstart += ent.vd_aux;
2542 eaux = (Elf_External_Verdaux *) vstart;
2544 aux.vda_name = BYTE_GET (eaux->vda_name);
2545 aux.vda_next = BYTE_GET (eaux->vda_next);
2547 if (dynamic_strings)
2548 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2549 else
2550 printf (_("Name index: %ld\n"), aux.vda_name);
2552 isum = idx + ent.vd_aux;
2554 for (j = 1; j < ent.vd_cnt; j ++)
2556 isum += aux.vda_next;
2557 vstart += aux.vda_next;
2559 eaux = (Elf_External_Verdaux *) vstart;
2561 aux.vda_name = BYTE_GET (eaux->vda_name);
2562 aux.vda_next = BYTE_GET (eaux->vda_next);
2564 if (dynamic_strings)
2565 printf (_(" %#06x: Parent %d: %s\n"),
2566 isum, j, dynamic_strings + aux.vda_name);
2567 else
2568 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2569 isum, j, aux.vda_name);
2572 idx += ent.vd_next;
2575 free (edefs);
2577 break;
2579 case SHT_GNU_verneed:
2581 Elf_External_Verneed * eneed;
2582 unsigned int idx;
2583 unsigned int cnt;
2585 found = 1;
2587 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2588 SECTION_NAME (section), section->sh_info);
2590 printf (_(" Addr: 0x"));
2591 printf_vma (section->sh_addr);
2592 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
2593 section->sh_offset, section->sh_link,
2594 SECTION_NAME (section_headers + section->sh_link));
2596 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2597 eneed, Elf_External_Verneed *,
2598 "version need section");
2600 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
2602 Elf_External_Verneed * entry;
2603 Elf_Internal_Verneed ent;
2604 int j;
2605 int isum;
2606 char * vstart;
2608 vstart = ((char *) eneed) + idx;
2610 entry = (Elf_External_Verneed *) vstart;
2612 ent.vn_version = BYTE_GET (entry->vn_version);
2613 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
2614 ent.vn_file = BYTE_GET (entry->vn_file);
2615 ent.vn_aux = BYTE_GET (entry->vn_aux);
2616 ent.vn_next = BYTE_GET (entry->vn_next);
2618 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
2620 if (dynamic_strings)
2621 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
2622 else
2623 printf (_(" File: %lx"), ent.vn_file);
2625 printf (_(" Cnt: %d\n"), ent.vn_cnt);
2627 vstart += ent.vn_aux;
2629 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
2631 Elf_External_Vernaux * eaux;
2632 Elf_Internal_Vernaux aux;
2634 eaux = (Elf_External_Vernaux *) vstart;
2636 aux.vna_hash = BYTE_GET (eaux->vna_hash);
2637 aux.vna_flags = BYTE_GET (eaux->vna_flags);
2638 aux.vna_other = BYTE_GET (eaux->vna_other);
2639 aux.vna_name = BYTE_GET (eaux->vna_name);
2640 aux.vna_next = BYTE_GET (eaux->vna_next);
2642 if (dynamic_strings)
2643 printf (_(" %#06x: Name: %s"),
2644 isum, dynamic_strings + aux.vna_name);
2645 else
2646 printf (_(" %#06x: Name index: %lx"),
2647 isum, aux.vna_name);
2649 printf (_(" Flags: %s Version: %d\n"),
2650 get_ver_flags (aux.vna_flags), aux.vna_other);
2652 isum += aux.vna_next;
2653 vstart += aux.vna_next;
2656 idx += ent.vn_next;
2659 free (eneed);
2661 break;
2663 case SHT_GNU_versym:
2665 Elf32_Internal_Shdr * link_section;
2666 int total;
2667 int cnt;
2668 unsigned char * edata;
2669 unsigned short * data;
2670 char * strtab;
2671 Elf_Internal_Sym * symbols;
2672 Elf32_Internal_Shdr * string_sec;
2674 link_section = section_headers + section->sh_link;
2675 total = section->sh_size / section->sh_entsize;
2677 found = 1;
2679 symbols = get_elf_symbols
2680 (file, link_section->sh_offset,
2681 link_section->sh_size / link_section->sh_entsize);
2683 string_sec = section_headers + link_section->sh_link;
2685 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2686 strtab, char *, "version string table");
2688 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2689 SECTION_NAME (section), total);
2691 printf (_(" Addr: "));
2692 printf_vma (section->sh_addr);
2693 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2694 section->sh_offset, section->sh_link,
2695 SECTION_NAME (link_section));
2697 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2698 - loadaddr,
2699 total * sizeof (short), edata,
2700 unsigned char *, "version symbol data");
2702 data = (unsigned short *) malloc (total * sizeof (short));
2704 for (cnt = total; cnt --;)
2705 data [cnt] = byte_get (edata + cnt * sizeof (short),
2706 sizeof (short));
2708 free (edata);
2710 for (cnt = 0; cnt < total; cnt += 4)
2712 int j, nn;
2714 printf (" %03x:", cnt);
2716 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2717 switch (data [cnt + j])
2719 case 0:
2720 fputs (_(" 0 (*local*) "), stdout);
2721 break;
2723 case 1:
2724 fputs (_(" 1 (*global*) "), stdout);
2725 break;
2727 default:
2728 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
2729 data [cnt + j] & 0x8000 ? 'h' : ' ');
2731 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
2732 && section_headers[symbols [cnt + j].st_shndx].sh_type
2733 == SHT_NOBITS)
2735 /* We must test both. */
2736 Elf_Internal_Verneed ivn;
2737 unsigned long offset;
2739 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2740 - loadaddr;
2744 Elf_External_Verneed evn;
2745 Elf_External_Vernaux evna;
2746 Elf_Internal_Vernaux ivna;
2747 unsigned long vna_off;
2749 GET_DATA (offset, evn, "version need");
2751 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2752 ivn.vn_next = BYTE_GET (evn.vn_next);
2754 vna_off = offset + ivn.vn_aux;
2758 GET_DATA (vna_off, evna,
2759 "version need aux (1)");
2761 ivna.vna_next = BYTE_GET (evna.vna_next);
2762 ivna.vna_other = BYTE_GET (evna.vna_other);
2764 vna_off += ivna.vna_next;
2766 while (ivna.vna_other != data [cnt + j]
2767 && ivna.vna_next != 0);
2769 if (ivna.vna_other == data [cnt + j])
2771 ivna.vna_name = BYTE_GET (evna.vna_name);
2773 nn += printf ("(%s%-*s",
2774 strtab + ivna.vna_name,
2775 12 - strlen (strtab
2776 + ivna.vna_name),
2777 ")");
2778 break;
2780 else if (ivn.vn_next == 0)
2782 if (data [cnt + j] != 0x8001)
2784 Elf_Internal_Verdef ivd;
2785 Elf_External_Verdef evd;
2787 offset = version_info
2788 [DT_VERSIONTAGIDX (DT_VERDEF)]
2789 - loadaddr;
2793 GET_DATA (offset, evd,
2794 "version definition");
2796 ivd.vd_next = BYTE_GET (evd.vd_next);
2797 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2799 offset += ivd.vd_next;
2801 while (ivd.vd_ndx
2802 != (data [cnt + j] & 0x7fff)
2803 && ivd.vd_next != 0);
2805 if (ivd.vd_ndx
2806 == (data [cnt + j] & 0x7fff))
2808 Elf_External_Verdaux evda;
2809 Elf_Internal_Verdaux ivda;
2811 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2813 GET_DATA (offset + ivd.vd_aux, evda,
2814 "version definition aux");
2816 ivda.vda_name =
2817 BYTE_GET (evda.vda_name);
2819 nn +=
2820 printf ("(%s%-*s",
2821 strtab + ivda.vda_name,
2823 - strlen (strtab
2824 + ivda.vda_name),
2825 ")");
2829 break;
2831 else
2832 offset += ivn.vn_next;
2834 while (ivn.vn_next);
2836 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
2838 Elf_Internal_Verneed ivn;
2839 unsigned long offset;
2841 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2842 - loadaddr;
2846 Elf_Internal_Vernaux ivna;
2847 Elf_External_Verneed evn;
2848 Elf_External_Vernaux evna;
2849 unsigned long a_off;
2851 GET_DATA (offset, evn, "version need");
2853 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2854 ivn.vn_next = BYTE_GET (evn.vn_next);
2856 a_off = offset + ivn.vn_aux;
2860 GET_DATA (a_off, evna,
2861 "version need aux (2)");
2863 ivna.vna_next = BYTE_GET (evna.vna_next);
2864 ivna.vna_other = BYTE_GET (evna.vna_other);
2866 a_off += ivna.vna_next;
2868 while (ivna.vna_other != data [cnt + j]
2869 && ivna.vna_next != 0);
2871 if (ivna.vna_other == data [cnt + j])
2873 ivna.vna_name = BYTE_GET (evna.vna_name);
2875 nn += printf ("(%s%-*s",
2876 strtab + ivna.vna_name,
2877 12 - strlen (strtab
2878 + ivna.vna_name),
2879 ")");
2880 break;
2883 offset += ivn.vn_next;
2885 while (ivn.vn_next);
2887 else if (data [cnt + j] != 0x8001)
2889 Elf_Internal_Verdef ivd;
2890 Elf_External_Verdef evd;
2891 unsigned long offset;
2893 offset = version_info
2894 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
2898 GET_DATA (offset, evd, "version def");
2900 ivd.vd_next = BYTE_GET (evd.vd_next);
2901 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2903 offset += ivd.vd_next;
2905 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
2906 && ivd.vd_next != 0);
2908 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
2910 Elf_External_Verdaux evda;
2911 Elf_Internal_Verdaux ivda;
2913 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2915 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
2916 evda, "version def aux");
2918 ivda.vda_name = BYTE_GET (evda.vda_name);
2920 nn += printf ("(%s%-*s",
2921 strtab + ivda.vda_name,
2922 12 - strlen (strtab
2923 + ivda.vda_name),
2924 ")");
2928 if (nn < 18)
2929 printf ("%*c", 18 - nn, ' ');
2932 putchar ('\n');
2935 free (data);
2936 free (strtab);
2937 free (symbols);
2939 break;
2941 default:
2942 break;
2946 if (! found)
2947 printf (_("\nNo version information found in this file.\n"));
2949 return 1;
2952 static char *
2953 get_symbol_binding (binding)
2954 unsigned int binding;
2956 static char buff [32];
2958 switch (binding)
2960 case STB_LOCAL: return _("LOCAL");
2961 case STB_GLOBAL: return _("GLOBAL");
2962 case STB_WEAK: return _("WEAK");
2963 default:
2964 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
2965 sprintf (buff, _("<processor specific>: %d"), binding);
2966 else if (binding >= STB_LOOS && binding <= STB_HIOS)
2967 sprintf (buff, _("<OS specific>: %d"), binding);
2968 else
2969 sprintf (buff, _("<unknown>: %d"), binding);
2970 return buff;
2974 static char *
2975 get_symbol_type (type)
2976 unsigned int type;
2978 static char buff [32];
2980 switch (type)
2982 case STT_NOTYPE: return _("NOTYPE");
2983 case STT_OBJECT: return _("OBJECT");
2984 case STT_FUNC: return _("FUNC");
2985 case STT_SECTION: return _("SECTION");
2986 case STT_FILE: return _("FILE");
2987 default:
2988 if (type >= STT_LOPROC && type <= STT_HIPROC)
2989 sprintf (buff, _("<processor specific>: %d"), type);
2990 else if (type >= STT_LOOS && type <= STT_HIOS)
2991 sprintf (buff, _("<OS specific>: %d"), type);
2992 else
2993 sprintf (buff, _("<unknown>: %d"), type);
2994 return buff;
2998 static char *
2999 get_symbol_index_type (type)
3000 unsigned int type;
3002 switch (type)
3004 case SHN_UNDEF: return "UND";
3005 case SHN_ABS: return "ABS";
3006 case SHN_COMMON: return "COM";
3007 default:
3008 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3009 return "PRC";
3010 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3011 return "RSV";
3012 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3013 return "OS ";
3014 else
3016 static char buff [32];
3018 sprintf (buff, "%3d", type);
3019 return buff;
3025 static int *
3026 get_dynamic_data (file, number)
3027 FILE * file;
3028 unsigned int number;
3030 char * e_data;
3031 int * i_data;
3033 e_data = (char *) malloc (number * 4);
3035 if (e_data == NULL)
3037 error (_("Out of memory\n"));
3038 return NULL;
3041 if (fread (e_data, 4, number, file) != number)
3043 error (_("Unable to read in dynamic data\n"));
3044 return NULL;
3047 i_data = (int *) malloc (number * sizeof (* i_data));
3049 if (i_data == NULL)
3051 error (_("Out of memory\n"));
3052 free (e_data);
3053 return NULL;
3056 while (number--)
3057 i_data [number] = byte_get (e_data + number * 4, 4);
3059 free (e_data);
3061 return i_data;
3064 /* Dump the symbol table */
3065 static int
3066 process_symbol_table (file)
3067 FILE * file;
3069 Elf32_Internal_Shdr * section;
3070 char nb [4];
3071 char nc [4];
3072 int nbuckets;
3073 int nchains;
3074 int * buckets = NULL;
3075 int * chains = NULL;
3077 if (! do_syms && !do_histogram)
3078 return 1;
3080 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3081 || do_histogram))
3083 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3085 error (_("Unable to seek to start of dynamic information"));
3086 return 0;
3089 if (fread (nb, sizeof (nb), 1, file) != 1)
3091 error (_("Failed to read in number of buckets\n"));
3092 return 0;
3095 if (fread (nc, sizeof (nc), 1, file) != 1)
3097 error (_("Failed to read in number of chains\n"));
3098 return 0;
3101 nbuckets = byte_get (nb, 4);
3102 nchains = byte_get (nc, 4);
3104 buckets = get_dynamic_data (file, nbuckets);
3105 chains = get_dynamic_data (file, nchains);
3107 if (buckets == NULL || chains == NULL)
3108 return 0;
3111 if (do_syms
3112 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3114 int hn;
3115 int si;
3117 printf (_("\nSymbol table for image:\n"));
3118 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3120 for (hn = 0; hn < nbuckets; hn++)
3122 if (! buckets [hn])
3123 continue;
3125 for (si = buckets [hn]; si; si = chains [si])
3127 Elf_Internal_Sym * psym;
3129 psym = dynamic_symbols + si;
3131 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3132 si, hn,
3133 (unsigned long) psym->st_value,
3134 (unsigned long) psym->st_size,
3135 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3136 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3137 psym->st_other);
3139 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3141 printf (" %s\n", dynamic_strings + psym->st_name);
3145 else if (do_syms && !do_using_dynamic)
3147 unsigned int i;
3149 for (i = 0, section = section_headers;
3150 i < elf_header.e_shnum;
3151 i++, section++)
3153 unsigned int si;
3154 char * strtab;
3155 Elf_Internal_Sym * symtab;
3156 Elf_Internal_Sym * psym;
3159 if ( section->sh_type != SHT_SYMTAB
3160 && section->sh_type != SHT_DYNSYM)
3161 continue;
3163 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3164 SECTION_NAME (section),
3165 (unsigned long) (section->sh_size / section->sh_entsize));
3166 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3167 stdout);
3169 symtab = get_elf_symbols (file, section->sh_offset,
3170 section->sh_size / section->sh_entsize);
3171 if (symtab == NULL)
3172 continue;
3174 if (section->sh_link == elf_header.e_shstrndx)
3175 strtab = string_table;
3176 else
3178 Elf32_Internal_Shdr * string_sec;
3180 string_sec = section_headers + section->sh_link;
3182 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3183 strtab, char *, "string table");
3186 for (si = 0, psym = symtab;
3187 si < section->sh_size / section->sh_entsize;
3188 si ++, psym ++)
3190 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3192 (unsigned long) psym->st_value,
3193 (unsigned long) psym->st_size,
3194 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3195 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3196 psym->st_other);
3198 if (psym->st_shndx == 0)
3199 fputs (" UND", stdout);
3200 else if ((psym->st_shndx & 0xffff) == 0xfff1)
3201 fputs (" ABS", stdout);
3202 else if ((psym->st_shndx & 0xffff) == 0xfff2)
3203 fputs (" COM", stdout);
3204 else
3205 printf ("%4x", psym->st_shndx);
3207 printf (" %s", strtab + psym->st_name);
3209 if (section->sh_type == SHT_DYNSYM &&
3210 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3212 unsigned char data[2];
3213 unsigned short vers_data;
3214 unsigned long offset;
3215 int is_nobits;
3216 int check_def;
3218 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3219 - loadaddr;
3221 GET_DATA (offset + si * sizeof (vers_data), data,
3222 "version data");
3224 vers_data = byte_get (data, 2);
3226 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3227 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3228 : 0;
3230 check_def = (psym->st_shndx != SHN_UNDEF);
3232 if ((vers_data & 0x8000) || vers_data > 1)
3234 if (is_nobits || ! check_def)
3236 Elf_External_Verneed evn;
3237 Elf_Internal_Verneed ivn;
3238 Elf_Internal_Vernaux ivna;
3240 /* We must test both. */
3241 offset = version_info
3242 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3244 GET_DATA (offset, evn, "version need");
3246 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3247 ivn.vn_next = BYTE_GET (evn.vn_next);
3251 unsigned long vna_off;
3253 vna_off = offset + ivn.vn_aux;
3257 Elf_External_Vernaux evna;
3259 GET_DATA (vna_off, evna,
3260 "version need aux (3)");
3262 ivna.vna_other = BYTE_GET (evna.vna_other);
3263 ivna.vna_next = BYTE_GET (evna.vna_next);
3264 ivna.vna_name = BYTE_GET (evna.vna_name);
3266 vna_off += ivna.vna_next;
3268 while (ivna.vna_other != vers_data
3269 && ivna.vna_next != 0);
3271 if (ivna.vna_other == vers_data)
3272 break;
3274 offset += ivn.vn_next;
3276 while (ivn.vn_next != 0);
3278 if (ivna.vna_other == vers_data)
3280 printf ("@%s (%d)",
3281 strtab + ivna.vna_name, ivna.vna_other);
3282 check_def = 0;
3284 else if (! is_nobits)
3285 error (_("bad dynamic symbol"));
3286 else
3287 check_def = 1;
3290 if (check_def)
3292 if (vers_data != 0x8001)
3294 Elf_Internal_Verdef ivd;
3295 Elf_Internal_Verdaux ivda;
3296 Elf_External_Verdaux evda;
3297 unsigned long offset;
3299 offset =
3300 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3301 - loadaddr;
3305 Elf_External_Verdef evd;
3307 GET_DATA (offset, evd, "version def");
3309 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3310 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3311 ivd.vd_next = BYTE_GET (evd.vd_next);
3313 offset += ivd.vd_next;
3315 while (ivd.vd_ndx != (vers_data & 0x7fff)
3316 && ivd.vd_next != 0);
3318 offset -= ivd.vd_next;
3319 offset += ivd.vd_aux;
3321 GET_DATA (offset, evda, "version def aux");
3323 ivda.vda_name = BYTE_GET (evda.vda_name);
3325 if (psym->st_name != ivda.vda_name)
3326 printf ((vers_data & 0x8000)
3327 ? "@%s" : "@@%s",
3328 strtab + ivda.vda_name);
3334 putchar ('\n');
3337 free (symtab);
3338 if (strtab != string_table)
3339 free (strtab);
3342 else if (do_syms)
3343 printf
3344 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3346 if (do_histogram && buckets != NULL)
3348 int *lengths;
3349 int *counts;
3350 int hn;
3351 int si;
3352 int maxlength = 0;
3353 int nzero_counts = 0;
3354 int nsyms = 0;
3356 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3357 nbuckets);
3358 printf (_(" Length Number %% of total Coverage\n"));
3360 lengths = (int *) calloc (nbuckets, sizeof (int));
3361 if (lengths == NULL)
3363 error (_("Out of memory"));
3364 return 0;
3366 for (hn = 0; hn < nbuckets; ++hn)
3368 if (! buckets [hn])
3369 continue;
3371 for (si = buckets[hn]; si; si = chains[si])
3373 ++nsyms;
3374 if (maxlength < ++lengths[hn])
3375 ++maxlength;
3379 counts = (int *) calloc (maxlength + 1, sizeof (int));
3380 if (counts == NULL)
3382 error (_("Out of memory"));
3383 return 0;
3386 for (hn = 0; hn < nbuckets; ++hn)
3387 ++ counts [lengths [hn]];
3389 printf (" 0 %-10d (%5.1f%%)\n",
3390 counts[0], (counts[0] * 100.0) / nbuckets);
3391 for (si = 1; si <= maxlength; ++si)
3393 nzero_counts += counts[si] * si;
3394 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3395 si, counts[si], (counts[si] * 100.0) / nbuckets,
3396 (nzero_counts * 100.0) / nsyms);
3399 free (counts);
3400 free (lengths);
3403 if (buckets != NULL)
3405 free (buckets);
3406 free (chains);
3409 return 1;
3412 static int
3413 process_syminfo (file)
3414 FILE * file;
3416 int i;
3418 if (dynamic_syminfo == NULL
3419 || !do_dynamic)
3420 /* No syminfo, this is ok. */
3421 return 1;
3423 /* There better should be a dynamic symbol section. */
3424 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3425 return 0;
3427 if (dynamic_addr)
3428 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3429 dynamic_syminfo_offset, dynamic_syminfo_nent);
3431 printf (_(" Num: Name BoundTo Flags\n"));
3432 for (i = 0; i < dynamic_syminfo_nent; ++i)
3434 unsigned short int flags = dynamic_syminfo[i].si_flags;
3436 printf ("%4d: %-30s ", i,
3437 dynamic_strings + dynamic_symbols[i].st_name);
3439 switch (dynamic_syminfo[i].si_boundto)
3441 case SYMINFO_BT_SELF:
3442 fputs ("SELF ", stdout);
3443 break;
3444 case SYMINFO_BT_PARENT:
3445 fputs ("PARENT ", stdout);
3446 break;
3447 default:
3448 if (dynamic_syminfo[i].si_boundto > 0
3449 && dynamic_syminfo[i].si_boundto < dynamic_size)
3450 printf ("%-10s ",
3451 dynamic_strings
3452 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3453 else
3454 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3455 break;
3458 if (flags & SYMINFO_FLG_DIRECT)
3459 printf (" DIRECT");
3460 if (flags & SYMINFO_FLG_PASSTHRU)
3461 printf (" PASSTHRU");
3462 if (flags & SYMINFO_FLG_COPY)
3463 printf (" COPY");
3464 if (flags & SYMINFO_FLG_LAZYLOAD)
3465 printf (" LAZYLOAD");
3467 puts ("");
3470 return 1;
3473 #ifdef SUPPORT_DISASSEMBLY
3474 static void
3475 disassemble_section (section, file)
3476 Elf32_Internal_Shdr * section;
3477 FILE * file;
3479 printf (_("\nAssembly dump of section %s\n"),
3480 SECTION_NAME (section));
3482 /* XXX -- to be done --- XXX */
3484 return 1;
3486 #endif
3488 static int
3489 dump_section (section, file)
3490 Elf32_Internal_Shdr * section;
3491 FILE * file;
3493 int bytes;
3494 int addr;
3495 unsigned char * data;
3496 unsigned char * start;
3498 bytes = section->sh_size;
3500 if (bytes == 0)
3502 printf (_("\nSection '%s' has no data to dump.\n"),
3503 SECTION_NAME (section));
3504 return 0;
3506 else
3507 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3509 addr = section->sh_addr;
3511 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3512 "section data");
3514 data = start;
3516 while (bytes)
3518 int j;
3519 int k;
3520 int lbytes;
3522 lbytes = (bytes > 16 ? 16 : bytes);
3524 printf (" 0x%8.8x ", addr);
3526 switch (elf_header.e_ident [EI_DATA])
3528 case ELFDATA2LSB:
3529 for (j = 15; j >= 0; j --)
3531 if (j < lbytes)
3532 printf ("%2.2x", data [j]);
3533 else
3534 printf (" ");
3536 if (!(j & 0x3))
3537 printf (" ");
3539 break;
3541 case ELFDATA2MSB:
3542 for (j = 0; j < 16; j++)
3544 if (j < lbytes)
3545 printf ("%2.2x", data [j]);
3546 else
3547 printf (" ");
3549 if ((j & 3) == 3)
3550 printf (" ");
3552 break;
3555 for (j = 0; j < lbytes; j++)
3557 k = data [j];
3558 if (k >= ' ' && k < 0x80)
3559 printf ("%c", k);
3560 else
3561 printf (".");
3564 putchar ('\n');
3566 data += lbytes;
3567 addr += lbytes;
3568 bytes -= lbytes;
3571 free (start);
3573 return 1;
3577 static unsigned long int
3578 read_leb128 (data, length_return, sign)
3579 unsigned char * data;
3580 int * length_return;
3581 int sign;
3583 unsigned long int result = 0;
3584 unsigned int num_read = 0;
3585 int shift = 0;
3586 unsigned char byte;
3590 byte = * data ++;
3591 num_read ++;
3593 result |= (byte & 0x7f) << shift;
3595 shift += 7;
3598 while (byte & 0x80);
3600 if (length_return != NULL)
3601 * length_return = num_read;
3603 if (sign && (shift < 32) && (byte & 0x40))
3604 result |= -1 << shift;
3606 return result;
3609 typedef struct State_Machine_Registers
3611 unsigned long address;
3612 unsigned int file;
3613 unsigned int line;
3614 unsigned int column;
3615 int is_stmt;
3616 int basic_block;
3617 int end_sequence;
3618 /* This variable hold the number of the last entry seen
3619 in the File Table. */
3620 unsigned int last_file_entry;
3621 } SMR;
3623 static SMR state_machine_regs;
3625 static void
3626 reset_state_machine (is_stmt)
3627 int is_stmt;
3629 state_machine_regs.address = 0;
3630 state_machine_regs.file = 1;
3631 state_machine_regs.line = 1;
3632 state_machine_regs.column = 0;
3633 state_machine_regs.is_stmt = is_stmt;
3634 state_machine_regs.basic_block = 0;
3635 state_machine_regs.end_sequence = 0;
3636 state_machine_regs.last_file_entry = 0;
3639 /* Handled an extend line op. Returns true if this is the end
3640 of sequence. */
3641 static int
3642 process_extended_line_op (data, is_stmt)
3643 unsigned char * data;
3644 int is_stmt;
3646 unsigned char op_code;
3647 int bytes_read;
3648 unsigned int len;
3649 unsigned char * name;
3650 unsigned long adr;
3652 len = read_leb128 (data, & bytes_read, 0);
3653 data += bytes_read;
3655 if (len == 0)
3657 warn (_("badly formed extended line op encountered!"));
3658 return bytes_read;
3661 len += bytes_read;
3662 op_code = * data ++;
3664 printf (_(" Extended opcode %d: "), op_code);
3666 switch (op_code)
3668 case DW_LNE_end_sequence:
3669 printf (_("End of Sequence\n\n"));
3670 reset_state_machine (is_stmt);
3671 break;
3673 case DW_LNE_set_address:
3674 /* XXX - assumption here that address size is 4! */
3675 adr = byte_get (data, 4);
3676 printf (_("set Address to 0x%lx\n"), adr);
3677 state_machine_regs.address = adr;
3678 break;
3680 case DW_LNE_define_file:
3681 printf (_(" define new File Table entry\n"));
3682 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3684 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3685 name = data;
3686 data += strlen (data) + 1;
3687 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3688 data += bytes_read;
3689 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3690 data += bytes_read;
3691 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3692 printf (_("%s\n\n"), name);
3693 break;
3695 default:
3696 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
3697 break;
3700 return len;
3704 static int
3705 display_debug_lines (section, start, file)
3706 Elf32_Internal_Shdr * section;
3707 unsigned char * start;
3708 FILE * file;
3710 DWARF2_External_LineInfo * external;
3711 DWARF2_Internal_LineInfo info;
3712 unsigned char * standard_opcodes;
3713 unsigned char * data = start;
3714 unsigned char * end = start + section->sh_size;
3715 unsigned char * end_of_sequence;
3716 int i;
3718 printf (_("\nDump of debug contents of section %s:\n\n"),
3719 SECTION_NAME (section));
3721 while (data < end)
3723 external = (DWARF2_External_LineInfo *) data;
3725 /* Check the length of the block. */
3726 info.li_length = BYTE_GET (external->li_length);
3727 if (info.li_length > section->sh_size)
3729 warn
3730 (_("The line info appears to be corrupt - the section is too small\n"));
3731 return 0;
3734 /* Check its version number. */
3735 info.li_version = BYTE_GET (external->li_version);
3736 if (info.li_version != 2)
3738 warn (_("Only DWARF version 2 line info is currently supported.\n"));
3739 return 0;
3742 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
3743 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
3744 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
3745 info.li_line_base = BYTE_GET (external->li_line_base);
3746 info.li_line_range = BYTE_GET (external->li_line_range);
3747 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
3749 /* Sign extend the line base field. */
3750 info.li_line_base <<= 24;
3751 info.li_line_base >>= 24;
3753 printf (_(" Length: %ld\n"), info.li_length);
3754 printf (_(" DWARF Version: %d\n"), info.li_version);
3755 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
3756 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
3757 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
3758 printf (_(" Line Base: %d\n"), info.li_line_base);
3759 printf (_(" Line Range: %d\n"), info.li_line_range);
3760 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
3762 end_of_sequence = data + info.li_length + sizeof (info.li_length);
3764 reset_state_machine (info.li_default_is_stmt);
3766 /* Display the contents of the Opcodes table. */
3767 standard_opcodes = data + sizeof (* external);
3769 printf (_("\n Opcodes:\n"));
3771 for (i = 1; i < info.li_opcode_base; i++)
3772 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
3774 /* Display the contents of the Directory table. */
3775 data = standard_opcodes + info.li_opcode_base - 1;
3777 if (* data == 0)
3778 printf (_("\n The Directory Table is empty.\n"));
3779 else
3781 printf (_("\n The Directory Table:\n"));
3783 while (* data != 0)
3785 printf (_(" %s\n"), data);
3787 data += strlen (data) + 1;
3791 /* Skip the NUL at the end of the table. */
3792 data ++;
3794 /* Display the contents of the File Name table. */
3795 if (* data == 0)
3796 printf (_("\n The File Name Table is empty.\n"));
3797 else
3799 printf (_("\n The File Name Table:\n"));
3800 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3802 while (* data != 0)
3804 char * name;
3805 int bytes_read;
3807 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3808 name = data;
3810 data += strlen (data) + 1;
3812 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3813 data += bytes_read;
3814 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3815 data += bytes_read;
3816 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3817 data += bytes_read;
3818 printf (_("%s\n"), name);
3822 /* Skip the NUL at the end of the table. */
3823 data ++;
3825 /* Now display the statements. */
3826 printf (_("\n Line Number Statements:\n"));
3829 while (data < end_of_sequence)
3831 unsigned char op_code;
3832 int adv;
3833 int bytes_read;
3835 op_code = * data ++;
3837 switch (op_code)
3839 case DW_LNS_extended_op:
3840 data += process_extended_line_op (data, info.li_default_is_stmt);
3841 break;
3843 case DW_LNS_copy:
3844 printf (_(" Copy\n"));
3845 break;
3847 case DW_LNS_advance_pc:
3848 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
3849 data += bytes_read;
3850 state_machine_regs.address += adv;
3851 printf (_(" Advance PC by %d to %lx\n"), adv,
3852 state_machine_regs.address);
3853 break;
3855 case DW_LNS_advance_line:
3856 adv = read_leb128 (data, & bytes_read, 1);
3857 data += bytes_read;
3858 state_machine_regs.line += adv;
3859 printf (_(" Advance Line by %d to %d\n"), adv,
3860 state_machine_regs.line);
3861 break;
3863 case DW_LNS_set_file:
3864 adv = read_leb128 (data, & bytes_read, 0);
3865 data += bytes_read;
3866 printf (_(" Set File Name to entry %d in the File Name Table\n"),
3867 adv);
3868 state_machine_regs.file = adv;
3869 break;
3871 case DW_LNS_set_column:
3872 adv = read_leb128 (data, & bytes_read, 0);
3873 data += bytes_read;
3874 printf (_(" Set column to %d\n"), adv);
3875 state_machine_regs.column = adv;
3876 break;
3878 case DW_LNS_negate_stmt:
3879 adv = state_machine_regs.is_stmt;
3880 adv = ! adv;
3881 printf (_(" Set is_stmt to %d\n"), adv);
3882 state_machine_regs.is_stmt = adv;
3883 break;
3885 case DW_LNS_set_basic_block:
3886 printf (_(" Set basic block\n"));
3887 state_machine_regs.basic_block = 1;
3888 break;
3890 case DW_LNS_const_add_pc:
3891 adv = (255 - info.li_opcode_base) / info.li_line_range;
3892 state_machine_regs.address += adv;
3893 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
3894 state_machine_regs.address);
3895 break;
3897 case DW_LNS_fixed_advance_pc:
3898 adv = byte_get (data, 2);
3899 data += 2;
3900 state_machine_regs.address += adv;
3901 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
3902 adv, state_machine_regs.address);
3903 break;
3905 default:
3906 op_code -= info.li_opcode_base;
3907 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
3908 state_machine_regs.address += adv;
3909 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
3910 op_code, adv, state_machine_regs.address);
3911 adv += (op_code % info.li_line_range) + info.li_line_base;
3912 state_machine_regs.line += adv;
3913 printf (_(" and Line by %d to %d\n"),
3914 adv, state_machine_regs.line);
3915 break;
3918 printf ("\n");
3921 return 1;
3924 static int
3925 display_debug_pubnames (section, start, file)
3926 Elf32_Internal_Shdr * section;
3927 unsigned char * start;
3928 FILE * file;
3930 DWARF2_External_PubNames * external;
3931 DWARF2_Internal_PubNames pubnames;
3932 unsigned char * end;
3934 end = start + section->sh_size;
3936 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
3938 while (start < end)
3940 unsigned char * data;
3941 unsigned long offset;
3943 external = (DWARF2_External_PubNames *) start;
3945 pubnames.pn_length = BYTE_GET (external->pn_length);
3946 pubnames.pn_version = BYTE_GET (external->pn_version);
3947 pubnames.pn_offset = BYTE_GET (external->pn_offset);
3948 pubnames.pn_size = BYTE_GET (external->pn_size);
3950 data = start + sizeof (* external);
3951 start += pubnames.pn_length + sizeof (external->pn_length);
3953 if (pubnames.pn_version != 2)
3955 warn (_("Only DWARF 2 pubnames are currently supported"));
3956 continue;
3959 printf (_(" Length: %ld\n"),
3960 pubnames.pn_length);
3961 printf (_(" Version: %d\n"),
3962 pubnames.pn_version);
3963 printf (_(" Offset into .debug_info section: %ld\n"),
3964 pubnames.pn_offset);
3965 printf (_(" Size of area in .debug_info section: %ld\n"),
3966 pubnames.pn_size);
3968 printf (_("\n Offset\tName\n"));
3972 offset = byte_get (data, 4);
3974 if (offset != 0)
3976 data += 4;
3977 printf (" %ld\t\t%s\n", offset, data);
3978 data += strlen (data) + 1;
3981 while (offset != 0);
3984 printf ("\n");
3985 return 1;
3988 static char *
3989 get_TAG_name (tag)
3990 unsigned long tag;
3992 switch (tag)
3994 case DW_TAG_padding: return "DW_TAG_padding";
3995 case DW_TAG_array_type: return "DW_TAG_array_type";
3996 case DW_TAG_class_type: return "DW_TAG_class_type";
3997 case DW_TAG_entry_point: return "DW_TAG_entry_point";
3998 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
3999 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4000 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4001 case DW_TAG_label: return "DW_TAG_label";
4002 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4003 case DW_TAG_member: return "DW_TAG_member";
4004 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4005 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4006 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4007 case DW_TAG_string_type: return "DW_TAG_string_type";
4008 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4009 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4010 case DW_TAG_typedef: return "DW_TAG_typedef";
4011 case DW_TAG_union_type: return "DW_TAG_union_type";
4012 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4013 case DW_TAG_variant: return "DW_TAG_variant";
4014 case DW_TAG_common_block: return "DW_TAG_common_block";
4015 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4016 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4017 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4018 case DW_TAG_module: return "DW_TAG_module";
4019 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4020 case DW_TAG_set_type: return "DW_TAG_set_type";
4021 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4022 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4023 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4024 case DW_TAG_base_type: return "DW_TAG_base_type";
4025 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4026 case DW_TAG_const_type: return "DW_TAG_const_type";
4027 case DW_TAG_constant: return "DW_TAG_constant";
4028 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4029 case DW_TAG_file_type: return "DW_TAG_file_type";
4030 case DW_TAG_friend: return "DW_TAG_friend";
4031 case DW_TAG_namelist: return "DW_TAG_namelist";
4032 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4033 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4034 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4035 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4036 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4037 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4038 case DW_TAG_try_block: return "DW_TAG_try_block";
4039 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4040 case DW_TAG_variable: return "DW_TAG_variable";
4041 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4042 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4043 case DW_TAG_format_label: return "DW_TAG_format_label";
4044 case DW_TAG_function_template: return "DW_TAG_function_template";
4045 case DW_TAG_class_template: return "DW_TAG_class_template";
4046 default:
4048 static char buffer [100];
4050 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4051 return buffer;
4056 static char *
4057 get_AT_name (attribute)
4058 unsigned long attribute;
4060 switch (attribute)
4062 case DW_AT_sibling: return "DW_AT_sibling";
4063 case DW_AT_location: return "DW_AT_location";
4064 case DW_AT_name: return "DW_AT_name";
4065 case DW_AT_ordering: return "DW_AT_ordering";
4066 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4067 case DW_AT_byte_size: return "DW_AT_byte_size";
4068 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4069 case DW_AT_bit_size: return "DW_AT_bit_size";
4070 case DW_AT_element_list: return "DW_AT_element_list";
4071 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4072 case DW_AT_low_pc: return "DW_AT_low_pc";
4073 case DW_AT_high_pc: return "DW_AT_high_pc";
4074 case DW_AT_language: return "DW_AT_language";
4075 case DW_AT_member: return "DW_AT_member";
4076 case DW_AT_discr: return "DW_AT_discr";
4077 case DW_AT_discr_value: return "DW_AT_discr_value";
4078 case DW_AT_visibility: return "DW_AT_visibility";
4079 case DW_AT_import: return "DW_AT_import";
4080 case DW_AT_string_length: return "DW_AT_string_length";
4081 case DW_AT_common_reference: return "DW_AT_common_reference";
4082 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4083 case DW_AT_const_value: return "DW_AT_const_value";
4084 case DW_AT_containing_type: return "DW_AT_containing_type";
4085 case DW_AT_default_value: return "DW_AT_default_value";
4086 case DW_AT_inline: return "DW_AT_inline";
4087 case DW_AT_is_optional: return "DW_AT_is_optional";
4088 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4089 case DW_AT_producer: return "DW_AT_producer";
4090 case DW_AT_prototyped: return "DW_AT_prototyped";
4091 case DW_AT_return_addr: return "DW_AT_return_addr";
4092 case DW_AT_start_scope: return "DW_AT_start_scope";
4093 case DW_AT_stride_size: return "DW_AT_stride_size";
4094 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4095 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4096 case DW_AT_accessibility: return "DW_AT_accessibility";
4097 case DW_AT_address_class: return "DW_AT_address_class";
4098 case DW_AT_artificial: return "DW_AT_artificial";
4099 case DW_AT_base_types: return "DW_AT_base_types";
4100 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4101 case DW_AT_count: return "DW_AT_count";
4102 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4103 case DW_AT_decl_column: return "DW_AT_decl_column";
4104 case DW_AT_decl_file: return "DW_AT_decl_file";
4105 case DW_AT_decl_line: return "DW_AT_decl_line";
4106 case DW_AT_declaration: return "DW_AT_declaration";
4107 case DW_AT_discr_list: return "DW_AT_discr_list";
4108 case DW_AT_encoding: return "DW_AT_encoding";
4109 case DW_AT_external: return "DW_AT_external";
4110 case DW_AT_frame_base: return "DW_AT_frame_base";
4111 case DW_AT_friend: return "DW_AT_friend";
4112 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4113 case DW_AT_macro_info: return "DW_AT_macro_info";
4114 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4115 case DW_AT_priority: return "DW_AT_priority";
4116 case DW_AT_segment: return "DW_AT_segment";
4117 case DW_AT_specification: return "DW_AT_specification";
4118 case DW_AT_static_link: return "DW_AT_static_link";
4119 case DW_AT_type: return "DW_AT_type";
4120 case DW_AT_use_location: return "DW_AT_use_location";
4121 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4122 case DW_AT_virtuality: return "DW_AT_virtuality";
4123 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4124 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4125 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4126 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4127 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4128 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4129 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4130 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4131 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4132 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4133 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4134 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4135 case DW_AT_sf_names: return "DW_AT_sf_names";
4136 case DW_AT_src_info: return "DW_AT_src_info";
4137 case DW_AT_mac_info: return "DW_AT_mac_info";
4138 case DW_AT_src_coords: return "DW_AT_src_coords";
4139 case DW_AT_body_begin: return "DW_AT_body_begin";
4140 case DW_AT_body_end: return "DW_AT_body_end";
4141 default:
4143 static char buffer [100];
4145 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4146 return buffer;
4151 static char *
4152 get_FORM_name (form)
4153 unsigned long form;
4155 switch (form)
4157 case DW_FORM_addr: return "DW_FORM_addr";
4158 case DW_FORM_block2: return "DW_FORM_block2";
4159 case DW_FORM_block4: return "DW_FORM_block4";
4160 case DW_FORM_data2: return "DW_FORM_data2";
4161 case DW_FORM_data4: return "DW_FORM_data4";
4162 case DW_FORM_data8: return "DW_FORM_data8";
4163 case DW_FORM_string: return "DW_FORM_string";
4164 case DW_FORM_block: return "DW_FORM_block";
4165 case DW_FORM_block1: return "DW_FORM_block1";
4166 case DW_FORM_data1: return "DW_FORM_data1";
4167 case DW_FORM_flag: return "DW_FORM_flag";
4168 case DW_FORM_sdata: return "DW_FORM_sdata";
4169 case DW_FORM_strp: return "DW_FORM_strp";
4170 case DW_FORM_udata: return "DW_FORM_udata";
4171 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4172 case DW_FORM_ref1: return "DW_FORM_ref1";
4173 case DW_FORM_ref2: return "DW_FORM_ref2";
4174 case DW_FORM_ref4: return "DW_FORM_ref4";
4175 case DW_FORM_ref8: return "DW_FORM_ref8";
4176 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4177 case DW_FORM_indirect: return "DW_FORM_indirect";
4178 default:
4180 static char buffer [100];
4182 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4183 return buffer;
4188 /* FIXME: There are better and more effiecint ways to handle
4189 these structures. For now though, I just want something that
4190 is simple to implement. */
4191 typedef struct abbrev_attr
4193 unsigned long attribute;
4194 unsigned long form;
4195 struct abbrev_attr * next;
4197 abbrev_attr;
4199 typedef struct abbrev_entry
4201 unsigned long entry;
4202 unsigned long tag;
4203 int children;
4204 struct abbrev_attr * first_attr;
4205 struct abbrev_attr * last_attr;
4206 struct abbrev_entry * next;
4208 abbrev_entry;
4210 static abbrev_entry * first_abbrev = NULL;
4211 static abbrev_entry * last_abbrev = NULL;
4213 static void
4214 free_abbrevs PARAMS ((void))
4216 abbrev_entry * abbrev;
4218 for (abbrev = first_abbrev; abbrev;)
4220 abbrev_entry * next = abbrev->next;
4221 abbrev_attr * attr;
4223 for (attr = abbrev->first_attr; attr;)
4225 abbrev_attr * next = attr->next;
4227 free (attr);
4228 attr = next;
4231 free (abbrev);
4232 abbrev = next;
4235 last_abbrev = first_abbrev = NULL;
4238 static void
4239 add_abbrev (number, tag, children)
4240 unsigned long number;
4241 unsigned long tag;
4242 int children;
4244 abbrev_entry * entry;
4246 entry = (abbrev_entry *) malloc (sizeof (* entry));
4248 if (entry == NULL)
4249 /* ugg */
4250 return;
4252 entry->entry = number;
4253 entry->tag = tag;
4254 entry->children = children;
4255 entry->first_attr = NULL;
4256 entry->last_attr = NULL;
4257 entry->next = NULL;
4259 if (first_abbrev == NULL)
4260 first_abbrev = entry;
4261 else
4262 last_abbrev->next = entry;
4264 last_abbrev = entry;
4267 static void
4268 add_abbrev_attr (attribute, form)
4269 unsigned long attribute;
4270 unsigned long form;
4272 abbrev_attr * attr;
4274 attr = (abbrev_attr *) malloc (sizeof (* attr));
4276 if (attr == NULL)
4277 /* ugg */
4278 return;
4280 attr->attribute = attribute;
4281 attr->form = form;
4282 attr->next = NULL;
4284 if (last_abbrev->first_attr == NULL)
4285 last_abbrev->first_attr = attr;
4286 else
4287 last_abbrev->last_attr->next = attr;
4289 last_abbrev->last_attr = attr;
4292 /* Processes the (partial) contents of a .debug_abbrev section.
4293 Returns NULL if the end of the section was encountered.
4294 Returns the address after the last byte read if the end of
4295 an abbreviation set was found. */
4297 static unsigned char *
4298 process_abbrev_section (start, end)
4299 unsigned char * start;
4300 unsigned char * end;
4302 if (first_abbrev != NULL)
4303 return NULL;
4305 while (start < end)
4307 int bytes_read;
4308 unsigned long entry;
4309 unsigned long tag;
4310 unsigned long attribute;
4311 int children;
4313 entry = read_leb128 (start, & bytes_read, 0);
4314 start += bytes_read;
4316 if (entry == 0)
4317 return start;
4319 tag = read_leb128 (start, & bytes_read, 0);
4320 start += bytes_read;
4322 children = * start ++;
4324 add_abbrev (entry, tag, children);
4328 unsigned long form;
4330 attribute = read_leb128 (start, & bytes_read, 0);
4331 start += bytes_read;
4333 form = read_leb128 (start, & bytes_read, 0);
4334 start += bytes_read;
4336 if (attribute != 0)
4337 add_abbrev_attr (attribute, form);
4339 while (attribute != 0);
4342 return NULL;
4346 static int
4347 display_debug_abbrev (section, start, file)
4348 Elf32_Internal_Shdr * section;
4349 unsigned char * start;
4350 FILE * file;
4352 abbrev_entry * entry;
4353 unsigned char * end = start + section->sh_size;
4355 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4359 start = process_abbrev_section (start, end);
4361 printf (_(" Number TAG\n"));
4363 for (entry = first_abbrev; entry; entry = entry->next)
4365 abbrev_attr * attr;
4367 printf (_(" %ld %s [%s]\n"),
4368 entry->entry,
4369 get_TAG_name (entry->tag),
4370 entry->children ? _("has children") : _("no children"));
4372 for (attr = entry->first_attr; attr; attr = attr->next)
4374 printf (_(" %-18s %s\n"),
4375 get_AT_name (attr->attribute),
4376 get_FORM_name (attr->form));
4380 while (start);
4382 printf ("\n");
4384 return 1;
4388 static unsigned char *
4389 display_block (data, length)
4390 unsigned char * data;
4391 unsigned long length;
4393 printf (_(" %lu byte block: "), length);
4395 while (length --)
4396 printf ("%lx ", byte_get (data ++, 1));
4398 return data;
4401 static void
4402 decode_location_expression (data, pointer_size)
4403 unsigned char * data;
4404 unsigned int pointer_size;
4406 unsigned char op;
4407 int bytes_read;
4409 op = * data ++;
4411 switch (op)
4413 case DW_OP_addr: printf ("DW_OP_addr: %lx", byte_get (data, pointer_size)); break;
4414 case DW_OP_deref: printf ("DW_OP_deref"); break;
4415 case DW_OP_const1u: printf ("DW_OP_const1u: %lu", byte_get (data, 1)); break;
4416 case DW_OP_const1s: printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1)); break;
4417 case DW_OP_const2u: printf ("DW_OP_const2u: %lu", byte_get (data, 2)); break;
4418 case DW_OP_const2s: printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2)); break;
4419 case DW_OP_const4u: printf ("DW_OP_const4u: %lu", byte_get (data, 4)); break;
4420 case DW_OP_const4s: printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4)); break;
4421 case DW_OP_const8u: printf ("DW_OP_const8u: %lu %lu", byte_get (data, 4), byte_get (data + 4, 4)); break;
4422 case DW_OP_const8s: printf ("DW_OP_const8s: %ld %ld", byte_get (data, 4), byte_get (data + 4, 4)); break;
4423 case DW_OP_constu: printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0)); break;
4424 case DW_OP_consts: printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1)); break;
4425 case DW_OP_dup: printf ("DW_OP_dup"); break;
4426 case DW_OP_drop: printf ("DW_OP_drop"); break;
4427 case DW_OP_over: printf ("DW_OP_over"); break;
4428 case DW_OP_pick: printf ("DW_OP_pick: %ld", byte_get (data, 1)); break;
4429 case DW_OP_swap: printf ("DW_OP_swap"); break;
4430 case DW_OP_rot: printf ("DW_OP_rot"); break;
4431 case DW_OP_xderef: printf ("DW_OP_xderef"); break;
4432 case DW_OP_abs: printf ("DW_OP_abs"); break;
4433 case DW_OP_and: printf ("DW_OP_and"); break;
4434 case DW_OP_div: printf ("DW_OP_div"); break;
4435 case DW_OP_minus: printf ("DW_OP_minus"); break;
4436 case DW_OP_mod: printf ("DW_OP_mod"); break;
4437 case DW_OP_mul: printf ("DW_OP_mul"); break;
4438 case DW_OP_neg: printf ("DW_OP_neg"); break;
4439 case DW_OP_not: printf ("DW_OP_not"); break;
4440 case DW_OP_or: printf ("DW_OP_or"); break;
4441 case DW_OP_plus: printf ("DW_OP_plus"); break;
4442 case DW_OP_plus_uconst: printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0)); break;
4443 case DW_OP_shl: printf ("DW_OP_shl"); break;
4444 case DW_OP_shr: printf ("DW_OP_shr"); break;
4445 case DW_OP_shra: printf ("DW_OP_shra"); break;
4446 case DW_OP_xor: printf ("DW_OP_xor"); break;
4447 case DW_OP_bra: printf ("DW_OP_bra: %ld", byte_get (data, 2)); break;
4448 case DW_OP_eq: printf ("DW_OP_eq"); break;
4449 case DW_OP_ge: printf ("DW_OP_ge"); break;
4450 case DW_OP_gt: printf ("DW_OP_gt"); break;
4451 case DW_OP_le: printf ("DW_OP_le"); break;
4452 case DW_OP_lt: printf ("DW_OP_lt"); break;
4453 case DW_OP_ne: printf ("DW_OP_ne"); break;
4454 case DW_OP_skip: printf ("DW_OP_skip: %ld", byte_get (data, 2)); break;
4455 case DW_OP_lit0: printf ("DW_OP_lit0"); break;
4456 case DW_OP_lit1: printf ("DW_OP_lit1"); break;
4457 case DW_OP_lit2: printf ("DW_OP_lit2"); break;
4458 case DW_OP_lit3: printf ("DW_OP_lit3"); break;
4459 case DW_OP_lit4: printf ("DW_OP_lit4"); break;
4460 case DW_OP_lit5: printf ("DW_OP_lit5"); break;
4461 case DW_OP_lit6: printf ("DW_OP_lit6"); break;
4462 case DW_OP_lit7: printf ("DW_OP_lit7"); break;
4463 case DW_OP_lit8: printf ("DW_OP_lit8"); break;
4464 case DW_OP_lit9: printf ("DW_OP_lit9"); break;
4465 case DW_OP_lit10: printf ("DW_OP_lit10"); break;
4466 case DW_OP_lit11: printf ("DW_OP_lit11"); break;
4467 case DW_OP_lit12: printf ("DW_OP_lit12"); break;
4468 case DW_OP_lit13: printf ("DW_OP_lit13"); break;
4469 case DW_OP_lit14: printf ("DW_OP_lit14"); break;
4470 case DW_OP_lit15: printf ("DW_OP_lit15"); break;
4471 case DW_OP_lit16: printf ("DW_OP_lit16"); break;
4472 case DW_OP_lit17: printf ("DW_OP_lit17"); break;
4473 case DW_OP_lit18: printf ("DW_OP_lit18"); break;
4474 case DW_OP_lit19: printf ("DW_OP_lit19"); break;
4475 case DW_OP_lit20: printf ("DW_OP_lit20"); break;
4476 case DW_OP_lit21: printf ("DW_OP_lit21"); break;
4477 case DW_OP_lit22: printf ("DW_OP_lit22"); break;
4478 case DW_OP_lit23: printf ("DW_OP_lit23"); break;
4479 case DW_OP_lit24: printf ("DW_OP_lit24"); break;
4480 case DW_OP_lit25: printf ("DW_OP_lit25"); break;
4481 case DW_OP_lit26: printf ("DW_OP_lit26"); break;
4482 case DW_OP_lit27: printf ("DW_OP_lit27"); break;
4483 case DW_OP_lit28: printf ("DW_OP_lit28"); break;
4484 case DW_OP_lit29: printf ("DW_OP_lit29"); break;
4485 case DW_OP_lit30: printf ("DW_OP_lit30"); break;
4486 case DW_OP_lit31: printf ("DW_OP_lit31"); break;
4487 case DW_OP_reg0: printf ("DW_OP_reg0"); break;
4488 case DW_OP_reg1: printf ("DW_OP_reg1"); break;
4489 case DW_OP_reg2: printf ("DW_OP_reg2"); break;
4490 case DW_OP_reg3: printf ("DW_OP_reg3"); break;
4491 case DW_OP_reg4: printf ("DW_OP_reg4"); break;
4492 case DW_OP_reg5: printf ("DW_OP_reg5"); break;
4493 case DW_OP_reg6: printf ("DW_OP_reg6"); break;
4494 case DW_OP_reg7: printf ("DW_OP_reg7"); break;
4495 case DW_OP_reg8: printf ("DW_OP_reg8"); break;
4496 case DW_OP_reg9: printf ("DW_OP_reg9"); break;
4497 case DW_OP_reg10: printf ("DW_OP_reg10"); break;
4498 case DW_OP_reg11: printf ("DW_OP_reg11"); break;
4499 case DW_OP_reg12: printf ("DW_OP_reg12"); break;
4500 case DW_OP_reg13: printf ("DW_OP_reg13"); break;
4501 case DW_OP_reg14: printf ("DW_OP_reg14"); break;
4502 case DW_OP_reg15: printf ("DW_OP_reg15"); break;
4503 case DW_OP_reg16: printf ("DW_OP_reg16"); break;
4504 case DW_OP_reg17: printf ("DW_OP_reg17"); break;
4505 case DW_OP_reg18: printf ("DW_OP_reg18"); break;
4506 case DW_OP_reg19: printf ("DW_OP_reg19"); break;
4507 case DW_OP_reg20: printf ("DW_OP_reg20"); break;
4508 case DW_OP_reg21: printf ("DW_OP_reg21"); break;
4509 case DW_OP_reg22: printf ("DW_OP_reg22"); break;
4510 case DW_OP_reg23: printf ("DW_OP_reg23"); break;
4511 case DW_OP_reg24: printf ("DW_OP_reg24"); break;
4512 case DW_OP_reg25: printf ("DW_OP_reg25"); break;
4513 case DW_OP_reg26: printf ("DW_OP_reg26"); break;
4514 case DW_OP_reg27: printf ("DW_OP_reg27"); break;
4515 case DW_OP_reg28: printf ("DW_OP_reg28"); break;
4516 case DW_OP_reg29: printf ("DW_OP_reg29"); break;
4517 case DW_OP_reg30: printf ("DW_OP_reg30"); break;
4518 case DW_OP_reg31: printf ("DW_OP_reg31"); break;
4519 case DW_OP_breg0: printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1)); break;
4520 case DW_OP_breg1: printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1)); break;
4521 case DW_OP_breg2: printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1)); break;
4522 case DW_OP_breg3: printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1)); break;
4523 case DW_OP_breg4: printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1)); break;
4524 case DW_OP_breg5: printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1)); break;
4525 case DW_OP_breg6: printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1)); break;
4526 case DW_OP_breg7: printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1)); break;
4527 case DW_OP_breg8: printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1)); break;
4528 case DW_OP_breg9: printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1)); break;
4529 case DW_OP_breg10: printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1)); break;
4530 case DW_OP_breg11: printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1)); break;
4531 case DW_OP_breg12: printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1)); break;
4532 case DW_OP_breg13: printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1)); break;
4533 case DW_OP_breg14: printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1)); break;
4534 case DW_OP_breg15: printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1)); break;
4535 case DW_OP_breg16: printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1)); break;
4536 case DW_OP_breg17: printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1)); break;
4537 case DW_OP_breg18: printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1)); break;
4538 case DW_OP_breg19: printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1)); break;
4539 case DW_OP_breg20: printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1)); break;
4540 case DW_OP_breg21: printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1)); break;
4541 case DW_OP_breg22: printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1)); break;
4542 case DW_OP_breg23: printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1)); break;
4543 case DW_OP_breg24: printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1)); break;
4544 case DW_OP_breg25: printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1)); break;
4545 case DW_OP_breg26: printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1)); break;
4546 case DW_OP_breg27: printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1)); break;
4547 case DW_OP_breg28: printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1)); break;
4548 case DW_OP_breg29: printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1)); break;
4549 case DW_OP_breg30: printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1)); break;
4550 case DW_OP_breg31: printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1)); break;
4551 case DW_OP_regx: printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0)); break;
4552 case DW_OP_fbreg: printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1)); break;
4553 case DW_OP_bregx: printf ("DW_OP_bregx: %lu %ld", read_leb128 (data, & bytes_read, 0), read_leb128 (data + bytes_read, NULL, 1)); break;
4554 case DW_OP_piece: printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0)); break;
4555 case DW_OP_deref_size: printf ("DW_OP_deref_size: %ld", byte_get (data, 1)); break;
4556 case DW_OP_xderef_size: printf ("DW_OP_xderef_size: %ld", byte_get (data, 1)); break;
4557 case DW_OP_nop: printf ("DW_OP_nop"); break;
4559 default:
4560 if (op >= DW_OP_lo_user
4561 && op <= DW_OP_hi_user)
4562 printf (_("(User defined location op)"));
4563 else
4564 printf (_("(Unknown location op)"));
4565 break;
4570 static unsigned char *
4571 read_and_display_attr (attribute, form, data, pointer_size)
4572 unsigned long attribute;
4573 unsigned long form;
4574 unsigned char * data;
4575 unsigned long pointer_size;
4577 unsigned long uvalue;
4578 unsigned char * block_start;
4579 int bytes_read;
4580 int is_ref = 0;
4582 printf (" %-18s:", get_AT_name (attribute));
4584 switch (form)
4586 case DW_FORM_ref_addr:
4587 case DW_FORM_ref1:
4588 case DW_FORM_ref2:
4589 case DW_FORM_ref4:
4590 case DW_FORM_ref8:
4591 case DW_FORM_ref_udata:
4592 is_ref = 1;
4595 switch (form)
4597 case DW_FORM_ref_addr:
4598 case DW_FORM_addr:
4599 uvalue = byte_get (data, pointer_size);
4600 printf (is_ref ? " <%x>" : " %#x", uvalue);
4601 data += pointer_size;
4602 break;
4604 case DW_FORM_ref1:
4605 case DW_FORM_flag:
4606 case DW_FORM_data1:
4607 uvalue = byte_get (data ++, 1);
4608 printf (is_ref ? " <%x>" : " %d", uvalue);
4609 break;
4611 case DW_FORM_ref2:
4612 case DW_FORM_data2:
4613 uvalue = byte_get (data, 2);
4614 data += 2;
4615 printf (is_ref ? " <%x>" : " %d", uvalue);
4616 break;
4618 case DW_FORM_ref4:
4619 case DW_FORM_data4:
4620 uvalue = byte_get (data, 4);
4621 data += 4;
4622 printf (is_ref ? " <%x>" : " %d", uvalue);
4623 break;
4625 case DW_FORM_ref8:
4626 case DW_FORM_data8:
4627 uvalue = byte_get (data, 4);
4628 printf (" %lx", uvalue);
4629 printf (" %lx", byte_get (data + 4, 4));
4630 data += 8;
4631 break;
4633 case DW_FORM_string:
4634 printf (" %s", data);
4635 data += strlen (data) + 1;
4636 break;
4638 case DW_FORM_sdata:
4639 uvalue = read_leb128 (data, & bytes_read, 1);
4640 data += bytes_read;
4641 printf (" %ld", (long) uvalue);
4642 break;
4644 case DW_FORM_ref_udata:
4645 case DW_FORM_udata:
4646 uvalue = read_leb128 (data, & bytes_read, 0);
4647 data += bytes_read;
4648 printf (is_ref ? " <%lx>" : " %ld", uvalue);
4649 break;
4651 case DW_FORM_block:
4652 uvalue = read_leb128 (data, & bytes_read, 0);
4653 block_start = data + bytes_read;
4654 data = display_block (block_start, uvalue);
4655 uvalue = * block_start;
4656 break;
4658 case DW_FORM_block1:
4659 uvalue = byte_get (data, 1);
4660 block_start = data + 1;
4661 data = display_block (block_start, uvalue);
4662 uvalue = * block_start;
4663 break;
4665 case DW_FORM_block2:
4666 uvalue = byte_get (data, 2);
4667 block_start = data + 2;
4668 data = display_block (block_start, uvalue);
4669 uvalue = * block_start;
4670 break;
4672 case DW_FORM_block4:
4673 uvalue = byte_get (data, 4);
4674 block_start = data + 4;
4675 data = display_block (block_start, uvalue);
4676 uvalue = * block_start;
4677 break;
4679 case DW_FORM_strp:
4680 case DW_FORM_indirect:
4681 warn (_("Unable to handle FORM: %d"), form);
4682 break;
4684 default:
4685 warn (_("Unrecognised form: %d"), form);
4686 break;
4689 /* For some attributes we can display futher information. */
4691 printf ("\t");
4693 switch (attribute)
4695 case DW_AT_inline:
4696 switch (uvalue)
4698 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
4699 case DW_INL_inlined: printf (_("(inlined)")); break;
4700 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
4701 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
4702 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
4704 break;
4706 case DW_AT_frame_base:
4707 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
4708 printf ("(reg %ld)", uvalue - DW_OP_reg0);
4709 break;
4711 case DW_AT_language:
4712 switch (uvalue)
4714 case DW_LANG_C: printf ("(non-ANSI C)"); break;
4715 case DW_LANG_C89: printf ("(ANSI C)"); break;
4716 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
4717 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
4718 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
4719 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
4720 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
4721 case DW_LANG_Ada83: printf ("(Ada)"); break;
4722 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
4723 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
4724 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
4725 default: printf ("(Unknown: %lx)", uvalue); break;
4727 break;
4729 case DW_AT_encoding:
4730 switch (uvalue)
4732 case DW_ATE_void: printf ("(void)"); break;
4733 case DW_ATE_address: printf ("(machine address)"); break;
4734 case DW_ATE_boolean: printf ("(boolean)"); break;
4735 case DW_ATE_complex_float: printf ("(complex float)"); break;
4736 case DW_ATE_float: printf ("(float)"); break;
4737 case DW_ATE_signed: printf ("(signed)"); break;
4738 case DW_ATE_signed_char: printf ("(signed char)"); break;
4739 case DW_ATE_unsigned: printf ("(unsigned)"); break;
4740 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
4741 default:
4742 if (uvalue >= DW_ATE_lo_user
4743 && uvalue <= DW_ATE_hi_user)
4744 printf ("(user defined type)");
4745 else
4746 printf ("(unknown type)");
4747 break;
4749 break;
4751 case DW_AT_accessibility:
4752 switch (uvalue)
4754 case DW_ACCESS_public: printf ("(public)"); break;
4755 case DW_ACCESS_protected: printf ("(protected)"); break;
4756 case DW_ACCESS_private: printf ("(private)"); break;
4757 default: printf ("(unknown accessibility)"); break;
4759 break;
4761 case DW_AT_visibility:
4762 switch (uvalue)
4764 case DW_VIS_local: printf ("(local)"); break;
4765 case DW_VIS_exported: printf ("(exported)"); break;
4766 case DW_VIS_qualified: printf ("(qualified)"); break;
4767 default: printf ("(unknown visibility)"); break;
4769 break;
4771 case DW_AT_virtuality:
4772 switch (uvalue)
4774 case DW_VIRTUALITY_none: printf ("(none)"); break;
4775 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
4776 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
4777 default: printf ("(unknown virtuality)"); break;
4779 break;
4781 case DW_AT_identifier_case:
4782 switch (uvalue)
4784 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
4785 case DW_ID_up_case: printf ("(up_case)"); break;
4786 case DW_ID_down_case: printf ("(down_case)"); break;
4787 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
4788 default: printf ("(unknown case)"); break;
4790 break;
4792 case DW_AT_calling_convention:
4793 switch (uvalue)
4795 case DW_CC_normal: printf ("(normal)"); break;
4796 case DW_CC_program: printf ("(program)"); break;
4797 case DW_CC_nocall: printf ("(nocall)"); break;
4798 default:
4799 if (uvalue >= DW_CC_lo_user
4800 && uvalue <= DW_CC_hi_user)
4801 printf ("(user defined)");
4802 else
4803 printf ("(unknown convention)");
4805 break;
4807 case DW_AT_location:
4808 case DW_AT_data_member_location:
4809 case DW_AT_vtable_elem_location:
4810 printf ("(");
4811 decode_location_expression (block_start, pointer_size);
4812 printf (")");
4813 break;
4815 default:
4816 break;
4819 printf ("\n");
4820 return data;
4823 static int
4824 display_debug_info (section, start, file)
4825 Elf32_Internal_Shdr * section;
4826 unsigned char * start;
4827 FILE * file;
4829 unsigned char * end = start + section->sh_size;
4830 unsigned char * section_begin = start;
4832 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4834 while (start < end)
4836 DWARF2_External_CompUnit * external;
4837 DWARF2_Internal_CompUnit compunit;
4838 unsigned char * tags;
4839 int i;
4840 int level;
4842 external = (DWARF2_External_CompUnit *) start;
4844 compunit.cu_length = BYTE_GET (external->cu_length);
4845 compunit.cu_version = BYTE_GET (external->cu_version);
4846 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
4847 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
4849 tags = start + sizeof (* external);
4850 start += compunit.cu_length + sizeof (external->cu_length);
4852 if (compunit.cu_version != 2)
4854 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
4855 continue;
4858 printf (_(" Compilation Unit:\n"));
4859 printf (_(" Length: %ld\n"), compunit.cu_length);
4860 printf (_(" Version: %d\n"), compunit.cu_version);
4861 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
4862 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
4864 if (first_abbrev != NULL)
4865 free_abbrevs ();
4867 /* Read in the abbrevs used by this compilation unit. */
4870 Elf32_Internal_Shdr * sec;
4871 unsigned char * begin;
4873 /* Locate the .debug_abbrev section and process it. */
4874 for (i = 0, sec = section_headers;
4875 i < elf_header.e_shnum;
4876 i ++, sec ++)
4877 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
4878 break;
4880 if (i == -1 || sec->sh_size == 0)
4882 warn (_("Unable to locate .debug_abbrev section!\n"));
4883 return 0;
4886 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
4887 "debug_abbrev section data");
4889 process_abbrev_section (begin + compunit.cu_abbrev_offset,
4890 begin + sec->sh_size);
4892 free (begin);
4895 level = 0;
4896 while (tags < start)
4898 int bytes_read;
4899 int abbrev_number;
4900 abbrev_entry * entry;
4901 abbrev_attr * attr;
4903 abbrev_number = read_leb128 (tags, & bytes_read, 0);
4904 tags += bytes_read;
4906 /* A null DIE marks the end of a list of children. */
4907 if (abbrev_number == 0)
4909 --level;
4910 continue;
4913 /* Scan through the abbreviation list until we reach the
4914 correct entry. */
4915 for (entry = first_abbrev;
4916 entry && entry->entry != abbrev_number;
4917 entry = entry->next)
4918 continue;
4920 if (entry == NULL)
4922 warn (_("Unable to locate entry %d in the abbreviation table\n"),
4923 abbrev_number);
4924 return 0;
4927 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
4928 level, tags - section_begin - bytes_read,
4929 abbrev_number,
4930 get_TAG_name (entry->tag));
4932 for (attr = entry->first_attr; attr; attr = attr->next)
4933 tags = read_and_display_attr (attr->attribute,
4934 attr->form,
4935 tags,
4936 compunit.cu_pointer_size);
4938 if (entry->children)
4939 ++level;
4943 printf ("\n");
4945 return 1;
4948 static int
4949 display_debug_aranges (section, start, file)
4950 Elf32_Internal_Shdr * section;
4951 unsigned char * start;
4952 FILE * file;
4954 unsigned char * end = start + section->sh_size;
4956 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4958 while (start < end)
4960 DWARF2_External_ARange * external;
4961 DWARF2_Internal_ARange arange;
4962 unsigned char * ranges;
4963 unsigned long length;
4964 unsigned long address;
4966 external = (DWARF2_External_ARange *) start;
4968 arange.ar_length = BYTE_GET (external->ar_length);
4969 arange.ar_version = BYTE_GET (external->ar_version);
4970 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
4971 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
4972 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
4974 printf (_(" Length: %ld\n"), arange.ar_length);
4975 printf (_(" Version: %d\n"), arange.ar_version);
4976 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
4977 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
4978 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
4980 printf (_("\n Address Length\n"));
4982 ranges = start + sizeof (* external);
4984 for (;;)
4986 address = byte_get (ranges, arange.ar_pointer_size);
4988 if (address == 0)
4989 break;
4991 ranges += arange.ar_pointer_size;
4993 length = byte_get (ranges, arange.ar_pointer_size);
4995 ranges += arange.ar_pointer_size;
4997 printf (" %8.8lx %lu\n", address, length);
5000 start += arange.ar_length + sizeof (external->ar_length);
5003 printf ("\n");
5005 return 1;
5009 static int
5010 display_debug_not_supported (section, start, file)
5011 Elf32_Internal_Shdr * section;
5012 unsigned char * start;
5013 FILE * file;
5015 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5016 SECTION_NAME (section));
5018 return 1;
5021 /* A structure containing the name of a debug section and a pointer
5022 to a function that can decode it. */
5023 struct
5025 char * name;
5026 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5028 debug_displays[] =
5030 { ".debug_info", display_debug_info },
5031 { ".debug_abbrev", display_debug_abbrev },
5032 { ".debug_line", display_debug_lines },
5033 { ".debug_aranges", display_debug_aranges },
5034 { ".debug_pubnames", display_debug_pubnames },
5035 { ".debug_macinfo", display_debug_not_supported },
5036 { ".debug_frame", display_debug_not_supported },
5037 { ".debug_str", display_debug_not_supported },
5038 { ".debug_static_func", display_debug_not_supported },
5039 { ".debug_static_vars", display_debug_not_supported },
5040 { ".debug_types", display_debug_not_supported },
5041 { ".debug_weaknames", display_debug_not_supported }
5044 static int
5045 display_debug_section (section, file)
5046 Elf32_Internal_Shdr * section;
5047 FILE * file;
5049 char * name = SECTION_NAME (section);
5050 bfd_size_type length;
5051 unsigned char * start;
5052 int i;
5054 length = section->sh_size;
5055 if (length == 0)
5057 printf (_("\nSection '%s' has no debugging data.\n"), name);
5058 return 0;
5061 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5062 "debug section data");
5064 /* See if we know how to display the contents of this section. */
5065 for (i = NUM_ELEM (debug_displays); i--;)
5066 if (strcmp (debug_displays[i].name, name) == 0)
5068 debug_displays[i].display (section, start, file);
5069 break;
5072 if (i == -1)
5073 printf (_("Unrecognised debug section: %s\n"), name);
5075 free (start);
5077 /* If we loaded in the abbrev section at some point,
5078 we must release it here. */
5079 if (first_abbrev != NULL)
5080 free_abbrevs ();
5082 return 1;
5085 static int
5086 process_section_contents (file)
5087 FILE * file;
5089 Elf32_Internal_Shdr * section;
5090 unsigned int i;
5092 if (! do_dump)
5093 return 1;
5095 for (i = 0, section = section_headers;
5096 i < elf_header.e_shnum
5097 && i < num_dump_sects;
5098 i ++, section ++)
5100 #ifdef SUPPORT_DISASSEMBLY
5101 if (dump_sects[i] & DISASS_DUMP)
5102 disassemble_section (section, file);
5103 #endif
5104 if (dump_sects[i] & HEX_DUMP)
5105 dump_section (section, file);
5107 if (dump_sects[i] & DEBUG_DUMP)
5108 display_debug_section (section, file);
5111 if (i < num_dump_sects)
5112 warn (_("Some sections were not dumped because they do not exist!\n"));
5114 return 1;
5117 static void
5118 process_mips_fpe_exception (mask)
5119 int mask;
5121 if (mask)
5123 int first = 1;
5124 if (mask & OEX_FPU_INEX)
5125 fputs ("INEX", stdout), first = 0;
5126 if (mask & OEX_FPU_UFLO)
5127 printf ("%sUFLO", first ? "" : "|"), first = 0;
5128 if (mask & OEX_FPU_OFLO)
5129 printf ("%sOFLO", first ? "" : "|"), first = 0;
5130 if (mask & OEX_FPU_DIV0)
5131 printf ("%sDIV0", first ? "" : "|"), first = 0;
5132 if (mask & OEX_FPU_INVAL)
5133 printf ("%sINVAL", first ? "" : "|");
5135 else
5136 fputs ("0", stdout);
5139 static int
5140 process_mips_specific (file)
5141 FILE *file;
5143 Elf_Internal_Dyn *entry;
5144 size_t liblist_offset = 0;
5145 size_t liblistno = 0;
5146 size_t conflictsno = 0;
5147 size_t options_offset = 0;
5148 size_t conflicts_offset = 0;
5150 /* We have a lot of special sections. Thanks SGI! */
5151 if (dynamic_segment == NULL)
5152 /* No information available. */
5153 return 0;
5155 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5156 switch (entry->d_tag)
5158 case DT_MIPS_LIBLIST:
5159 liblist_offset = entry->d_un.d_val - loadaddr;
5160 break;
5161 case DT_MIPS_LIBLISTNO:
5162 liblistno = entry->d_un.d_val;
5163 break;
5164 case DT_MIPS_OPTIONS:
5165 options_offset = entry->d_un.d_val - loadaddr;
5166 break;
5167 case DT_MIPS_CONFLICT:
5168 conflicts_offset = entry->d_un.d_val - loadaddr;
5169 break;
5170 case DT_MIPS_CONFLICTNO:
5171 conflictsno = entry->d_un.d_val;
5172 break;
5173 default:
5174 break;
5177 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5179 Elf32_External_Lib *elib;
5180 size_t cnt;
5182 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5183 elib, Elf32_External_Lib *, "liblist");
5185 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5186 fputs (" Library Time Stamp Checksum Version Flags\n",
5187 stdout);
5189 for (cnt = 0; cnt < liblistno; ++cnt)
5191 Elf32_Lib liblist;
5192 time_t time;
5193 char timebuf[20];
5195 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5196 time = BYTE_GET (elib[cnt].l_time_stamp);
5197 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5198 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5199 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5201 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5203 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5204 dynamic_strings + liblist.l_name, timebuf,
5205 liblist.l_checksum, liblist.l_version);
5207 if (liblist.l_flags == 0)
5208 puts (" NONE");
5209 else
5211 static const struct
5213 const char *name;
5214 int bit;
5215 } l_flags_vals[] =
5217 { " EXACT_MATCH", LL_EXACT_MATCH },
5218 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5219 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5220 { " EXPORTS", LL_EXPORTS },
5221 { " DELAY_LOAD", LL_DELAY_LOAD },
5222 { " DELTA", LL_DELTA }
5224 int flags = liblist.l_flags;
5225 int fcnt;
5227 for (fcnt = 0;
5228 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5229 ++fcnt)
5230 if ((flags & l_flags_vals[fcnt].bit) != 0)
5232 fputs (l_flags_vals[fcnt].name, stdout);
5233 flags ^= l_flags_vals[fcnt].bit;
5235 if (flags != 0)
5236 printf (" %#x", (unsigned int) flags);
5238 puts ("");
5242 free (elib);
5245 if (options_offset != 0)
5247 Elf_External_Options *eopt;
5248 Elf_Internal_Shdr *sect = section_headers;
5249 Elf_Internal_Options *iopt;
5250 Elf_Internal_Options *option;
5251 size_t offset;
5252 int cnt;
5254 /* Find the section header so that we get the size. */
5255 while (sect->sh_type != SHT_MIPS_OPTIONS)
5256 ++sect;
5258 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5259 Elf_External_Options *, "options");
5261 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5262 * sizeof (*iopt));
5263 if (iopt == NULL)
5265 error (_("Out of memory"));
5266 return 0;
5269 offset = cnt = 0;
5270 option = iopt;
5271 while (offset < sect->sh_size)
5273 Elf_External_Options *eoption;
5275 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5277 option->kind = BYTE_GET (eoption->kind);
5278 option->size = BYTE_GET (eoption->size);
5279 option->section = BYTE_GET (eoption->section);
5280 option->info = BYTE_GET (eoption->info);
5282 offset += option->size;
5283 ++option;
5284 ++cnt;
5287 printf (_("\nSection '%s' contains %d entries:\n"),
5288 string_table + sect->sh_name, cnt);
5290 option = iopt;
5291 while (cnt-- > 0)
5293 size_t len;
5295 switch (option->kind)
5297 case ODK_NULL:
5298 /* This shouldn't happen. */
5299 printf (" NULL %d %lx", option->section, option->info);
5300 break;
5301 case ODK_REGINFO:
5302 printf (" REGINFO ");
5303 if (elf_header.e_machine == EM_MIPS)
5305 /* 32bit form. */
5306 Elf32_External_RegInfo *ereg;
5307 Elf32_RegInfo reginfo;
5309 ereg = (Elf32_External_RegInfo *) (option + 1);
5310 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5311 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5312 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5313 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5314 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5315 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5317 printf ("GPR %08lx GP 0x%lx\n",
5318 reginfo.ri_gprmask,
5319 (unsigned long) reginfo.ri_gp_value);
5320 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5321 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5322 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5324 else
5326 /* 64 bit form. */
5327 Elf64_External_RegInfo *ereg;
5328 Elf64_Internal_RegInfo reginfo;
5330 ereg = (Elf64_External_RegInfo *) (option + 1);
5331 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5332 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5333 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5334 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5335 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5336 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5338 printf ("GPR %08lx GP 0x",
5339 reginfo.ri_gprmask);
5340 printf_vma (reginfo.ri_gp_value);
5341 printf ("\n");
5343 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5344 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5345 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5347 ++option;
5348 continue;
5349 case ODK_EXCEPTIONS:
5350 fputs (" EXCEPTIONS fpe_min(", stdout);
5351 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
5352 fputs (") fpe_max(", stdout);
5353 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
5354 fputs (")", stdout);
5356 if (option->info & OEX_PAGE0)
5357 fputs (" PAGE0", stdout);
5358 if (option->info & OEX_SMM)
5359 fputs (" SMM", stdout);
5360 if (option->info & OEX_FPDBUG)
5361 fputs (" FPDBUG", stdout);
5362 if (option->info & OEX_DISMISS)
5363 fputs (" DISMISS", stdout);
5364 break;
5365 case ODK_PAD:
5366 fputs (" PAD ", stdout);
5367 if (option->info & OPAD_PREFIX)
5368 fputs (" PREFIX", stdout);
5369 if (option->info & OPAD_POSTFIX)
5370 fputs (" POSTFIX", stdout);
5371 if (option->info & OPAD_SYMBOL)
5372 fputs (" SYMBOL", stdout);
5373 break;
5374 case ODK_HWPATCH:
5375 fputs (" HWPATCH ", stdout);
5376 if (option->info & OHW_R4KEOP)
5377 fputs (" R4KEOP", stdout);
5378 if (option->info & OHW_R8KPFETCH)
5379 fputs (" R8KPFETCH", stdout);
5380 if (option->info & OHW_R5KEOP)
5381 fputs (" R5KEOP", stdout);
5382 if (option->info & OHW_R5KCVTL)
5383 fputs (" R5KCVTL", stdout);
5384 break;
5385 case ODK_FILL:
5386 fputs (" FILL ", stdout);
5387 /* XXX Print content of info word? */
5388 break;
5389 case ODK_TAGS:
5390 fputs (" TAGS ", stdout);
5391 /* XXX Print content of info word? */
5392 break;
5393 case ODK_HWAND:
5394 fputs (" HWAND ", stdout);
5395 if (option->info & OHWA0_R4KEOP_CHECKED)
5396 fputs (" R4KEOP_CHECKED", stdout);
5397 if (option->info & OHWA0_R4KEOP_CLEAN)
5398 fputs (" R4KEOP_CLEAN", stdout);
5399 break;
5400 case ODK_HWOR:
5401 fputs (" HWOR ", stdout);
5402 if (option->info & OHWA0_R4KEOP_CHECKED)
5403 fputs (" R4KEOP_CHECKED", stdout);
5404 if (option->info & OHWA0_R4KEOP_CLEAN)
5405 fputs (" R4KEOP_CLEAN", stdout);
5406 break;
5407 case ODK_GP_GROUP:
5408 printf (" GP_GROUP %#06lx self-contained %#06lx",
5409 option->info & OGP_GROUP,
5410 (option->info & OGP_SELF) >> 16);
5411 break;
5412 case ODK_IDENT:
5413 printf (" IDENT %#06lx self-contained %#06lx",
5414 option->info & OGP_GROUP,
5415 (option->info & OGP_SELF) >> 16);
5416 break;
5417 default:
5418 /* This shouldn't happen. */
5419 printf (" %3d ??? %d %lx",
5420 option->kind, option->section, option->info);
5421 break;
5424 len = sizeof (*eopt);
5425 while (len < option->size)
5426 if (((char *) option)[len] >= ' '
5427 && ((char *) option)[len] < 0x7f)
5428 printf ("%c", ((char *) option)[len++]);
5429 else
5430 printf ("\\%03o", ((char *) option)[len++]);
5432 fputs ("\n", stdout);
5433 ++option;
5436 free (eopt);
5439 if (conflicts_offset != 0 && conflictsno != 0)
5441 Elf32_External_Conflict *econf32;
5442 Elf64_External_Conflict *econf64;
5443 Elf32_Conflict *iconf;
5444 size_t cnt;
5446 if (dynamic_symbols == NULL)
5448 error (_("conflict list with without table"));
5449 return 0;
5452 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
5453 if (iconf == NULL)
5455 error (_("Out of memory"));
5456 return 0;
5459 if (binary_class == ELFCLASS32)
5461 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
5462 econf32, Elf32_External_Conflict *, "conflict");
5464 for (cnt = 0; cnt < conflictsno; ++cnt)
5465 iconf[cnt] = BYTE_GET (econf32[cnt]);
5467 else
5469 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
5470 econf64, Elf64_External_Conflict *, "conflict");
5472 for (cnt = 0; cnt < conflictsno; ++cnt)
5473 iconf[cnt] = BYTE_GET (econf64[cnt]);
5476 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
5477 puts (_(" Num: Index Value Name"));
5479 for (cnt = 0; cnt < conflictsno; ++cnt)
5481 Elf_Internal_Sym *psym = &dynamic_symbols[iconf[cnt]];
5483 printf ("%5u: %8lu %#10lx %s\n",
5484 cnt, iconf[cnt], (unsigned long) psym->st_value,
5485 dynamic_strings + psym->st_name);
5489 free (iconf);
5492 return 1;
5495 static int
5496 process_arch_specific (file)
5497 FILE *file;
5499 switch (elf_header.e_machine)
5501 case EM_MIPS:
5502 case EM_MIPS_RS4_BE:
5503 return process_mips_specific (file);
5504 break;
5505 default:
5506 break;
5508 return 1;
5511 static int
5512 get_file_header (file)
5513 FILE * file;
5515 Elf32_External_Ehdr ehdr;
5517 if (fread (& ehdr, sizeof (ehdr), 1, file) != 1)
5518 return 0;
5520 memcpy (elf_header.e_ident, ehdr.e_ident, EI_NIDENT);
5522 if (elf_header.e_ident [EI_DATA] == ELFDATA2LSB)
5523 byte_get = byte_get_little_endian;
5524 else
5525 byte_get = byte_get_big_endian;
5527 elf_header.e_entry = BYTE_GET (ehdr.e_entry);
5528 elf_header.e_phoff = BYTE_GET (ehdr.e_phoff);
5529 elf_header.e_shoff = BYTE_GET (ehdr.e_shoff);
5530 elf_header.e_version = BYTE_GET (ehdr.e_version);
5531 elf_header.e_flags = BYTE_GET (ehdr.e_flags);
5532 elf_header.e_type = BYTE_GET (ehdr.e_type);
5533 elf_header.e_machine = BYTE_GET (ehdr.e_machine);
5534 elf_header.e_ehsize = BYTE_GET (ehdr.e_ehsize);
5535 elf_header.e_phentsize = BYTE_GET (ehdr.e_phentsize);
5536 elf_header.e_phnum = BYTE_GET (ehdr.e_phnum);
5537 elf_header.e_shentsize = BYTE_GET (ehdr.e_shentsize);
5538 elf_header.e_shnum = BYTE_GET (ehdr.e_shnum);
5539 elf_header.e_shstrndx = BYTE_GET (ehdr.e_shstrndx);
5541 return 1;
5544 static void
5545 process_file (file_name)
5546 char * file_name;
5548 FILE * file;
5549 struct stat statbuf;
5550 unsigned int i;
5552 if (stat (file_name, & statbuf) < 0)
5554 error (_("Cannot stat input file %s.\n"), file_name);
5555 return;
5558 file = fopen (file_name, "rb");
5559 if (file == NULL)
5561 error (_("Input file %s not found.\n"), file_name);
5562 return;
5565 if (! get_file_header (file))
5567 error (_("%s: Failed to read file header\n"), file_name);
5568 fclose (file);
5569 return;
5572 /* Initialise per file variables. */
5573 for (i = NUM_ELEM (version_info); i--;)
5574 version_info[i] = 0;
5576 for (i = NUM_ELEM (dynamic_info); i--;)
5577 dynamic_info[i] = 0;
5579 /* Process the file. */
5580 if (show_name)
5581 printf (_("\nFile: %s\n"), file_name);
5583 if (! process_file_header ())
5585 fclose (file);
5586 return;
5589 process_section_headers (file);
5591 process_program_headers (file);
5593 process_dynamic_segment (file);
5595 process_relocs (file);
5597 process_symbol_table (file);
5599 process_syminfo (file);
5601 process_version_sections (file);
5603 process_section_contents (file);
5605 process_arch_specific (file);
5607 fclose (file);
5609 if (section_headers)
5611 free (section_headers);
5612 section_headers = NULL;
5615 if (string_table)
5617 free (string_table);
5618 string_table = NULL;
5621 if (dynamic_strings)
5623 free (dynamic_strings);
5624 dynamic_strings = NULL;
5627 if (dynamic_symbols)
5629 free (dynamic_symbols);
5630 dynamic_symbols = NULL;
5633 if (dynamic_syminfo)
5635 free (dynamic_syminfo);
5636 dynamic_syminfo = NULL;
5640 #ifdef SUPPORT_DISASSEMBLY
5641 /* Needed by the i386 disassembler. For extra credit, someone could
5642 fix this so that we insert symbolic addresses here, esp for GOT/PLT
5643 symbols */
5645 void
5646 print_address (unsigned int addr, FILE * outfile)
5648 fprintf (outfile,"0x%8.8x", addr);
5651 /* Needed by the i386 disassembler. */
5652 void
5653 db_task_printsym (unsigned int addr)
5655 print_address (addr, stderr);
5657 #endif
5660 main (argc, argv)
5661 int argc;
5662 char ** argv;
5664 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
5665 setlocale (LC_MESSAGES, "");
5666 #endif
5667 bindtextdomain (PACKAGE, LOCALEDIR);
5668 textdomain (PACKAGE);
5670 parse_args (argc, argv);
5672 if (optind < (argc - 1))
5673 show_name = 1;
5675 while (optind < argc)
5676 process_file (argv [optind ++]);
5678 if (dump_sects != NULL)
5679 free (dump_sects);
5681 return 0;