* Makefile.am: Rebuild dependencies.
[binutils.git] / binutils / readelf.c
blob8c69d961e78afc37bbfc3559b9aed77119128cd4
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"
61 #include "elf/i960.h"
63 #include "bucomm.h"
64 #include "getopt.h"
66 #ifdef ANSI_PROTOTYPES
67 #include <stdarg.h>
68 #else
69 #include <varargs.h>
70 #endif
72 char * program_name = "readelf";
73 unsigned int dynamic_addr;
74 unsigned int dynamic_size;
75 unsigned int rela_addr;
76 unsigned int rela_size;
77 char * dynamic_strings;
78 char * string_table;
79 Elf_Internal_Sym * dynamic_symbols;
80 Elf_Internal_Syminfo * dynamic_syminfo;
81 unsigned long dynamic_syminfo_offset;
82 unsigned int dynamic_syminfo_nent;
83 char program_interpreter [64];
84 int dynamic_info[DT_JMPREL + 1];
85 int version_info[16];
86 int loadaddr = 0;
87 Elf_Internal_Ehdr elf_header;
88 Elf_Internal_Shdr * section_headers;
89 Elf_Internal_Dyn * dynamic_segment;
90 int show_name;
91 int do_dynamic;
92 int do_syms;
93 int do_reloc;
94 int do_sections;
95 int do_segments;
96 int do_using_dynamic;
97 int do_header;
98 int do_dump;
99 int do_version;
100 int do_histogram;
101 int do_debugging;
102 int do_debug_info;
103 int do_debug_abbrevs;
104 int do_debug_lines;
105 int do_debug_pubnames;
106 int do_debug_aranges;
107 int binary_class;
109 /* A dynamic array of flags indicating which sections require dumping. */
110 char * dump_sects = NULL;
111 unsigned int num_dump_sects = 0;
113 #define HEX_DUMP (1 << 0)
114 #define DISASS_DUMP (1 << 1)
115 #define DEBUG_DUMP (1 << 2)
117 /* Forward declarations for dumb compilers. */
118 static unsigned long (* byte_get) PARAMS ((unsigned char *, int));
119 static const char * get_mips_dynamic_type PARAMS ((unsigned long type));
120 static const char * get_dynamic_type PARAMS ((unsigned long type));
121 static int dump_relocations PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, char *, int));
122 static char * get_file_type PARAMS ((unsigned e_type));
123 static char * get_machine_name PARAMS ((unsigned e_machine));
124 static char * get_machine_data PARAMS ((unsigned e_data));
125 static char * get_machine_flags PARAMS ((unsigned, unsigned e_machine));
126 static const char * get_mips_segment_type PARAMS ((unsigned long type));
127 static const char * get_segment_type PARAMS ((unsigned long p_type));
128 static const char * get_mips_section_type_name PARAMS ((unsigned int sh_type));
129 static const char * get_section_type_name PARAMS ((unsigned int sh_type));
130 static char * get_symbol_binding PARAMS ((unsigned int binding));
131 static char * get_symbol_type PARAMS ((unsigned int type));
132 static void usage PARAMS ((void));
133 static void parse_args PARAMS ((int argc, char ** argv));
134 static int process_file_header PARAMS ((void));
135 static int process_program_headers PARAMS ((FILE *));
136 static int process_section_headers PARAMS ((FILE *));
137 static void dynamic_segment_mips_val PARAMS ((Elf_Internal_Dyn *entry));
138 static int process_dynamic_segment PARAMS ((FILE *));
139 static int process_symbol_table PARAMS ((FILE *));
140 static int process_section_contents PARAMS ((FILE *));
141 static void process_file PARAMS ((char * file_name));
142 static int process_relocs PARAMS ((FILE *));
143 static int process_version_sections PARAMS ((FILE *));
144 static char * get_ver_flags PARAMS ((unsigned int flags));
145 static char * get_symbol_index_type PARAMS ((unsigned int type));
146 static int get_section_headers PARAMS ((FILE * file));
147 static int get_file_header PARAMS ((FILE * file));
148 static Elf_Internal_Sym * get_elf_symbols PARAMS ((FILE * file, unsigned long offset, unsigned long number));
149 static int * get_dynamic_data PARAMS ((FILE * file, unsigned int number));
150 #ifdef SUPPORT_DISASSEMBLY
151 static int disassemble_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
152 #endif
153 static int dump_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
154 static int display_debug_section PARAMS ((Elf32_Internal_Shdr *, FILE *));
155 static int display_debug_info PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
156 static int display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
157 static int display_debug_lines PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
158 static int display_debug_abbrev PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
159 static int display_debug_aranges PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
160 static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *));
161 static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int));
162 static int process_extended_line_op PARAMS ((unsigned char *, int));
163 static void reset_state_machine PARAMS ((int));
164 static char * get_TAG_name PARAMS ((unsigned long));
165 static char * get_AT_name PARAMS ((unsigned long));
166 static char * get_FORM_name PARAMS ((unsigned long));
167 static void free_abbrevs PARAMS ((void));
168 static void add_abbrev PARAMS ((unsigned long, unsigned long, int));
169 static void add_abbrev_attr PARAMS ((unsigned long, unsigned long));
170 static unsigned char * read_and_display_attr PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
171 static unsigned char * display_block PARAMS ((unsigned char *, unsigned long));
172 static void decode_location_expression PARAMS ((unsigned char *, unsigned int));
173 static void request_dump PARAMS ((unsigned int, char));
174 static const char * get_elf_class PARAMS ((unsigned char));
175 static const char * get_data_encoding PARAMS ((unsigned char));
176 static const char * get_osabi_name PARAMS ((unsigned char));
177 static int guess_is_rela PARAMS ((unsigned long));
179 typedef int Elf32_Word;
181 #ifndef TRUE
182 #define TRUE 1
183 #define FALSE 0
184 #endif
185 #define UNKNOWN -1
187 #define SECTION_NAME(X) (string_table + (X)->sh_name)
189 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
191 #define BYTE_GET(field) byte_get (field, sizeof (field))
193 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
195 #define GET_DATA_ALLOC(offset, size, var, type, reason) \
196 if (fseek (file, offset, SEEK_SET)) \
198 error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
199 return 0; \
202 var = (type) malloc (size); \
204 if (var == NULL) \
206 error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
207 return 0; \
210 if (fread (var, size, 1, file) != 1) \
212 error (_("Unable to read in %d bytes of %s\n"), size, reason); \
213 free (var); \
214 var = NULL; \
215 return 0; \
219 #define GET_DATA(offset, var, reason) \
220 if (fseek (file, offset, SEEK_SET)) \
222 error (_("Unable to seek to %x for %s\n"), offset, reason); \
223 return 0; \
225 else if (fread (& var, sizeof (var), 1, file) != 1) \
227 error (_("Unable to read data at %x for %s\n"), offset, reason); \
228 return 0; \
231 #ifdef ANSI_PROTOTYPES
232 static void
233 error (const char * message, ...)
235 va_list args;
237 fprintf (stderr, _("%s: Error: "), program_name);
238 va_start (args, message);
239 vfprintf (stderr, message, args);
240 va_end (args);
241 return;
244 static void
245 warn (const char * message, ...)
247 va_list args;
249 fprintf (stderr, _("%s: Warning: "), program_name);
250 va_start (args, message);
251 vfprintf (stderr, message, args);
252 va_end (args);
253 return;
255 #else
256 static void
257 error (va_alist)
258 va_dcl
260 char * message;
261 va_list args;
263 fprintf (stderr, _("%s: Error: "), program_name);
264 va_start (args);
265 message = va_arg (args, char *);
266 vfprintf (stderr, message, args);
267 va_end (args);
268 return;
271 static void
272 warn (va_alist)
273 va_dcl
275 char * message;
276 va_list args;
278 fprintf (stderr, _("%s: Warning: "), program_name);
279 va_start (args);
280 message = va_arg (args, char *);
281 vfprintf (stderr, message, args);
282 va_end (args);
283 return;
285 #endif
287 static unsigned long int
288 byte_get_little_endian (field, size)
289 unsigned char * field;
290 int size;
292 switch (size)
294 case 1:
295 return * field;
297 case 2:
298 return ((unsigned int) (field [0]))
299 | (((unsigned int) (field [1])) << 8);
301 case 4:
302 return ((unsigned long) (field [0]))
303 | (((unsigned long) (field [1])) << 8)
304 | (((unsigned long) (field [2])) << 16)
305 | (((unsigned long) (field [3])) << 24);
307 default:
308 error (_("Unhandled data length: %d\n"), size);
309 abort();
313 static unsigned long int
314 byte_get_big_endian (field, size)
315 unsigned char * field;
316 int size;
318 switch (size)
320 case 1:
321 return * field;
323 case 2:
324 return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
326 case 4:
327 return ((unsigned long) (field [3]))
328 | (((unsigned long) (field [2])) << 8)
329 | (((unsigned long) (field [1])) << 16)
330 | (((unsigned long) (field [0])) << 24);
332 default:
333 error (_("Unhandled data length: %d\n"), size);
334 abort();
339 /* Guess the relocation sized based on the sized commonly used by the specific machine. */
340 static int
341 guess_is_rela (e_machine)
342 unsigned long e_machine;
344 switch (e_machine)
346 /* Targets that use REL relocations. */
347 case EM_ARM:
348 case EM_386:
349 case EM_486:
350 case EM_960:
351 case EM_CYGNUS_M32R:
352 case EM_CYGNUS_D10V:
353 case EM_MIPS:
354 case EM_MIPS_RS4_BE:
355 return FALSE;
357 /* Targets that use RELA relocations. */
358 case EM_68K:
359 case EM_SPARC:
360 case EM_PPC:
361 case EM_CYGNUS_V850:
362 case EM_CYGNUS_D30V:
363 case EM_CYGNUS_MN10200:
364 case EM_CYGNUS_MN10300:
365 case EM_CYGNUS_FR30:
366 case EM_SH:
367 case EM_ALPHA:
368 case EM_MCORE:
369 return TRUE;
371 default:
372 warn (_("Don't know about relocations on this machine architecture\n"));
373 return FALSE;
377 /* Display the contents of the relocation data
378 found at the specified offset. */
379 static int
380 dump_relocations (file, rel_offset, rel_size, symtab, strtab, is_rela)
381 FILE * file;
382 unsigned long rel_offset;
383 unsigned long rel_size;
384 Elf_Internal_Sym * symtab;
385 char * strtab;
386 int is_rela;
388 unsigned int i;
389 Elf_Internal_Rel * rels;
390 Elf_Internal_Rela * relas;
393 if (is_rela == UNKNOWN)
394 is_rela = guess_is_rela (elf_header.e_machine);
396 if (is_rela)
398 Elf32_External_Rela * erelas;
400 GET_DATA_ALLOC (rel_offset, rel_size, erelas,
401 Elf32_External_Rela *, "relocs");
403 rel_size = rel_size / sizeof (Elf32_External_Rela);
405 relas = (Elf_Internal_Rela *) malloc (rel_size *
406 sizeof (Elf_Internal_Rela));
408 if (relas == NULL)
410 error(_("out of memory parsing relocs"));
411 return 0;
414 for (i = 0; i < rel_size; i++)
416 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
417 relas[i].r_info = BYTE_GET (erelas[i].r_info);
418 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
421 free (erelas);
423 rels = (Elf_Internal_Rel *) relas;
425 else
427 Elf32_External_Rel * erels;
428 unsigned long saved_rel_size = rel_size;
430 GET_DATA_ALLOC (rel_offset, rel_size, erels,
431 Elf32_External_Rel *, "relocs");
433 rel_size = rel_size / sizeof (Elf32_External_Rel);
435 rels = (Elf_Internal_Rel *) malloc (rel_size *
436 sizeof (Elf_Internal_Rel));
437 if (rels == NULL)
439 error(_("out of memory parsing relocs"));
440 return 0;
443 for (i = 0; i < rel_size; i++)
445 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
446 rels[i].r_info = BYTE_GET (erels[i].r_info);
449 free (erels);
451 relas = (Elf_Internal_Rela *) rels;
454 if (is_rela)
455 printf
456 (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n"));
457 else
458 printf
459 (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
461 for (i = 0; i < rel_size; i++)
463 const char * rtype;
464 unsigned long offset;
465 unsigned long info;
466 int symtab_index;
468 if (is_rela)
470 offset = relas [i].r_offset;
471 info = relas [i].r_info;
473 else
475 offset = rels [i].r_offset;
476 info = rels [i].r_info;
479 printf (" %8.8lx %5.5lx ", offset, info);
481 switch (elf_header.e_machine)
483 default:
484 rtype = NULL;
485 break;
487 case EM_CYGNUS_M32R:
488 rtype = elf_m32r_reloc_type (ELF32_R_TYPE (info));
489 break;
491 case EM_386:
492 case EM_486:
493 rtype = elf_i386_reloc_type (ELF32_R_TYPE (info));
494 break;
496 case EM_68K:
497 rtype = elf_m68k_reloc_type (ELF32_R_TYPE (info));
498 break;
500 case EM_960:
501 rtype = elf_i960_reloc_type (ELF32_R_TYPE (info));
502 break;
504 case EM_SPARC:
505 rtype = elf_sparc_reloc_type (ELF32_R_TYPE (info));
506 break;
508 case EM_CYGNUS_V850:
509 rtype = v850_reloc_type (ELF32_R_TYPE (info));
510 break;
512 case EM_CYGNUS_D10V:
513 rtype = elf_d10v_reloc_type (ELF32_R_TYPE (info));
514 break;
516 case EM_CYGNUS_D30V:
517 rtype = elf_d30v_reloc_type (ELF32_R_TYPE (info));
518 break;
520 case EM_SH:
521 rtype = elf_sh_reloc_type (ELF32_R_TYPE (info));
522 break;
524 case EM_CYGNUS_MN10300:
525 rtype = elf_mn10300_reloc_type (ELF32_R_TYPE (info));
526 break;
528 case EM_CYGNUS_MN10200:
529 rtype = elf_mn10200_reloc_type (ELF32_R_TYPE (info));
530 break;
532 case EM_CYGNUS_FR30:
533 rtype = elf_fr30_reloc_type (ELF32_R_TYPE (info));
534 break;
536 case EM_MCORE:
537 rtype = elf_mcore_reloc_type (ELF32_R_TYPE (info));
538 break;
540 case EM_PPC:
541 rtype = elf_ppc_reloc_type (ELF32_R_TYPE (info));
542 break;
544 case EM_MIPS:
545 case EM_MIPS_RS4_BE:
546 rtype = elf_mips_reloc_type (ELF32_R_TYPE (info));
547 break;
549 case EM_ALPHA:
550 rtype = elf_alpha_reloc_type (ELF32_R_TYPE (info));
551 break;
553 case EM_ARM:
554 rtype = elf_arm_reloc_type (ELF32_R_TYPE (info));
555 break;
557 case EM_CYGNUS_ARC:
558 rtype = elf_arc_reloc_type (ELF32_R_TYPE (info));
559 break;
561 case EM_PARISC:
562 rtype = elf32_hppa_reloc_type (ELF32_R_TYPE (info));
563 break;
566 if (rtype == NULL)
567 printf (_("unrecognised: %-7lx"), ELF32_R_TYPE (info));
568 else
569 printf ("%-21.21s", rtype);
571 symtab_index = ELF32_R_SYM (info);
573 if (symtab_index && symtab != NULL)
575 Elf_Internal_Sym * psym;
577 psym = symtab + symtab_index;
579 printf (" %08lx ", (unsigned long) psym->st_value);
581 if (psym->st_name == 0)
582 printf ("%-25.25s",
583 SECTION_NAME (section_headers + psym->st_shndx));
584 else if (strtab == NULL)
585 printf (_("<string table index %3ld>"), psym->st_name);
586 else
587 printf ("%-25.25s", strtab + psym->st_name);
589 if (is_rela)
590 printf (" + %lx", (unsigned long) relas [i].r_addend);
592 else if (is_rela)
593 printf ("%34c%lx", ' ', (unsigned long) relas[i].r_addend);
595 putchar ('\n');
598 free (relas);
600 return 1;
603 static const char *
604 get_mips_dynamic_type (type)
605 unsigned long type;
607 switch (type)
609 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
610 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
611 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
612 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
613 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
614 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
615 case DT_MIPS_MSYM: return "MIPS_MSYM";
616 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
617 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
618 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
619 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
620 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
621 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
622 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
623 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
624 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
625 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
626 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
627 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
628 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
629 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
630 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
631 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
632 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
633 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
634 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
635 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
636 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
637 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
638 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
639 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
640 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
641 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
642 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
643 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
644 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
645 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
646 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
647 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
648 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
649 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
650 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
651 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
652 default:
653 return NULL;
657 static const char *
658 get_dynamic_type (type)
659 unsigned long type;
661 static char buff [32];
663 switch (type)
665 case DT_NULL: return "NULL";
666 case DT_NEEDED: return "NEEDED";
667 case DT_PLTRELSZ: return "PLTRELSZ";
668 case DT_PLTGOT: return "PLTGOT";
669 case DT_HASH: return "HASH";
670 case DT_STRTAB: return "STRTAB";
671 case DT_SYMTAB: return "SYMTAB";
672 case DT_RELA: return "RELA";
673 case DT_RELASZ: return "RELASZ";
674 case DT_RELAENT: return "RELAENT";
675 case DT_STRSZ: return "STRSZ";
676 case DT_SYMENT: return "SYMENT";
677 case DT_INIT: return "INIT";
678 case DT_FINI: return "FINI";
679 case DT_SONAME: return "SONAME";
680 case DT_RPATH: return "RPATH";
681 case DT_SYMBOLIC: return "SYMBOLIC";
682 case DT_REL: return "REL";
683 case DT_RELSZ: return "RELSZ";
684 case DT_RELENT: return "RELENT";
685 case DT_PLTREL: return "PLTREL";
686 case DT_DEBUG: return "DEBUG";
687 case DT_TEXTREL: return "TEXTREL";
688 case DT_JMPREL: return "JMPREL";
689 case DT_BIND_NOW: return "BIND_NOW";
690 case DT_INIT_ARRAY: return "INIT_ARRAY";
691 case DT_FINI_ARRAY: return "FINI_ARRAY";
692 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
693 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
695 case DT_PLTPADSZ: return "PLTPADSZ";
696 case DT_MOVEENT: return "MOVEENT";
697 case DT_MOVESZ: return "MOVESZ";
698 case DT_FEATURE_1: return "FEATURE_1";
699 case DT_POSFLAG_1: return "POSFLAG_1";
700 case DT_SYMINSZ: return "SYMINSZ";
701 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
703 case DT_ADDRRNGLO: return "ADDRRNGLO";
704 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
706 case DT_VERSYM: return "VERSYM";
708 case DT_RELACOUNT: return "RELACOUNT";
709 case DT_RELCOUNT: return "RELCOUNT";
710 case DT_FLAGS_1: return "FLAGS_1";
711 case DT_VERDEF: return "VERDEF";
712 case DT_VERDEFNUM: return "VERDEFNUM";
713 case DT_VERNEED: return "VERNEED";
714 case DT_VERNEEDNUM: return "VERNEEDNUM";
716 case DT_AUXILIARY: return "AUXILARY";
717 case DT_USED: return "USED";
718 case DT_FILTER: return "FILTER";
720 default:
721 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
723 const char * result;
725 switch (elf_header.e_machine)
727 case EM_MIPS:
728 case EM_MIPS_RS4_BE:
729 result = get_mips_dynamic_type (type);
730 break;
731 default:
732 result = NULL;
733 break;
736 if (result != NULL)
737 return result;
739 sprintf (buff, _("Processor Specific: %lx"), type);
741 else if ((type >= DT_LOOS) && (type <= DT_HIOS))
742 sprintf (buff, _("Operating System specific: %lx"), type);
743 else
744 sprintf (buff, _("<unknown>: %lx"), type);
746 return buff;
750 static char *
751 get_file_type (e_type)
752 unsigned e_type;
754 static char buff [32];
756 switch (e_type)
758 case ET_NONE: return _("NONE (None)");
759 case ET_REL: return _("REL (Relocatable file)");
760 case ET_EXEC: return _("EXEC (Executable file)");
761 case ET_DYN: return _("DYN (Shared object file)");
762 case ET_CORE: return _("CORE (Core file)");
764 default:
765 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
766 sprintf (buff, _("Processor Specific: (%x)"), e_type);
767 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
768 sprintf (buff, _("OS Specific: (%x)"), e_type);
769 else
770 sprintf (buff, _("<unknown>: %x"), e_type);
771 return buff;
775 static char *
776 get_machine_name (e_machine)
777 unsigned e_machine;
779 static char buff [32];
781 switch (e_machine)
783 case EM_NONE: return _("None");
784 case EM_M32: return "WE32100";
785 case EM_SPARC: return "Sparc";
786 case EM_386: return "Intel 80386";
787 case EM_68K: return "MC68000";
788 case EM_88K: return "MC88000";
789 case EM_486: return "Intel 80486";
790 case EM_860: return "Intel 80860";
791 case EM_MIPS: return "MIPS R3000 big-endian";
792 case EM_S370: return "Amdahl";
793 case EM_MIPS_RS4_BE: return "MIPS R4000 big-endian";
794 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
795 case EM_PARISC: return "HPPA";
796 case EM_PPC_OLD: return "Power PC (old)";
797 case EM_SPARC32PLUS: return "Sparc v8+" ;
798 case EM_960: return "Intel 90860";
799 case EM_PPC: return "PowerPC";
800 case EM_V800: return "NEC V800";
801 case EM_FR20: return "Fujitsu FR20";
802 case EM_RH32: return "TRW RH32";
803 case EM_MCORE: return "MCORE";
804 case EM_ARM: return "ARM";
805 case EM_OLD_ALPHA: return "Digital Alpha (old)";
806 case EM_SH: return "Hitachi SH";
807 case EM_SPARCV9: return "Sparc v9";
808 case EM_TRICORE: return "Siemens Tricore";
809 case EM_ARC: return "Argonaut RISC Core";
810 case EM_H8_300: return "Hitachi H8/300";
811 case EM_H8_300H: return "Hitachi H8/300H";
812 case EM_H8S: return "Hitachi H8S";
813 case EM_H8_500: return "Hitachi H8/500";
814 case EM_IA_64: return "Intel Merced";
815 case EM_MIPS_X: return "Stanford MIPS-X";
816 case EM_COLDFIRE: return "Motorola Coldfire";
817 case EM_68HC12: return "Motorola M68HC12";
818 case EM_ALPHA: return "Alpha";
819 case EM_CYGNUS_D10V: return "d10v";
820 case EM_CYGNUS_D30V: return "d30v";
821 case EM_CYGNUS_ARC: return "Arc";
822 case EM_CYGNUS_M32R: return "Mitsubishi M32r";
823 case EM_CYGNUS_V850: return "NEC v850";
824 case EM_CYGNUS_MN10300: return "mn10300";
825 case EM_CYGNUS_MN10200: return "mn10200";
826 case EM_CYGNUS_FR30: return "Fujitsu FR30";
828 default:
829 sprintf (buff, _("<unknown>: %x"), e_machine);
830 return buff;
834 static char *
835 get_machine_flags (e_flags, e_machine)
836 unsigned e_flags;
837 unsigned e_machine;
839 static char buf [1024];
841 buf[0] = '\0';
842 if (e_flags)
844 switch (e_machine)
846 default:
847 break;
849 case EM_68K:
850 if (e_flags & EF_CPU32)
851 strcat (buf, ", cpu32");
852 break;
854 case EM_PPC:
855 if (e_flags & EF_PPC_EMB)
856 strcat (buf, ", emb");
858 if (e_flags & EF_PPC_RELOCATABLE)
859 strcat (buf, ", relocatable");
861 if (e_flags & EF_PPC_RELOCATABLE_LIB)
862 strcat (buf, ", relocatable-lib");
863 break;
865 case EM_CYGNUS_V850:
866 switch (e_flags & EF_V850_ARCH)
868 case E_V850E_ARCH:
869 strcat (buf, ", v850e");
870 break;
871 case E_V850EA_ARCH:
872 strcat (buf, ", v850ea");
873 break;
874 case E_V850_ARCH:
875 strcat (buf, ", v850");
876 break;
877 default:
878 strcat (buf, ", unknown v850 architecture variant");
879 break;
881 break;
883 case EM_CYGNUS_M32R:
884 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
885 strcat (buf, ", m32r");
887 break;
889 case EM_MIPS:
890 case EM_MIPS_RS4_BE:
891 if (e_flags & EF_MIPS_NOREORDER)
892 strcat (buf, ", noreorder");
894 if (e_flags & EF_MIPS_PIC)
895 strcat (buf, ", pic");
897 if (e_flags & EF_MIPS_CPIC)
898 strcat (buf, ", cpic");
900 if (e_flags & EF_MIPS_ABI2)
901 strcat (buf, ", abi2");
903 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
904 strcat (buf, ", mips1");
906 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
907 strcat (buf, ", mips2");
909 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
910 strcat (buf, ", mips3");
912 if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
913 strcat (buf, ", mips4");
914 break;
918 return buf;
921 static char *
922 get_machine_data (e_data)
923 unsigned e_data;
925 static char buff [32];
927 switch (e_data)
929 case ELFDATA2LSB: return _("ELFDATA2LSB (little endian)");
930 case ELFDATA2MSB: return _("ELFDATA2MSB (big endian)");
931 default:
932 sprintf (buff, _("<unknown>: %x"), e_data);
933 return buff;
937 static const char *
938 get_mips_segment_type (type)
939 unsigned long type;
941 switch (type)
943 case PT_MIPS_REGINFO:
944 return "REGINFO";
945 case PT_MIPS_RTPROC:
946 return "RTPROC";
947 case PT_MIPS_OPTIONS:
948 return "OPTIONS";
949 default:
950 break;
953 return NULL;
956 static const char *
957 get_segment_type (p_type)
958 unsigned long p_type;
960 static char buff [32];
962 switch (p_type)
964 case PT_NULL: return "NULL";
965 case PT_LOAD: return "LOAD";
966 case PT_DYNAMIC: return "DYNAMIC";
967 case PT_INTERP: return "INTERP";
968 case PT_NOTE: return "NOTE";
969 case PT_SHLIB: return "SHLIB";
970 case PT_PHDR: return "PHDR";
972 default:
973 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
975 const char * result;
977 switch (elf_header.e_machine)
979 case EM_MIPS:
980 case EM_MIPS_RS4_BE:
981 result = get_mips_segment_type (p_type);
982 break;
983 default:
984 result = NULL;
985 break;
988 if (result != NULL)
989 return result;
991 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
993 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
994 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
995 else
996 sprintf (buff, _("<unknown>: %lx"), p_type);
998 return buff;
1002 static const char *
1003 get_mips_section_type_name (sh_type)
1004 unsigned int sh_type;
1006 switch (sh_type)
1008 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1009 case SHT_MIPS_MSYM: return "MIPS_MSYM";
1010 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1011 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
1012 case SHT_MIPS_UCODE: return "MIPS_UCODE";
1013 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
1014 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
1015 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
1016 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
1017 case SHT_MIPS_RELD: return "MIPS_RELD";
1018 case SHT_MIPS_IFACE: return "MIPS_IFACE";
1019 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
1020 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1021 case SHT_MIPS_SHDR: return "MIPS_SHDR";
1022 case SHT_MIPS_FDESC: return "MIPS_FDESC";
1023 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
1024 case SHT_MIPS_DENSE: return "MIPS_DENSE";
1025 case SHT_MIPS_PDESC: return "MIPS_PDESC";
1026 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
1027 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
1028 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
1029 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
1030 case SHT_MIPS_LINE: return "MIPS_LINE";
1031 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
1032 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
1033 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
1034 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
1035 case SHT_MIPS_DWARF: return "MIPS_DWARF";
1036 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
1037 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1038 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
1039 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
1040 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
1041 case SHT_MIPS_XLATE: return "MIPS_XLATE";
1042 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
1043 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
1044 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
1045 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
1046 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1047 default:
1048 break;
1050 return NULL;
1053 static const char *
1054 get_section_type_name (sh_type)
1055 unsigned int sh_type;
1057 static char buff [32];
1059 switch (sh_type)
1061 case SHT_NULL: return "NULL";
1062 case SHT_PROGBITS: return "PROGBITS";
1063 case SHT_SYMTAB: return "SYMTAB";
1064 case SHT_STRTAB: return "STRTAB";
1065 case SHT_RELA: return "RELA";
1066 case SHT_HASH: return "HASH";
1067 case SHT_DYNAMIC: return "DYNAMIC";
1068 case SHT_NOTE: return "NOTE";
1069 case SHT_NOBITS: return "NOBITS";
1070 case SHT_REL: return "REL";
1071 case SHT_SHLIB: return "SHLIB";
1072 case SHT_DYNSYM: return "DYNSYM";
1073 case SHT_GNU_verdef: return "VERDEF";
1074 case SHT_GNU_verneed: return "VERNEED";
1075 case SHT_GNU_versym: return "VERSYM";
1076 case 0x6ffffff0: return "VERSYM";
1077 case 0x6ffffffc: return "VERDEF";
1078 case 0x7ffffffd: return "AUXILIARY";
1079 case 0x7fffffff: return "FILTER";
1081 default:
1082 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1084 const char * result;
1086 switch (elf_header.e_machine)
1088 case EM_MIPS:
1089 case EM_MIPS_RS4_BE:
1090 result = get_mips_section_type_name (sh_type);
1091 break;
1092 default:
1093 result = NULL;
1094 break;
1097 if (result != NULL)
1098 return result;
1100 sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1102 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1103 sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1104 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1105 sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1106 else
1107 sprintf (buff, _("<unknown>: %x"), sh_type);
1109 return buff;
1113 struct option options [] =
1115 {"all", no_argument, 0, 'a'},
1116 {"file-header", no_argument, 0, 'h'},
1117 {"program-headers", no_argument, 0, 'l'},
1118 {"headers", no_argument, 0, 'e'},
1119 {"histogram", no_argument, & do_histogram, 1},
1120 {"segments", no_argument, 0, 'l'},
1121 {"sections", no_argument, 0, 'S'},
1122 {"section-headers", no_argument, 0, 'S'},
1123 {"symbols", no_argument, 0, 's'},
1124 {"syms", no_argument, 0, 's'},
1125 {"relocs", no_argument, 0, 'r'},
1126 {"dynamic", no_argument, 0, 'd'},
1127 {"version-info", no_argument, 0, 'V'},
1128 {"use-dynamic", no_argument, 0, 'D'},
1129 {"hex-dump", required_argument, 0, 'x'},
1130 {"debug-dump", optional_argument, 0, 'w'},
1131 #ifdef SUPPORT_DISASSEMBLY
1132 {"instruction-dump", required_argument, 0, 'i'},
1133 #endif
1135 {"version", no_argument, 0, 'v'},
1136 {"help", no_argument, 0, 'H'},
1137 {0, no_argument, 0, 0}
1140 static void
1141 usage ()
1143 fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1144 fprintf (stdout, _(" Options are:\n"));
1145 fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n"));
1146 fprintf (stdout, _(" -h or --file-header Display the ELF file header\n"));
1147 fprintf (stdout, _(" -l or --program-headers or --segments\n"));
1148 fprintf (stdout, _(" Display the program headers\n"));
1149 fprintf (stdout, _(" -S or --section-headers or --sections\n"));
1150 fprintf (stdout, _(" Display the sections' header\n"));
1151 fprintf (stdout, _(" -e or --headers Equivalent to: -h -l -S\n"));
1152 fprintf (stdout, _(" -s or --syms or --symbols Display the symbol table\n"));
1153 fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n"));
1154 fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n"));
1155 fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n"));
1156 fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n"));
1157 fprintf (stdout, _(" -x <number> or --hex-dump=<number>\n"));
1158 fprintf (stdout, _(" Dump the contents of section <number>\n"));
1159 fprintf (stdout, _(" -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1160 fprintf (stdout, _(" Display the contents of DWARF2 debug sections\n"));
1161 #ifdef SUPPORT_DISASSEMBLY
1162 fprintf (stdout, _(" -i <number> or --instruction-dump=<number>\n"));
1163 fprintf (stdout, _(" Disassemble the contents of section <number>\n"));
1164 #endif
1165 fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n"));
1166 fprintf (stdout, _(" -v or --version Display the version number of readelf\n"));
1167 fprintf (stdout, _(" -H or --help Display this information\n"));
1168 fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1170 exit (0);
1173 static void
1174 request_dump (section, type)
1175 unsigned int section;
1176 char type;
1178 if (section >= num_dump_sects)
1180 char * new_dump_sects;
1182 new_dump_sects = (char *) calloc (section + 1, 1);
1184 if (new_dump_sects == NULL)
1185 error (_("Out of memory allocating dump request table."));
1186 else
1188 /* Copy current flag settings. */
1189 memcpy (new_dump_sects, dump_sects, num_dump_sects);
1191 free (dump_sects);
1193 dump_sects = new_dump_sects;
1194 num_dump_sects = section + 1;
1198 if (dump_sects)
1199 dump_sects [section] |= type;
1201 return;
1204 static void
1205 parse_args (argc, argv)
1206 int argc;
1207 char ** argv;
1209 int c;
1211 if (argc < 2)
1212 usage ();
1214 while ((c = getopt_long
1215 (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
1217 char * cp;
1218 int section;
1220 switch (c)
1222 case 0:
1223 /* Long options. */
1224 break;
1225 case 'H':
1226 usage ();
1227 break;
1229 case 'a':
1230 do_syms ++;
1231 do_reloc ++;
1232 do_dynamic ++;
1233 do_header ++;
1234 do_sections ++;
1235 do_segments ++;
1236 do_version ++;
1237 do_histogram ++;
1238 break;
1239 case 'e':
1240 do_header ++;
1241 do_sections ++;
1242 do_segments ++;
1243 break;
1244 case 'D':
1245 do_using_dynamic ++;
1246 break;
1247 case 'r':
1248 do_reloc ++;
1249 break;
1250 case 'h':
1251 do_header ++;
1252 break;
1253 case 'l':
1254 do_segments ++;
1255 break;
1256 case 's':
1257 do_syms ++;
1258 break;
1259 case 'S':
1260 do_sections ++;
1261 break;
1262 case 'd':
1263 do_dynamic ++;
1264 break;
1265 case 'x':
1266 do_dump ++;
1267 section = strtoul (optarg, & cp, 0);
1268 if (! * cp && section >= 0)
1270 request_dump (section, HEX_DUMP);
1271 break;
1273 goto oops;
1274 case 'w':
1275 do_dump ++;
1276 if (optarg == 0)
1277 do_debugging = 1;
1278 else
1280 do_debugging = 0;
1281 switch (optarg[0])
1283 case 'i':
1284 case 'I':
1285 do_debug_info = 1;
1286 break;
1288 case 'a':
1289 case 'A':
1290 do_debug_abbrevs = 1;
1291 break;
1293 case 'l':
1294 case 'L':
1295 do_debug_lines = 1;
1296 break;
1298 case 'p':
1299 case 'P':
1300 do_debug_pubnames = 1;
1301 break;
1303 case 'r':
1304 case 'R':
1305 do_debug_aranges = 1;
1306 break;
1308 default:
1309 warn (_("Unrecognised debug option '%s'\n"), optarg);
1310 break;
1313 break;
1314 #ifdef SUPPORT_DISASSEMBLY
1315 case 'i':
1316 do_dump ++;
1317 section = strtoul (optarg, & cp, 0);
1318 if (! * cp && section >= 0)
1320 request_dump (section, DISASS_DUMP);
1321 break;
1323 goto oops;
1324 #endif
1325 case 'v':
1326 print_version (program_name);
1327 break;
1328 case 'V':
1329 do_version ++;
1330 break;
1331 default:
1332 oops:
1333 /* xgettext:c-format */
1334 error (_("Invalid option '-%c'\n"), c);
1335 /* Drop through. */
1336 case '?':
1337 usage ();
1341 if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1342 && !do_segments && !do_header && !do_dump && !do_version
1343 && !do_histogram && !do_debugging)
1344 usage ();
1345 else if (argc < 3)
1347 warn (_("Nothing to do.\n"));
1348 usage();
1352 static const char *
1353 get_elf_class (elf_class)
1354 unsigned char elf_class;
1356 static char buff [32];
1358 switch (elf_class)
1360 case ELFCLASSNONE: return _("none");
1361 case ELFCLASS32: return _("ELF32");
1362 case ELFCLASS64: return _("ELF64");
1363 default:
1364 sprintf (buff, _("<unknown: %lx>"), elf_class);
1365 return buff;
1369 static const char *
1370 get_data_encoding (encoding)
1371 unsigned char encoding;
1373 static char buff [32];
1375 switch (encoding)
1377 case ELFDATANONE: return _("none");
1378 case ELFDATA2LSB: return _("2's complement, little endian");
1379 case ELFDATA2MSB: return _("2's complement, big endian");
1380 default:
1381 sprintf (buff, _("<unknown: %lx>"), encoding);
1382 return buff;
1386 static const char *
1387 get_osabi_name (osabi)
1388 unsigned char osabi;
1390 static char buff [32];
1392 switch (osabi)
1394 case ELFOSABI_SYSV: return _("UNIX - System V");
1395 case ELFOSABI_HPUX: return _("UNIX - HP-UX");
1396 case ELFOSABI_STANDALONE: return _("Standalone App");
1397 default:
1398 sprintf (buff, _("<unknown: %lx>"), osabi);
1399 return buff;
1403 /* Decode the data held in 'elf_header'. */
1404 static int
1405 process_file_header ()
1407 if ( elf_header.e_ident [EI_MAG0] != ELFMAG0
1408 || elf_header.e_ident [EI_MAG1] != ELFMAG1
1409 || elf_header.e_ident [EI_MAG2] != ELFMAG2
1410 || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1412 error
1413 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1414 return 0;
1417 if (do_header)
1419 int i;
1421 printf (_("ELF Header:\n"));
1422 printf (_(" Magic: "));
1423 for (i = 0; i < EI_NIDENT; i ++)
1424 printf ("%2.2x ", elf_header.e_ident [i]);
1425 printf ("\n");
1426 printf (_(" Class: %s\n"),
1427 get_elf_class (elf_header.e_ident [EI_CLASS]));
1428 printf (_(" Data: %s\n"),
1429 get_data_encoding (elf_header.e_ident [EI_DATA]));
1430 printf (_(" Version: %d %s\n"),
1431 elf_header.e_ident [EI_VERSION],
1432 elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
1433 elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown: %lx>" : "",
1434 elf_header.e_ident [EI_VERSION]);
1435 printf (_(" OS/ABI: %s\n"),
1436 get_osabi_name (elf_header.e_ident [EI_OSABI]));
1437 printf (_(" ABI Version: %d\n"),
1438 elf_header.e_ident [EI_ABIVERSION]);
1439 printf (_(" Type: %s\n"),
1440 get_file_type (elf_header.e_type));
1441 printf (_(" Machine: %s\n"),
1442 get_machine_name (elf_header.e_machine));
1443 printf (_(" Version: 0x%lx\n"),
1444 (unsigned long) elf_header.e_version);
1445 printf (_(" Data: %s\n"),
1446 get_machine_data (elf_header.e_ident [EI_DATA]));
1447 printf (_(" Entry point address: 0x%lx\n"),
1448 (unsigned long) elf_header.e_entry);
1449 printf (_(" Start of program headers: %ld (bytes into file)\n"),
1450 (long) elf_header.e_phoff);
1451 printf (_(" Start of section headers: %ld (bytes into file)\n"),
1452 (long) elf_header.e_shoff);
1453 printf (_(" Flags: 0x%lx%s\n"),
1454 (unsigned long) elf_header.e_flags,
1455 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1456 printf (_(" Size of this header: %ld (bytes)\n"),
1457 (long) elf_header.e_ehsize);
1458 printf (_(" Size of program headers: %ld (bytes)\n"),
1459 (long) elf_header.e_phentsize);
1460 printf (_(" Number of program headers: %ld\n"),
1461 (long) elf_header.e_phnum);
1462 printf (_(" Size of section headers: %ld (bytes)\n"),
1463 (long) elf_header.e_shentsize);
1464 printf (_(" Number of section headers: %ld\n"),
1465 (long) elf_header.e_shnum);
1466 printf (_(" Section header string table index: %ld\n"),
1467 (long) elf_header.e_shstrndx);
1470 /* Test class after dumping header so that at least the header can be
1471 display on 64 bit binaries. */
1473 binary_class = elf_header.e_ident [EI_CLASS];
1474 if (binary_class != ELFCLASS32)
1476 error (_("Not a 32 bit ELF file\n"));
1477 return 0;
1480 return 1;
1484 static int
1485 process_program_headers (file)
1486 FILE * file;
1488 Elf32_External_Phdr * phdrs;
1489 Elf32_Internal_Phdr * program_headers;
1490 Elf32_Internal_Phdr * segment;
1491 unsigned int i;
1493 if (elf_header.e_phnum == 0)
1495 if (do_segments)
1496 printf (_("\nThere are no program headers in this file.\n"));
1497 return 1;
1500 if (do_segments && !do_header)
1502 printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1503 printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1504 printf (_("There are %d program headers, starting at offset %lx:\n"),
1505 elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1508 GET_DATA_ALLOC (elf_header.e_phoff,
1509 elf_header.e_phentsize * elf_header.e_phnum,
1510 phdrs, Elf32_External_Phdr *, "program headers");
1512 program_headers = (Elf32_Internal_Phdr *) malloc
1513 (elf_header.e_phnum * sizeof (Elf32_Internal_Phdr));
1515 if (program_headers == NULL)
1517 error (_("Out of memory\n"));
1518 return 0;
1521 for (i = 0, segment = program_headers;
1522 i < elf_header.e_phnum;
1523 i ++, segment ++)
1525 segment->p_type = BYTE_GET (phdrs[i].p_type);
1526 segment->p_offset = BYTE_GET (phdrs[i].p_offset);
1527 segment->p_vaddr = BYTE_GET (phdrs[i].p_vaddr);
1528 segment->p_paddr = BYTE_GET (phdrs[i].p_paddr);
1529 segment->p_filesz = BYTE_GET (phdrs[i].p_filesz);
1530 segment->p_memsz = BYTE_GET (phdrs[i].p_memsz);
1531 segment->p_flags = BYTE_GET (phdrs[i].p_flags);
1532 segment->p_align = BYTE_GET (phdrs[i].p_align);
1535 free (phdrs);
1537 if (do_segments)
1539 printf
1540 (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1541 printf
1542 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
1545 loadaddr = -1;
1546 dynamic_addr = 0;
1547 dynamic_size = 0;
1549 for (i = 0, segment = program_headers;
1550 i < elf_header.e_phnum;
1551 i ++, segment ++)
1553 if (do_segments)
1555 printf (" %-11.11s ", get_segment_type (segment->p_type));
1556 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1557 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1558 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1559 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1560 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1561 printf ("%c%c%c ",
1562 (segment->p_flags & PF_R ? 'R' : ' '),
1563 (segment->p_flags & PF_W ? 'W' : ' '),
1564 (segment->p_flags & PF_X ? 'E' : ' '));
1565 printf ("%#lx", (unsigned long) segment->p_align);
1568 switch (segment->p_type)
1570 case PT_LOAD:
1571 if (loadaddr == -1)
1572 loadaddr = (segment->p_vaddr & 0xfffff000)
1573 - (segment->p_offset & 0xfffff000);
1574 break;
1576 case PT_DYNAMIC:
1577 if (dynamic_addr)
1578 error (_("more than one dynamic segment\n"));
1580 dynamic_addr = segment->p_offset;
1581 dynamic_size = segment->p_filesz;
1582 break;
1584 case PT_INTERP:
1585 if (fseek (file, segment->p_offset, SEEK_SET))
1586 error (_("Unable to find program interpreter name\n"));
1587 else
1589 program_interpreter[0] = 0;
1590 fscanf (file, "%63s", program_interpreter);
1592 if (do_segments)
1593 printf (_("\n [Requesting program interpreter: %s]"),
1594 program_interpreter);
1596 break;
1599 if (do_segments)
1600 putc ('\n', stdout);
1603 if (loadaddr == -1)
1605 /* Very strange. */
1606 loadaddr = 0;
1609 if (do_segments && section_headers != NULL)
1611 printf (_("\n Section to Segment mapping:\n"));
1612 printf (_(" Segment Sections...\n"));
1614 assert (string_table != NULL);
1616 for (i = 0; i < elf_header.e_phnum; i++)
1618 int j;
1619 Elf32_Internal_Shdr * section;
1621 segment = program_headers + i;
1622 section = section_headers;
1624 printf (" %2.2d ", i);
1626 for (j = 0; j < elf_header.e_shnum; j++, section ++)
1628 if (section->sh_size > 0
1629 /* Compare allocated sections by VMA, unallocated
1630 sections by file offset. */
1631 && (section->sh_flags & SHF_ALLOC
1632 ? (section->sh_addr >= segment->p_vaddr
1633 && section->sh_addr + section->sh_size
1634 <= segment->p_vaddr + segment->p_memsz)
1635 : (section->sh_offset >= segment->p_offset
1636 && (section->sh_offset + section->sh_size
1637 <= segment->p_offset + segment->p_filesz))))
1638 printf ("%s ", SECTION_NAME (section));
1641 putc ('\n',stdout);
1645 free (program_headers);
1647 return 1;
1651 static int
1652 get_section_headers (file)
1653 FILE * file;
1655 Elf32_External_Shdr * shdrs;
1656 Elf32_Internal_Shdr * internal;
1657 unsigned int i;
1659 GET_DATA_ALLOC (elf_header.e_shoff,
1660 elf_header.e_shentsize * elf_header.e_shnum,
1661 shdrs, Elf32_External_Shdr *, "section headers");
1663 section_headers = (Elf32_Internal_Shdr *) malloc
1664 (elf_header.e_shnum * sizeof (Elf32_Internal_Shdr));
1666 if (section_headers == NULL)
1668 error (_("Out of memory\n"));
1669 return 0;
1672 for (i = 0, internal = section_headers;
1673 i < elf_header.e_shnum;
1674 i ++, internal ++)
1676 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
1677 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
1678 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
1679 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
1680 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
1681 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
1682 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
1683 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
1684 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1685 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
1688 free (shdrs);
1690 return 1;
1693 static Elf_Internal_Sym *
1694 get_elf_symbols (file, offset, number)
1695 FILE * file;
1696 unsigned long offset;
1697 unsigned long number;
1699 Elf32_External_Sym * esyms;
1700 Elf_Internal_Sym * isyms;
1701 Elf_Internal_Sym * psym;
1702 unsigned int j;
1704 GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1705 esyms, Elf32_External_Sym *, "symbols");
1707 isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1709 if (isyms == NULL)
1711 error (_("Out of memory\n"));
1712 free (esyms);
1714 return NULL;
1717 for (j = 0, psym = isyms;
1718 j < number;
1719 j ++, psym ++)
1721 psym->st_name = BYTE_GET (esyms[j].st_name);
1722 psym->st_value = BYTE_GET (esyms[j].st_value);
1723 psym->st_size = BYTE_GET (esyms[j].st_size);
1724 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1725 psym->st_info = BYTE_GET (esyms[j].st_info);
1726 psym->st_other = BYTE_GET (esyms[j].st_other);
1729 free (esyms);
1731 return isyms;
1734 static int
1735 process_section_headers (file)
1736 FILE * file;
1738 Elf32_Internal_Shdr * section;
1739 int i;
1741 section_headers = NULL;
1743 if (elf_header.e_shnum == 0)
1745 if (do_sections)
1746 printf (_("\nThere are no sections in this file.\n"));
1748 return 1;
1751 if (do_sections && !do_header)
1752 printf (_("There are %d section headers, starting at offset %lx:\n"),
1753 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
1755 if (! get_section_headers (file))
1756 return 0;
1758 /* Read in the string table, so that we have names to display. */
1759 section = section_headers + elf_header.e_shstrndx;
1761 if (section->sh_size != 0)
1763 unsigned long string_table_offset;
1765 string_table_offset = section->sh_offset;
1767 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1768 string_table, char *, "string table");
1771 /* Scan the sections for the dynamic symbol table
1772 and dynamic string table and debug sections. */
1773 dynamic_symbols = NULL;
1774 dynamic_strings = NULL;
1775 dynamic_syminfo = NULL;
1776 for (i = 0, section = section_headers;
1777 i < elf_header.e_shnum;
1778 i ++, section ++)
1780 char * name = SECTION_NAME (section);
1782 if (section->sh_type == SHT_DYNSYM)
1784 if (dynamic_symbols != NULL)
1786 error (_("File contains multiple dynamic symbol tables\n"));
1787 continue;
1790 dynamic_symbols = get_elf_symbols
1791 (file, section->sh_offset,
1792 section->sh_size / section->sh_entsize);
1794 else if (section->sh_type == SHT_STRTAB
1795 && strcmp (name, ".dynstr") == 0)
1797 if (dynamic_strings != NULL)
1799 error (_("File contains multiple dynamic string tables\n"));
1800 continue;
1803 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
1804 dynamic_strings, char *, "dynamic strings");
1806 else if ((do_debugging || do_debug_info || do_debug_abbrevs
1807 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
1808 && strncmp (name, ".debug_", 7) == 0)
1810 name += 7;
1812 if (do_debugging
1813 || (do_debug_info && (strcmp (name, "info") == 0))
1814 || (do_debug_abbrevs && (strcmp (name, "abbrev") == 0))
1815 || (do_debug_lines && (strcmp (name, "line") == 0))
1816 || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
1817 || (do_debug_aranges && (strcmp (name, "aranges") == 0))
1819 request_dump (i, DEBUG_DUMP);
1823 if (! do_sections)
1824 return 1;
1826 printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
1827 printf
1828 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
1830 for (i = 0, section = section_headers;
1831 i < elf_header.e_shnum;
1832 i ++, section ++)
1834 printf (" [%2d] %-17.17s %-15.15s ",
1836 SECTION_NAME (section),
1837 get_section_type_name (section->sh_type));
1839 printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
1840 (unsigned long) section->sh_addr,
1841 (unsigned long) section->sh_offset,
1842 (unsigned long) section->sh_size,
1843 (unsigned long) section->sh_entsize);
1845 printf (" %c%c%c %2ld %3lx %ld\n",
1846 (section->sh_flags & SHF_WRITE ? 'W' : ' '),
1847 (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
1848 (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
1849 (unsigned long) section->sh_link,
1850 (unsigned long) section->sh_info,
1851 (unsigned long) section->sh_addralign);
1854 return 1;
1857 /* Process the reloc section. */
1858 static int
1859 process_relocs (file)
1860 FILE * file;
1862 unsigned long rel_size;
1863 unsigned long rel_offset;
1866 if (!do_reloc)
1867 return 1;
1869 if (do_using_dynamic)
1871 int is_rela;
1873 rel_size = 0;
1874 rel_offset = 0;
1876 if (dynamic_info[DT_REL])
1878 rel_offset = dynamic_info[DT_REL];
1879 rel_size = dynamic_info[DT_RELSZ];
1880 is_rela = FALSE;
1882 else if (dynamic_info [DT_RELA])
1884 rel_offset = dynamic_info[DT_RELA];
1885 rel_size = dynamic_info[DT_RELASZ];
1886 is_rela = TRUE;
1888 else if (dynamic_info[DT_JMPREL])
1890 rel_offset = dynamic_info[DT_JMPREL];
1891 rel_size = dynamic_info[DT_PLTRELSZ];
1892 switch (dynamic_info[DT_PLTREL])
1894 case DT_REL:
1895 is_rela = FALSE;
1896 break;
1897 case DT_RELA:
1898 is_rela = TRUE;
1899 break;
1900 default:
1901 is_rela = UNKNOWN;
1902 break;
1906 if (rel_size)
1908 printf
1909 (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
1910 rel_offset, rel_size);
1912 dump_relocations (file, rel_offset - loadaddr, rel_size,
1913 dynamic_symbols, dynamic_strings, is_rela);
1915 else
1916 printf (_("\nThere are no dynamic relocations in this file.\n"));
1918 else
1920 Elf32_Internal_Shdr * section;
1921 unsigned long i;
1922 int found = 0;
1924 for (i = 0, section = section_headers;
1925 i < elf_header.e_shnum;
1926 i++, section ++)
1928 if ( section->sh_type != SHT_RELA
1929 && section->sh_type != SHT_REL)
1930 continue;
1932 rel_offset = section->sh_offset;
1933 rel_size = section->sh_size;
1935 if (rel_size)
1937 Elf32_Internal_Shdr * strsec;
1938 Elf32_Internal_Shdr * symsec;
1939 Elf_Internal_Sym * symtab;
1940 char * strtab;
1941 int is_rela;
1943 printf (_("\nRelocation section "));
1945 if (string_table == NULL)
1947 printf ("%d", section->sh_name);
1949 else
1951 printf ("'%s'", SECTION_NAME (section));
1954 printf (_(" at offset 0x%lx contains %lu entries:\n"),
1955 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
1957 symsec = section_headers + section->sh_link;
1959 symtab = get_elf_symbols (file, symsec->sh_offset,
1960 symsec->sh_size / symsec->sh_entsize);
1962 if (symtab == NULL)
1963 continue;
1965 strsec = section_headers + symsec->sh_link;
1967 GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
1968 char *, "string table");
1970 is_rela = section->sh_type == SHT_RELA;
1972 dump_relocations (file, rel_offset, rel_size, symtab, strtab, is_rela);
1974 free (strtab);
1975 free (symtab);
1977 found = 1;
1981 if (! found)
1982 printf (_("\nThere are no relocations in this file.\n"));
1985 return 1;
1989 static void
1990 dynamic_segment_mips_val (entry)
1991 Elf_Internal_Dyn * entry;
1993 switch (entry->d_tag)
1995 case DT_MIPS_FLAGS:
1996 if (entry->d_un.d_val == 0)
1997 printf ("NONE\n");
1998 else
2000 static const char * opts[] =
2002 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2003 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2004 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2005 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2006 "RLD_ORDER_SAFE"
2008 unsigned int cnt;
2009 int first = 1;
2010 for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2011 if (entry->d_un.d_val & (1 << cnt))
2013 printf ("%s%s", first ? "" : " ", opts[cnt]);
2014 first = 0;
2016 puts ("");
2018 break;
2020 case DT_MIPS_IVERSION:
2021 if (dynamic_strings != NULL)
2022 printf ("Interface Version: %s\n",
2023 dynamic_strings + entry->d_un.d_val);
2024 else
2025 printf ("%ld\n", (long) entry->d_un.d_ptr);
2026 break;
2028 case DT_MIPS_TIME_STAMP:
2030 char timebuf[20];
2031 time_t time = entry->d_un.d_val;
2032 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
2033 printf ("Time Stamp: %s\n", timebuf);
2035 break;
2037 case DT_MIPS_RLD_VERSION:
2038 case DT_MIPS_LOCAL_GOTNO:
2039 case DT_MIPS_CONFLICTNO:
2040 case DT_MIPS_LIBLISTNO:
2041 case DT_MIPS_SYMTABNO:
2042 case DT_MIPS_UNREFEXTNO:
2043 case DT_MIPS_HIPAGENO:
2044 case DT_MIPS_DELTA_CLASS_NO:
2045 case DT_MIPS_DELTA_INSTANCE_NO:
2046 case DT_MIPS_DELTA_RELOC_NO:
2047 case DT_MIPS_DELTA_SYM_NO:
2048 case DT_MIPS_DELTA_CLASSSYM_NO:
2049 case DT_MIPS_COMPACT_SIZE:
2050 printf ("%ld\n", (long) entry->d_un.d_ptr);
2051 break;
2053 default:
2054 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2058 /* Parse the dynamic segment */
2059 static int
2060 process_dynamic_segment (file)
2061 FILE * file;
2063 Elf_Internal_Dyn * entry;
2064 Elf32_External_Dyn * edyn;
2065 unsigned int i;
2067 if (dynamic_size == 0)
2069 if (do_dynamic)
2070 printf (_("\nThere is no dynamic segment in this file.\n"));
2072 return 1;
2075 GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2076 edyn, Elf32_External_Dyn *, "dynamic segment");
2078 /* SGI's ELF has more than one section in the DYNAMIC segment. Determine
2079 how large .dynamic is now. We can do this even before the byte
2080 swapping since the DT_NULL tag is recognizable. */
2081 dynamic_size = 0;
2082 while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
2085 dynamic_segment = (Elf_Internal_Dyn *)
2086 malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2088 if (dynamic_segment == NULL)
2090 error (_("Out of memory\n"));
2091 free (edyn);
2092 return 0;
2095 for (i = 0, entry = dynamic_segment;
2096 i < dynamic_size;
2097 i ++, entry ++)
2099 entry->d_tag = BYTE_GET (edyn [i].d_tag);
2100 entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2103 free (edyn);
2105 /* Find the appropriate symbol table. */
2106 if (dynamic_symbols == NULL)
2108 for (i = 0, entry = dynamic_segment;
2109 i < dynamic_size;
2110 ++i, ++ entry)
2112 unsigned long offset;
2113 long num_syms;
2115 if (entry->d_tag != DT_SYMTAB)
2116 continue;
2118 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2120 /* Since we do not know how big the symbol table is,
2121 we default to reading in the entire file (!) and
2122 processing that. This is overkill, I know, but it
2123 should work. */
2125 offset = entry->d_un.d_val - loadaddr;
2127 if (fseek (file, 0, SEEK_END))
2128 error (_("Unable to seek to end of file!"));
2130 num_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2132 if (num_syms < 1)
2134 error (_("Unable to determine the number of symbols to load\n"));
2135 continue;
2138 dynamic_symbols = get_elf_symbols (file, offset, num_syms);
2142 /* Similarly find a string table. */
2143 if (dynamic_strings == NULL)
2145 for (i = 0, entry = dynamic_segment;
2146 i < dynamic_size;
2147 ++i, ++ entry)
2149 unsigned long offset;
2150 long str_tab_len;
2152 if (entry->d_tag != DT_STRTAB)
2153 continue;
2155 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2157 /* Since we do not know how big the string table is,
2158 we default to reading in the entire file (!) and
2159 processing that. This is overkill, I know, but it
2160 should work. */
2162 offset = entry->d_un.d_val - loadaddr;
2163 if (fseek (file, 0, SEEK_END))
2164 error (_("Unable to seek to end of file\n"));
2165 str_tab_len = ftell (file) - offset;
2167 if (str_tab_len < 1)
2169 error
2170 (_("Unable to determine the length of the dynamic string table\n"));
2171 continue;
2174 GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2175 "dynamic string table");
2177 break;
2181 /* And find the syminfo section if available. */
2182 if (dynamic_syminfo == NULL)
2184 unsigned int syminsz = 0;
2186 for (i = 0, entry = dynamic_segment;
2187 i < dynamic_size;
2188 ++i, ++ entry)
2190 if (entry->d_tag == DT_SYMINENT)
2192 /* Note: these braces are necessary to avoid a syntax
2193 error from the SunOS4 C compiler. */
2194 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2196 else if (entry->d_tag == DT_SYMINSZ)
2197 syminsz = entry->d_un.d_val;
2198 else if (entry->d_tag == DT_SYMINFO)
2199 dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2202 if (dynamic_syminfo_offset != 0 && syminsz != 0)
2204 Elf_External_Syminfo *extsyminfo;
2205 Elf_Internal_Syminfo *syminfo;
2207 /* There is a syminfo section. Read the data. */
2208 GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2209 Elf_External_Syminfo *, "symbol information");
2211 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2212 if (dynamic_syminfo == NULL)
2214 error (_("Out of memory\n"));
2215 return 0;
2218 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2219 for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2220 ++i, ++syminfo)
2222 syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2223 syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2226 free (extsyminfo);
2230 if (do_dynamic && dynamic_addr)
2231 printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
2232 dynamic_addr, dynamic_size);
2233 if (do_dynamic)
2234 printf (_(" Tag Type Name/Value\n"));
2236 for (i = 0, entry = dynamic_segment;
2237 i < dynamic_size;
2238 i++, entry ++)
2240 if (do_dynamic)
2241 printf (_(" 0x%-8.8lx (%s)%*s"),
2242 (unsigned long) entry->d_tag,
2243 get_dynamic_type (entry->d_tag),
2244 27 - strlen (get_dynamic_type (entry->d_tag)),
2245 " ");
2247 switch (entry->d_tag)
2249 case DT_AUXILIARY:
2250 case DT_FILTER:
2251 if (do_dynamic)
2253 if (entry->d_tag == DT_AUXILIARY)
2254 printf (_("Auxiliary library"));
2255 else
2256 printf (_("Filter library"));
2258 if (dynamic_strings)
2259 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2260 else
2261 printf (": %#lx\n", (long) entry->d_un.d_val);
2263 break;
2265 case DT_FEATURE_1:
2266 if (do_dynamic)
2268 printf (_("Flags:"));
2269 if (entry->d_un.d_val == 0)
2270 printf (_(" None\n"));
2271 else
2273 unsigned long int val = entry->d_un.d_val;
2274 if (val & DTF_1_PARINIT)
2276 printf (" PARINIT");
2277 val ^= DTF_1_PARINIT;
2279 if (val != 0)
2280 printf (" %lx", val);
2281 puts ("");
2284 break;
2286 case DT_POSFLAG_1:
2287 if (do_dynamic)
2289 printf (_("Flags:"));
2290 if (entry->d_un.d_val == 0)
2291 printf (_(" None\n"));
2292 else
2294 unsigned long int val = entry->d_un.d_val;
2295 if (val & DF_P1_LAZYLOAD)
2297 printf (" LAZYLOAD");
2298 val ^= DF_P1_LAZYLOAD;
2300 if (val & DF_P1_GROUPPERM)
2302 printf (" GROUPPERM");
2303 val ^= DF_P1_GROUPPERM;
2305 if (val != 0)
2306 printf (" %lx", val);
2307 puts ("");
2310 break;
2312 case DT_FLAGS_1:
2313 if (do_dynamic)
2315 printf (_("Flags:"));
2316 if (entry->d_un.d_val == 0)
2317 printf (_(" None\n"));
2318 else
2320 unsigned long int val = entry->d_un.d_val;
2321 if (val & DF_1_NOW)
2323 printf (" NOW");
2324 val ^= DF_1_NOW;
2326 if (val & DF_1_GLOBAL)
2328 printf (" GLOBAL");
2329 val ^= DF_1_GLOBAL;
2331 if (val & DF_1_GROUP)
2333 printf (" GROUP");
2334 val ^= DF_1_GROUP;
2336 if (val & DF_1_NODELETE)
2338 printf (" NODELETE");
2339 val ^= DF_1_NODELETE;
2341 if (val & DF_1_LOADFLTR)
2343 printf (" LOADFLTR");
2344 val ^= DF_1_LOADFLTR;
2346 if (val & DF_1_INITFIRST)
2348 printf (" INITFIRST");
2349 val ^= DF_1_INITFIRST;
2351 if (val & DF_1_NOOPEN)
2353 printf (" NOOPEN");
2354 val ^= DF_1_NOOPEN;
2356 if (val & DF_1_ORIGIN)
2358 printf (" ORIGIN");
2359 val ^= DF_1_ORIGIN;
2361 if (val & DF_1_DIRECT)
2363 printf (" DIRECT");
2364 val ^= DF_1_DIRECT;
2366 if (val & DF_1_TRANS)
2368 printf (" TRANS");
2369 val ^= DF_1_TRANS;
2371 if (val & DF_1_INTERPOSE)
2373 printf (" INTERPOSE");
2374 val ^= DF_1_INTERPOSE;
2376 if (val != 0)
2377 printf (" %lx", val);
2378 puts ("");
2381 break;
2383 case DT_PLTREL:
2384 if (do_dynamic)
2385 puts (get_dynamic_type (entry->d_un.d_val));
2386 break;
2388 case DT_NULL :
2389 case DT_NEEDED :
2390 case DT_PLTGOT :
2391 case DT_HASH :
2392 case DT_STRTAB :
2393 case DT_SYMTAB :
2394 case DT_RELA :
2395 case DT_INIT :
2396 case DT_FINI :
2397 case DT_SONAME :
2398 case DT_RPATH :
2399 case DT_SYMBOLIC:
2400 case DT_REL :
2401 case DT_DEBUG :
2402 case DT_TEXTREL :
2403 case DT_JMPREL :
2404 dynamic_info[entry->d_tag] = entry->d_un.d_val;
2406 if (do_dynamic)
2408 char * name;
2410 if (dynamic_strings == NULL)
2411 name = NULL;
2412 else
2413 name = dynamic_strings + entry->d_un.d_val;
2415 if (name)
2417 switch (entry->d_tag)
2419 case DT_NEEDED:
2420 printf (_("Shared library: [%s]"), name);
2422 if (strcmp (name, program_interpreter))
2423 printf ("\n");
2424 else
2425 printf (_(" program interpreter\n"));
2426 break;
2428 case DT_SONAME:
2429 printf (_("Library soname: [%s]\n"), name);
2430 break;
2432 case DT_RPATH:
2433 printf (_("Library rpath: [%s]\n"), name);
2434 break;
2436 default:
2437 printf ("%#lx\n", (long) entry->d_un.d_val);
2440 else
2441 printf ("%#lx\n", (long) entry->d_un.d_val);
2443 break;
2445 case DT_PLTRELSZ:
2446 case DT_RELASZ :
2447 case DT_STRSZ :
2448 case DT_RELSZ :
2449 case DT_RELAENT :
2450 case DT_SYMENT :
2451 case DT_RELENT :
2452 case DT_PLTPADSZ:
2453 case DT_MOVEENT :
2454 case DT_MOVESZ :
2455 case DT_INIT_ARRAYSZ:
2456 case DT_FINI_ARRAYSZ:
2457 if (do_dynamic)
2458 printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2459 break;
2461 case DT_VERDEFNUM:
2462 case DT_VERNEEDNUM:
2463 case DT_RELACOUNT:
2464 case DT_RELCOUNT:
2465 if (do_dynamic)
2466 printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2467 break;
2469 case DT_SYMINSZ:
2470 case DT_SYMINENT:
2471 case DT_SYMINFO:
2472 case DT_USED:
2473 case DT_INIT_ARRAY:
2474 case DT_FINI_ARRAY:
2475 if (do_dynamic)
2477 if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2479 char * name;
2481 name = dynamic_strings + entry->d_un.d_val;
2483 if (* name)
2485 printf (_("Not needed object: [%s]\n"), name);
2486 break;
2490 printf ("%#lx\n", (long) entry->d_un.d_val);
2492 break;
2494 case DT_BIND_NOW:
2495 /* The value of this entry is ignored. */
2496 break;
2498 default:
2499 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2500 version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2501 entry->d_un.d_val;
2503 if (do_dynamic)
2505 switch (elf_header.e_machine)
2507 case EM_MIPS:
2508 case EM_MIPS_RS4_BE:
2509 dynamic_segment_mips_val (entry);
2510 break;
2511 default:
2512 printf ("%#lx\n", (long) entry->d_un.d_ptr);
2515 break;
2519 return 1;
2522 static char *
2523 get_ver_flags (flags)
2524 unsigned int flags;
2526 static char buff [32];
2528 buff[0] = 0;
2530 if (flags == 0)
2531 return _("none");
2533 if (flags & VER_FLG_BASE)
2534 strcat (buff, "BASE ");
2536 if (flags & VER_FLG_WEAK)
2538 if (flags & VER_FLG_BASE)
2539 strcat (buff, "| ");
2541 strcat (buff, "WEAK ");
2544 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2545 strcat (buff, "| <unknown>");
2547 return buff;
2550 /* Display the contents of the version sections. */
2551 static int
2552 process_version_sections (file)
2553 FILE * file;
2555 Elf32_Internal_Shdr * section;
2556 unsigned i;
2557 int found = 0;
2559 if (! do_version)
2560 return 1;
2562 for (i = 0, section = section_headers;
2563 i < elf_header.e_shnum;
2564 i++, section ++)
2566 switch (section->sh_type)
2568 case SHT_GNU_verdef:
2570 Elf_External_Verdef * edefs;
2571 unsigned int idx;
2572 unsigned int cnt;
2574 found = 1;
2576 printf
2577 (_("\nVersion definition section '%s' contains %ld entries:\n"),
2578 SECTION_NAME (section), section->sh_info);
2580 printf (_(" Addr: 0x"));
2581 printf_vma (section->sh_addr);
2582 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2583 (unsigned long) section->sh_offset, section->sh_link,
2584 SECTION_NAME (section_headers + section->sh_link));
2586 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2587 edefs, Elf_External_Verdef *,
2588 "version definition section");
2590 for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2592 char * vstart;
2593 Elf_External_Verdef * edef;
2594 Elf_Internal_Verdef ent;
2595 Elf_External_Verdaux * eaux;
2596 Elf_Internal_Verdaux aux;
2597 int j;
2598 int isum;
2600 vstart = ((char *) edefs) + idx;
2602 edef = (Elf_External_Verdef *) vstart;
2604 ent.vd_version = BYTE_GET (edef->vd_version);
2605 ent.vd_flags = BYTE_GET (edef->vd_flags);
2606 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
2607 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
2608 ent.vd_hash = BYTE_GET (edef->vd_hash);
2609 ent.vd_aux = BYTE_GET (edef->vd_aux);
2610 ent.vd_next = BYTE_GET (edef->vd_next);
2612 printf (_(" %#06x: Rev: %d Flags: %s"),
2613 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2615 printf (_(" Index: %d Cnt: %d "),
2616 ent.vd_ndx, ent.vd_cnt);
2618 vstart += ent.vd_aux;
2620 eaux = (Elf_External_Verdaux *) vstart;
2622 aux.vda_name = BYTE_GET (eaux->vda_name);
2623 aux.vda_next = BYTE_GET (eaux->vda_next);
2625 if (dynamic_strings)
2626 printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2627 else
2628 printf (_("Name index: %ld\n"), aux.vda_name);
2630 isum = idx + ent.vd_aux;
2632 for (j = 1; j < ent.vd_cnt; j ++)
2634 isum += aux.vda_next;
2635 vstart += aux.vda_next;
2637 eaux = (Elf_External_Verdaux *) vstart;
2639 aux.vda_name = BYTE_GET (eaux->vda_name);
2640 aux.vda_next = BYTE_GET (eaux->vda_next);
2642 if (dynamic_strings)
2643 printf (_(" %#06x: Parent %d: %s\n"),
2644 isum, j, dynamic_strings + aux.vda_name);
2645 else
2646 printf (_(" %#06x: Parent %d, name index: %ld\n"),
2647 isum, j, aux.vda_name);
2650 idx += ent.vd_next;
2653 free (edefs);
2655 break;
2657 case SHT_GNU_verneed:
2659 Elf_External_Verneed * eneed;
2660 unsigned int idx;
2661 unsigned int cnt;
2663 found = 1;
2665 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2666 SECTION_NAME (section), section->sh_info);
2668 printf (_(" Addr: 0x"));
2669 printf_vma (section->sh_addr);
2670 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
2671 (unsigned long) section->sh_offset, section->sh_link,
2672 SECTION_NAME (section_headers + section->sh_link));
2674 GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2675 eneed, Elf_External_Verneed *,
2676 "version need section");
2678 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
2680 Elf_External_Verneed * entry;
2681 Elf_Internal_Verneed ent;
2682 int j;
2683 int isum;
2684 char * vstart;
2686 vstart = ((char *) eneed) + idx;
2688 entry = (Elf_External_Verneed *) vstart;
2690 ent.vn_version = BYTE_GET (entry->vn_version);
2691 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
2692 ent.vn_file = BYTE_GET (entry->vn_file);
2693 ent.vn_aux = BYTE_GET (entry->vn_aux);
2694 ent.vn_next = BYTE_GET (entry->vn_next);
2696 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
2698 if (dynamic_strings)
2699 printf (_(" File: %s"), dynamic_strings + ent.vn_file);
2700 else
2701 printf (_(" File: %lx"), ent.vn_file);
2703 printf (_(" Cnt: %d\n"), ent.vn_cnt);
2705 vstart += ent.vn_aux;
2707 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
2709 Elf_External_Vernaux * eaux;
2710 Elf_Internal_Vernaux aux;
2712 eaux = (Elf_External_Vernaux *) vstart;
2714 aux.vna_hash = BYTE_GET (eaux->vna_hash);
2715 aux.vna_flags = BYTE_GET (eaux->vna_flags);
2716 aux.vna_other = BYTE_GET (eaux->vna_other);
2717 aux.vna_name = BYTE_GET (eaux->vna_name);
2718 aux.vna_next = BYTE_GET (eaux->vna_next);
2720 if (dynamic_strings)
2721 printf (_(" %#06x: Name: %s"),
2722 isum, dynamic_strings + aux.vna_name);
2723 else
2724 printf (_(" %#06x: Name index: %lx"),
2725 isum, aux.vna_name);
2727 printf (_(" Flags: %s Version: %d\n"),
2728 get_ver_flags (aux.vna_flags), aux.vna_other);
2730 isum += aux.vna_next;
2731 vstart += aux.vna_next;
2734 idx += ent.vn_next;
2737 free (eneed);
2739 break;
2741 case SHT_GNU_versym:
2743 Elf32_Internal_Shdr * link_section;
2744 int total;
2745 int cnt;
2746 unsigned char * edata;
2747 unsigned short * data;
2748 char * strtab;
2749 Elf_Internal_Sym * symbols;
2750 Elf32_Internal_Shdr * string_sec;
2752 link_section = section_headers + section->sh_link;
2753 total = section->sh_size / section->sh_entsize;
2755 found = 1;
2757 symbols = get_elf_symbols
2758 (file, link_section->sh_offset,
2759 link_section->sh_size / link_section->sh_entsize);
2761 string_sec = section_headers + link_section->sh_link;
2763 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
2764 strtab, char *, "version string table");
2766 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
2767 SECTION_NAME (section), total);
2769 printf (_(" Addr: "));
2770 printf_vma (section->sh_addr);
2771 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
2772 (unsigned long) section->sh_offset, section->sh_link,
2773 SECTION_NAME (link_section));
2775 GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
2776 - loadaddr,
2777 total * sizeof (short), edata,
2778 unsigned char *, "version symbol data");
2780 data = (unsigned short *) malloc (total * sizeof (short));
2782 for (cnt = total; cnt --;)
2783 data [cnt] = byte_get (edata + cnt * sizeof (short),
2784 sizeof (short));
2786 free (edata);
2788 for (cnt = 0; cnt < total; cnt += 4)
2790 int j, nn;
2792 printf (" %03x:", cnt);
2794 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
2795 switch (data [cnt + j])
2797 case 0:
2798 fputs (_(" 0 (*local*) "), stdout);
2799 break;
2801 case 1:
2802 fputs (_(" 1 (*global*) "), stdout);
2803 break;
2805 default:
2806 nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
2807 data [cnt + j] & 0x8000 ? 'h' : ' ');
2809 if (symbols [cnt + j].st_shndx < SHN_LORESERVE
2810 && section_headers[symbols [cnt + j].st_shndx].sh_type
2811 == SHT_NOBITS)
2813 /* We must test both. */
2814 Elf_Internal_Verneed ivn;
2815 unsigned long offset;
2817 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2818 - loadaddr;
2822 Elf_External_Verneed evn;
2823 Elf_External_Vernaux evna;
2824 Elf_Internal_Vernaux ivna;
2825 unsigned long vna_off;
2827 GET_DATA (offset, evn, "version need");
2829 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2830 ivn.vn_next = BYTE_GET (evn.vn_next);
2832 vna_off = offset + ivn.vn_aux;
2836 GET_DATA (vna_off, evna,
2837 "version need aux (1)");
2839 ivna.vna_next = BYTE_GET (evna.vna_next);
2840 ivna.vna_other = BYTE_GET (evna.vna_other);
2842 vna_off += ivna.vna_next;
2844 while (ivna.vna_other != data [cnt + j]
2845 && ivna.vna_next != 0);
2847 if (ivna.vna_other == data [cnt + j])
2849 ivna.vna_name = BYTE_GET (evna.vna_name);
2851 nn += printf ("(%s%-*s",
2852 strtab + ivna.vna_name,
2853 12 - strlen (strtab
2854 + ivna.vna_name),
2855 ")");
2856 break;
2858 else if (ivn.vn_next == 0)
2860 if (data [cnt + j] != 0x8001)
2862 Elf_Internal_Verdef ivd;
2863 Elf_External_Verdef evd;
2865 offset = version_info
2866 [DT_VERSIONTAGIDX (DT_VERDEF)]
2867 - loadaddr;
2871 GET_DATA (offset, evd,
2872 "version definition");
2874 ivd.vd_next = BYTE_GET (evd.vd_next);
2875 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2877 offset += ivd.vd_next;
2879 while (ivd.vd_ndx
2880 != (data [cnt + j] & 0x7fff)
2881 && ivd.vd_next != 0);
2883 if (ivd.vd_ndx
2884 == (data [cnt + j] & 0x7fff))
2886 Elf_External_Verdaux evda;
2887 Elf_Internal_Verdaux ivda;
2889 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2891 GET_DATA (offset + ivd.vd_aux, evda,
2892 "version definition aux");
2894 ivda.vda_name =
2895 BYTE_GET (evda.vda_name);
2897 nn +=
2898 printf ("(%s%-*s",
2899 strtab + ivda.vda_name,
2901 - strlen (strtab
2902 + ivda.vda_name),
2903 ")");
2907 break;
2909 else
2910 offset += ivn.vn_next;
2912 while (ivn.vn_next);
2914 else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
2916 Elf_Internal_Verneed ivn;
2917 unsigned long offset;
2919 offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
2920 - loadaddr;
2924 Elf_Internal_Vernaux ivna;
2925 Elf_External_Verneed evn;
2926 Elf_External_Vernaux evna;
2927 unsigned long a_off;
2929 GET_DATA (offset, evn, "version need");
2931 ivn.vn_aux = BYTE_GET (evn.vn_aux);
2932 ivn.vn_next = BYTE_GET (evn.vn_next);
2934 a_off = offset + ivn.vn_aux;
2938 GET_DATA (a_off, evna,
2939 "version need aux (2)");
2941 ivna.vna_next = BYTE_GET (evna.vna_next);
2942 ivna.vna_other = BYTE_GET (evna.vna_other);
2944 a_off += ivna.vna_next;
2946 while (ivna.vna_other != data [cnt + j]
2947 && ivna.vna_next != 0);
2949 if (ivna.vna_other == data [cnt + j])
2951 ivna.vna_name = BYTE_GET (evna.vna_name);
2953 nn += printf ("(%s%-*s",
2954 strtab + ivna.vna_name,
2955 12 - strlen (strtab
2956 + ivna.vna_name),
2957 ")");
2958 break;
2961 offset += ivn.vn_next;
2963 while (ivn.vn_next);
2965 else if (data [cnt + j] != 0x8001)
2967 Elf_Internal_Verdef ivd;
2968 Elf_External_Verdef evd;
2969 unsigned long offset;
2971 offset = version_info
2972 [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
2976 GET_DATA (offset, evd, "version def");
2978 ivd.vd_next = BYTE_GET (evd.vd_next);
2979 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
2981 offset += ivd.vd_next;
2983 while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
2984 && ivd.vd_next != 0);
2986 if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
2988 Elf_External_Verdaux evda;
2989 Elf_Internal_Verdaux ivda;
2991 ivd.vd_aux = BYTE_GET (evd.vd_aux);
2993 GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
2994 evda, "version def aux");
2996 ivda.vda_name = BYTE_GET (evda.vda_name);
2998 nn += printf ("(%s%-*s",
2999 strtab + ivda.vda_name,
3000 12 - strlen (strtab
3001 + ivda.vda_name),
3002 ")");
3006 if (nn < 18)
3007 printf ("%*c", 18 - nn, ' ');
3010 putchar ('\n');
3013 free (data);
3014 free (strtab);
3015 free (symbols);
3017 break;
3019 default:
3020 break;
3024 if (! found)
3025 printf (_("\nNo version information found in this file.\n"));
3027 return 1;
3030 static char *
3031 get_symbol_binding (binding)
3032 unsigned int binding;
3034 static char buff [32];
3036 switch (binding)
3038 case STB_LOCAL: return _("LOCAL");
3039 case STB_GLOBAL: return _("GLOBAL");
3040 case STB_WEAK: return _("WEAK");
3041 default:
3042 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
3043 sprintf (buff, _("<processor specific>: %d"), binding);
3044 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3045 sprintf (buff, _("<OS specific>: %d"), binding);
3046 else
3047 sprintf (buff, _("<unknown>: %d"), binding);
3048 return buff;
3052 static char *
3053 get_symbol_type (type)
3054 unsigned int type;
3056 static char buff [32];
3058 switch (type)
3060 case STT_NOTYPE: return _("NOTYPE");
3061 case STT_OBJECT: return _("OBJECT");
3062 case STT_FUNC: return _("FUNC");
3063 case STT_SECTION: return _("SECTION");
3064 case STT_FILE: return _("FILE");
3065 default:
3066 if (type >= STT_LOPROC && type <= STT_HIPROC)
3067 sprintf (buff, _("<processor specific>: %d"), type);
3068 else if (type >= STT_LOOS && type <= STT_HIOS)
3069 sprintf (buff, _("<OS specific>: %d"), type);
3070 else
3071 sprintf (buff, _("<unknown>: %d"), type);
3072 return buff;
3076 static char *
3077 get_symbol_index_type (type)
3078 unsigned int type;
3080 switch (type)
3082 case SHN_UNDEF: return "UND";
3083 case SHN_ABS: return "ABS";
3084 case SHN_COMMON: return "COM";
3085 default:
3086 if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3087 return "PRC";
3088 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3089 return "RSV";
3090 else if (type >= SHN_LOOS && type <= SHN_HIOS)
3091 return "OS ";
3092 else
3094 static char buff [32];
3096 sprintf (buff, "%3d", type);
3097 return buff;
3103 static int *
3104 get_dynamic_data (file, number)
3105 FILE * file;
3106 unsigned int number;
3108 char * e_data;
3109 int * i_data;
3111 e_data = (char *) malloc (number * 4);
3113 if (e_data == NULL)
3115 error (_("Out of memory\n"));
3116 return NULL;
3119 if (fread (e_data, 4, number, file) != number)
3121 error (_("Unable to read in dynamic data\n"));
3122 return NULL;
3125 i_data = (int *) malloc (number * sizeof (* i_data));
3127 if (i_data == NULL)
3129 error (_("Out of memory\n"));
3130 free (e_data);
3131 return NULL;
3134 while (number--)
3135 i_data [number] = byte_get (e_data + number * 4, 4);
3137 free (e_data);
3139 return i_data;
3142 /* Dump the symbol table */
3143 static int
3144 process_symbol_table (file)
3145 FILE * file;
3147 Elf32_Internal_Shdr * section;
3148 char nb [4];
3149 char nc [4];
3150 int nbuckets;
3151 int nchains;
3152 int * buckets = NULL;
3153 int * chains = NULL;
3155 if (! do_syms && !do_histogram)
3156 return 1;
3158 if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3159 || do_histogram))
3161 if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3163 error (_("Unable to seek to start of dynamic information"));
3164 return 0;
3167 if (fread (nb, sizeof (nb), 1, file) != 1)
3169 error (_("Failed to read in number of buckets\n"));
3170 return 0;
3173 if (fread (nc, sizeof (nc), 1, file) != 1)
3175 error (_("Failed to read in number of chains\n"));
3176 return 0;
3179 nbuckets = byte_get (nb, 4);
3180 nchains = byte_get (nc, 4);
3182 buckets = get_dynamic_data (file, nbuckets);
3183 chains = get_dynamic_data (file, nchains);
3185 if (buckets == NULL || chains == NULL)
3186 return 0;
3189 if (do_syms
3190 && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3192 int hn;
3193 int si;
3195 printf (_("\nSymbol table for image:\n"));
3196 printf (_(" Num Buc: Value Size Type Bind Ot Ndx Name\n"));
3198 for (hn = 0; hn < nbuckets; hn++)
3200 if (! buckets [hn])
3201 continue;
3203 for (si = buckets [hn]; si; si = chains [si])
3205 Elf_Internal_Sym * psym;
3207 psym = dynamic_symbols + si;
3209 printf (" %3d %3d: %8lx %5ld %6s %6s %2d ",
3210 si, hn,
3211 (unsigned long) psym->st_value,
3212 (unsigned long) psym->st_size,
3213 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3214 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3215 psym->st_other);
3217 printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3219 printf (" %s\n", dynamic_strings + psym->st_name);
3223 else if (do_syms && !do_using_dynamic)
3225 unsigned int i;
3227 for (i = 0, section = section_headers;
3228 i < elf_header.e_shnum;
3229 i++, section++)
3231 unsigned int si;
3232 char * strtab;
3233 Elf_Internal_Sym * symtab;
3234 Elf_Internal_Sym * psym;
3237 if ( section->sh_type != SHT_SYMTAB
3238 && section->sh_type != SHT_DYNSYM)
3239 continue;
3241 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3242 SECTION_NAME (section),
3243 (unsigned long) (section->sh_size / section->sh_entsize));
3244 fputs (_(" Num: Value Size Type Bind Ot Ndx Name\n"),
3245 stdout);
3247 symtab = get_elf_symbols (file, section->sh_offset,
3248 section->sh_size / section->sh_entsize);
3249 if (symtab == NULL)
3250 continue;
3252 if (section->sh_link == elf_header.e_shstrndx)
3253 strtab = string_table;
3254 else
3256 Elf32_Internal_Shdr * string_sec;
3258 string_sec = section_headers + section->sh_link;
3260 GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3261 strtab, char *, "string table");
3264 for (si = 0, psym = symtab;
3265 si < section->sh_size / section->sh_entsize;
3266 si ++, psym ++)
3268 printf (" %3d: %8lx %5ld %-7s %-6s %2d ",
3270 (unsigned long) psym->st_value,
3271 (unsigned long) psym->st_size,
3272 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3273 get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3274 psym->st_other);
3276 printf ("%4s", get_symbol_index_type (psym->st_shndx));
3278 printf (" %s", strtab + psym->st_name);
3280 if (section->sh_type == SHT_DYNSYM &&
3281 version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3283 unsigned char data[2];
3284 unsigned short vers_data;
3285 unsigned long offset;
3286 int is_nobits;
3287 int check_def;
3289 offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3290 - loadaddr;
3292 GET_DATA (offset + si * sizeof (vers_data), data,
3293 "version data");
3295 vers_data = byte_get (data, 2);
3297 is_nobits = psym->st_shndx < SHN_LORESERVE ?
3298 (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3299 : 0;
3301 check_def = (psym->st_shndx != SHN_UNDEF);
3303 if ((vers_data & 0x8000) || vers_data > 1)
3305 if (is_nobits || ! check_def)
3307 Elf_External_Verneed evn;
3308 Elf_Internal_Verneed ivn;
3309 Elf_Internal_Vernaux ivna;
3311 /* We must test both. */
3312 offset = version_info
3313 [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3315 GET_DATA (offset, evn, "version need");
3317 ivn.vn_aux = BYTE_GET (evn.vn_aux);
3318 ivn.vn_next = BYTE_GET (evn.vn_next);
3322 unsigned long vna_off;
3324 vna_off = offset + ivn.vn_aux;
3328 Elf_External_Vernaux evna;
3330 GET_DATA (vna_off, evna,
3331 "version need aux (3)");
3333 ivna.vna_other = BYTE_GET (evna.vna_other);
3334 ivna.vna_next = BYTE_GET (evna.vna_next);
3335 ivna.vna_name = BYTE_GET (evna.vna_name);
3337 vna_off += ivna.vna_next;
3339 while (ivna.vna_other != vers_data
3340 && ivna.vna_next != 0);
3342 if (ivna.vna_other == vers_data)
3343 break;
3345 offset += ivn.vn_next;
3347 while (ivn.vn_next != 0);
3349 if (ivna.vna_other == vers_data)
3351 printf ("@%s (%d)",
3352 strtab + ivna.vna_name, ivna.vna_other);
3353 check_def = 0;
3355 else if (! is_nobits)
3356 error (_("bad dynamic symbol"));
3357 else
3358 check_def = 1;
3361 if (check_def)
3363 if (vers_data != 0x8001)
3365 Elf_Internal_Verdef ivd;
3366 Elf_Internal_Verdaux ivda;
3367 Elf_External_Verdaux evda;
3368 unsigned long offset;
3370 offset =
3371 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3372 - loadaddr;
3376 Elf_External_Verdef evd;
3378 GET_DATA (offset, evd, "version def");
3380 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
3381 ivd.vd_aux = BYTE_GET (evd.vd_aux);
3382 ivd.vd_next = BYTE_GET (evd.vd_next);
3384 offset += ivd.vd_next;
3386 while (ivd.vd_ndx != (vers_data & 0x7fff)
3387 && ivd.vd_next != 0);
3389 offset -= ivd.vd_next;
3390 offset += ivd.vd_aux;
3392 GET_DATA (offset, evda, "version def aux");
3394 ivda.vda_name = BYTE_GET (evda.vda_name);
3396 if (psym->st_name != ivda.vda_name)
3397 printf ((vers_data & 0x8000)
3398 ? "@%s" : "@@%s",
3399 strtab + ivda.vda_name);
3405 putchar ('\n');
3408 free (symtab);
3409 if (strtab != string_table)
3410 free (strtab);
3413 else if (do_syms)
3414 printf
3415 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3417 if (do_histogram && buckets != NULL)
3419 int *lengths;
3420 int *counts;
3421 int hn;
3422 int si;
3423 int maxlength = 0;
3424 int nzero_counts = 0;
3425 int nsyms = 0;
3427 printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3428 nbuckets);
3429 printf (_(" Length Number %% of total Coverage\n"));
3431 lengths = (int *) calloc (nbuckets, sizeof (int));
3432 if (lengths == NULL)
3434 error (_("Out of memory"));
3435 return 0;
3437 for (hn = 0; hn < nbuckets; ++hn)
3439 if (! buckets [hn])
3440 continue;
3442 for (si = buckets[hn]; si; si = chains[si])
3444 ++nsyms;
3445 if (maxlength < ++lengths[hn])
3446 ++maxlength;
3450 counts = (int *) calloc (maxlength + 1, sizeof (int));
3451 if (counts == NULL)
3453 error (_("Out of memory"));
3454 return 0;
3457 for (hn = 0; hn < nbuckets; ++hn)
3458 ++ counts [lengths [hn]];
3460 printf (" 0 %-10d (%5.1f%%)\n",
3461 counts[0], (counts[0] * 100.0) / nbuckets);
3462 for (si = 1; si <= maxlength; ++si)
3464 nzero_counts += counts[si] * si;
3465 printf ("%7d %-10d (%5.1f%%) %5.1f%%\n",
3466 si, counts[si], (counts[si] * 100.0) / nbuckets,
3467 (nzero_counts * 100.0) / nsyms);
3470 free (counts);
3471 free (lengths);
3474 if (buckets != NULL)
3476 free (buckets);
3477 free (chains);
3480 return 1;
3483 static int
3484 process_syminfo (file)
3485 FILE * file;
3487 int i;
3489 if (dynamic_syminfo == NULL
3490 || !do_dynamic)
3491 /* No syminfo, this is ok. */
3492 return 1;
3494 /* There better should be a dynamic symbol section. */
3495 if (dynamic_symbols == NULL || dynamic_strings == NULL)
3496 return 0;
3498 if (dynamic_addr)
3499 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3500 dynamic_syminfo_offset, dynamic_syminfo_nent);
3502 printf (_(" Num: Name BoundTo Flags\n"));
3503 for (i = 0; i < dynamic_syminfo_nent; ++i)
3505 unsigned short int flags = dynamic_syminfo[i].si_flags;
3507 printf ("%4d: %-30s ", i,
3508 dynamic_strings + dynamic_symbols[i].st_name);
3510 switch (dynamic_syminfo[i].si_boundto)
3512 case SYMINFO_BT_SELF:
3513 fputs ("SELF ", stdout);
3514 break;
3515 case SYMINFO_BT_PARENT:
3516 fputs ("PARENT ", stdout);
3517 break;
3518 default:
3519 if (dynamic_syminfo[i].si_boundto > 0
3520 && dynamic_syminfo[i].si_boundto < dynamic_size)
3521 printf ("%-10s ",
3522 dynamic_strings
3523 + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3524 else
3525 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3526 break;
3529 if (flags & SYMINFO_FLG_DIRECT)
3530 printf (" DIRECT");
3531 if (flags & SYMINFO_FLG_PASSTHRU)
3532 printf (" PASSTHRU");
3533 if (flags & SYMINFO_FLG_COPY)
3534 printf (" COPY");
3535 if (flags & SYMINFO_FLG_LAZYLOAD)
3536 printf (" LAZYLOAD");
3538 puts ("");
3541 return 1;
3544 #ifdef SUPPORT_DISASSEMBLY
3545 static void
3546 disassemble_section (section, file)
3547 Elf32_Internal_Shdr * section;
3548 FILE * file;
3550 printf (_("\nAssembly dump of section %s\n"),
3551 SECTION_NAME (section));
3553 /* XXX -- to be done --- XXX */
3555 return 1;
3557 #endif
3559 static int
3560 dump_section (section, file)
3561 Elf32_Internal_Shdr * section;
3562 FILE * file;
3564 int bytes;
3565 int addr;
3566 unsigned char * data;
3567 unsigned char * start;
3569 bytes = section->sh_size;
3571 if (bytes == 0)
3573 printf (_("\nSection '%s' has no data to dump.\n"),
3574 SECTION_NAME (section));
3575 return 0;
3577 else
3578 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3580 addr = section->sh_addr;
3582 GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3583 "section data");
3585 data = start;
3587 while (bytes)
3589 int j;
3590 int k;
3591 int lbytes;
3593 lbytes = (bytes > 16 ? 16 : bytes);
3595 printf (" 0x%8.8x ", addr);
3597 switch (elf_header.e_ident [EI_DATA])
3599 case ELFDATA2LSB:
3600 for (j = 15; j >= 0; j --)
3602 if (j < lbytes)
3603 printf ("%2.2x", data [j]);
3604 else
3605 printf (" ");
3607 if (!(j & 0x3))
3608 printf (" ");
3610 break;
3612 case ELFDATA2MSB:
3613 for (j = 0; j < 16; j++)
3615 if (j < lbytes)
3616 printf ("%2.2x", data [j]);
3617 else
3618 printf (" ");
3620 if ((j & 3) == 3)
3621 printf (" ");
3623 break;
3626 for (j = 0; j < lbytes; j++)
3628 k = data [j];
3629 if (k >= ' ' && k < 0x80)
3630 printf ("%c", k);
3631 else
3632 printf (".");
3635 putchar ('\n');
3637 data += lbytes;
3638 addr += lbytes;
3639 bytes -= lbytes;
3642 free (start);
3644 return 1;
3648 static unsigned long int
3649 read_leb128 (data, length_return, sign)
3650 unsigned char * data;
3651 int * length_return;
3652 int sign;
3654 unsigned long int result = 0;
3655 unsigned int num_read = 0;
3656 int shift = 0;
3657 unsigned char byte;
3661 byte = * data ++;
3662 num_read ++;
3664 result |= (byte & 0x7f) << shift;
3666 shift += 7;
3669 while (byte & 0x80);
3671 if (length_return != NULL)
3672 * length_return = num_read;
3674 if (sign && (shift < 32) && (byte & 0x40))
3675 result |= -1 << shift;
3677 return result;
3680 typedef struct State_Machine_Registers
3682 unsigned long address;
3683 unsigned int file;
3684 unsigned int line;
3685 unsigned int column;
3686 int is_stmt;
3687 int basic_block;
3688 int end_sequence;
3689 /* This variable hold the number of the last entry seen
3690 in the File Table. */
3691 unsigned int last_file_entry;
3692 } SMR;
3694 static SMR state_machine_regs;
3696 static void
3697 reset_state_machine (is_stmt)
3698 int is_stmt;
3700 state_machine_regs.address = 0;
3701 state_machine_regs.file = 1;
3702 state_machine_regs.line = 1;
3703 state_machine_regs.column = 0;
3704 state_machine_regs.is_stmt = is_stmt;
3705 state_machine_regs.basic_block = 0;
3706 state_machine_regs.end_sequence = 0;
3707 state_machine_regs.last_file_entry = 0;
3710 /* Handled an extend line op. Returns true if this is the end
3711 of sequence. */
3712 static int
3713 process_extended_line_op (data, is_stmt)
3714 unsigned char * data;
3715 int is_stmt;
3717 unsigned char op_code;
3718 int bytes_read;
3719 unsigned int len;
3720 unsigned char * name;
3721 unsigned long adr;
3723 len = read_leb128 (data, & bytes_read, 0);
3724 data += bytes_read;
3726 if (len == 0)
3728 warn (_("badly formed extended line op encountered!"));
3729 return bytes_read;
3732 len += bytes_read;
3733 op_code = * data ++;
3735 printf (_(" Extended opcode %d: "), op_code);
3737 switch (op_code)
3739 case DW_LNE_end_sequence:
3740 printf (_("End of Sequence\n\n"));
3741 reset_state_machine (is_stmt);
3742 break;
3744 case DW_LNE_set_address:
3745 /* XXX - assumption here that address size is 4! */
3746 adr = byte_get (data, 4);
3747 printf (_("set Address to 0x%lx\n"), adr);
3748 state_machine_regs.address = adr;
3749 break;
3751 case DW_LNE_define_file:
3752 printf (_(" define new File Table entry\n"));
3753 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3755 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3756 name = data;
3757 data += strlen (data) + 1;
3758 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3759 data += bytes_read;
3760 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3761 data += bytes_read;
3762 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3763 printf (_("%s\n\n"), name);
3764 break;
3766 default:
3767 printf (_("UNKNOWN: length %d\n"), len - bytes_read);
3768 break;
3771 return len;
3775 static int
3776 display_debug_lines (section, start, file)
3777 Elf32_Internal_Shdr * section;
3778 unsigned char * start;
3779 FILE * file;
3781 DWARF2_External_LineInfo * external;
3782 DWARF2_Internal_LineInfo info;
3783 unsigned char * standard_opcodes;
3784 unsigned char * data = start;
3785 unsigned char * end = start + section->sh_size;
3786 unsigned char * end_of_sequence;
3787 int i;
3789 printf (_("\nDump of debug contents of section %s:\n\n"),
3790 SECTION_NAME (section));
3792 while (data < end)
3794 external = (DWARF2_External_LineInfo *) data;
3796 /* Check the length of the block. */
3797 info.li_length = BYTE_GET (external->li_length);
3798 if (info.li_length > section->sh_size)
3800 warn
3801 (_("The line info appears to be corrupt - the section is too small\n"));
3802 return 0;
3805 /* Check its version number. */
3806 info.li_version = BYTE_GET (external->li_version);
3807 if (info.li_version != 2)
3809 warn (_("Only DWARF version 2 line info is currently supported.\n"));
3810 return 0;
3813 info.li_prologue_length = BYTE_GET (external->li_prologue_length);
3814 info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
3815 info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
3816 info.li_line_base = BYTE_GET (external->li_line_base);
3817 info.li_line_range = BYTE_GET (external->li_line_range);
3818 info.li_opcode_base = BYTE_GET (external->li_opcode_base);
3820 /* Sign extend the line base field. */
3821 info.li_line_base <<= 24;
3822 info.li_line_base >>= 24;
3824 printf (_(" Length: %ld\n"), info.li_length);
3825 printf (_(" DWARF Version: %d\n"), info.li_version);
3826 printf (_(" Prolgue Length: %d\n"), info.li_prologue_length);
3827 printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length);
3828 printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt);
3829 printf (_(" Line Base: %d\n"), info.li_line_base);
3830 printf (_(" Line Range: %d\n"), info.li_line_range);
3831 printf (_(" Opcode Base: %d\n"), info.li_opcode_base);
3833 end_of_sequence = data + info.li_length + sizeof (info.li_length);
3835 reset_state_machine (info.li_default_is_stmt);
3837 /* Display the contents of the Opcodes table. */
3838 standard_opcodes = data + sizeof (* external);
3840 printf (_("\n Opcodes:\n"));
3842 for (i = 1; i < info.li_opcode_base; i++)
3843 printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i]);
3845 /* Display the contents of the Directory table. */
3846 data = standard_opcodes + info.li_opcode_base - 1;
3848 if (* data == 0)
3849 printf (_("\n The Directory Table is empty.\n"));
3850 else
3852 printf (_("\n The Directory Table:\n"));
3854 while (* data != 0)
3856 printf (_(" %s\n"), data);
3858 data += strlen (data) + 1;
3862 /* Skip the NUL at the end of the table. */
3863 data ++;
3865 /* Display the contents of the File Name table. */
3866 if (* data == 0)
3867 printf (_("\n The File Name Table is empty.\n"));
3868 else
3870 printf (_("\n The File Name Table:\n"));
3871 printf (_(" Entry\tDir\tTime\tSize\tName\n"));
3873 while (* data != 0)
3875 char * name;
3876 int bytes_read;
3878 printf (_(" %d\t"), ++ state_machine_regs.last_file_entry);
3879 name = data;
3881 data += strlen (data) + 1;
3883 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3884 data += bytes_read;
3885 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3886 data += bytes_read;
3887 printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
3888 data += bytes_read;
3889 printf (_("%s\n"), name);
3893 /* Skip the NUL at the end of the table. */
3894 data ++;
3896 /* Now display the statements. */
3897 printf (_("\n Line Number Statements:\n"));
3900 while (data < end_of_sequence)
3902 unsigned char op_code;
3903 int adv;
3904 int bytes_read;
3906 op_code = * data ++;
3908 switch (op_code)
3910 case DW_LNS_extended_op:
3911 data += process_extended_line_op (data, info.li_default_is_stmt);
3912 break;
3914 case DW_LNS_copy:
3915 printf (_(" Copy\n"));
3916 break;
3918 case DW_LNS_advance_pc:
3919 adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
3920 data += bytes_read;
3921 state_machine_regs.address += adv;
3922 printf (_(" Advance PC by %d to %lx\n"), adv,
3923 state_machine_regs.address);
3924 break;
3926 case DW_LNS_advance_line:
3927 adv = read_leb128 (data, & bytes_read, 1);
3928 data += bytes_read;
3929 state_machine_regs.line += adv;
3930 printf (_(" Advance Line by %d to %d\n"), adv,
3931 state_machine_regs.line);
3932 break;
3934 case DW_LNS_set_file:
3935 adv = read_leb128 (data, & bytes_read, 0);
3936 data += bytes_read;
3937 printf (_(" Set File Name to entry %d in the File Name Table\n"),
3938 adv);
3939 state_machine_regs.file = adv;
3940 break;
3942 case DW_LNS_set_column:
3943 adv = read_leb128 (data, & bytes_read, 0);
3944 data += bytes_read;
3945 printf (_(" Set column to %d\n"), adv);
3946 state_machine_regs.column = adv;
3947 break;
3949 case DW_LNS_negate_stmt:
3950 adv = state_machine_regs.is_stmt;
3951 adv = ! adv;
3952 printf (_(" Set is_stmt to %d\n"), adv);
3953 state_machine_regs.is_stmt = adv;
3954 break;
3956 case DW_LNS_set_basic_block:
3957 printf (_(" Set basic block\n"));
3958 state_machine_regs.basic_block = 1;
3959 break;
3961 case DW_LNS_const_add_pc:
3962 adv = (255 - info.li_opcode_base) / info.li_line_range;
3963 state_machine_regs.address += adv;
3964 printf (_(" Advance PC by constant %d to 0x%lx\n"), adv,
3965 state_machine_regs.address);
3966 break;
3968 case DW_LNS_fixed_advance_pc:
3969 adv = byte_get (data, 2);
3970 data += 2;
3971 state_machine_regs.address += adv;
3972 printf (_(" Advance PC by fixed size amount %d to 0x%lx\n"),
3973 adv, state_machine_regs.address);
3974 break;
3976 default:
3977 op_code -= info.li_opcode_base;
3978 adv = (op_code / info.li_line_range) * info.li_min_insn_length;
3979 state_machine_regs.address += adv;
3980 printf (_(" Special opcode %d: advance Address by %d to 0x%lx"),
3981 op_code, adv, state_machine_regs.address);
3982 adv += (op_code % info.li_line_range) + info.li_line_base;
3983 state_machine_regs.line += adv;
3984 printf (_(" and Line by %d to %d\n"),
3985 adv, state_machine_regs.line);
3986 break;
3989 printf ("\n");
3992 return 1;
3995 static int
3996 display_debug_pubnames (section, start, file)
3997 Elf32_Internal_Shdr * section;
3998 unsigned char * start;
3999 FILE * file;
4001 DWARF2_External_PubNames * external;
4002 DWARF2_Internal_PubNames pubnames;
4003 unsigned char * end;
4005 end = start + section->sh_size;
4007 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4009 while (start < end)
4011 unsigned char * data;
4012 unsigned long offset;
4014 external = (DWARF2_External_PubNames *) start;
4016 pubnames.pn_length = BYTE_GET (external->pn_length);
4017 pubnames.pn_version = BYTE_GET (external->pn_version);
4018 pubnames.pn_offset = BYTE_GET (external->pn_offset);
4019 pubnames.pn_size = BYTE_GET (external->pn_size);
4021 data = start + sizeof (* external);
4022 start += pubnames.pn_length + sizeof (external->pn_length);
4024 if (pubnames.pn_version != 2)
4026 warn (_("Only DWARF 2 pubnames are currently supported"));
4027 continue;
4030 printf (_(" Length: %ld\n"),
4031 pubnames.pn_length);
4032 printf (_(" Version: %d\n"),
4033 pubnames.pn_version);
4034 printf (_(" Offset into .debug_info section: %ld\n"),
4035 pubnames.pn_offset);
4036 printf (_(" Size of area in .debug_info section: %ld\n"),
4037 pubnames.pn_size);
4039 printf (_("\n Offset\tName\n"));
4043 offset = byte_get (data, 4);
4045 if (offset != 0)
4047 data += 4;
4048 printf (" %ld\t\t%s\n", offset, data);
4049 data += strlen (data) + 1;
4052 while (offset != 0);
4055 printf ("\n");
4056 return 1;
4059 static char *
4060 get_TAG_name (tag)
4061 unsigned long tag;
4063 switch (tag)
4065 case DW_TAG_padding: return "DW_TAG_padding";
4066 case DW_TAG_array_type: return "DW_TAG_array_type";
4067 case DW_TAG_class_type: return "DW_TAG_class_type";
4068 case DW_TAG_entry_point: return "DW_TAG_entry_point";
4069 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4070 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4071 case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4072 case DW_TAG_label: return "DW_TAG_label";
4073 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4074 case DW_TAG_member: return "DW_TAG_member";
4075 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4076 case DW_TAG_reference_type: return "DW_TAG_reference_type";
4077 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4078 case DW_TAG_string_type: return "DW_TAG_string_type";
4079 case DW_TAG_structure_type: return "DW_TAG_structure_type";
4080 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4081 case DW_TAG_typedef: return "DW_TAG_typedef";
4082 case DW_TAG_union_type: return "DW_TAG_union_type";
4083 case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4084 case DW_TAG_variant: return "DW_TAG_variant";
4085 case DW_TAG_common_block: return "DW_TAG_common_block";
4086 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4087 case DW_TAG_inheritance: return "DW_TAG_inheritance";
4088 case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4089 case DW_TAG_module: return "DW_TAG_module";
4090 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4091 case DW_TAG_set_type: return "DW_TAG_set_type";
4092 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4093 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4094 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4095 case DW_TAG_base_type: return "DW_TAG_base_type";
4096 case DW_TAG_catch_block: return "DW_TAG_catch_block";
4097 case DW_TAG_const_type: return "DW_TAG_const_type";
4098 case DW_TAG_constant: return "DW_TAG_constant";
4099 case DW_TAG_enumerator: return "DW_TAG_enumerator";
4100 case DW_TAG_file_type: return "DW_TAG_file_type";
4101 case DW_TAG_friend: return "DW_TAG_friend";
4102 case DW_TAG_namelist: return "DW_TAG_namelist";
4103 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4104 case DW_TAG_packed_type: return "DW_TAG_packed_type";
4105 case DW_TAG_subprogram: return "DW_TAG_subprogram";
4106 case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4107 case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4108 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4109 case DW_TAG_try_block: return "DW_TAG_try_block";
4110 case DW_TAG_variant_part: return "DW_TAG_variant_part";
4111 case DW_TAG_variable: return "DW_TAG_variable";
4112 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4113 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4114 case DW_TAG_format_label: return "DW_TAG_format_label";
4115 case DW_TAG_function_template: return "DW_TAG_function_template";
4116 case DW_TAG_class_template: return "DW_TAG_class_template";
4117 default:
4119 static char buffer [100];
4121 sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4122 return buffer;
4127 static char *
4128 get_AT_name (attribute)
4129 unsigned long attribute;
4131 switch (attribute)
4133 case DW_AT_sibling: return "DW_AT_sibling";
4134 case DW_AT_location: return "DW_AT_location";
4135 case DW_AT_name: return "DW_AT_name";
4136 case DW_AT_ordering: return "DW_AT_ordering";
4137 case DW_AT_subscr_data: return "DW_AT_subscr_data";
4138 case DW_AT_byte_size: return "DW_AT_byte_size";
4139 case DW_AT_bit_offset: return "DW_AT_bit_offset";
4140 case DW_AT_bit_size: return "DW_AT_bit_size";
4141 case DW_AT_element_list: return "DW_AT_element_list";
4142 case DW_AT_stmt_list: return "DW_AT_stmt_list";
4143 case DW_AT_low_pc: return "DW_AT_low_pc";
4144 case DW_AT_high_pc: return "DW_AT_high_pc";
4145 case DW_AT_language: return "DW_AT_language";
4146 case DW_AT_member: return "DW_AT_member";
4147 case DW_AT_discr: return "DW_AT_discr";
4148 case DW_AT_discr_value: return "DW_AT_discr_value";
4149 case DW_AT_visibility: return "DW_AT_visibility";
4150 case DW_AT_import: return "DW_AT_import";
4151 case DW_AT_string_length: return "DW_AT_string_length";
4152 case DW_AT_common_reference: return "DW_AT_common_reference";
4153 case DW_AT_comp_dir: return "DW_AT_comp_dir";
4154 case DW_AT_const_value: return "DW_AT_const_value";
4155 case DW_AT_containing_type: return "DW_AT_containing_type";
4156 case DW_AT_default_value: return "DW_AT_default_value";
4157 case DW_AT_inline: return "DW_AT_inline";
4158 case DW_AT_is_optional: return "DW_AT_is_optional";
4159 case DW_AT_lower_bound: return "DW_AT_lower_bound";
4160 case DW_AT_producer: return "DW_AT_producer";
4161 case DW_AT_prototyped: return "DW_AT_prototyped";
4162 case DW_AT_return_addr: return "DW_AT_return_addr";
4163 case DW_AT_start_scope: return "DW_AT_start_scope";
4164 case DW_AT_stride_size: return "DW_AT_stride_size";
4165 case DW_AT_upper_bound: return "DW_AT_upper_bound";
4166 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4167 case DW_AT_accessibility: return "DW_AT_accessibility";
4168 case DW_AT_address_class: return "DW_AT_address_class";
4169 case DW_AT_artificial: return "DW_AT_artificial";
4170 case DW_AT_base_types: return "DW_AT_base_types";
4171 case DW_AT_calling_convention: return "DW_AT_calling_convention";
4172 case DW_AT_count: return "DW_AT_count";
4173 case DW_AT_data_member_location: return "DW_AT_data_member_location";
4174 case DW_AT_decl_column: return "DW_AT_decl_column";
4175 case DW_AT_decl_file: return "DW_AT_decl_file";
4176 case DW_AT_decl_line: return "DW_AT_decl_line";
4177 case DW_AT_declaration: return "DW_AT_declaration";
4178 case DW_AT_discr_list: return "DW_AT_discr_list";
4179 case DW_AT_encoding: return "DW_AT_encoding";
4180 case DW_AT_external: return "DW_AT_external";
4181 case DW_AT_frame_base: return "DW_AT_frame_base";
4182 case DW_AT_friend: return "DW_AT_friend";
4183 case DW_AT_identifier_case: return "DW_AT_identifier_case";
4184 case DW_AT_macro_info: return "DW_AT_macro_info";
4185 case DW_AT_namelist_items: return "DW_AT_namelist_items";
4186 case DW_AT_priority: return "DW_AT_priority";
4187 case DW_AT_segment: return "DW_AT_segment";
4188 case DW_AT_specification: return "DW_AT_specification";
4189 case DW_AT_static_link: return "DW_AT_static_link";
4190 case DW_AT_type: return "DW_AT_type";
4191 case DW_AT_use_location: return "DW_AT_use_location";
4192 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4193 case DW_AT_virtuality: return "DW_AT_virtuality";
4194 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4195 case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4196 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4197 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4198 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4199 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4200 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4201 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4202 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4203 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4204 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4205 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4206 case DW_AT_sf_names: return "DW_AT_sf_names";
4207 case DW_AT_src_info: return "DW_AT_src_info";
4208 case DW_AT_mac_info: return "DW_AT_mac_info";
4209 case DW_AT_src_coords: return "DW_AT_src_coords";
4210 case DW_AT_body_begin: return "DW_AT_body_begin";
4211 case DW_AT_body_end: return "DW_AT_body_end";
4212 default:
4214 static char buffer [100];
4216 sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4217 return buffer;
4222 static char *
4223 get_FORM_name (form)
4224 unsigned long form;
4226 switch (form)
4228 case DW_FORM_addr: return "DW_FORM_addr";
4229 case DW_FORM_block2: return "DW_FORM_block2";
4230 case DW_FORM_block4: return "DW_FORM_block4";
4231 case DW_FORM_data2: return "DW_FORM_data2";
4232 case DW_FORM_data4: return "DW_FORM_data4";
4233 case DW_FORM_data8: return "DW_FORM_data8";
4234 case DW_FORM_string: return "DW_FORM_string";
4235 case DW_FORM_block: return "DW_FORM_block";
4236 case DW_FORM_block1: return "DW_FORM_block1";
4237 case DW_FORM_data1: return "DW_FORM_data1";
4238 case DW_FORM_flag: return "DW_FORM_flag";
4239 case DW_FORM_sdata: return "DW_FORM_sdata";
4240 case DW_FORM_strp: return "DW_FORM_strp";
4241 case DW_FORM_udata: return "DW_FORM_udata";
4242 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4243 case DW_FORM_ref1: return "DW_FORM_ref1";
4244 case DW_FORM_ref2: return "DW_FORM_ref2";
4245 case DW_FORM_ref4: return "DW_FORM_ref4";
4246 case DW_FORM_ref8: return "DW_FORM_ref8";
4247 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4248 case DW_FORM_indirect: return "DW_FORM_indirect";
4249 default:
4251 static char buffer [100];
4253 sprintf (buffer, _("Unknown FORM value: %lx"), form);
4254 return buffer;
4259 /* FIXME: There are better and more effiecint ways to handle
4260 these structures. For now though, I just want something that
4261 is simple to implement. */
4262 typedef struct abbrev_attr
4264 unsigned long attribute;
4265 unsigned long form;
4266 struct abbrev_attr * next;
4268 abbrev_attr;
4270 typedef struct abbrev_entry
4272 unsigned long entry;
4273 unsigned long tag;
4274 int children;
4275 struct abbrev_attr * first_attr;
4276 struct abbrev_attr * last_attr;
4277 struct abbrev_entry * next;
4279 abbrev_entry;
4281 static abbrev_entry * first_abbrev = NULL;
4282 static abbrev_entry * last_abbrev = NULL;
4284 static void
4285 free_abbrevs PARAMS ((void))
4287 abbrev_entry * abbrev;
4289 for (abbrev = first_abbrev; abbrev;)
4291 abbrev_entry * next = abbrev->next;
4292 abbrev_attr * attr;
4294 for (attr = abbrev->first_attr; attr;)
4296 abbrev_attr * next = attr->next;
4298 free (attr);
4299 attr = next;
4302 free (abbrev);
4303 abbrev = next;
4306 last_abbrev = first_abbrev = NULL;
4309 static void
4310 add_abbrev (number, tag, children)
4311 unsigned long number;
4312 unsigned long tag;
4313 int children;
4315 abbrev_entry * entry;
4317 entry = (abbrev_entry *) malloc (sizeof (* entry));
4319 if (entry == NULL)
4320 /* ugg */
4321 return;
4323 entry->entry = number;
4324 entry->tag = tag;
4325 entry->children = children;
4326 entry->first_attr = NULL;
4327 entry->last_attr = NULL;
4328 entry->next = NULL;
4330 if (first_abbrev == NULL)
4331 first_abbrev = entry;
4332 else
4333 last_abbrev->next = entry;
4335 last_abbrev = entry;
4338 static void
4339 add_abbrev_attr (attribute, form)
4340 unsigned long attribute;
4341 unsigned long form;
4343 abbrev_attr * attr;
4345 attr = (abbrev_attr *) malloc (sizeof (* attr));
4347 if (attr == NULL)
4348 /* ugg */
4349 return;
4351 attr->attribute = attribute;
4352 attr->form = form;
4353 attr->next = NULL;
4355 if (last_abbrev->first_attr == NULL)
4356 last_abbrev->first_attr = attr;
4357 else
4358 last_abbrev->last_attr->next = attr;
4360 last_abbrev->last_attr = attr;
4363 /* Processes the (partial) contents of a .debug_abbrev section.
4364 Returns NULL if the end of the section was encountered.
4365 Returns the address after the last byte read if the end of
4366 an abbreviation set was found. */
4368 static unsigned char *
4369 process_abbrev_section (start, end)
4370 unsigned char * start;
4371 unsigned char * end;
4373 if (first_abbrev != NULL)
4374 return NULL;
4376 while (start < end)
4378 int bytes_read;
4379 unsigned long entry;
4380 unsigned long tag;
4381 unsigned long attribute;
4382 int children;
4384 entry = read_leb128 (start, & bytes_read, 0);
4385 start += bytes_read;
4387 if (entry == 0)
4388 return start;
4390 tag = read_leb128 (start, & bytes_read, 0);
4391 start += bytes_read;
4393 children = * start ++;
4395 add_abbrev (entry, tag, children);
4399 unsigned long form;
4401 attribute = read_leb128 (start, & bytes_read, 0);
4402 start += bytes_read;
4404 form = read_leb128 (start, & bytes_read, 0);
4405 start += bytes_read;
4407 if (attribute != 0)
4408 add_abbrev_attr (attribute, form);
4410 while (attribute != 0);
4413 return NULL;
4417 static int
4418 display_debug_abbrev (section, start, file)
4419 Elf32_Internal_Shdr * section;
4420 unsigned char * start;
4421 FILE * file;
4423 abbrev_entry * entry;
4424 unsigned char * end = start + section->sh_size;
4426 printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4430 start = process_abbrev_section (start, end);
4432 printf (_(" Number TAG\n"));
4434 for (entry = first_abbrev; entry; entry = entry->next)
4436 abbrev_attr * attr;
4438 printf (_(" %ld %s [%s]\n"),
4439 entry->entry,
4440 get_TAG_name (entry->tag),
4441 entry->children ? _("has children") : _("no children"));
4443 for (attr = entry->first_attr; attr; attr = attr->next)
4445 printf (_(" %-18s %s\n"),
4446 get_AT_name (attr->attribute),
4447 get_FORM_name (attr->form));
4451 while (start);
4453 printf ("\n");
4455 return 1;
4459 static unsigned char *
4460 display_block (data, length)
4461 unsigned char * data;
4462 unsigned long length;
4464 printf (_(" %lu byte block: "), length);
4466 while (length --)
4467 printf ("%lx ", byte_get (data ++, 1));
4469 return data;
4472 static void
4473 decode_location_expression (data, pointer_size)
4474 unsigned char * data;
4475 unsigned int pointer_size;
4477 unsigned char op;
4478 int bytes_read;
4480 op = * data ++;
4482 switch (op)
4484 case DW_OP_addr: printf ("DW_OP_addr: %lx", byte_get (data, pointer_size)); break;
4485 case DW_OP_deref: printf ("DW_OP_deref"); break;
4486 case DW_OP_const1u: printf ("DW_OP_const1u: %lu", byte_get (data, 1)); break;
4487 case DW_OP_const1s: printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1)); break;
4488 case DW_OP_const2u: printf ("DW_OP_const2u: %lu", byte_get (data, 2)); break;
4489 case DW_OP_const2s: printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2)); break;
4490 case DW_OP_const4u: printf ("DW_OP_const4u: %lu", byte_get (data, 4)); break;
4491 case DW_OP_const4s: printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4)); break;
4492 case DW_OP_const8u: printf ("DW_OP_const8u: %lu %lu", byte_get (data, 4), byte_get (data + 4, 4)); break;
4493 case DW_OP_const8s: printf ("DW_OP_const8s: %ld %ld", byte_get (data, 4), byte_get (data + 4, 4)); break;
4494 case DW_OP_constu: printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0)); break;
4495 case DW_OP_consts: printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1)); break;
4496 case DW_OP_dup: printf ("DW_OP_dup"); break;
4497 case DW_OP_drop: printf ("DW_OP_drop"); break;
4498 case DW_OP_over: printf ("DW_OP_over"); break;
4499 case DW_OP_pick: printf ("DW_OP_pick: %ld", byte_get (data, 1)); break;
4500 case DW_OP_swap: printf ("DW_OP_swap"); break;
4501 case DW_OP_rot: printf ("DW_OP_rot"); break;
4502 case DW_OP_xderef: printf ("DW_OP_xderef"); break;
4503 case DW_OP_abs: printf ("DW_OP_abs"); break;
4504 case DW_OP_and: printf ("DW_OP_and"); break;
4505 case DW_OP_div: printf ("DW_OP_div"); break;
4506 case DW_OP_minus: printf ("DW_OP_minus"); break;
4507 case DW_OP_mod: printf ("DW_OP_mod"); break;
4508 case DW_OP_mul: printf ("DW_OP_mul"); break;
4509 case DW_OP_neg: printf ("DW_OP_neg"); break;
4510 case DW_OP_not: printf ("DW_OP_not"); break;
4511 case DW_OP_or: printf ("DW_OP_or"); break;
4512 case DW_OP_plus: printf ("DW_OP_plus"); break;
4513 case DW_OP_plus_uconst: printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0)); break;
4514 case DW_OP_shl: printf ("DW_OP_shl"); break;
4515 case DW_OP_shr: printf ("DW_OP_shr"); break;
4516 case DW_OP_shra: printf ("DW_OP_shra"); break;
4517 case DW_OP_xor: printf ("DW_OP_xor"); break;
4518 case DW_OP_bra: printf ("DW_OP_bra: %ld", byte_get (data, 2)); break;
4519 case DW_OP_eq: printf ("DW_OP_eq"); break;
4520 case DW_OP_ge: printf ("DW_OP_ge"); break;
4521 case DW_OP_gt: printf ("DW_OP_gt"); break;
4522 case DW_OP_le: printf ("DW_OP_le"); break;
4523 case DW_OP_lt: printf ("DW_OP_lt"); break;
4524 case DW_OP_ne: printf ("DW_OP_ne"); break;
4525 case DW_OP_skip: printf ("DW_OP_skip: %ld", byte_get (data, 2)); break;
4526 case DW_OP_lit0: printf ("DW_OP_lit0"); break;
4527 case DW_OP_lit1: printf ("DW_OP_lit1"); break;
4528 case DW_OP_lit2: printf ("DW_OP_lit2"); break;
4529 case DW_OP_lit3: printf ("DW_OP_lit3"); break;
4530 case DW_OP_lit4: printf ("DW_OP_lit4"); break;
4531 case DW_OP_lit5: printf ("DW_OP_lit5"); break;
4532 case DW_OP_lit6: printf ("DW_OP_lit6"); break;
4533 case DW_OP_lit7: printf ("DW_OP_lit7"); break;
4534 case DW_OP_lit8: printf ("DW_OP_lit8"); break;
4535 case DW_OP_lit9: printf ("DW_OP_lit9"); break;
4536 case DW_OP_lit10: printf ("DW_OP_lit10"); break;
4537 case DW_OP_lit11: printf ("DW_OP_lit11"); break;
4538 case DW_OP_lit12: printf ("DW_OP_lit12"); break;
4539 case DW_OP_lit13: printf ("DW_OP_lit13"); break;
4540 case DW_OP_lit14: printf ("DW_OP_lit14"); break;
4541 case DW_OP_lit15: printf ("DW_OP_lit15"); break;
4542 case DW_OP_lit16: printf ("DW_OP_lit16"); break;
4543 case DW_OP_lit17: printf ("DW_OP_lit17"); break;
4544 case DW_OP_lit18: printf ("DW_OP_lit18"); break;
4545 case DW_OP_lit19: printf ("DW_OP_lit19"); break;
4546 case DW_OP_lit20: printf ("DW_OP_lit20"); break;
4547 case DW_OP_lit21: printf ("DW_OP_lit21"); break;
4548 case DW_OP_lit22: printf ("DW_OP_lit22"); break;
4549 case DW_OP_lit23: printf ("DW_OP_lit23"); break;
4550 case DW_OP_lit24: printf ("DW_OP_lit24"); break;
4551 case DW_OP_lit25: printf ("DW_OP_lit25"); break;
4552 case DW_OP_lit26: printf ("DW_OP_lit26"); break;
4553 case DW_OP_lit27: printf ("DW_OP_lit27"); break;
4554 case DW_OP_lit28: printf ("DW_OP_lit28"); break;
4555 case DW_OP_lit29: printf ("DW_OP_lit29"); break;
4556 case DW_OP_lit30: printf ("DW_OP_lit30"); break;
4557 case DW_OP_lit31: printf ("DW_OP_lit31"); break;
4558 case DW_OP_reg0: printf ("DW_OP_reg0"); break;
4559 case DW_OP_reg1: printf ("DW_OP_reg1"); break;
4560 case DW_OP_reg2: printf ("DW_OP_reg2"); break;
4561 case DW_OP_reg3: printf ("DW_OP_reg3"); break;
4562 case DW_OP_reg4: printf ("DW_OP_reg4"); break;
4563 case DW_OP_reg5: printf ("DW_OP_reg5"); break;
4564 case DW_OP_reg6: printf ("DW_OP_reg6"); break;
4565 case DW_OP_reg7: printf ("DW_OP_reg7"); break;
4566 case DW_OP_reg8: printf ("DW_OP_reg8"); break;
4567 case DW_OP_reg9: printf ("DW_OP_reg9"); break;
4568 case DW_OP_reg10: printf ("DW_OP_reg10"); break;
4569 case DW_OP_reg11: printf ("DW_OP_reg11"); break;
4570 case DW_OP_reg12: printf ("DW_OP_reg12"); break;
4571 case DW_OP_reg13: printf ("DW_OP_reg13"); break;
4572 case DW_OP_reg14: printf ("DW_OP_reg14"); break;
4573 case DW_OP_reg15: printf ("DW_OP_reg15"); break;
4574 case DW_OP_reg16: printf ("DW_OP_reg16"); break;
4575 case DW_OP_reg17: printf ("DW_OP_reg17"); break;
4576 case DW_OP_reg18: printf ("DW_OP_reg18"); break;
4577 case DW_OP_reg19: printf ("DW_OP_reg19"); break;
4578 case DW_OP_reg20: printf ("DW_OP_reg20"); break;
4579 case DW_OP_reg21: printf ("DW_OP_reg21"); break;
4580 case DW_OP_reg22: printf ("DW_OP_reg22"); break;
4581 case DW_OP_reg23: printf ("DW_OP_reg23"); break;
4582 case DW_OP_reg24: printf ("DW_OP_reg24"); break;
4583 case DW_OP_reg25: printf ("DW_OP_reg25"); break;
4584 case DW_OP_reg26: printf ("DW_OP_reg26"); break;
4585 case DW_OP_reg27: printf ("DW_OP_reg27"); break;
4586 case DW_OP_reg28: printf ("DW_OP_reg28"); break;
4587 case DW_OP_reg29: printf ("DW_OP_reg29"); break;
4588 case DW_OP_reg30: printf ("DW_OP_reg30"); break;
4589 case DW_OP_reg31: printf ("DW_OP_reg31"); break;
4590 case DW_OP_breg0: printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1)); break;
4591 case DW_OP_breg1: printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1)); break;
4592 case DW_OP_breg2: printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1)); break;
4593 case DW_OP_breg3: printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1)); break;
4594 case DW_OP_breg4: printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1)); break;
4595 case DW_OP_breg5: printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1)); break;
4596 case DW_OP_breg6: printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1)); break;
4597 case DW_OP_breg7: printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1)); break;
4598 case DW_OP_breg8: printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1)); break;
4599 case DW_OP_breg9: printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1)); break;
4600 case DW_OP_breg10: printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1)); break;
4601 case DW_OP_breg11: printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1)); break;
4602 case DW_OP_breg12: printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1)); break;
4603 case DW_OP_breg13: printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1)); break;
4604 case DW_OP_breg14: printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1)); break;
4605 case DW_OP_breg15: printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1)); break;
4606 case DW_OP_breg16: printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1)); break;
4607 case DW_OP_breg17: printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1)); break;
4608 case DW_OP_breg18: printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1)); break;
4609 case DW_OP_breg19: printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1)); break;
4610 case DW_OP_breg20: printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1)); break;
4611 case DW_OP_breg21: printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1)); break;
4612 case DW_OP_breg22: printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1)); break;
4613 case DW_OP_breg23: printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1)); break;
4614 case DW_OP_breg24: printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1)); break;
4615 case DW_OP_breg25: printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1)); break;
4616 case DW_OP_breg26: printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1)); break;
4617 case DW_OP_breg27: printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1)); break;
4618 case DW_OP_breg28: printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1)); break;
4619 case DW_OP_breg29: printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1)); break;
4620 case DW_OP_breg30: printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1)); break;
4621 case DW_OP_breg31: printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1)); break;
4622 case DW_OP_regx: printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0)); break;
4623 case DW_OP_fbreg: printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1)); break;
4624 case DW_OP_bregx: printf ("DW_OP_bregx: %lu %ld", read_leb128 (data, & bytes_read, 0), read_leb128 (data + bytes_read, NULL, 1)); break;
4625 case DW_OP_piece: printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0)); break;
4626 case DW_OP_deref_size: printf ("DW_OP_deref_size: %ld", byte_get (data, 1)); break;
4627 case DW_OP_xderef_size: printf ("DW_OP_xderef_size: %ld", byte_get (data, 1)); break;
4628 case DW_OP_nop: printf ("DW_OP_nop"); break;
4630 default:
4631 if (op >= DW_OP_lo_user
4632 && op <= DW_OP_hi_user)
4633 printf (_("(User defined location op)"));
4634 else
4635 printf (_("(Unknown location op)"));
4636 break;
4641 static unsigned char *
4642 read_and_display_attr (attribute, form, data, pointer_size)
4643 unsigned long attribute;
4644 unsigned long form;
4645 unsigned char * data;
4646 unsigned long pointer_size;
4648 unsigned long uvalue;
4649 unsigned char * block_start;
4650 int bytes_read;
4651 int is_ref = 0;
4653 printf (" %-18s:", get_AT_name (attribute));
4655 switch (form)
4657 case DW_FORM_ref_addr:
4658 case DW_FORM_ref1:
4659 case DW_FORM_ref2:
4660 case DW_FORM_ref4:
4661 case DW_FORM_ref8:
4662 case DW_FORM_ref_udata:
4663 is_ref = 1;
4666 switch (form)
4668 case DW_FORM_ref_addr:
4669 case DW_FORM_addr:
4670 uvalue = byte_get (data, pointer_size);
4671 printf (is_ref ? " <%x>" : " %#x", uvalue);
4672 data += pointer_size;
4673 break;
4675 case DW_FORM_ref1:
4676 case DW_FORM_flag:
4677 case DW_FORM_data1:
4678 uvalue = byte_get (data ++, 1);
4679 printf (is_ref ? " <%x>" : " %d", uvalue);
4680 break;
4682 case DW_FORM_ref2:
4683 case DW_FORM_data2:
4684 uvalue = byte_get (data, 2);
4685 data += 2;
4686 printf (is_ref ? " <%x>" : " %d", uvalue);
4687 break;
4689 case DW_FORM_ref4:
4690 case DW_FORM_data4:
4691 uvalue = byte_get (data, 4);
4692 data += 4;
4693 printf (is_ref ? " <%x>" : " %d", uvalue);
4694 break;
4696 case DW_FORM_ref8:
4697 case DW_FORM_data8:
4698 uvalue = byte_get (data, 4);
4699 printf (" %lx", uvalue);
4700 printf (" %lx", byte_get (data + 4, 4));
4701 data += 8;
4702 break;
4704 case DW_FORM_string:
4705 printf (" %s", data);
4706 data += strlen (data) + 1;
4707 break;
4709 case DW_FORM_sdata:
4710 uvalue = read_leb128 (data, & bytes_read, 1);
4711 data += bytes_read;
4712 printf (" %ld", (long) uvalue);
4713 break;
4715 case DW_FORM_ref_udata:
4716 case DW_FORM_udata:
4717 uvalue = read_leb128 (data, & bytes_read, 0);
4718 data += bytes_read;
4719 printf (is_ref ? " <%lx>" : " %ld", uvalue);
4720 break;
4722 case DW_FORM_block:
4723 uvalue = read_leb128 (data, & bytes_read, 0);
4724 block_start = data + bytes_read;
4725 data = display_block (block_start, uvalue);
4726 uvalue = * block_start;
4727 break;
4729 case DW_FORM_block1:
4730 uvalue = byte_get (data, 1);
4731 block_start = data + 1;
4732 data = display_block (block_start, uvalue);
4733 uvalue = * block_start;
4734 break;
4736 case DW_FORM_block2:
4737 uvalue = byte_get (data, 2);
4738 block_start = data + 2;
4739 data = display_block (block_start, uvalue);
4740 uvalue = * block_start;
4741 break;
4743 case DW_FORM_block4:
4744 uvalue = byte_get (data, 4);
4745 block_start = data + 4;
4746 data = display_block (block_start, uvalue);
4747 uvalue = * block_start;
4748 break;
4750 case DW_FORM_strp:
4751 case DW_FORM_indirect:
4752 warn (_("Unable to handle FORM: %d"), form);
4753 break;
4755 default:
4756 warn (_("Unrecognised form: %d"), form);
4757 break;
4760 /* For some attributes we can display futher information. */
4762 printf ("\t");
4764 switch (attribute)
4766 case DW_AT_inline:
4767 switch (uvalue)
4769 case DW_INL_not_inlined: printf (_("(not inlined)")); break;
4770 case DW_INL_inlined: printf (_("(inlined)")); break;
4771 case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
4772 case DW_INL_declared_inlined: printf (_("(declared as inline and inlined)")); break;
4773 default: printf (_(" (Unknown inline attribute value: %lx)"), uvalue); break;
4775 break;
4777 case DW_AT_frame_base:
4778 if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
4779 printf ("(reg %ld)", uvalue - DW_OP_reg0);
4780 break;
4782 case DW_AT_language:
4783 switch (uvalue)
4785 case DW_LANG_C: printf ("(non-ANSI C)"); break;
4786 case DW_LANG_C89: printf ("(ANSI C)"); break;
4787 case DW_LANG_C_plus_plus: printf ("(C++)"); break;
4788 case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
4789 case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
4790 case DW_LANG_Modula2: printf ("(Modula 2)"); break;
4791 case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
4792 case DW_LANG_Ada83: printf ("(Ada)"); break;
4793 case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
4794 case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
4795 case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
4796 default: printf ("(Unknown: %lx)", uvalue); break;
4798 break;
4800 case DW_AT_encoding:
4801 switch (uvalue)
4803 case DW_ATE_void: printf ("(void)"); break;
4804 case DW_ATE_address: printf ("(machine address)"); break;
4805 case DW_ATE_boolean: printf ("(boolean)"); break;
4806 case DW_ATE_complex_float: printf ("(complex float)"); break;
4807 case DW_ATE_float: printf ("(float)"); break;
4808 case DW_ATE_signed: printf ("(signed)"); break;
4809 case DW_ATE_signed_char: printf ("(signed char)"); break;
4810 case DW_ATE_unsigned: printf ("(unsigned)"); break;
4811 case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
4812 default:
4813 if (uvalue >= DW_ATE_lo_user
4814 && uvalue <= DW_ATE_hi_user)
4815 printf ("(user defined type)");
4816 else
4817 printf ("(unknown type)");
4818 break;
4820 break;
4822 case DW_AT_accessibility:
4823 switch (uvalue)
4825 case DW_ACCESS_public: printf ("(public)"); break;
4826 case DW_ACCESS_protected: printf ("(protected)"); break;
4827 case DW_ACCESS_private: printf ("(private)"); break;
4828 default: printf ("(unknown accessibility)"); break;
4830 break;
4832 case DW_AT_visibility:
4833 switch (uvalue)
4835 case DW_VIS_local: printf ("(local)"); break;
4836 case DW_VIS_exported: printf ("(exported)"); break;
4837 case DW_VIS_qualified: printf ("(qualified)"); break;
4838 default: printf ("(unknown visibility)"); break;
4840 break;
4842 case DW_AT_virtuality:
4843 switch (uvalue)
4845 case DW_VIRTUALITY_none: printf ("(none)"); break;
4846 case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
4847 case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
4848 default: printf ("(unknown virtuality)"); break;
4850 break;
4852 case DW_AT_identifier_case:
4853 switch (uvalue)
4855 case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
4856 case DW_ID_up_case: printf ("(up_case)"); break;
4857 case DW_ID_down_case: printf ("(down_case)"); break;
4858 case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
4859 default: printf ("(unknown case)"); break;
4861 break;
4863 case DW_AT_calling_convention:
4864 switch (uvalue)
4866 case DW_CC_normal: printf ("(normal)"); break;
4867 case DW_CC_program: printf ("(program)"); break;
4868 case DW_CC_nocall: printf ("(nocall)"); break;
4869 default:
4870 if (uvalue >= DW_CC_lo_user
4871 && uvalue <= DW_CC_hi_user)
4872 printf ("(user defined)");
4873 else
4874 printf ("(unknown convention)");
4876 break;
4878 case DW_AT_location:
4879 case DW_AT_data_member_location:
4880 case DW_AT_vtable_elem_location:
4881 printf ("(");
4882 decode_location_expression (block_start, pointer_size);
4883 printf (")");
4884 break;
4886 default:
4887 break;
4890 printf ("\n");
4891 return data;
4894 static int
4895 display_debug_info (section, start, file)
4896 Elf32_Internal_Shdr * section;
4897 unsigned char * start;
4898 FILE * file;
4900 unsigned char * end = start + section->sh_size;
4901 unsigned char * section_begin = start;
4903 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
4905 while (start < end)
4907 DWARF2_External_CompUnit * external;
4908 DWARF2_Internal_CompUnit compunit;
4909 unsigned char * tags;
4910 int i;
4911 int level;
4913 external = (DWARF2_External_CompUnit *) start;
4915 compunit.cu_length = BYTE_GET (external->cu_length);
4916 compunit.cu_version = BYTE_GET (external->cu_version);
4917 compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
4918 compunit.cu_pointer_size = BYTE_GET (external->cu_pointer_size);
4920 tags = start + sizeof (* external);
4921 start += compunit.cu_length + sizeof (external->cu_length);
4923 if (compunit.cu_version != 2)
4925 warn (_("Only version 2 DWARF debug information is currently supported.\n"));
4926 continue;
4929 printf (_(" Compilation Unit:\n"));
4930 printf (_(" Length: %ld\n"), compunit.cu_length);
4931 printf (_(" Version: %d\n"), compunit.cu_version);
4932 printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
4933 printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
4935 if (first_abbrev != NULL)
4936 free_abbrevs ();
4938 /* Read in the abbrevs used by this compilation unit. */
4941 Elf32_Internal_Shdr * sec;
4942 unsigned char * begin;
4944 /* Locate the .debug_abbrev section and process it. */
4945 for (i = 0, sec = section_headers;
4946 i < elf_header.e_shnum;
4947 i ++, sec ++)
4948 if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
4949 break;
4951 if (i == -1 || sec->sh_size == 0)
4953 warn (_("Unable to locate .debug_abbrev section!\n"));
4954 return 0;
4957 GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
4958 "debug_abbrev section data");
4960 process_abbrev_section (begin + compunit.cu_abbrev_offset,
4961 begin + sec->sh_size);
4963 free (begin);
4966 level = 0;
4967 while (tags < start)
4969 int bytes_read;
4970 int abbrev_number;
4971 abbrev_entry * entry;
4972 abbrev_attr * attr;
4974 abbrev_number = read_leb128 (tags, & bytes_read, 0);
4975 tags += bytes_read;
4977 /* A null DIE marks the end of a list of children. */
4978 if (abbrev_number == 0)
4980 --level;
4981 continue;
4984 /* Scan through the abbreviation list until we reach the
4985 correct entry. */
4986 for (entry = first_abbrev;
4987 entry && entry->entry != abbrev_number;
4988 entry = entry->next)
4989 continue;
4991 if (entry == NULL)
4993 warn (_("Unable to locate entry %d in the abbreviation table\n"),
4994 abbrev_number);
4995 return 0;
4998 printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
4999 level, tags - section_begin - bytes_read,
5000 abbrev_number,
5001 get_TAG_name (entry->tag));
5003 for (attr = entry->first_attr; attr; attr = attr->next)
5004 tags = read_and_display_attr (attr->attribute,
5005 attr->form,
5006 tags,
5007 compunit.cu_pointer_size);
5009 if (entry->children)
5010 ++level;
5014 printf ("\n");
5016 return 1;
5019 static int
5020 display_debug_aranges (section, start, file)
5021 Elf32_Internal_Shdr * section;
5022 unsigned char * start;
5023 FILE * file;
5025 unsigned char * end = start + section->sh_size;
5027 printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5029 while (start < end)
5031 DWARF2_External_ARange * external;
5032 DWARF2_Internal_ARange arange;
5033 unsigned char * ranges;
5034 unsigned long length;
5035 unsigned long address;
5037 external = (DWARF2_External_ARange *) start;
5039 arange.ar_length = BYTE_GET (external->ar_length);
5040 arange.ar_version = BYTE_GET (external->ar_version);
5041 arange.ar_info_offset = BYTE_GET (external->ar_info_offset);
5042 arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
5043 arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
5045 printf (_(" Length: %ld\n"), arange.ar_length);
5046 printf (_(" Version: %d\n"), arange.ar_version);
5047 printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset);
5048 printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size);
5049 printf (_(" Segment Size: %d\n"), arange.ar_segment_size);
5051 printf (_("\n Address Length\n"));
5053 ranges = start + sizeof (* external);
5055 for (;;)
5057 address = byte_get (ranges, arange.ar_pointer_size);
5059 if (address == 0)
5060 break;
5062 ranges += arange.ar_pointer_size;
5064 length = byte_get (ranges, arange.ar_pointer_size);
5066 ranges += arange.ar_pointer_size;
5068 printf (" %8.8lx %lu\n", address, length);
5071 start += arange.ar_length + sizeof (external->ar_length);
5074 printf ("\n");
5076 return 1;
5080 static int
5081 display_debug_not_supported (section, start, file)
5082 Elf32_Internal_Shdr * section;
5083 unsigned char * start;
5084 FILE * file;
5086 printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5087 SECTION_NAME (section));
5089 return 1;
5092 /* A structure containing the name of a debug section and a pointer
5093 to a function that can decode it. */
5094 struct
5096 char * name;
5097 int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5099 debug_displays[] =
5101 { ".debug_info", display_debug_info },
5102 { ".debug_abbrev", display_debug_abbrev },
5103 { ".debug_line", display_debug_lines },
5104 { ".debug_aranges", display_debug_aranges },
5105 { ".debug_pubnames", display_debug_pubnames },
5106 { ".debug_macinfo", display_debug_not_supported },
5107 { ".debug_frame", display_debug_not_supported },
5108 { ".debug_str", display_debug_not_supported },
5109 { ".debug_static_func", display_debug_not_supported },
5110 { ".debug_static_vars", display_debug_not_supported },
5111 { ".debug_types", display_debug_not_supported },
5112 { ".debug_weaknames", display_debug_not_supported }
5115 static int
5116 display_debug_section (section, file)
5117 Elf32_Internal_Shdr * section;
5118 FILE * file;
5120 char * name = SECTION_NAME (section);
5121 bfd_size_type length;
5122 unsigned char * start;
5123 int i;
5125 length = section->sh_size;
5126 if (length == 0)
5128 printf (_("\nSection '%s' has no debugging data.\n"), name);
5129 return 0;
5132 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5133 "debug section data");
5135 /* See if we know how to display the contents of this section. */
5136 for (i = NUM_ELEM (debug_displays); i--;)
5137 if (strcmp (debug_displays[i].name, name) == 0)
5139 debug_displays[i].display (section, start, file);
5140 break;
5143 if (i == -1)
5144 printf (_("Unrecognised debug section: %s\n"), name);
5146 free (start);
5148 /* If we loaded in the abbrev section at some point,
5149 we must release it here. */
5150 if (first_abbrev != NULL)
5151 free_abbrevs ();
5153 return 1;
5156 static int
5157 process_section_contents (file)
5158 FILE * file;
5160 Elf32_Internal_Shdr * section;
5161 unsigned int i;
5163 if (! do_dump)
5164 return 1;
5166 for (i = 0, section = section_headers;
5167 i < elf_header.e_shnum
5168 && i < num_dump_sects;
5169 i ++, section ++)
5171 #ifdef SUPPORT_DISASSEMBLY
5172 if (dump_sects[i] & DISASS_DUMP)
5173 disassemble_section (section, file);
5174 #endif
5175 if (dump_sects[i] & HEX_DUMP)
5176 dump_section (section, file);
5178 if (dump_sects[i] & DEBUG_DUMP)
5179 display_debug_section (section, file);
5182 if (i < num_dump_sects)
5183 warn (_("Some sections were not dumped because they do not exist!\n"));
5185 return 1;
5188 static void
5189 process_mips_fpe_exception (mask)
5190 int mask;
5192 if (mask)
5194 int first = 1;
5195 if (mask & OEX_FPU_INEX)
5196 fputs ("INEX", stdout), first = 0;
5197 if (mask & OEX_FPU_UFLO)
5198 printf ("%sUFLO", first ? "" : "|"), first = 0;
5199 if (mask & OEX_FPU_OFLO)
5200 printf ("%sOFLO", first ? "" : "|"), first = 0;
5201 if (mask & OEX_FPU_DIV0)
5202 printf ("%sDIV0", first ? "" : "|"), first = 0;
5203 if (mask & OEX_FPU_INVAL)
5204 printf ("%sINVAL", first ? "" : "|");
5206 else
5207 fputs ("0", stdout);
5210 static int
5211 process_mips_specific (file)
5212 FILE *file;
5214 Elf_Internal_Dyn *entry;
5215 size_t liblist_offset = 0;
5216 size_t liblistno = 0;
5217 size_t conflictsno = 0;
5218 size_t options_offset = 0;
5219 size_t conflicts_offset = 0;
5221 /* We have a lot of special sections. Thanks SGI! */
5222 if (dynamic_segment == NULL)
5223 /* No information available. */
5224 return 0;
5226 for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5227 switch (entry->d_tag)
5229 case DT_MIPS_LIBLIST:
5230 liblist_offset = entry->d_un.d_val - loadaddr;
5231 break;
5232 case DT_MIPS_LIBLISTNO:
5233 liblistno = entry->d_un.d_val;
5234 break;
5235 case DT_MIPS_OPTIONS:
5236 options_offset = entry->d_un.d_val - loadaddr;
5237 break;
5238 case DT_MIPS_CONFLICT:
5239 conflicts_offset = entry->d_un.d_val - loadaddr;
5240 break;
5241 case DT_MIPS_CONFLICTNO:
5242 conflictsno = entry->d_un.d_val;
5243 break;
5244 default:
5245 break;
5248 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5250 Elf32_External_Lib *elib;
5251 size_t cnt;
5253 GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5254 elib, Elf32_External_Lib *, "liblist");
5256 printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5257 fputs (" Library Time Stamp Checksum Version Flags\n",
5258 stdout);
5260 for (cnt = 0; cnt < liblistno; ++cnt)
5262 Elf32_Lib liblist;
5263 time_t time;
5264 char timebuf[20];
5266 liblist.l_name = BYTE_GET (elib[cnt].l_name);
5267 time = BYTE_GET (elib[cnt].l_time_stamp);
5268 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5269 liblist.l_version = BYTE_GET (elib[cnt].l_version);
5270 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5272 strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5274 printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5275 dynamic_strings + liblist.l_name, timebuf,
5276 liblist.l_checksum, liblist.l_version);
5278 if (liblist.l_flags == 0)
5279 puts (" NONE");
5280 else
5282 static const struct
5284 const char *name;
5285 int bit;
5286 } l_flags_vals[] =
5288 { " EXACT_MATCH", LL_EXACT_MATCH },
5289 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5290 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5291 { " EXPORTS", LL_EXPORTS },
5292 { " DELAY_LOAD", LL_DELAY_LOAD },
5293 { " DELTA", LL_DELTA }
5295 int flags = liblist.l_flags;
5296 int fcnt;
5298 for (fcnt = 0;
5299 fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5300 ++fcnt)
5301 if ((flags & l_flags_vals[fcnt].bit) != 0)
5303 fputs (l_flags_vals[fcnt].name, stdout);
5304 flags ^= l_flags_vals[fcnt].bit;
5306 if (flags != 0)
5307 printf (" %#x", (unsigned int) flags);
5309 puts ("");
5313 free (elib);
5316 if (options_offset != 0)
5318 Elf_External_Options *eopt;
5319 Elf_Internal_Shdr *sect = section_headers;
5320 Elf_Internal_Options *iopt;
5321 Elf_Internal_Options *option;
5322 size_t offset;
5323 int cnt;
5325 /* Find the section header so that we get the size. */
5326 while (sect->sh_type != SHT_MIPS_OPTIONS)
5327 ++sect;
5329 GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5330 Elf_External_Options *, "options");
5332 iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5333 * sizeof (*iopt));
5334 if (iopt == NULL)
5336 error (_("Out of memory"));
5337 return 0;
5340 offset = cnt = 0;
5341 option = iopt;
5342 while (offset < sect->sh_size)
5344 Elf_External_Options *eoption;
5346 eoption = (Elf_External_Options *) ((char *) eopt + offset);
5348 option->kind = BYTE_GET (eoption->kind);
5349 option->size = BYTE_GET (eoption->size);
5350 option->section = BYTE_GET (eoption->section);
5351 option->info = BYTE_GET (eoption->info);
5353 offset += option->size;
5354 ++option;
5355 ++cnt;
5358 printf (_("\nSection '%s' contains %d entries:\n"),
5359 string_table + sect->sh_name, cnt);
5361 option = iopt;
5362 while (cnt-- > 0)
5364 size_t len;
5366 switch (option->kind)
5368 case ODK_NULL:
5369 /* This shouldn't happen. */
5370 printf (" NULL %d %lx", option->section, option->info);
5371 break;
5372 case ODK_REGINFO:
5373 printf (" REGINFO ");
5374 if (elf_header.e_machine == EM_MIPS)
5376 /* 32bit form. */
5377 Elf32_External_RegInfo *ereg;
5378 Elf32_RegInfo reginfo;
5380 ereg = (Elf32_External_RegInfo *) (option + 1);
5381 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5382 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5383 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5384 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5385 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5386 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5388 printf ("GPR %08lx GP 0x%lx\n",
5389 reginfo.ri_gprmask,
5390 (unsigned long) reginfo.ri_gp_value);
5391 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5392 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5393 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5395 else
5397 /* 64 bit form. */
5398 Elf64_External_RegInfo *ereg;
5399 Elf64_Internal_RegInfo reginfo;
5401 ereg = (Elf64_External_RegInfo *) (option + 1);
5402 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
5403 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
5404 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
5405 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
5406 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
5407 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
5409 printf ("GPR %08lx GP 0x",
5410 reginfo.ri_gprmask);
5411 printf_vma (reginfo.ri_gp_value);
5412 printf ("\n");
5414 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
5415 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
5416 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
5418 ++option;
5419 continue;
5420 case ODK_EXCEPTIONS:
5421 fputs (" EXCEPTIONS fpe_min(", stdout);
5422 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
5423 fputs (") fpe_max(", stdout);
5424 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
5425 fputs (")", stdout);
5427 if (option->info & OEX_PAGE0)
5428 fputs (" PAGE0", stdout);
5429 if (option->info & OEX_SMM)
5430 fputs (" SMM", stdout);
5431 if (option->info & OEX_FPDBUG)
5432 fputs (" FPDBUG", stdout);
5433 if (option->info & OEX_DISMISS)
5434 fputs (" DISMISS", stdout);
5435 break;
5436 case ODK_PAD:
5437 fputs (" PAD ", stdout);
5438 if (option->info & OPAD_PREFIX)
5439 fputs (" PREFIX", stdout);
5440 if (option->info & OPAD_POSTFIX)
5441 fputs (" POSTFIX", stdout);
5442 if (option->info & OPAD_SYMBOL)
5443 fputs (" SYMBOL", stdout);
5444 break;
5445 case ODK_HWPATCH:
5446 fputs (" HWPATCH ", stdout);
5447 if (option->info & OHW_R4KEOP)
5448 fputs (" R4KEOP", stdout);
5449 if (option->info & OHW_R8KPFETCH)
5450 fputs (" R8KPFETCH", stdout);
5451 if (option->info & OHW_R5KEOP)
5452 fputs (" R5KEOP", stdout);
5453 if (option->info & OHW_R5KCVTL)
5454 fputs (" R5KCVTL", stdout);
5455 break;
5456 case ODK_FILL:
5457 fputs (" FILL ", stdout);
5458 /* XXX Print content of info word? */
5459 break;
5460 case ODK_TAGS:
5461 fputs (" TAGS ", stdout);
5462 /* XXX Print content of info word? */
5463 break;
5464 case ODK_HWAND:
5465 fputs (" HWAND ", stdout);
5466 if (option->info & OHWA0_R4KEOP_CHECKED)
5467 fputs (" R4KEOP_CHECKED", stdout);
5468 if (option->info & OHWA0_R4KEOP_CLEAN)
5469 fputs (" R4KEOP_CLEAN", stdout);
5470 break;
5471 case ODK_HWOR:
5472 fputs (" HWOR ", stdout);
5473 if (option->info & OHWA0_R4KEOP_CHECKED)
5474 fputs (" R4KEOP_CHECKED", stdout);
5475 if (option->info & OHWA0_R4KEOP_CLEAN)
5476 fputs (" R4KEOP_CLEAN", stdout);
5477 break;
5478 case ODK_GP_GROUP:
5479 printf (" GP_GROUP %#06lx self-contained %#06lx",
5480 option->info & OGP_GROUP,
5481 (option->info & OGP_SELF) >> 16);
5482 break;
5483 case ODK_IDENT:
5484 printf (" IDENT %#06lx self-contained %#06lx",
5485 option->info & OGP_GROUP,
5486 (option->info & OGP_SELF) >> 16);
5487 break;
5488 default:
5489 /* This shouldn't happen. */
5490 printf (" %3d ??? %d %lx",
5491 option->kind, option->section, option->info);
5492 break;
5495 len = sizeof (*eopt);
5496 while (len < option->size)
5497 if (((char *) option)[len] >= ' '
5498 && ((char *) option)[len] < 0x7f)
5499 printf ("%c", ((char *) option)[len++]);
5500 else
5501 printf ("\\%03o", ((char *) option)[len++]);
5503 fputs ("\n", stdout);
5504 ++option;
5507 free (eopt);
5510 if (conflicts_offset != 0 && conflictsno != 0)
5512 Elf32_External_Conflict *econf32;
5513 Elf64_External_Conflict *econf64;
5514 Elf32_Conflict *iconf;
5515 size_t cnt;
5517 if (dynamic_symbols == NULL)
5519 error (_("conflict list with without table"));
5520 return 0;
5523 iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
5524 if (iconf == NULL)
5526 error (_("Out of memory"));
5527 return 0;
5530 if (binary_class == ELFCLASS32)
5532 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
5533 econf32, Elf32_External_Conflict *, "conflict");
5535 for (cnt = 0; cnt < conflictsno; ++cnt)
5536 iconf[cnt] = BYTE_GET (econf32[cnt]);
5538 else
5540 GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
5541 econf64, Elf64_External_Conflict *, "conflict");
5543 for (cnt = 0; cnt < conflictsno; ++cnt)
5544 iconf[cnt] = BYTE_GET (econf64[cnt]);
5547 printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
5548 puts (_(" Num: Index Value Name"));
5550 for (cnt = 0; cnt < conflictsno; ++cnt)
5552 Elf_Internal_Sym *psym = &dynamic_symbols[iconf[cnt]];
5554 printf ("%5u: %8lu %#10lx %s\n",
5555 cnt, iconf[cnt], (unsigned long) psym->st_value,
5556 dynamic_strings + psym->st_name);
5560 free (iconf);
5563 return 1;
5566 static int
5567 process_arch_specific (file)
5568 FILE *file;
5570 switch (elf_header.e_machine)
5572 case EM_MIPS:
5573 case EM_MIPS_RS4_BE:
5574 return process_mips_specific (file);
5575 break;
5576 default:
5577 break;
5579 return 1;
5582 static int
5583 get_file_header (file)
5584 FILE * file;
5586 Elf32_External_Ehdr ehdr;
5588 if (fread (& ehdr, sizeof (ehdr), 1, file) != 1)
5589 return 0;
5591 memcpy (elf_header.e_ident, ehdr.e_ident, EI_NIDENT);
5593 if (elf_header.e_ident [EI_DATA] == ELFDATA2LSB)
5594 byte_get = byte_get_little_endian;
5595 else
5596 byte_get = byte_get_big_endian;
5598 elf_header.e_entry = BYTE_GET (ehdr.e_entry);
5599 elf_header.e_phoff = BYTE_GET (ehdr.e_phoff);
5600 elf_header.e_shoff = BYTE_GET (ehdr.e_shoff);
5601 elf_header.e_version = BYTE_GET (ehdr.e_version);
5602 elf_header.e_flags = BYTE_GET (ehdr.e_flags);
5603 elf_header.e_type = BYTE_GET (ehdr.e_type);
5604 elf_header.e_machine = BYTE_GET (ehdr.e_machine);
5605 elf_header.e_ehsize = BYTE_GET (ehdr.e_ehsize);
5606 elf_header.e_phentsize = BYTE_GET (ehdr.e_phentsize);
5607 elf_header.e_phnum = BYTE_GET (ehdr.e_phnum);
5608 elf_header.e_shentsize = BYTE_GET (ehdr.e_shentsize);
5609 elf_header.e_shnum = BYTE_GET (ehdr.e_shnum);
5610 elf_header.e_shstrndx = BYTE_GET (ehdr.e_shstrndx);
5612 return 1;
5615 static void
5616 process_file (file_name)
5617 char * file_name;
5619 FILE * file;
5620 struct stat statbuf;
5621 unsigned int i;
5623 if (stat (file_name, & statbuf) < 0)
5625 error (_("Cannot stat input file %s.\n"), file_name);
5626 return;
5629 file = fopen (file_name, "rb");
5630 if (file == NULL)
5632 error (_("Input file %s not found.\n"), file_name);
5633 return;
5636 if (! get_file_header (file))
5638 error (_("%s: Failed to read file header\n"), file_name);
5639 fclose (file);
5640 return;
5643 /* Initialise per file variables. */
5644 for (i = NUM_ELEM (version_info); i--;)
5645 version_info[i] = 0;
5647 for (i = NUM_ELEM (dynamic_info); i--;)
5648 dynamic_info[i] = 0;
5650 /* Process the file. */
5651 if (show_name)
5652 printf (_("\nFile: %s\n"), file_name);
5654 if (! process_file_header ())
5656 fclose (file);
5657 return;
5660 process_section_headers (file);
5662 process_program_headers (file);
5664 process_dynamic_segment (file);
5666 process_relocs (file);
5668 process_symbol_table (file);
5670 process_syminfo (file);
5672 process_version_sections (file);
5674 process_section_contents (file);
5676 process_arch_specific (file);
5678 fclose (file);
5680 if (section_headers)
5682 free (section_headers);
5683 section_headers = NULL;
5686 if (string_table)
5688 free (string_table);
5689 string_table = NULL;
5692 if (dynamic_strings)
5694 free (dynamic_strings);
5695 dynamic_strings = NULL;
5698 if (dynamic_symbols)
5700 free (dynamic_symbols);
5701 dynamic_symbols = NULL;
5704 if (dynamic_syminfo)
5706 free (dynamic_syminfo);
5707 dynamic_syminfo = NULL;
5711 #ifdef SUPPORT_DISASSEMBLY
5712 /* Needed by the i386 disassembler. For extra credit, someone could
5713 fix this so that we insert symbolic addresses here, esp for GOT/PLT
5714 symbols */
5716 void
5717 print_address (unsigned int addr, FILE * outfile)
5719 fprintf (outfile,"0x%8.8x", addr);
5722 /* Needed by the i386 disassembler. */
5723 void
5724 db_task_printsym (unsigned int addr)
5726 print_address (addr, stderr);
5728 #endif
5731 main (argc, argv)
5732 int argc;
5733 char ** argv;
5735 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
5736 setlocale (LC_MESSAGES, "");
5737 #endif
5738 bindtextdomain (PACKAGE, LOCALEDIR);
5739 textdomain (PACKAGE);
5741 parse_args (argc, argv);
5743 if (optind < (argc - 1))
5744 show_name = 1;
5746 while (optind < argc)
5747 process_file (argv [optind ++]);
5749 if (dump_sects != NULL)
5750 free (dump_sects);
5752 return 0;