1999-09-15 Ulrich Drepper <drepper@cygnus.com>
[platform/upstream/binutils.git] / binutils / readelf.c
1 /* readelf.c -- display contents of an ELF format file
2    Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
4    Originally developed by Eric Youngdale <eric@andante.jic.com>
5    Modifications by Nick Clifton <nickc@cygnus.com>
6
7    This file is part of GNU Binutils.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22    02111-1307, USA.  */
23 \f
24
25 #include <assert.h>
26 #include <sys/stat.h>
27 #include <stdio.h>
28 #include <time.h>
29
30 #if __GNUC__ >= 2
31 /* Define BFD64 here, even if our default architecture is 32 bit ELF
32    as this will allow us to read in and parse 64bit and 32bit ELF files.
33    Only do this if we belive that the compiler can support a 64 bit
34    data type.  For now we only rely on GCC being able to do this.  */
35 #define BFD64
36 #endif
37
38 #include "bfd.h"
39
40 #include "elf/common.h"
41 #include "elf/external.h"
42 #include "elf/internal.h"
43 #include "elf/dwarf2.h"
44
45 /* The following headers use the elf/reloc-macros.h file to
46    automatically generate relocation recognition functions
47    such as elf_mips_reloc_type()  */
48
49 #define RELOC_MACROS_GEN_FUNC
50
51 #include "elf/i386.h"
52 #include "elf/v850.h"
53 #include "elf/ppc.h"
54 #include "elf/mips.h"
55 #include "elf/alpha.h"
56 #include "elf/arm.h"
57 #include "elf/m68k.h"
58 #include "elf/sparc.h"
59 #include "elf/m32r.h"
60 #include "elf/d10v.h"
61 #include "elf/d30v.h"
62 #include "elf/sh.h"
63 #include "elf/mn10200.h"
64 #include "elf/mn10300.h"
65 #include "elf/hppa.h"
66 #include "elf/arc.h"
67 #include "elf/fr30.h"
68 #include "elf/mcore.h"
69 #include "elf/i960.h"
70 #include "elf/pj.h"
71
72 #include "bucomm.h"
73 #include "getopt.h"
74
75 #ifdef ANSI_PROTOTYPES
76 #include <stdarg.h>
77 #else
78 #include <varargs.h>
79 #endif
80
81 char *                  program_name = "readelf";
82 unsigned int            dynamic_addr;
83 bfd_size_type           dynamic_size;
84 unsigned int            rela_addr;
85 unsigned int            rela_size;
86 char *                  dynamic_strings;
87 char *                  string_table;
88 unsigned long           num_dynamic_syms;
89 Elf_Internal_Sym *      dynamic_symbols;
90 Elf_Internal_Syminfo *  dynamic_syminfo;
91 unsigned long           dynamic_syminfo_offset;
92 unsigned int            dynamic_syminfo_nent;
93 char                    program_interpreter [64];
94 int                     dynamic_info[DT_JMPREL + 1];
95 int                     version_info[16];
96 int                     loadaddr = 0;
97 Elf_Internal_Ehdr       elf_header;
98 Elf_Internal_Shdr *     section_headers;
99 Elf_Internal_Dyn *      dynamic_segment;
100 int                     show_name;
101 int                     do_dynamic;
102 int                     do_syms;
103 int                     do_reloc;
104 int                     do_sections;
105 int                     do_segments;
106 int                     do_using_dynamic;
107 int                     do_header;
108 int                     do_dump;
109 int                     do_version;
110 int                     do_histogram;
111 int                     do_debugging;
112 int                     do_debug_info;
113 int                     do_debug_abbrevs;
114 int                     do_debug_lines;
115 int                     do_debug_pubnames;
116 int                     do_debug_aranges;
117 int                     do_arch;
118 int                     do_notes;
119 int                     is_32bit_elf;
120
121 /* A dynamic array of flags indicating which sections require dumping.  */
122 char *                  dump_sects = NULL;
123 unsigned int            num_dump_sects = 0;
124
125 #define HEX_DUMP        (1 << 0)
126 #define DISASS_DUMP     (1 << 1)
127 #define DEBUG_DUMP      (1 << 2)
128
129 /* Forward declarations for dumb compilers.  */
130 static bfd_vma (*         byte_get)                   PARAMS ((unsigned char *, int));
131 static bfd_vma            byte_get_little_endian      PARAMS ((unsigned char *, int));
132 static bfd_vma            byte_get_big_endian         PARAMS ((unsigned char *, int));
133 static const char *       get_mips_dynamic_type       PARAMS ((unsigned long));
134 static const char *       get_sparc64_dynamic_type    PARAMS ((unsigned long));
135 static const char *       get_parisc_dynamic_type     PARAMS ((unsigned long));
136 static const char *       get_dynamic_type            PARAMS ((unsigned long));
137 static int                dump_relocations            PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
138 static char *             get_file_type               PARAMS ((unsigned));
139 static char *             get_machine_name            PARAMS ((unsigned));
140 static char *             get_machine_flags           PARAMS ((unsigned, unsigned));
141 static const char *       get_mips_segment_type       PARAMS ((unsigned long));
142 static const char *       get_parisc_segment_type     PARAMS ((unsigned long));
143 static const char *       get_segment_type            PARAMS ((unsigned long));
144 static const char *       get_mips_section_type_name  PARAMS ((unsigned int));
145 static const char *       get_parisc_section_type_name PARAMS ((unsigned int));
146 static const char *       get_section_type_name       PARAMS ((unsigned int));
147 static char *             get_symbol_binding          PARAMS ((unsigned int));
148 static char *             get_symbol_type             PARAMS ((unsigned int));
149 static void               usage                       PARAMS ((void));
150 static void               parse_args                  PARAMS ((int, char **));
151 static int                process_file_header         PARAMS ((void));
152 static int                process_program_headers     PARAMS ((FILE *));
153 static int                process_section_headers     PARAMS ((FILE *));
154 static void               dynamic_segment_mips_val    PARAMS ((Elf_Internal_Dyn *));
155 static void               dynamic_segment_parisc_val  PARAMS ((Elf_Internal_Dyn *));
156 static int                process_dynamic_segment     PARAMS ((FILE *));
157 static int                process_symbol_table        PARAMS ((FILE *));
158 static int                process_section_contents    PARAMS ((FILE *));
159 static void               process_file                PARAMS ((char *));
160 static int                process_relocs              PARAMS ((FILE *));
161 static int                process_version_sections    PARAMS ((FILE *));
162 static char *             get_ver_flags               PARAMS ((unsigned int));
163 static char *             get_symbol_index_type       PARAMS ((unsigned int));
164 static int                get_32bit_section_headers   PARAMS ((FILE *));
165 static int                get_64bit_section_headers   PARAMS ((FILE *));
166 static int                get_32bit_program_headers   PARAMS ((FILE *, Elf_Internal_Phdr *));
167 static int                get_64bit_program_headers   PARAMS ((FILE *, Elf_Internal_Phdr *));
168 static int                get_file_header             PARAMS ((FILE *));
169 static Elf_Internal_Sym * get_32bit_elf_symbols       PARAMS ((FILE *, unsigned long, unsigned long));
170 static Elf_Internal_Sym * get_64bit_elf_symbols       PARAMS ((FILE *, unsigned long, unsigned long));
171 static int *              get_dynamic_data            PARAMS ((FILE *, unsigned int));
172 static int                get_32bit_dynamic_segment   PARAMS ((FILE *));
173 static int                get_64bit_dynamic_segment   PARAMS ((FILE *));
174 #ifdef SUPPORT_DISASSEMBLY
175 static int                disassemble_section         PARAMS ((Elf32_Internal_Shdr *, FILE *));
176 #endif
177 static int                dump_section                PARAMS ((Elf32_Internal_Shdr *, FILE *));
178 static int                display_debug_section       PARAMS ((Elf32_Internal_Shdr *, FILE *));
179 static int                display_debug_info          PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
180 static int                display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
181 static int                display_debug_lines         PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
182 static int                display_debug_abbrev        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
183 static int                display_debug_aranges       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
184 static unsigned char *    process_abbrev_section      PARAMS ((unsigned char *, unsigned char *));
185 static unsigned long      read_leb128                 PARAMS ((unsigned char *, int *, int));
186 static int                process_extended_line_op    PARAMS ((unsigned char *, int, int));
187 static void               reset_state_machine         PARAMS ((int));
188 static char *             get_TAG_name                PARAMS ((unsigned long));
189 static char *             get_AT_name                 PARAMS ((unsigned long));
190 static char *             get_FORM_name               PARAMS ((unsigned long));
191 static void               free_abbrevs                PARAMS ((void));
192 static void               add_abbrev                  PARAMS ((unsigned long, unsigned long, int));
193 static void               add_abbrev_attr             PARAMS ((unsigned long, unsigned long));
194 static unsigned char *    read_and_display_attr       PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long));
195 static unsigned char *    display_block               PARAMS ((unsigned char *, unsigned long));
196 static void               decode_location_expression  PARAMS ((unsigned char *, unsigned int));
197 static void               request_dump                PARAMS ((unsigned int, char));
198 static const char *       get_elf_class               PARAMS ((unsigned char));
199 static const char *       get_data_encoding           PARAMS ((unsigned char));
200 static const char *       get_osabi_name              PARAMS ((unsigned char));
201 static int                guess_is_rela               PARAMS ((unsigned long));
202 static char *             get_note_type                  PARAMS ((unsigned int));
203 static int                process_note                   PARAMS ((Elf_External_Note *));
204 static int                process_corefile_note_segment  PARAMS ((FILE *, unsigned long, unsigned long));
205 static int                process_corefile_note_segments PARAMS ((FILE *));
206 static int                process_corefile_contents      PARAMS ((FILE *));
207
208 typedef int Elf32_Word;
209
210 #ifndef TRUE
211 #define TRUE     1
212 #define FALSE    0
213 #endif
214 #define UNKNOWN -1
215
216 #define SECTION_NAME(X)         (string_table + (X)->sh_name)
217
218 #define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
219
220 #define BYTE_GET(field)         byte_get (field, sizeof (field))
221
222 /* If we can support a 64 bit data type then BFD64 should be defined
223    and sizeof (bfd_vma) == 8.  In this case when translating from an
224    external 8 byte field to an internal field, we can assume that the
225    internal field is also 8 bytes wide and so we can extact all the data.
226    If, however, BFD64 is not defined, then we must assume that the
227    internal data structure only has 4 byte wide fields that are the
228    equivalent of the 8 byte wide external counterparts, and so we must
229    truncate the data.  */
230 #ifdef  BFD64
231 #define BYTE_GET8(field)        byte_get (field, -8)
232 #else
233 #define BYTE_GET8(field)        byte_get (field, 8)
234 #endif
235
236 #define NUM_ELEM(array)         (sizeof (array) / sizeof ((array)[0]))
237
238 #define GET_DATA_ALLOC(offset, size, var, type, reason)                 \
239   if (fseek (file, offset, SEEK_SET))                                   \
240     {                                                                   \
241       error (_("Unable to seek to start of %s at %x\n"), reason, offset); \
242       return 0;                                                         \
243     }                                                                   \
244                                                                         \
245   var = (type) malloc (size);                                           \
246                                                                         \
247   if (var == NULL)                                                      \
248     {                                                                   \
249       error (_("Out of memory allocating %d bytes for %s\n"), size, reason); \
250       return 0;                                                         \
251     }                                                                   \
252                                                                         \
253   if (fread (var, size, 1, file) != 1)                                  \
254     {                                                                   \
255       error (_("Unable to read in %d bytes of %s\n"), size, reason);    \
256       free (var);                                                       \
257       var = NULL;                                                       \
258       return 0;                                                         \
259     }
260
261
262 #define GET_DATA(offset, var, reason)                                   \
263   if (fseek (file, offset, SEEK_SET))                                   \
264     {                                                                   \
265       error (_("Unable to seek to %x for %s\n"), offset, reason);       \
266       return 0;                                                         \
267     }                                                                   \
268   else if (fread (& var, sizeof (var), 1, file) != 1)                   \
269     {                                                                   \
270       error (_("Unable to read data at %x for %s\n"), offset, reason);  \
271       return 0;                                                         \
272     }
273
274 #define GET_ELF_SYMBOLS(file, offset, size)                     \
275   (is_32bit_elf ? get_32bit_elf_symbols (file, offset, size)    \
276    : get_64bit_elf_symbols (file, offset, size))
277
278
279 #ifdef ANSI_PROTOTYPES
280 static void
281 error (const char * message, ...)
282 {
283   va_list args;
284
285   fprintf (stderr, _("%s: Error: "), program_name);
286   va_start (args, message);
287   vfprintf (stderr, message, args);
288   va_end (args);
289   return;
290 }
291
292 static void
293 warn (const char * message, ...)
294 {
295   va_list args;
296
297   fprintf (stderr, _("%s: Warning: "), program_name);
298   va_start (args, message);
299   vfprintf (stderr, message, args);
300   va_end (args);
301   return;
302 }
303 #else
304 static void
305 error (va_alist)
306      va_dcl
307 {
308   char * message;
309   va_list args;
310
311   fprintf (stderr, _("%s: Error: "), program_name);
312   va_start (args);
313   message = va_arg (args, char *);
314   vfprintf (stderr, message, args);
315   va_end (args);
316   return;
317 }
318
319 static void
320 warn (va_alist)
321      va_dcl
322 {
323   char * message;
324   va_list args;
325
326   fprintf (stderr, _("%s: Warning: "), program_name);
327   va_start (args);
328   message = va_arg (args, char *);
329   vfprintf (stderr, message, args);
330   va_end (args);
331   return;
332 }
333 #endif
334
335 static bfd_vma
336 byte_get_little_endian (field, size)
337      unsigned char * field;
338      int             size;
339 {
340   switch (size)
341     {
342     case 1:
343       return * field;
344
345     case 2:
346       return  ((unsigned int) (field [0]))
347         |    (((unsigned int) (field [1])) << 8);
348
349     case 8:
350       /* We want to extract data from an 8 byte wide field and
351          place it into a 4 byte wide field.  Since this is a little
352          endian source we can juts use the 4 byte extraction code.  */
353       /* Fall through.  */
354     case 4:
355       return  ((unsigned long) (field [0]))
356         |    (((unsigned long) (field [1])) << 8)
357         |    (((unsigned long) (field [2])) << 16)
358         |    (((unsigned long) (field [3])) << 24);
359
360 #ifdef BFD64
361     case -8:
362       /* This is a special case, generated by the BYTE_GET8 macro.
363          It means that we are loading an 8 byte value from a field
364          in an external structure into an 8 byte value in a field
365          in an internal strcuture.  */
366       return  ((bfd_vma) (field [0]))
367         |    (((bfd_vma) (field [1])) << 8)
368         |    (((bfd_vma) (field [2])) << 16)
369         |    (((bfd_vma) (field [3])) << 24)
370         |    (((bfd_vma) (field [4])) << 32)
371         |    (((bfd_vma) (field [5])) << 40)
372         |    (((bfd_vma) (field [6])) << 48)
373         |    (((bfd_vma) (field [7])) << 56);
374 #endif
375     default:
376       error (_("Unhandled data length: %d\n"), size);
377       abort ();
378     }
379 }
380
381 static bfd_vma
382 byte_get_big_endian (field, size)
383      unsigned char * field;
384      int             size;
385 {
386   switch (size)
387     {
388     case 1:
389       return * field;
390
391     case 2:
392       return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
393
394     case 4:
395       return ((unsigned long) (field [3]))
396         |   (((unsigned long) (field [2])) << 8)
397         |   (((unsigned long) (field [1])) << 16)
398         |   (((unsigned long) (field [0])) << 24);
399
400     case 8:
401       /* Although we are extracing data from an 8 byte wide field, we
402          are returning only 4 bytes of data.  */
403       return ((unsigned long) (field [7]))
404         |   (((unsigned long) (field [6])) << 8)
405         |   (((unsigned long) (field [5])) << 16)
406         |   (((unsigned long) (field [4])) << 24);
407
408 #ifdef BFD64
409     case -8:
410       /* This is a special case, generated by the BYTE_GET8 macro.
411          It means that we are loading an 8 byte value from a field
412          in an external structure into an 8 byte value in a field
413          in an internal strcuture.  */
414       return ((bfd_vma) (field [7]))
415         |   (((bfd_vma) (field [6])) << 8)
416         |   (((bfd_vma) (field [5])) << 16)
417         |   (((bfd_vma) (field [4])) << 24)
418         |   (((bfd_vma) (field [3])) << 32)
419         |   (((bfd_vma) (field [2])) << 40)
420         |   (((bfd_vma) (field [1])) << 48)
421         |   (((bfd_vma) (field [0])) << 56);
422 #endif
423
424     default:
425       error (_("Unhandled data length: %d\n"), size);
426       abort ();
427     }
428 }
429
430
431 /* Guess the relocation sized based on the sized commonly used by the specific machine.  */
432 static int
433 guess_is_rela (e_machine)
434      unsigned long e_machine;
435 {
436   switch (e_machine)
437     {
438       /* Targets that use REL relocations.  */
439     case EM_ARM:
440     case EM_386:
441     case EM_486:
442     case EM_960:
443     case EM_CYGNUS_M32R:
444     case EM_CYGNUS_D10V:
445     case EM_MIPS:
446     case EM_MIPS_RS4_BE:
447       return FALSE;
448
449       /* Targets that use RELA relocations.  */
450     case EM_68K:
451     case EM_SPARC32PLUS:
452     case EM_SPARCV9:
453     case EM_SPARC:
454     case EM_PPC:
455     case EM_CYGNUS_V850:
456     case EM_CYGNUS_D30V:
457     case EM_CYGNUS_MN10200:
458     case EM_CYGNUS_MN10300:
459     case EM_CYGNUS_FR30:
460     case EM_SH:
461     case EM_ALPHA:
462     case EM_MCORE:
463       return TRUE;
464
465     default:
466       warn (_("Don't know about relocations on this machine architecture\n"));
467       return FALSE;
468     }
469 }
470
471 /* Display the contents of the relocation data found at the specified offset.  */
472 static int
473 dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
474      FILE *             file;
475      unsigned long      rel_offset;
476      unsigned long      rel_size;
477      Elf_Internal_Sym * symtab;
478      unsigned long      nsyms;
479      char *             strtab;
480      int                is_rela;
481 {
482   unsigned int        i;
483   Elf_Internal_Rel *  rels;
484   Elf_Internal_Rela * relas;
485
486
487   if (is_rela == UNKNOWN)
488     is_rela = guess_is_rela (elf_header.e_machine);
489
490   if (is_rela)
491     {
492       if (is_32bit_elf)
493         {
494           Elf32_External_Rela * erelas;
495
496           GET_DATA_ALLOC (rel_offset, rel_size, erelas,
497                           Elf32_External_Rela *, "relocs");
498
499           rel_size = rel_size / sizeof (Elf32_External_Rela);
500
501           relas = (Elf_Internal_Rela *)
502             malloc (rel_size * sizeof (Elf_Internal_Rela));
503
504           if (relas == NULL)
505             {
506               error(_("out of memory parsing relocs"));
507               return 0;
508             }
509
510           for (i = 0; i < rel_size; i++)
511             {
512               relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
513               relas[i].r_info   = BYTE_GET (erelas[i].r_info);
514               relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
515             }
516
517           free (erelas);
518
519           rels = (Elf_Internal_Rel *) relas;
520         }
521       else
522         {
523           Elf64_External_Rela * erelas;
524
525           GET_DATA_ALLOC (rel_offset, rel_size, erelas,
526                           Elf64_External_Rela *, "relocs");
527
528           rel_size = rel_size / sizeof (Elf64_External_Rela);
529
530           relas = (Elf_Internal_Rela *)
531             malloc (rel_size * sizeof (Elf_Internal_Rela));
532
533           if (relas == NULL)
534             {
535               error(_("out of memory parsing relocs"));
536               return 0;
537             }
538
539           for (i = 0; i < rel_size; i++)
540             {
541               relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset);
542               relas[i].r_info   = BYTE_GET8 (erelas[i].r_info);
543               relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend);
544             }
545
546           free (erelas);
547
548           rels = (Elf_Internal_Rel *) relas;
549         }
550     }
551   else
552     {
553       if (is_32bit_elf)
554         {
555           Elf32_External_Rel * erels;
556
557           GET_DATA_ALLOC (rel_offset, rel_size, erels,
558                           Elf32_External_Rel *, "relocs");
559
560           rel_size = rel_size / sizeof (Elf32_External_Rel);
561
562           rels = (Elf_Internal_Rel *)
563             malloc (rel_size * sizeof (Elf_Internal_Rel));
564
565           if (rels == NULL)
566             {
567               error(_("out of memory parsing relocs"));
568               return 0;
569             }
570
571           for (i = 0; i < rel_size; i++)
572             {
573               rels[i].r_offset = BYTE_GET (erels[i].r_offset);
574               rels[i].r_info   = BYTE_GET (erels[i].r_info);
575             }
576
577           free (erels);
578
579           relas = (Elf_Internal_Rela *) rels;
580         }
581       else
582         {
583           Elf64_External_Rel * erels;
584
585           GET_DATA_ALLOC (rel_offset, rel_size, erels,
586                           Elf64_External_Rel *, "relocs");
587
588           rel_size = rel_size / sizeof (Elf64_External_Rel);
589
590           rels = (Elf_Internal_Rel *)
591             malloc (rel_size * sizeof (Elf_Internal_Rel));
592
593           if (rels == NULL)
594             {
595               error(_("out of memory parsing relocs"));
596               return 0;
597             }
598
599           for (i = 0; i < rel_size; i++)
600             {
601               rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
602               rels[i].r_info   = BYTE_GET8 (erels[i].r_info);
603             }
604
605           free (erels);
606
607           relas = (Elf_Internal_Rela *) rels;
608         }
609     }
610
611   if (is_rela)
612     printf
613       (_("  Offset    Info  Type            Symbol's Value  Symbol's Name          Addend\n"));
614   else
615     printf
616       (_("  Offset    Info  Type            Symbol's Value  Symbol's Name\n"));
617
618   for (i = 0; i < rel_size; i++)
619     {
620       const char * rtype;
621       bfd_vma      offset;
622       bfd_vma      info;
623       bfd_vma      symtab_index;
624       bfd_vma      type;
625
626       if (is_rela)
627         {
628           offset = relas [i].r_offset;
629           info   = relas [i].r_info;
630         }
631       else
632         {
633           offset = rels [i].r_offset;
634           info   = rels [i].r_info;
635         }
636
637       if (is_32bit_elf)
638         {
639           type         = ELF32_R_TYPE (info);
640           symtab_index = ELF32_R_SYM  (info);
641         }
642       else
643         {
644           if (elf_header.e_machine == EM_SPARCV9)
645             type       = ELF64_R_TYPE_ID (info);
646           else
647             type       = ELF64_R_TYPE (info);
648           /* The #ifdef BFD64 below is to prevent a compile time warning.
649              We know that if we do not have a 64 bit data type that we
650              will never execute this code anyway.  */
651 #ifdef BFD64
652           symtab_index = ELF64_R_SYM  (info);
653 #endif
654         }
655
656 #ifdef _bfd_int64_low
657       printf ("  %8.8lx  %5.5lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
658 #else
659       printf ("  %8.8lx  %5.5lx ", offset, info);
660 #endif
661
662       switch (elf_header.e_machine)
663         {
664         default:
665           rtype = NULL;
666           break;
667
668         case EM_CYGNUS_M32R:
669           rtype = elf_m32r_reloc_type (type);
670           break;
671
672         case EM_386:
673         case EM_486:
674           rtype = elf_i386_reloc_type (type);
675           break;
676
677         case EM_68K:
678           rtype = elf_m68k_reloc_type (type);
679           break;
680
681         case EM_960:
682           rtype = elf_i960_reloc_type (type);
683           break;
684
685         case EM_OLD_SPARCV9:
686         case EM_SPARC32PLUS:
687         case EM_SPARCV9:
688         case EM_SPARC:
689           rtype = elf_sparc_reloc_type (type);
690           break;
691
692         case EM_CYGNUS_V850:
693           rtype = v850_reloc_type (type);
694           break;
695
696         case EM_CYGNUS_D10V:
697           rtype = elf_d10v_reloc_type (type);
698           break;
699
700         case EM_CYGNUS_D30V:
701           rtype = elf_d30v_reloc_type (type);
702           break;
703
704         case EM_SH:
705           rtype = elf_sh_reloc_type (type);
706           break;
707
708         case EM_CYGNUS_MN10300:
709           rtype = elf_mn10300_reloc_type (type);
710           break;
711
712         case EM_CYGNUS_MN10200:
713           rtype = elf_mn10200_reloc_type (type);
714           break;
715
716         case EM_CYGNUS_FR30:
717           rtype = elf_fr30_reloc_type (type);
718           break;
719
720         case EM_MCORE:
721           rtype = elf_mcore_reloc_type (type);
722           break;
723
724         case EM_PPC:
725           rtype = elf_ppc_reloc_type (type);
726           break;
727
728         case EM_MIPS:
729         case EM_MIPS_RS4_BE:
730           rtype = elf_mips_reloc_type (type);
731           break;
732
733         case EM_ALPHA:
734           rtype = elf_alpha_reloc_type (type);
735           break;
736
737         case EM_ARM:
738           rtype = elf_arm_reloc_type (type);
739           break;
740
741         case EM_CYGNUS_ARC:
742           rtype = elf_arc_reloc_type (type);
743           break;
744
745         case EM_PARISC:
746           rtype = elf_hppa_reloc_type (type);
747           break;
748
749         case EM_PJ:
750           rtype = elf_pj_reloc_type (type);
751           break;
752         }
753
754       if (rtype == NULL)
755 #ifdef _bfd_int64_low
756         printf (_("unrecognised: %-7lx"), _bfd_int64_low (type));
757 #else
758         printf (_("unrecognised: %-7lx"), type);
759 #endif
760       else
761         printf ("%-21.21s", rtype);
762
763       if (symtab_index)
764         {
765           if (symtab != NULL)
766             {
767               if (symtab_index >= nsyms)
768                 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
769               else
770                 {
771                   Elf_Internal_Sym * psym;
772
773                   psym = symtab + symtab_index;
774
775                   printf (" %08lx  ", (unsigned long) psym->st_value);
776
777                   if (psym->st_name == 0)
778                     printf ("%-25.25s",
779                             SECTION_NAME (section_headers + psym->st_shndx));
780                   else if (strtab == NULL)
781                     printf (_("<string table index %3ld>"), psym->st_name);
782                   else
783                     printf ("%-25.25s", strtab + psym->st_name);
784
785                   if (is_rela)
786                     printf (" + %lx", (unsigned long) relas [i].r_addend);
787                 }
788             }
789         }
790       else if (is_rela)
791         printf ("%34c%lx", ' ', (unsigned long) relas[i].r_addend);
792
793       if (elf_header.e_machine == EM_SPARCV9
794           && !strcmp (rtype, "R_SPARC_OLO10"))
795         printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
796
797       putchar ('\n');
798     }
799
800   free (relas);
801
802   return 1;
803 }
804
805 static const char *
806 get_mips_dynamic_type (type)
807      unsigned long type;
808 {
809   switch (type)
810     {
811     case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
812     case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
813     case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
814     case DT_MIPS_IVERSION: return "MIPS_IVERSION";
815     case DT_MIPS_FLAGS: return "MIPS_FLAGS";
816     case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
817     case DT_MIPS_MSYM: return "MIPS_MSYM";
818     case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
819     case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
820     case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
821     case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
822     case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
823     case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
824     case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
825     case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
826     case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
827     case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
828     case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
829     case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
830     case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
831     case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
832     case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
833     case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
834     case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
835     case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
836     case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
837     case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
838     case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
839     case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
840     case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
841     case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
842     case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
843     case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
844     case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
845     case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
846     case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
847     case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
848     case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
849     case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
850     case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
851     case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
852     case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
853     case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
854     default:
855       return NULL;
856     }
857 }
858
859 static const char *
860 get_sparc64_dynamic_type (type)
861      unsigned long type;
862 {
863   switch (type)
864     {
865     case DT_SPARC_REGISTER: return "SPARC_REGISTER";
866     default:
867       return NULL;
868     }
869 }
870
871 static const char *
872 get_parisc_dynamic_type (type)
873      unsigned long type;
874 {
875   switch (type)
876     {
877     case DT_HP_LOAD_MAP:        return "HP_LOAD_MAP";
878     case DT_HP_DLD_FLAGS:       return "HP_DLD_FLAGS";
879     case DT_HP_DLD_HOOK:        return "HP_DLD_HOOK";
880     case DT_HP_UX10_INIT:       return "HP_UX10_INIT";
881     case DT_HP_UX10_INITSZ:     return "HP_UX10_INITSZ";
882     case DT_HP_PREINIT:         return "HP_PREINIT";
883     case DT_HP_PREINITSZ:       return "HP_PREINITSZ";
884     case DT_HP_NEEDED:          return "HP_NEEDED";
885     case DT_HP_TIME_STAMP:      return "HP_TIME_STAMP";
886     case DT_HP_CHECKSUM:        return "HP_CHECKSUM";
887     case DT_HP_GST_SIZE:        return "HP_GST_SIZE";
888     case DT_HP_GST_VERSION:     return "HP_GST_VERSION";
889     case DT_HP_GST_HASHVAL:     return "HP_GST_HASHVAL";
890     default:
891       return NULL;
892     }
893 }
894
895 static const char *
896 get_dynamic_type (type)
897      unsigned long type;
898 {
899   static char buff [32];
900
901   switch (type)
902     {
903     case DT_NULL:       return "NULL";
904     case DT_NEEDED:     return "NEEDED";
905     case DT_PLTRELSZ:   return "PLTRELSZ";
906     case DT_PLTGOT:     return "PLTGOT";
907     case DT_HASH:       return "HASH";
908     case DT_STRTAB:     return "STRTAB";
909     case DT_SYMTAB:     return "SYMTAB";
910     case DT_RELA:       return "RELA";
911     case DT_RELASZ:     return "RELASZ";
912     case DT_RELAENT:    return "RELAENT";
913     case DT_STRSZ:      return "STRSZ";
914     case DT_SYMENT:     return "SYMENT";
915     case DT_INIT:       return "INIT";
916     case DT_FINI:       return "FINI";
917     case DT_SONAME:     return "SONAME";
918     case DT_RPATH:      return "RPATH";
919     case DT_SYMBOLIC:   return "SYMBOLIC";
920     case DT_REL:        return "REL";
921     case DT_RELSZ:      return "RELSZ";
922     case DT_RELENT:     return "RELENT";
923     case DT_PLTREL:     return "PLTREL";
924     case DT_DEBUG:      return "DEBUG";
925     case DT_TEXTREL:    return "TEXTREL";
926     case DT_JMPREL:     return "JMPREL";
927     case DT_BIND_NOW:   return "BIND_NOW";
928     case DT_INIT_ARRAY: return "INIT_ARRAY";
929     case DT_FINI_ARRAY: return "FINI_ARRAY";
930     case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
931     case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
932
933     case DT_PLTPADSZ:   return "PLTPADSZ";
934     case DT_MOVEENT:    return "MOVEENT";
935     case DT_MOVESZ:     return "MOVESZ";
936     case DT_FEATURE_1:  return "FEATURE_1";
937     case DT_POSFLAG_1:  return "POSFLAG_1";
938     case DT_SYMINSZ:    return "SYMINSZ";
939     case DT_SYMINENT:   return "SYMINENT"; /* aka VALRNGHI */
940
941     case DT_ADDRRNGLO:  return "ADDRRNGLO";
942     case DT_SYMINFO:    return "SYMINFO"; /* aka ADDRRNGHI */
943
944     case DT_VERSYM:     return "VERSYM";
945
946     case DT_RELACOUNT:  return "RELACOUNT";
947     case DT_RELCOUNT:   return "RELCOUNT";
948     case DT_FLAGS_1:    return "FLAGS_1";
949     case DT_VERDEF:     return "VERDEF";
950     case DT_VERDEFNUM:  return "VERDEFNUM";
951     case DT_VERNEED:    return "VERNEED";
952     case DT_VERNEEDNUM: return "VERNEEDNUM";
953
954     case DT_AUXILIARY:  return "AUXILARY";
955     case DT_USED:       return "USED";
956     case DT_FILTER:     return "FILTER";
957
958     default:
959       if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
960         {
961           const char * result;
962
963           switch (elf_header.e_machine)
964             {
965             case EM_MIPS:
966             case EM_MIPS_RS4_BE:
967               result = get_mips_dynamic_type (type);
968               break;
969             case EM_SPARCV9:
970               result = get_sparc64_dynamic_type (type);
971               break;
972             default:
973               result = NULL;
974               break;
975             }
976
977           if (result != NULL)
978             return result;
979
980           sprintf (buff, _("Processor Specific: %lx"), type);
981         }
982       else if ((type >= DT_LOOS) && (type <= DT_HIOS))
983         {
984           const char * result;
985
986           switch (elf_header.e_machine)
987             {
988             case EM_PARISC:
989               result = get_parisc_dynamic_type (type);
990               break;
991             default:
992               result = NULL;
993               break;
994             }
995
996           if (result != NULL)
997             return result;
998
999           sprintf (buff, _("Operating System specific: %lx"), type);
1000         }
1001       else
1002         sprintf (buff, _("<unknown>: %lx"), type);
1003
1004       return buff;
1005     }
1006 }
1007
1008 static char *
1009 get_file_type (e_type)
1010      unsigned e_type;
1011 {
1012   static char buff [32];
1013
1014   switch (e_type)
1015     {
1016     case ET_NONE:       return _("NONE (None)");
1017     case ET_REL:        return _("REL (Relocatable file)");
1018     case ET_EXEC:       return _("EXEC (Executable file)");
1019     case ET_DYN:        return _("DYN (Shared object file)");
1020     case ET_CORE:       return _("CORE (Core file)");
1021
1022     default:
1023       if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
1024         sprintf (buff, _("Processor Specific: (%x)"), e_type);
1025       else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
1026         sprintf (buff, _("OS Specific: (%x)"), e_type);
1027       else
1028         sprintf (buff, _("<unknown>: %x"), e_type);
1029       return buff;
1030     }
1031 }
1032
1033 static char *
1034 get_machine_name (e_machine)
1035      unsigned e_machine;
1036 {
1037   static char buff [32];
1038
1039   switch (e_machine)
1040     {
1041     case EM_NONE:               return _("None");
1042     case EM_M32:                return "WE32100";
1043     case EM_SPARC:              return "Sparc";
1044     case EM_386:                return "Intel 80386";
1045     case EM_68K:                return "MC68000";
1046     case EM_88K:                return "MC88000";
1047     case EM_486:                return "Intel 80486";
1048     case EM_860:                return "Intel 80860";
1049     case EM_MIPS:               return "MIPS R3000 big-endian";
1050     case EM_S370:               return "Amdahl";
1051     case EM_MIPS_RS4_BE:        return "MIPS R4000 big-endian";
1052     case EM_OLD_SPARCV9:        return "Sparc v9 (old)";
1053     case EM_PARISC:             return "HPPA";
1054     case EM_PPC_OLD:            return "Power PC (old)";
1055     case EM_SPARC32PLUS:        return "Sparc v8+" ;
1056     case EM_960:                return "Intel 90860";
1057     case EM_PPC:                return "PowerPC";
1058     case EM_V800:               return "NEC V800";
1059     case EM_FR20:               return "Fujitsu FR20";
1060     case EM_RH32:               return "TRW RH32";
1061     case EM_MCORE:              return "MCORE";
1062     case EM_ARM:                return "ARM";
1063     case EM_OLD_ALPHA:          return "Digital Alpha (old)";
1064     case EM_SH:                 return "Hitachi SH";
1065     case EM_SPARCV9:            return "Sparc v9";
1066     case EM_TRICORE:            return "Siemens Tricore";
1067     case EM_ARC:                return "Argonaut RISC Core";
1068     case EM_H8_300:             return "Hitachi H8/300";
1069     case EM_H8_300H:            return "Hitachi H8/300H";
1070     case EM_H8S:                return "Hitachi H8S";
1071     case EM_H8_500:             return "Hitachi H8/500";
1072     case EM_IA_64:              return "Intel Merced";
1073     case EM_MIPS_X:             return "Stanford MIPS-X";
1074     case EM_COLDFIRE:           return "Motorola Coldfire";
1075     case EM_68HC12:             return "Motorola M68HC12";
1076     case EM_ALPHA:              return "Alpha";
1077     case EM_CYGNUS_D10V:        return "d10v";
1078     case EM_CYGNUS_D30V:        return "d30v";
1079     case EM_CYGNUS_ARC:         return "Arc";
1080     case EM_CYGNUS_M32R:        return "Mitsubishi M32r";
1081     case EM_CYGNUS_V850:        return "NEC v850";
1082     case EM_CYGNUS_MN10300:     return "mn10300";
1083     case EM_CYGNUS_MN10200:     return "mn10200";
1084     case EM_CYGNUS_FR30:        return "Fujitsu FR30";
1085     case EM_PJ:                 return "picoJava";
1086     default:
1087       sprintf (buff, _("<unknown>: %x"), e_machine);
1088       return buff;
1089     }
1090 }
1091
1092 static char *
1093 get_machine_flags (e_flags, e_machine)
1094      unsigned e_flags;
1095      unsigned e_machine;
1096 {
1097   static char buf [1024];
1098
1099   buf[0] = '\0';
1100   if (e_flags)
1101     {
1102       switch (e_machine)
1103         {
1104         default:
1105           break;
1106
1107         case EM_68K:
1108           if (e_flags & EF_CPU32)
1109             strcat (buf, ", cpu32");
1110           break;
1111
1112         case EM_PPC:
1113           if (e_flags & EF_PPC_EMB)
1114             strcat (buf, ", emb");
1115
1116           if (e_flags & EF_PPC_RELOCATABLE)
1117             strcat (buf, ", relocatable");
1118
1119           if (e_flags & EF_PPC_RELOCATABLE_LIB)
1120             strcat (buf, ", relocatable-lib");
1121           break;
1122
1123         case EM_CYGNUS_V850:
1124           switch (e_flags & EF_V850_ARCH)
1125             {
1126             case E_V850E_ARCH:
1127               strcat (buf, ", v850e");
1128               break;
1129             case E_V850EA_ARCH:
1130               strcat (buf, ", v850ea");
1131               break;
1132             case E_V850_ARCH:
1133               strcat (buf, ", v850");
1134               break;
1135             default:
1136               strcat (buf, ", unknown v850 architecture variant");
1137               break;
1138             }
1139           break;
1140
1141         case EM_CYGNUS_M32R:
1142           if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
1143             strcat (buf, ", m32r");
1144
1145           break;
1146
1147         case EM_MIPS:
1148         case EM_MIPS_RS4_BE:
1149           if (e_flags & EF_MIPS_NOREORDER)
1150             strcat (buf, ", noreorder");
1151
1152           if (e_flags & EF_MIPS_PIC)
1153             strcat (buf, ", pic");
1154
1155           if (e_flags & EF_MIPS_CPIC)
1156             strcat (buf, ", cpic");
1157
1158           if (e_flags & EF_MIPS_ABI2)
1159             strcat (buf, ", abi2");
1160
1161           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
1162             strcat (buf, ", mips1");
1163
1164           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
1165             strcat (buf, ", mips2");
1166
1167           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
1168             strcat (buf, ", mips3");
1169
1170           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
1171             strcat (buf, ", mips4");
1172           break;
1173
1174         case EM_SPARCV9:
1175           if (e_flags & EF_SPARC_32PLUS)
1176             strcat (buf, ", v8+");
1177
1178           if (e_flags & EF_SPARC_SUN_US1)
1179             strcat (buf, ", ultrasparcI");
1180
1181           if (e_flags & EF_SPARC_SUN_US3)
1182             strcat (buf, ", ultrasparcIII");
1183
1184           if (e_flags & EF_SPARC_HAL_R1)
1185             strcat (buf, ", halr1");
1186
1187           if (e_flags & EF_SPARC_LEDATA)
1188             strcat (buf, ", ledata");
1189
1190           if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
1191             strcat (buf, ", tso");
1192
1193           if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
1194             strcat (buf, ", pso");
1195
1196           if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
1197             strcat (buf, ", rmo");
1198           break;
1199
1200         case EM_PARISC:
1201           switch (e_flags & EF_PARISC_ARCH)
1202             {
1203             case EFA_PARISC_1_0:
1204               strcpy (buf, ", PA-RISC 1.0");
1205               break;
1206             case EFA_PARISC_1_1:
1207               strcpy (buf, ", PA-RISC 1.1");
1208               break;
1209             case EFA_PARISC_2_0:
1210               strcpy (buf, ", PA-RISC 2.0");
1211               break;
1212             default:
1213               break;
1214             }
1215           if (e_flags & EF_PARISC_TRAPNIL)
1216             strcat (buf, ", trapnil");
1217           if (e_flags & EF_PARISC_EXT)
1218             strcat (buf, ", ext");
1219           if (e_flags & EF_PARISC_LSB)
1220             strcat (buf, ", lsb");
1221           if (e_flags & EF_PARISC_WIDE)
1222             strcat (buf, ", wide");
1223           if (e_flags & EF_PARISC_NO_KABP)
1224             strcat (buf, ", no kabp");
1225           if (e_flags & EF_PARISC_LAZYSWAP)
1226             strcat (buf, ", lazyswap");
1227
1228         case EM_PJ:
1229           if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
1230             strcat (buf, ", new calling convention");
1231
1232           if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
1233             strcat (buf, ", gnu calling convention");
1234           break;
1235         }
1236     }
1237
1238   return buf;
1239 }
1240
1241 static const char *
1242 get_mips_segment_type (type)
1243      unsigned long type;
1244 {
1245   switch (type)
1246     {
1247     case PT_MIPS_REGINFO:
1248       return "REGINFO";
1249     case PT_MIPS_RTPROC:
1250       return "RTPROC";
1251     case PT_MIPS_OPTIONS:
1252       return "OPTIONS";
1253     default:
1254       break;
1255     }
1256
1257   return NULL;
1258 }
1259
1260 static const char *
1261 get_parisc_segment_type (type)
1262      unsigned long type;
1263 {
1264   switch (type)
1265     {
1266     case PT_HP_TLS:             return "HP_TLS";
1267     case PT_HP_CORE_NONE:       return "HP_CORE_NONE";
1268     case PT_HP_CORE_VERSION:    return "HP_CORE_VERSION";
1269     case PT_HP_CORE_KERNEL:     return "HP_CORE_KERNEL";
1270     case PT_HP_CORE_COMM:       return "HP_CORE_COMM";
1271     case PT_HP_CORE_PROC:       return "HP_CORE_PROC";
1272     case PT_HP_CORE_LOADABLE:   return "HP_CORE_LOADABLE";
1273     case PT_HP_CORE_STACK:      return "HP_CORE_STACK";
1274     case PT_HP_CORE_SHM:        return "HP_CORE_SHM";
1275     case PT_HP_CORE_MMF:        return "HP_CORE_MMF";
1276     case PT_HP_PARALLEL:        return "HP_PARALLEL";
1277     case PT_HP_FASTBIND:        return "HP_FASTBIND";
1278     case PT_PARISC_ARCHEXT:     return "PARISC_ARCHEXT";
1279     case PT_PARISC_UNWIND:      return "PARISC_UNWIND";
1280     default:
1281       break;
1282     }
1283
1284   return NULL;
1285 }
1286
1287 static const char *
1288 get_segment_type (p_type)
1289      unsigned long p_type;
1290 {
1291   static char buff [32];
1292
1293   switch (p_type)
1294     {
1295     case PT_NULL:       return "NULL";
1296     case PT_LOAD:       return "LOAD";
1297     case PT_DYNAMIC:    return "DYNAMIC";
1298     case PT_INTERP:     return "INTERP";
1299     case PT_NOTE:       return "NOTE";
1300     case PT_SHLIB:      return "SHLIB";
1301     case PT_PHDR:       return "PHDR";
1302
1303     default:
1304       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
1305         {
1306           const char * result;
1307
1308           switch (elf_header.e_machine)
1309             {
1310             case EM_MIPS:
1311             case EM_MIPS_RS4_BE:
1312               result = get_mips_segment_type (p_type);
1313               break;
1314             case EM_PARISC:
1315               result = get_parisc_segment_type (p_type);
1316               break;
1317             default:
1318               result = NULL;
1319               break;
1320             }
1321
1322           if (result != NULL)
1323             return result;
1324
1325           sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
1326         }
1327       else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
1328         {
1329           const char * result;
1330
1331           switch (elf_header.e_machine)
1332             {
1333             case EM_PARISC:
1334               result = get_parisc_segment_type (p_type);
1335               break;
1336             default:
1337               result = NULL;
1338               break;
1339             }
1340
1341           if (result != NULL)
1342             return result;
1343
1344           sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
1345         }
1346       else
1347         sprintf (buff, _("<unknown>: %lx"), p_type);
1348
1349       return buff;
1350     }
1351 }
1352
1353 static const char *
1354 get_mips_section_type_name (sh_type)
1355      unsigned int sh_type;
1356 {
1357   switch (sh_type)
1358     {
1359     case SHT_MIPS_LIBLIST:       return "MIPS_LIBLIST";
1360     case SHT_MIPS_MSYM:          return "MIPS_MSYM";
1361     case SHT_MIPS_CONFLICT:      return "MIPS_CONFLICT";
1362     case SHT_MIPS_GPTAB:         return "MIPS_GPTAB";
1363     case SHT_MIPS_UCODE:         return "MIPS_UCODE";
1364     case SHT_MIPS_DEBUG:         return "MIPS_DEBUG";
1365     case SHT_MIPS_REGINFO:       return "MIPS_REGINFO";
1366     case SHT_MIPS_PACKAGE:       return "MIPS_PACKAGE";
1367     case SHT_MIPS_PACKSYM:       return "MIPS_PACKSYM";
1368     case SHT_MIPS_RELD:          return "MIPS_RELD";
1369     case SHT_MIPS_IFACE:         return "MIPS_IFACE";
1370     case SHT_MIPS_CONTENT:       return "MIPS_CONTENT";
1371     case SHT_MIPS_OPTIONS:       return "MIPS_OPTIONS";
1372     case SHT_MIPS_SHDR:          return "MIPS_SHDR";
1373     case SHT_MIPS_FDESC:         return "MIPS_FDESC";
1374     case SHT_MIPS_EXTSYM:        return "MIPS_EXTSYM";
1375     case SHT_MIPS_DENSE:         return "MIPS_DENSE";
1376     case SHT_MIPS_PDESC:         return "MIPS_PDESC";
1377     case SHT_MIPS_LOCSYM:        return "MIPS_LOCSYM";
1378     case SHT_MIPS_AUXSYM:        return "MIPS_AUXSYM";
1379     case SHT_MIPS_OPTSYM:        return "MIPS_OPTSYM";
1380     case SHT_MIPS_LOCSTR:        return "MIPS_LOCSTR";
1381     case SHT_MIPS_LINE:          return "MIPS_LINE";
1382     case SHT_MIPS_RFDESC:        return "MIPS_RFDESC";
1383     case SHT_MIPS_DELTASYM:      return "MIPS_DELTASYM";
1384     case SHT_MIPS_DELTAINST:     return "MIPS_DELTAINST";
1385     case SHT_MIPS_DELTACLASS:    return "MIPS_DELTACLASS";
1386     case SHT_MIPS_DWARF:         return "MIPS_DWARF";
1387     case SHT_MIPS_DELTADECL:     return "MIPS_DELTADECL";
1388     case SHT_MIPS_SYMBOL_LIB:    return "MIPS_SYMBOL_LIB";
1389     case SHT_MIPS_EVENTS:        return "MIPS_EVENTS";
1390     case SHT_MIPS_TRANSLATE:     return "MIPS_TRANSLATE";
1391     case SHT_MIPS_PIXIE:         return "MIPS_PIXIE";
1392     case SHT_MIPS_XLATE:         return "MIPS_XLATE";
1393     case SHT_MIPS_XLATE_DEBUG:   return "MIPS_XLATE_DEBUG";
1394     case SHT_MIPS_WHIRL:         return "MIPS_WHIRL";
1395     case SHT_MIPS_EH_REGION:     return "MIPS_EH_REGION";
1396     case SHT_MIPS_XLATE_OLD:     return "MIPS_XLATE_OLD";
1397     case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1398     default:
1399       break;
1400     }
1401   return NULL;
1402 }
1403
1404 static const char *
1405 get_parisc_section_type_name (sh_type)
1406      unsigned int sh_type;
1407 {
1408   switch (sh_type)
1409     {
1410     case SHT_PARISC_EXT:        return "PARISC_EXT";
1411     case SHT_PARISC_UNWIND:     return "PARISC_UNWIND";
1412     case SHT_PARISC_DOC:        return "PARISC_DOC";
1413     default:
1414       break;
1415     }
1416   return NULL;
1417 }
1418
1419 static const char *
1420 get_section_type_name (sh_type)
1421      unsigned int sh_type;
1422 {
1423   static char buff [32];
1424
1425   switch (sh_type)
1426     {
1427     case SHT_NULL:              return "NULL";
1428     case SHT_PROGBITS:          return "PROGBITS";
1429     case SHT_SYMTAB:            return "SYMTAB";
1430     case SHT_STRTAB:            return "STRTAB";
1431     case SHT_RELA:              return "RELA";
1432     case SHT_HASH:              return "HASH";
1433     case SHT_DYNAMIC:           return "DYNAMIC";
1434     case SHT_NOTE:              return "NOTE";
1435     case SHT_NOBITS:            return "NOBITS";
1436     case SHT_REL:               return "REL";
1437     case SHT_SHLIB:             return "SHLIB";
1438     case SHT_DYNSYM:            return "DYNSYM";
1439     case SHT_GNU_verdef:        return "VERDEF";
1440     case SHT_GNU_verneed:       return "VERNEED";
1441     case SHT_GNU_versym:        return "VERSYM";
1442     case 0x6ffffff0:            return "VERSYM";
1443     case 0x6ffffffc:            return "VERDEF";
1444     case 0x7ffffffd:            return "AUXILIARY";
1445     case 0x7fffffff:            return "FILTER";
1446
1447     default:
1448       if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1449         {
1450           const char * result;
1451
1452           switch (elf_header.e_machine)
1453             {
1454             case EM_MIPS:
1455             case EM_MIPS_RS4_BE:
1456               result = get_mips_section_type_name (sh_type);
1457               break;
1458             case EM_PARISC:
1459               result = get_parisc_section_type_name (sh_type);
1460               break;
1461             default:
1462               result = NULL;
1463               break;
1464             }
1465
1466           if (result != NULL)
1467             return result;
1468
1469           sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1470         }
1471       else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1472         sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1473       else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1474         sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1475       else
1476         sprintf (buff, _("<unknown>: %x"), sh_type);
1477
1478       return buff;
1479     }
1480 }
1481
1482 struct option options [] =
1483 {
1484   {"all",              no_argument, 0, 'a'},
1485   {"file-header",      no_argument, 0, 'h'},
1486   {"program-headers",  no_argument, 0, 'l'},
1487   {"headers",          no_argument, 0, 'e'},
1488   {"histogram",        no_argument, 0, 'I'},
1489   {"segments",         no_argument, 0, 'l'},
1490   {"sections",         no_argument, 0, 'S'},
1491   {"section-headers",  no_argument, 0, 'S'},
1492   {"symbols",          no_argument, 0, 's'},
1493   {"syms",             no_argument, 0, 's'},
1494   {"relocs",           no_argument, 0, 'r'},
1495   {"notes",            no_argument, 0, 'n'},
1496   {"dynamic",          no_argument, 0, 'd'},
1497   {"arch-specific",    no_argument, 0, 'A'},
1498   {"version-info",     no_argument, 0, 'V'},
1499   {"use-dynamic",      no_argument, 0, 'D'},
1500   {"hex-dump",         required_argument, 0, 'x'},
1501   {"debug-dump",       optional_argument, 0, 'w'},
1502 #ifdef SUPPORT_DISASSEMBLY
1503   {"instruction-dump", required_argument, 0, 'i'},
1504 #endif
1505
1506   {"version",          no_argument, 0, 'v'},
1507   {"help",             no_argument, 0, 'H'},
1508   {0,                  no_argument, 0, 0}
1509 };
1510
1511 static void
1512 usage ()
1513 {
1514   fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
1515   fprintf (stdout, _("  Options are:\n"));
1516   fprintf (stdout, _("  -a or --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
1517   fprintf (stdout, _("  -h or --file-header       Display the ELF file header\n"));
1518   fprintf (stdout, _("  -l or --program-headers or --segments\n"));
1519   fprintf (stdout, _("                            Display the program headers\n"));
1520   fprintf (stdout, _("  -S or --section-headers or --sections\n"));
1521   fprintf (stdout, _("                            Display the sections' header\n"));
1522   fprintf (stdout, _("  -e or --headers           Equivalent to: -h -l -S\n"));
1523   fprintf (stdout, _("  -s or --syms or --symbols Display the symbol table\n"));
1524   fprintf (stdout, _("  -n or --notes             Display the core notes (if present)\n"));
1525   fprintf (stdout, _("  -r or --relocs            Display the relocations (if present)\n"));
1526   fprintf (stdout, _("  -d or --dynamic           Display the dynamic segment (if present)\n"));
1527   fprintf (stdout, _("  -V or --version-info      Display the version sections (if present)\n"));
1528   fprintf (stdout, _("  -A or --arch-specific     Display architecture specific information (if any).\n"));
1529   fprintf (stdout, _("  -D or --use-dynamic       Use the dynamic section info when displaying symbols\n"));
1530   fprintf (stdout, _("  -x <number> or --hex-dump=<number>\n"));
1531   fprintf (stdout, _("                            Dump the contents of section <number>\n"));
1532   fprintf (stdout, _("  -w[liapr] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges]\n"));
1533   fprintf (stdout, _("                            Display the contents of DWARF2 debug sections\n"));
1534 #ifdef SUPPORT_DISASSEMBLY
1535   fprintf (stdout, _("  -i <number> or --instruction-dump=<number>\n"));
1536   fprintf (stdout, _("                            Disassemble the contents of section <number>\n"));
1537 #endif
1538   fprintf (stdout, _("  -I or --histogram         Display histogram of bucket list lengths\n"));
1539   fprintf (stdout, _("  -v or --version           Display the version number of readelf\n"));
1540   fprintf (stdout, _("  -H or --help              Display this information\n"));
1541   fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n"));
1542
1543   exit (0);
1544 }
1545
1546 static void
1547 request_dump (section, type)
1548      unsigned int section;
1549      char         type;
1550 {
1551   if (section >= num_dump_sects)
1552     {
1553       char * new_dump_sects;
1554
1555       new_dump_sects = (char *) calloc (section + 1, 1);
1556
1557       if (new_dump_sects == NULL)
1558         error (_("Out of memory allocating dump request table."));
1559       else
1560         {
1561           /* Copy current flag settings.  */
1562           memcpy (new_dump_sects, dump_sects, num_dump_sects);
1563
1564           free (dump_sects);
1565
1566           dump_sects = new_dump_sects;
1567           num_dump_sects = section + 1;
1568         }
1569     }
1570
1571   if (dump_sects)
1572     dump_sects [section] |= type;
1573
1574   return;
1575 }
1576
1577 static void
1578 parse_args (argc, argv)
1579      int argc;
1580      char ** argv;
1581 {
1582   int c;
1583
1584   if (argc < 2)
1585     usage ();
1586
1587   while ((c = getopt_long
1588           (argc, argv, "ersahnldSDAIw::x:i:vV", options, NULL)) != EOF)
1589     {
1590       char *    cp;
1591       int       section;
1592
1593       switch (c)
1594         {
1595         case 0:
1596           /* Long options.  */
1597           break;
1598         case 'H':
1599           usage ();
1600           break;
1601
1602         case 'a':
1603           do_syms ++;
1604           do_reloc ++;
1605           do_dynamic ++;
1606           do_header ++;
1607           do_sections ++;
1608           do_segments ++;
1609           do_version ++;
1610           do_histogram ++;
1611           do_arch ++;
1612           do_notes ++;
1613           break;
1614         case 'e':
1615           do_header ++;
1616           do_sections ++;
1617           do_segments ++;
1618           break;
1619         case 'A':
1620           do_arch ++;
1621           break;
1622         case 'D':
1623           do_using_dynamic ++;
1624           break;
1625         case 'r':
1626           do_reloc ++;
1627           break;
1628         case 'h':
1629           do_header ++;
1630           break;
1631         case 'l':
1632           do_segments ++;
1633           break;
1634         case 's':
1635           do_syms ++;
1636           break;
1637         case 'S':
1638           do_sections ++;
1639           break;
1640         case 'd':
1641           do_dynamic ++;
1642           break;
1643         case 'I':
1644           do_histogram ++;
1645           break;
1646         case 'n':
1647           do_notes ++;
1648           break;
1649         case 'x':
1650           do_dump ++;
1651           section = strtoul (optarg, & cp, 0);
1652           if (! * cp && section >= 0)
1653             {
1654               request_dump (section, HEX_DUMP);
1655               break;
1656             }
1657           goto oops;
1658         case 'w':
1659           do_dump ++;
1660           if (optarg == 0)
1661             do_debugging = 1;
1662           else
1663             {
1664               do_debugging = 0;
1665               switch (optarg[0])
1666                 {
1667                 case 'i':
1668                 case 'I':
1669                   do_debug_info = 1;
1670                   break;
1671
1672                 case 'a':
1673                 case 'A':
1674                   do_debug_abbrevs = 1;
1675                   break;
1676
1677                 case 'l':
1678                 case 'L':
1679                   do_debug_lines = 1;
1680                   break;
1681
1682                 case 'p':
1683                 case 'P':
1684                   do_debug_pubnames = 1;
1685                   break;
1686
1687                 case 'r':
1688                 case 'R':
1689                   do_debug_aranges = 1;
1690                   break;
1691
1692                 default:
1693                   warn (_("Unrecognised debug option '%s'\n"), optarg);
1694                   break;
1695                 }
1696             }
1697           break;
1698 #ifdef SUPPORT_DISASSEMBLY
1699         case 'i':
1700           do_dump ++;
1701           section = strtoul (optarg, & cp, 0);
1702           if (! * cp && section >= 0)
1703             {
1704               request_dump (section, DISASS_DUMP);
1705               break;
1706             }
1707           goto oops;
1708 #endif
1709         case 'v':
1710           print_version (program_name);
1711           break;
1712         case 'V':
1713           do_version ++;
1714           break;
1715         default:
1716         oops:
1717           /* xgettext:c-format */
1718           error (_("Invalid option '-%c'\n"), c);
1719           /* Drop through.  */
1720         case '?':
1721           usage ();
1722         }
1723     }
1724
1725   if (!do_dynamic && !do_syms && !do_reloc && !do_sections
1726       && !do_segments && !do_header && !do_dump && !do_version
1727       && !do_histogram && !do_debugging && !do_arch && !do_notes)
1728     usage ();
1729   else if (argc < 3)
1730     {
1731       warn (_("Nothing to do.\n"));
1732       usage();
1733     }
1734 }
1735
1736 static const char *
1737 get_elf_class (elf_class)
1738      unsigned char elf_class;
1739 {
1740   static char buff [32];
1741
1742   switch (elf_class)
1743     {
1744     case ELFCLASSNONE: return _("none");
1745     case ELFCLASS32:   return _("ELF32");
1746     case ELFCLASS64:   return _("ELF64");
1747     default:
1748       sprintf (buff, _("<unknown: %x>"), elf_class);
1749       return buff;
1750     }
1751 }
1752
1753 static const char *
1754 get_data_encoding (encoding)
1755      unsigned char encoding;
1756 {
1757   static char buff [32];
1758
1759   switch (encoding)
1760     {
1761     case ELFDATANONE: return _("none");
1762     case ELFDATA2LSB: return _("2's complement, little endian");
1763     case ELFDATA2MSB: return _("2's complement, big endian");
1764     default:
1765       sprintf (buff, _("<unknown: %x>"), encoding);
1766       return buff;
1767     }
1768 }
1769
1770 static const char *
1771 get_osabi_name (osabi)
1772      unsigned char osabi;
1773 {
1774   static char buff [32];
1775
1776   switch (osabi)
1777     {
1778     case ELFOSABI_SYSV:       return _("UNIX - System V");
1779     case ELFOSABI_HPUX:       return _("UNIX - HP-UX");
1780     case ELFOSABI_STANDALONE: return _("Standalone App");
1781     default:
1782       sprintf (buff, _("<unknown: %x>"), osabi);
1783       return buff;
1784     }
1785 }
1786
1787 /* Decode the data held in 'elf_header'.  */
1788 static int
1789 process_file_header ()
1790 {
1791   if (   elf_header.e_ident [EI_MAG0] != ELFMAG0
1792       || elf_header.e_ident [EI_MAG1] != ELFMAG1
1793       || elf_header.e_ident [EI_MAG2] != ELFMAG2
1794       || elf_header.e_ident [EI_MAG3] != ELFMAG3)
1795     {
1796       error
1797         (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
1798       return 0;
1799     }
1800
1801   if (do_header)
1802     {
1803       int i;
1804
1805       printf (_("ELF Header:\n"));
1806       printf (_("  Magic:   "));
1807       for (i = 0; i < EI_NIDENT; i ++)
1808         printf ("%2.2x ", elf_header.e_ident [i]);
1809       printf ("\n");
1810       printf (_("  Class:                             %s\n"),
1811               get_elf_class (elf_header.e_ident [EI_CLASS]));
1812       printf (_("  Data:                              %s\n"),
1813               get_data_encoding (elf_header.e_ident [EI_DATA]));
1814       printf (_("  Version:                           %d %s\n"),
1815               elf_header.e_ident [EI_VERSION],
1816               (elf_header.e_ident [EI_VERSION] == EV_CURRENT
1817                ? "(current)"
1818                : (elf_header.e_ident [EI_VERSION] != EV_NONE
1819                   ? "<unknown: %lx>"
1820                   : "")));
1821       printf (_("  OS/ABI:                            %s\n"),
1822               get_osabi_name (elf_header.e_ident [EI_OSABI]));
1823       printf (_("  ABI Version:                       %d\n"),
1824               elf_header.e_ident [EI_ABIVERSION]);
1825       printf (_("  Type:                              %s\n"),
1826               get_file_type (elf_header.e_type));
1827       printf (_("  Machine:                           %s\n"),
1828               get_machine_name (elf_header.e_machine));
1829       printf (_("  Version:                           0x%lx\n"),
1830               (unsigned long) elf_header.e_version);
1831       printf (_("  Entry point address:               0x%lx\n"),
1832               (unsigned long) elf_header.e_entry);
1833       printf (_("  Start of program headers:          %ld (bytes into file)\n"),
1834               (long) elf_header.e_phoff);
1835       printf (_("  Start of section headers:          %ld (bytes into file)\n"),
1836               (long) elf_header.e_shoff);
1837       printf (_("  Flags:                             0x%lx%s\n"),
1838               (unsigned long) elf_header.e_flags,
1839               get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1840       printf (_("  Size of this header:               %ld (bytes)\n"),
1841               (long) elf_header.e_ehsize);
1842       printf (_("  Size of program headers:           %ld (bytes)\n"),
1843               (long) elf_header.e_phentsize);
1844       printf (_("  Number of program headers:         %ld\n"),
1845               (long) elf_header.e_phnum);
1846       printf (_("  Size of section headers:           %ld (bytes)\n"),
1847               (long) elf_header.e_shentsize);
1848       printf (_("  Number of section headers:         %ld\n"),
1849               (long) elf_header.e_shnum);
1850       printf (_("  Section header string table index: %ld\n"),
1851               (long) elf_header.e_shstrndx);
1852     }
1853
1854   return 1;
1855 }
1856
1857
1858 static int
1859 get_32bit_program_headers (file, program_headers)
1860      FILE * file;
1861      Elf_Internal_Phdr * program_headers;
1862 {
1863   Elf32_External_Phdr * phdrs;
1864   Elf32_External_Phdr * external;
1865   Elf32_Internal_Phdr * internal;
1866   unsigned int          i;
1867
1868   GET_DATA_ALLOC (elf_header.e_phoff,
1869                   elf_header.e_phentsize * elf_header.e_phnum,
1870                   phdrs, Elf32_External_Phdr *, "program headers");
1871
1872   for (i = 0, internal = program_headers, external = phdrs;
1873        i < elf_header.e_phnum;
1874        i ++, internal ++, external ++)
1875     {
1876       internal->p_type   = BYTE_GET (external->p_type);
1877       internal->p_offset = BYTE_GET (external->p_offset);
1878       internal->p_vaddr  = BYTE_GET (external->p_vaddr);
1879       internal->p_paddr  = BYTE_GET (external->p_paddr);
1880       internal->p_filesz = BYTE_GET (external->p_filesz);
1881       internal->p_memsz  = BYTE_GET (external->p_memsz);
1882       internal->p_flags  = BYTE_GET (external->p_flags);
1883       internal->p_align  = BYTE_GET (external->p_align);
1884     }
1885
1886   free (phdrs);
1887
1888   return 1;
1889 }
1890
1891 static int
1892 get_64bit_program_headers (file, program_headers)
1893      FILE * file;
1894      Elf_Internal_Phdr * program_headers;
1895 {
1896   Elf64_External_Phdr * phdrs;
1897   Elf64_External_Phdr * external;
1898   Elf64_Internal_Phdr * internal;
1899   unsigned int          i;
1900
1901   GET_DATA_ALLOC (elf_header.e_phoff,
1902                   elf_header.e_phentsize * elf_header.e_phnum,
1903                   phdrs, Elf64_External_Phdr *, "program headers");
1904
1905   for (i = 0, internal = program_headers, external = phdrs;
1906        i < elf_header.e_phnum;
1907        i ++, internal ++, external ++)
1908     {
1909       internal->p_type   = BYTE_GET (external->p_type);
1910       internal->p_flags  = BYTE_GET (external->p_flags);
1911       internal->p_offset = BYTE_GET8 (external->p_offset);
1912       internal->p_vaddr  = BYTE_GET8 (external->p_vaddr);
1913       internal->p_paddr  = BYTE_GET8 (external->p_paddr);
1914       internal->p_filesz = BYTE_GET8 (external->p_filesz);
1915       internal->p_memsz  = BYTE_GET8 (external->p_memsz);
1916       internal->p_align  = BYTE_GET8 (external->p_align);
1917     }
1918
1919   free (phdrs);
1920
1921   return 1;
1922 }
1923
1924 static int
1925 process_program_headers (file)
1926      FILE * file;
1927 {
1928   Elf_Internal_Phdr * program_headers;
1929   Elf_Internal_Phdr * segment;
1930   unsigned int        i;
1931
1932   if (elf_header.e_phnum == 0)
1933     {
1934       if (do_segments)
1935         printf (_("\nThere are no program headers in this file.\n"));
1936       return 1;
1937     }
1938
1939   if (do_segments && !do_header)
1940     {
1941       printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1942       printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1943       printf (_("There are %d program headers, starting at offset %lx:\n"),
1944               elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1945     }
1946
1947   program_headers = (Elf_Internal_Phdr *) malloc
1948     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
1949
1950   if (program_headers == NULL)
1951     {
1952       error (_("Out of memory\n"));
1953       return 0;
1954     }
1955
1956   if (is_32bit_elf)
1957     i = get_32bit_program_headers (file, program_headers);
1958   else
1959     i = get_64bit_program_headers (file, program_headers);
1960
1961   if (i == 0)
1962     {
1963       free (program_headers);
1964       return 0;
1965     }
1966
1967   if (do_segments)
1968     {
1969       printf
1970         (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1971       printf
1972         (_("  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align\n"));
1973     }
1974
1975   loadaddr = -1;
1976   dynamic_addr = 0;
1977   dynamic_size = 0;
1978
1979   for (i = 0, segment = program_headers;
1980        i < elf_header.e_phnum;
1981        i ++, segment ++)
1982     {
1983       if (do_segments)
1984         {
1985           printf ("  %-14.14s ", get_segment_type (segment->p_type));
1986           printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1987           printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1988           printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1989           printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1990           printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1991           printf ("%c%c%c ",
1992                   (segment->p_flags & PF_R ? 'R' : ' '),
1993                   (segment->p_flags & PF_W ? 'W' : ' '),
1994                   (segment->p_flags & PF_X ? 'E' : ' '));
1995           printf ("%#lx", (unsigned long) segment->p_align);
1996         }
1997
1998       switch (segment->p_type)
1999         {
2000         case PT_LOAD:
2001           if (loadaddr == -1)
2002             loadaddr = (segment->p_vaddr & 0xfffff000)
2003               - (segment->p_offset & 0xfffff000);
2004           break;
2005
2006         case PT_DYNAMIC:
2007           if (dynamic_addr)
2008             error (_("more than one dynamic segment\n"));
2009
2010           dynamic_addr = segment->p_offset;
2011           dynamic_size = segment->p_filesz;
2012           break;
2013
2014         case PT_INTERP:
2015           if (fseek (file, segment->p_offset, SEEK_SET))
2016             error (_("Unable to find program interpreter name\n"));
2017           else
2018             {
2019               program_interpreter[0] = 0;
2020               fscanf (file, "%63s", program_interpreter);
2021
2022               if (do_segments)
2023                 printf (_("\n      [Requesting program interpreter: %s]"),
2024                     program_interpreter);
2025             }
2026           break;
2027         }
2028
2029       if (do_segments)
2030         putc ('\n', stdout);
2031     }
2032
2033   if (loadaddr == -1)
2034     {
2035       /* Very strange. */
2036       loadaddr = 0;
2037     }
2038
2039   if (do_segments && section_headers != NULL)
2040     {
2041       printf (_("\n Section to Segment mapping:\n"));
2042       printf (_("  Segment Sections...\n"));
2043
2044       assert (string_table != NULL);
2045
2046       for (i = 0; i < elf_header.e_phnum; i++)
2047         {
2048           int                 j;
2049           Elf_Internal_Shdr * section;
2050
2051           segment = program_headers + i;
2052           section = section_headers;
2053
2054           printf ("   %2.2d     ", i);
2055
2056           for (j = 0; j < elf_header.e_shnum; j++, section ++)
2057             {
2058               if (section->sh_size > 0
2059                   /* Compare allocated sections by VMA, unallocated
2060                      sections by file offset.  */
2061                   && (section->sh_flags & SHF_ALLOC
2062                       ? (section->sh_addr >= segment->p_vaddr
2063                          && section->sh_addr + section->sh_size
2064                          <= segment->p_vaddr + segment->p_memsz)
2065                       : ((bfd_vma) section->sh_offset >= segment->p_offset
2066                          && (section->sh_offset + section->sh_size
2067                              <= segment->p_offset + segment->p_filesz))))
2068                 printf ("%s ", SECTION_NAME (section));
2069             }
2070
2071           putc ('\n',stdout);
2072         }
2073     }
2074
2075   free (program_headers);
2076
2077   return 1;
2078 }
2079
2080
2081 static int
2082 get_32bit_section_headers (file)
2083      FILE * file;
2084 {
2085   Elf32_External_Shdr * shdrs;
2086   Elf32_Internal_Shdr * internal;
2087   unsigned int          i;
2088
2089   GET_DATA_ALLOC (elf_header.e_shoff,
2090                   elf_header.e_shentsize * elf_header.e_shnum,
2091                   shdrs, Elf32_External_Shdr *, "section headers");
2092
2093   section_headers = (Elf_Internal_Shdr *) malloc
2094     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
2095
2096   if (section_headers == NULL)
2097     {
2098       error (_("Out of memory\n"));
2099       return 0;
2100     }
2101
2102   for (i = 0, internal = section_headers;
2103        i < elf_header.e_shnum;
2104        i ++, internal ++)
2105     {
2106       internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
2107       internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
2108       internal->sh_flags     = BYTE_GET (shdrs[i].sh_flags);
2109       internal->sh_addr      = BYTE_GET (shdrs[i].sh_addr);
2110       internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
2111       internal->sh_size      = BYTE_GET (shdrs[i].sh_size);
2112       internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
2113       internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
2114       internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
2115       internal->sh_entsize   = BYTE_GET (shdrs[i].sh_entsize);
2116     }
2117
2118   free (shdrs);
2119
2120   return 1;
2121 }
2122
2123 static int
2124 get_64bit_section_headers (file)
2125      FILE * file;
2126 {
2127   Elf64_External_Shdr * shdrs;
2128   Elf64_Internal_Shdr * internal;
2129   unsigned int          i;
2130
2131   GET_DATA_ALLOC (elf_header.e_shoff,
2132                   elf_header.e_shentsize * elf_header.e_shnum,
2133                   shdrs, Elf64_External_Shdr *, "section headers");
2134
2135   section_headers = (Elf_Internal_Shdr *) malloc
2136     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
2137
2138   if (section_headers == NULL)
2139     {
2140       error (_("Out of memory\n"));
2141       return 0;
2142     }
2143
2144   for (i = 0, internal = section_headers;
2145        i < elf_header.e_shnum;
2146        i ++, internal ++)
2147     {
2148       internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
2149       internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
2150       internal->sh_flags     = BYTE_GET8 (shdrs[i].sh_flags);
2151       internal->sh_addr      = BYTE_GET8 (shdrs[i].sh_addr);
2152       internal->sh_size      = BYTE_GET8 (shdrs[i].sh_size);
2153       internal->sh_entsize   = BYTE_GET8 (shdrs[i].sh_entsize);
2154       internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
2155       internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
2156       internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
2157       internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
2158     }
2159
2160   free (shdrs);
2161
2162   return 1;
2163 }
2164
2165 static Elf_Internal_Sym *
2166 get_32bit_elf_symbols (file, offset, number)
2167      FILE * file;
2168      unsigned long offset;
2169      unsigned long number;
2170 {
2171   Elf32_External_Sym * esyms;
2172   Elf_Internal_Sym *   isyms;
2173   Elf_Internal_Sym *   psym;
2174   unsigned int         j;
2175
2176   GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
2177                   esyms, Elf32_External_Sym *, "symbols");
2178
2179   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
2180
2181   if (isyms == NULL)
2182     {
2183       error (_("Out of memory\n"));
2184       free (esyms);
2185
2186       return NULL;
2187     }
2188
2189   for (j = 0, psym = isyms;
2190        j < number;
2191        j ++, psym ++)
2192     {
2193       psym->st_name  = BYTE_GET (esyms[j].st_name);
2194       psym->st_value = BYTE_GET (esyms[j].st_value);
2195       psym->st_size  = BYTE_GET (esyms[j].st_size);
2196       psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
2197       psym->st_info  = BYTE_GET (esyms[j].st_info);
2198       psym->st_other = BYTE_GET (esyms[j].st_other);
2199     }
2200
2201   free (esyms);
2202
2203   return isyms;
2204 }
2205
2206 static Elf_Internal_Sym *
2207 get_64bit_elf_symbols (file, offset, number)
2208      FILE * file;
2209      unsigned long offset;
2210      unsigned long number;
2211 {
2212   Elf64_External_Sym * esyms;
2213   Elf_Internal_Sym *   isyms;
2214   Elf_Internal_Sym *   psym;
2215   unsigned int         j;
2216
2217   GET_DATA_ALLOC (offset, number * sizeof (Elf64_External_Sym),
2218                   esyms, Elf64_External_Sym *, "symbols");
2219
2220   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
2221
2222   if (isyms == NULL)
2223     {
2224       error (_("Out of memory\n"));
2225       free (esyms);
2226
2227       return NULL;
2228     }
2229
2230   for (j = 0, psym = isyms;
2231        j < number;
2232        j ++, psym ++)
2233     {
2234       psym->st_name  = BYTE_GET (esyms[j].st_name);
2235       psym->st_info  = BYTE_GET (esyms[j].st_info);
2236       psym->st_other = BYTE_GET (esyms[j].st_other);
2237       psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
2238       psym->st_value = BYTE_GET8 (esyms[j].st_value);
2239       psym->st_size  = BYTE_GET8 (esyms[j].st_size);
2240     }
2241
2242   free (esyms);
2243
2244   return isyms;
2245 }
2246
2247 static int
2248 process_section_headers (file)
2249      FILE * file;
2250 {
2251   Elf_Internal_Shdr * section;
2252   int                 i;
2253
2254   section_headers = NULL;
2255
2256   if (elf_header.e_shnum == 0)
2257     {
2258       if (do_sections)
2259         printf (_("\nThere are no sections in this file.\n"));
2260
2261       return 1;
2262     }
2263
2264   if (do_sections && !do_header)
2265     printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
2266             elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
2267
2268   if (is_32bit_elf)
2269     {
2270       if (! get_32bit_section_headers (file))
2271         return 0;
2272     }
2273   else if (! get_64bit_section_headers (file))
2274     return 0;
2275
2276   /* Read in the string table, so that we have names to display.  */
2277   section = section_headers + elf_header.e_shstrndx;
2278
2279   if (section->sh_size != 0)
2280     {
2281       unsigned long string_table_offset;
2282
2283       string_table_offset = section->sh_offset;
2284
2285       GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2286                       string_table, char *, "string table");
2287     }
2288
2289   /* Scan the sections for the dynamic symbol table
2290      and dynamic string table and debug sections. */
2291   dynamic_symbols = NULL;
2292   dynamic_strings = NULL;
2293   dynamic_syminfo = NULL;
2294
2295   for (i = 0, section = section_headers;
2296        i < elf_header.e_shnum;
2297        i ++, section ++)
2298     {
2299       char * name = SECTION_NAME (section);
2300
2301       if (section->sh_type == SHT_DYNSYM)
2302         {
2303           if (dynamic_symbols != NULL)
2304             {
2305               error (_("File contains multiple dynamic symbol tables\n"));
2306               continue;
2307             }
2308
2309           num_dynamic_syms = section->sh_size / section->sh_entsize;
2310           dynamic_symbols =
2311             GET_ELF_SYMBOLS (file, section->sh_offset, num_dynamic_syms);
2312         }
2313       else if (section->sh_type == SHT_STRTAB
2314                && strcmp (name, ".dynstr") == 0)
2315         {
2316           if (dynamic_strings != NULL)
2317             {
2318               error (_("File contains multiple dynamic string tables\n"));
2319               continue;
2320             }
2321
2322           GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2323                           dynamic_strings, char *, "dynamic strings");
2324         }
2325       else if ((do_debugging || do_debug_info || do_debug_abbrevs
2326                 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
2327                && strncmp (name, ".debug_", 7) == 0)
2328         {
2329           name += 7;
2330
2331           if (do_debugging
2332               || (do_debug_info     && (strcmp (name, "info") == 0))
2333               || (do_debug_abbrevs  && (strcmp (name, "abbrev") == 0))
2334               || (do_debug_lines    && (strcmp (name, "line") == 0))
2335               || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
2336               || (do_debug_aranges  && (strcmp (name, "aranges") == 0))
2337               )
2338             request_dump (i, DEBUG_DUMP);
2339         }
2340     }
2341
2342   if (! do_sections)
2343     return 1;
2344
2345   printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2346   printf
2347     (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
2348
2349   for (i = 0, section = section_headers;
2350        i < elf_header.e_shnum;
2351        i ++, section ++)
2352     {
2353       printf ("  [%2d] %-17.17s %-15.15s ",
2354               i,
2355               SECTION_NAME (section),
2356               get_section_type_name (section->sh_type));
2357
2358       printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
2359                (unsigned long) section->sh_addr,
2360                (unsigned long) section->sh_offset,
2361                (unsigned long) section->sh_size,
2362                (unsigned long) section->sh_entsize);
2363
2364       printf (" %c%c%c %2ld %3lx %ld\n",
2365               (section->sh_flags & SHF_WRITE ? 'W' : ' '),
2366               (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
2367               (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
2368               (unsigned long) section->sh_link,
2369               (unsigned long) section->sh_info,
2370               (unsigned long) section->sh_addralign);
2371     }
2372
2373   return 1;
2374 }
2375
2376 /* Process the reloc section.  */
2377 static int
2378 process_relocs (file)
2379      FILE * file;
2380 {
2381   unsigned long    rel_size;
2382   unsigned long    rel_offset;
2383
2384
2385   if (!do_reloc)
2386     return 1;
2387
2388   if (do_using_dynamic)
2389     {
2390       int is_rela = FALSE;
2391
2392       rel_size   = 0;
2393       rel_offset = 0;
2394
2395       if (dynamic_info[DT_REL])
2396         {
2397           rel_offset = dynamic_info[DT_REL];
2398           rel_size   = dynamic_info[DT_RELSZ];
2399           is_rela    = FALSE;
2400         }
2401       else if (dynamic_info [DT_RELA])
2402         {
2403           rel_offset = dynamic_info[DT_RELA];
2404           rel_size   = dynamic_info[DT_RELASZ];
2405           is_rela    = TRUE;
2406         }
2407       else if (dynamic_info[DT_JMPREL])
2408         {
2409           rel_offset = dynamic_info[DT_JMPREL];
2410           rel_size   = dynamic_info[DT_PLTRELSZ];
2411
2412           switch (dynamic_info[DT_PLTREL])
2413             {
2414             case DT_REL:
2415               is_rela = FALSE;
2416               break;
2417             case DT_RELA:
2418               is_rela = TRUE;
2419               break;
2420             default:
2421               is_rela = UNKNOWN;
2422               break;
2423             }
2424         }
2425
2426       if (rel_size)
2427         {
2428           printf
2429             (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
2430              rel_offset, rel_size);
2431
2432           dump_relocations (file, rel_offset - loadaddr, rel_size,
2433                             dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
2434         }
2435       else
2436         printf (_("\nThere are no dynamic relocations in this file.\n"));
2437     }
2438   else
2439     {
2440       Elf32_Internal_Shdr *     section;
2441       unsigned long             i;
2442       int                       found = 0;
2443
2444       for (i = 0, section = section_headers;
2445            i < elf_header.e_shnum;
2446            i++, section ++)
2447         {
2448           if (   section->sh_type != SHT_RELA
2449               && section->sh_type != SHT_REL)
2450             continue;
2451
2452           rel_offset = section->sh_offset;
2453           rel_size   = section->sh_size;
2454
2455           if (rel_size)
2456             {
2457               Elf32_Internal_Shdr * strsec;
2458               Elf32_Internal_Shdr * symsec;
2459               Elf_Internal_Sym *    symtab;
2460               char *                strtab;
2461               int                   is_rela;
2462               unsigned long         nsyms;
2463
2464               printf (_("\nRelocation section "));
2465
2466               if (string_table == NULL)
2467                 printf ("%d", section->sh_name);
2468               else
2469                 printf ("'%s'", SECTION_NAME (section));
2470
2471               printf (_(" at offset 0x%lx contains %lu entries:\n"),
2472                  rel_offset, (unsigned long) (rel_size / section->sh_entsize));
2473
2474               symsec = section_headers + section->sh_link;
2475
2476               nsyms = symsec->sh_size / symsec->sh_entsize;
2477               symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
2478
2479               if (symtab == NULL)
2480                 continue;
2481
2482               strsec = section_headers + symsec->sh_link;
2483
2484               GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
2485                               char *, "string table");
2486
2487               is_rela = section->sh_type == SHT_RELA;
2488
2489               dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela);
2490
2491               free (strtab);
2492               free (symtab);
2493
2494               found = 1;
2495             }
2496         }
2497
2498       if (! found)
2499         printf (_("\nThere are no relocations in this file.\n"));
2500     }
2501
2502   return 1;
2503 }
2504
2505
2506 static void
2507 dynamic_segment_mips_val (entry)
2508      Elf_Internal_Dyn * entry;
2509 {
2510   switch (entry->d_tag)
2511     {
2512     case DT_MIPS_FLAGS:
2513       if (entry->d_un.d_val == 0)
2514         printf ("NONE\n");
2515       else
2516         {
2517           static const char * opts[] =
2518           {
2519             "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2520             "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2521             "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2522             "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2523             "RLD_ORDER_SAFE"
2524           };
2525           unsigned int cnt;
2526           int first = 1;
2527           for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2528             if (entry->d_un.d_val & (1 << cnt))
2529               {
2530                 printf ("%s%s", first ? "" : " ", opts[cnt]);
2531                 first = 0;
2532               }
2533           puts ("");
2534         }
2535       break;
2536
2537     case DT_MIPS_IVERSION:
2538       if (dynamic_strings != NULL)
2539         printf ("Interface Version: %s\n",
2540                 dynamic_strings + entry->d_un.d_val);
2541       else
2542         printf ("%ld\n", (long) entry->d_un.d_ptr);
2543       break;
2544
2545     case DT_MIPS_TIME_STAMP:
2546       {
2547         char timebuf[20];
2548         time_t time = entry->d_un.d_val;
2549         strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
2550         printf ("Time Stamp: %s\n", timebuf);
2551       }
2552       break;
2553
2554     case DT_MIPS_RLD_VERSION:
2555     case DT_MIPS_LOCAL_GOTNO:
2556     case DT_MIPS_CONFLICTNO:
2557     case DT_MIPS_LIBLISTNO:
2558     case DT_MIPS_SYMTABNO:
2559     case DT_MIPS_UNREFEXTNO:
2560     case DT_MIPS_HIPAGENO:
2561     case DT_MIPS_DELTA_CLASS_NO:
2562     case DT_MIPS_DELTA_INSTANCE_NO:
2563     case DT_MIPS_DELTA_RELOC_NO:
2564     case DT_MIPS_DELTA_SYM_NO:
2565     case DT_MIPS_DELTA_CLASSSYM_NO:
2566     case DT_MIPS_COMPACT_SIZE:
2567       printf ("%ld\n", (long) entry->d_un.d_ptr);
2568       break;
2569
2570     default:
2571       printf ("%#lx\n", (long) entry->d_un.d_ptr);
2572     }
2573 }
2574
2575
2576 static void
2577 dynamic_segment_parisc_val (entry)
2578      Elf_Internal_Dyn * entry;
2579 {
2580   switch (entry->d_tag)
2581     {
2582     case DT_HP_DLD_FLAGS:
2583       {
2584         static struct
2585         {
2586           long int bit;
2587           const char *str;
2588         } flags[] =
2589           {
2590             { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
2591             { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
2592             { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
2593             { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
2594             { DT_HP_BIND_NOW, "HP_BIND_NOW" },
2595             { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
2596             { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
2597             { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
2598             { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
2599             { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
2600             { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
2601           };
2602         int first = 1;
2603         int cnt;
2604         long int val = entry->d_un.d_val;
2605
2606         for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
2607           if (val & flags[cnt].bit)
2608            {
2609              if (! first)
2610                putchar (' ');
2611              fputs (flags[cnt].str, stdout);
2612              first = 0;
2613              val ^= flags[cnt].bit;
2614            }
2615         if (val != 0 || first)
2616           printf ("%s%#lx", first ? "" : " ", val);
2617         puts ("");
2618       }
2619       break;
2620
2621     default:
2622       printf ("%#lx\n", (long) entry->d_un.d_ptr);
2623     }
2624 }
2625
2626 static int
2627 get_32bit_dynamic_segment (file)
2628      FILE * file;
2629 {
2630   Elf32_External_Dyn * edyn;
2631   Elf_Internal_Dyn *   entry;
2632   bfd_size_type        i;
2633
2634   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2635                   edyn, Elf32_External_Dyn *, "dynamic segment");
2636
2637   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
2638      how large this .dynamic is now.  We can do this even before the byte
2639      swapping since the DT_NULL tag is recognizable.  */
2640   dynamic_size = 0;
2641   while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
2642     ;
2643
2644   dynamic_segment = (Elf_Internal_Dyn *)
2645     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2646
2647   if (dynamic_segment == NULL)
2648     {
2649       error (_("Out of memory\n"));
2650       free (edyn);
2651       return 0;
2652     }
2653
2654   for (i = 0, entry = dynamic_segment;
2655        i < dynamic_size;
2656        i ++, entry ++)
2657     {
2658       entry->d_tag      = BYTE_GET (edyn [i].d_tag);
2659       entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2660     }
2661
2662   free (edyn);
2663
2664   return 1;
2665 }
2666
2667 static int
2668 get_64bit_dynamic_segment (file)
2669      FILE * file;
2670 {
2671   Elf64_External_Dyn * edyn;
2672   Elf_Internal_Dyn *   entry;
2673   bfd_size_type        i;
2674
2675   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2676                   edyn, Elf64_External_Dyn *, "dynamic segment");
2677
2678   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
2679      how large this .dynamic is now.  We can do this even before the byte
2680      swapping since the DT_NULL tag is recognizable.  */
2681   dynamic_size = 0;
2682   while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
2683     ;
2684
2685   dynamic_segment = (Elf_Internal_Dyn *)
2686     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2687
2688   if (dynamic_segment == NULL)
2689     {
2690       error (_("Out of memory\n"));
2691       free (edyn);
2692       return 0;
2693     }
2694
2695   for (i = 0, entry = dynamic_segment;
2696        i < dynamic_size;
2697        i ++, entry ++)
2698     {
2699       entry->d_tag      = BYTE_GET8 (edyn [i].d_tag);
2700       entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
2701     }
2702
2703   free (edyn);
2704
2705   return 1;
2706 }
2707
2708 /* Parse and display the contents of the dynamic segment.  */
2709 static int
2710 process_dynamic_segment (file)
2711      FILE * file;
2712 {
2713   Elf_Internal_Dyn * entry;
2714   bfd_size_type      i;
2715
2716   if (dynamic_size == 0)
2717     {
2718       if (do_dynamic)
2719         printf (_("\nThere is no dynamic segment in this file.\n"));
2720
2721       return 1;
2722     }
2723
2724   if (is_32bit_elf)
2725     {
2726       if (! get_32bit_dynamic_segment (file))
2727         return 0;
2728     }
2729   else if (! get_64bit_dynamic_segment (file))
2730     return 0;
2731
2732   /* Find the appropriate symbol table.  */
2733   if (dynamic_symbols == NULL)
2734     {
2735       for (i = 0, entry = dynamic_segment;
2736            i < dynamic_size;
2737            ++i, ++ entry)
2738         {
2739           unsigned long        offset;
2740
2741           if (entry->d_tag != DT_SYMTAB)
2742             continue;
2743
2744           dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2745
2746           /* Since we do not know how big the symbol table is,
2747              we default to reading in the entire file (!) and
2748              processing that.  This is overkill, I know, but it
2749              should work. */
2750           offset = entry->d_un.d_val - loadaddr;
2751
2752           if (fseek (file, 0, SEEK_END))
2753             error (_("Unable to seek to end of file!"));
2754
2755           if (is_32bit_elf)
2756             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2757           else
2758             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
2759
2760           if (num_dynamic_syms < 1)
2761             {
2762               error (_("Unable to determine the number of symbols to load\n"));
2763               continue;
2764             }
2765
2766           dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
2767         }
2768     }
2769
2770   /* Similarly find a string table.  */
2771   if (dynamic_strings == NULL)
2772     {
2773       for (i = 0, entry = dynamic_segment;
2774            i < dynamic_size;
2775            ++i, ++ entry)
2776         {
2777           unsigned long offset;
2778           long          str_tab_len;
2779
2780           if (entry->d_tag != DT_STRTAB)
2781             continue;
2782
2783           dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2784
2785           /* Since we do not know how big the string table is,
2786              we default to reading in the entire file (!) and
2787              processing that.  This is overkill, I know, but it
2788              should work. */
2789
2790           offset = entry->d_un.d_val - loadaddr;
2791           if (fseek (file, 0, SEEK_END))
2792             error (_("Unable to seek to end of file\n"));
2793           str_tab_len = ftell (file) - offset;
2794
2795           if (str_tab_len < 1)
2796             {
2797               error
2798                 (_("Unable to determine the length of the dynamic string table\n"));
2799               continue;
2800             }
2801
2802           GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2803                           "dynamic string table");
2804
2805           break;
2806         }
2807     }
2808
2809   /* And find the syminfo section if available.  */
2810   if (dynamic_syminfo == NULL)
2811     {
2812       unsigned int syminsz = 0;
2813
2814       for (i = 0, entry = dynamic_segment;
2815            i < dynamic_size;
2816            ++i, ++ entry)
2817         {
2818           if (entry->d_tag == DT_SYMINENT)
2819             {
2820               /* Note: these braces are necessary to avoid a syntax
2821                  error from the SunOS4 C compiler.  */
2822               assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2823             }
2824           else if (entry->d_tag == DT_SYMINSZ)
2825             syminsz = entry->d_un.d_val;
2826           else if (entry->d_tag == DT_SYMINFO)
2827             dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2828         }
2829
2830       if (dynamic_syminfo_offset != 0 && syminsz != 0)
2831         {
2832           Elf_External_Syminfo * extsyminfo;
2833           Elf_Internal_Syminfo * syminfo;
2834
2835           /* There is a syminfo section.  Read the data.  */
2836           GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2837                           Elf_External_Syminfo *, "symbol information");
2838
2839           dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2840           if (dynamic_syminfo == NULL)
2841             {
2842               error (_("Out of memory\n"));
2843               return 0;
2844             }
2845
2846           dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2847           for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2848                ++i, ++syminfo)
2849             {
2850               syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2851               syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2852             }
2853
2854           free (extsyminfo);
2855         }
2856     }
2857
2858   if (do_dynamic && dynamic_addr)
2859     printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
2860             dynamic_addr, (long) dynamic_size);
2861   if (do_dynamic)
2862     printf (_("  Tag        Type                         Name/Value\n"));
2863
2864   for (i = 0, entry = dynamic_segment;
2865        i < dynamic_size;
2866        i++, entry ++)
2867     {
2868       if (do_dynamic)
2869         printf (_("  0x%-8.8lx (%s)%*s"),
2870                 (unsigned long) entry->d_tag,
2871                 get_dynamic_type (entry->d_tag),
2872                 27 - strlen (get_dynamic_type (entry->d_tag)),
2873                 " ");
2874
2875       switch (entry->d_tag)
2876         {
2877         case DT_AUXILIARY:
2878         case DT_FILTER:
2879           if (do_dynamic)
2880             {
2881               if (entry->d_tag == DT_AUXILIARY)
2882                 printf (_("Auxiliary library"));
2883               else
2884                 printf (_("Filter library"));
2885
2886               if (dynamic_strings)
2887                 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2888               else
2889                 printf (": %#lx\n", (long) entry->d_un.d_val);
2890             }
2891           break;
2892
2893         case DT_FEATURE_1:
2894           if (do_dynamic)
2895             {
2896               printf (_("Flags:"));
2897               if (entry->d_un.d_val == 0)
2898                 printf (_(" None\n"));
2899               else
2900                 {
2901                   unsigned long int val = entry->d_un.d_val;
2902                   if (val & DTF_1_PARINIT)
2903                     {
2904                       printf (" PARINIT");
2905                       val ^= DTF_1_PARINIT;
2906                     }
2907                   if (val != 0)
2908                     printf (" %lx", val);
2909                   puts ("");
2910                 }
2911             }
2912           break;
2913
2914         case DT_POSFLAG_1:
2915           if (do_dynamic)
2916             {
2917               printf (_("Flags:"));
2918               if (entry->d_un.d_val == 0)
2919                 printf (_(" None\n"));
2920               else
2921                 {
2922                   unsigned long int val = entry->d_un.d_val;
2923                   if (val & DF_P1_LAZYLOAD)
2924                     {
2925                       printf (" LAZYLOAD");
2926                       val ^= DF_P1_LAZYLOAD;
2927                     }
2928                   if (val & DF_P1_GROUPPERM)
2929                     {
2930                       printf (" GROUPPERM");
2931                       val ^= DF_P1_GROUPPERM;
2932                     }
2933                   if (val != 0)
2934                     printf (" %lx", val);
2935                   puts ("");
2936                 }
2937             }
2938           break;
2939
2940         case DT_FLAGS_1:
2941           if (do_dynamic)
2942             {
2943               printf (_("Flags:"));
2944               if (entry->d_un.d_val == 0)
2945                 printf (_(" None\n"));
2946               else
2947                 {
2948                   unsigned long int val = entry->d_un.d_val;
2949                   if (val & DF_1_NOW)
2950                     {
2951                       printf (" NOW");
2952                       val ^= DF_1_NOW;
2953                     }
2954                   if (val & DF_1_GLOBAL)
2955                     {
2956                       printf (" GLOBAL");
2957                       val ^= DF_1_GLOBAL;
2958                     }
2959                   if (val & DF_1_GROUP)
2960                     {
2961                       printf (" GROUP");
2962                       val ^= DF_1_GROUP;
2963                     }
2964                   if (val & DF_1_NODELETE)
2965                     {
2966                       printf (" NODELETE");
2967                       val ^= DF_1_NODELETE;
2968                     }
2969                   if (val & DF_1_LOADFLTR)
2970                     {
2971                       printf (" LOADFLTR");
2972                       val ^= DF_1_LOADFLTR;
2973                     }
2974                   if (val & DF_1_INITFIRST)
2975                     {
2976                       printf (" INITFIRST");
2977                       val ^= DF_1_INITFIRST;
2978                     }
2979                   if (val & DF_1_NOOPEN)
2980                     {
2981                       printf (" NOOPEN");
2982                       val ^= DF_1_NOOPEN;
2983                     }
2984                   if (val & DF_1_ORIGIN)
2985                     {
2986                       printf (" ORIGIN");
2987                       val ^= DF_1_ORIGIN;
2988                     }
2989                   if (val & DF_1_DIRECT)
2990                     {
2991                       printf (" DIRECT");
2992                       val ^= DF_1_DIRECT;
2993                     }
2994                   if (val & DF_1_TRANS)
2995                     {
2996                       printf (" TRANS");
2997                       val ^= DF_1_TRANS;
2998                     }
2999                   if (val & DF_1_INTERPOSE)
3000                     {
3001                       printf (" INTERPOSE");
3002                       val ^= DF_1_INTERPOSE;
3003                     }
3004                   if (val != 0)
3005                     printf (" %lx", val);
3006                   puts ("");
3007                 }
3008             }
3009           break;
3010
3011         case DT_PLTREL:
3012           if (do_dynamic)
3013             puts (get_dynamic_type (entry->d_un.d_val));
3014           break;
3015
3016         case DT_NULL    :
3017         case DT_NEEDED  :
3018         case DT_PLTGOT  :
3019         case DT_HASH    :
3020         case DT_STRTAB  :
3021         case DT_SYMTAB  :
3022         case DT_RELA    :
3023         case DT_INIT    :
3024         case DT_FINI    :
3025         case DT_SONAME  :
3026         case DT_RPATH   :
3027         case DT_SYMBOLIC:
3028         case DT_REL     :
3029         case DT_DEBUG   :
3030         case DT_TEXTREL :
3031         case DT_JMPREL  :
3032           dynamic_info[entry->d_tag] = entry->d_un.d_val;
3033
3034           if (do_dynamic)
3035             {
3036               char * name;
3037
3038               if (dynamic_strings == NULL)
3039                 name = NULL;
3040               else
3041                 name = dynamic_strings + entry->d_un.d_val;
3042
3043               if (name)
3044                 {
3045                   switch (entry->d_tag)
3046                     {
3047                     case DT_NEEDED:
3048                       printf (_("Shared library: [%s]"), name);
3049
3050                       if (strcmp (name, program_interpreter))
3051                         printf ("\n");
3052                       else
3053                         printf (_(" program interpreter\n"));
3054                       break;
3055
3056                     case DT_SONAME:
3057                       printf (_("Library soname: [%s]\n"), name);
3058                       break;
3059
3060                     case DT_RPATH:
3061                       printf (_("Library rpath: [%s]\n"), name);
3062                       break;
3063
3064                     default:
3065                       printf ("%#lx\n", (long) entry->d_un.d_val);
3066                     }
3067                 }
3068               else
3069                 printf ("%#lx\n", (long) entry->d_un.d_val);
3070             }
3071           break;
3072
3073         case DT_PLTRELSZ:
3074         case DT_RELASZ  :
3075         case DT_STRSZ   :
3076         case DT_RELSZ   :
3077         case DT_RELAENT :
3078         case DT_SYMENT  :
3079         case DT_RELENT  :
3080         case DT_PLTPADSZ:
3081         case DT_MOVEENT :
3082         case DT_MOVESZ  :
3083         case DT_INIT_ARRAYSZ:
3084         case DT_FINI_ARRAYSZ:
3085           if (do_dynamic)
3086             printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
3087           break;
3088
3089         case DT_VERDEFNUM:
3090         case DT_VERNEEDNUM:
3091         case DT_RELACOUNT:
3092         case DT_RELCOUNT:
3093           if (do_dynamic)
3094             printf ("%lu\n", (unsigned long) entry->d_un.d_val);
3095           break;
3096
3097         case DT_SYMINSZ:
3098         case DT_SYMINENT:
3099         case DT_SYMINFO:
3100         case DT_USED:
3101         case DT_INIT_ARRAY:
3102         case DT_FINI_ARRAY:
3103           if (do_dynamic)
3104             {
3105               if (dynamic_strings != NULL && entry->d_tag == DT_USED)
3106                 {
3107                   char * name;
3108
3109                   name = dynamic_strings + entry->d_un.d_val;
3110
3111                   if (* name)
3112                     {
3113                       printf (_("Not needed object: [%s]\n"), name);
3114                       break;
3115                     }
3116                 }
3117
3118               printf ("%#lx\n", (long) entry->d_un.d_val);
3119             }
3120           break;
3121
3122         case DT_BIND_NOW:
3123           /* The value of this entry is ignored.  */
3124           break;
3125
3126         default:
3127           if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
3128             version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
3129               entry->d_un.d_val;
3130
3131           if (do_dynamic)
3132             {
3133               switch (elf_header.e_machine)
3134                 {
3135                 case EM_MIPS:
3136                 case EM_MIPS_RS4_BE:
3137                   dynamic_segment_mips_val (entry);
3138                   break;
3139                 case EM_PARISC:
3140                   dynamic_segment_parisc_val (entry);
3141                   break;
3142                 default:
3143                   printf ("%#lx\n", (long) entry->d_un.d_ptr);
3144                 }
3145             }
3146           break;
3147         }
3148     }
3149
3150   return 1;
3151 }
3152
3153 static char *
3154 get_ver_flags (flags)
3155      unsigned int flags;
3156 {
3157   static char buff [32];
3158
3159   buff[0] = 0;
3160
3161   if (flags == 0)
3162     return _("none");
3163
3164   if (flags & VER_FLG_BASE)
3165     strcat (buff, "BASE ");
3166
3167   if (flags & VER_FLG_WEAK)
3168     {
3169       if (flags & VER_FLG_BASE)
3170         strcat (buff, "| ");
3171
3172       strcat (buff, "WEAK ");
3173     }
3174
3175   if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
3176     strcat (buff, "| <unknown>");
3177
3178   return buff;
3179 }
3180
3181 /* Display the contents of the version sections.  */
3182 static int
3183 process_version_sections (file)
3184      FILE * file;
3185 {
3186   Elf32_Internal_Shdr * section;
3187   unsigned   i;
3188   int        found = 0;
3189
3190   if (! do_version)
3191     return 1;
3192
3193   for (i = 0, section = section_headers;
3194        i < elf_header.e_shnum;
3195        i++, section ++)
3196     {
3197       switch (section->sh_type)
3198         {
3199         case SHT_GNU_verdef:
3200           {
3201             Elf_External_Verdef * edefs;
3202             unsigned int          idx;
3203             unsigned int          cnt;
3204
3205             found = 1;
3206
3207             printf
3208               (_("\nVersion definition section '%s' contains %ld entries:\n"),
3209                SECTION_NAME (section), section->sh_info);
3210
3211             printf (_("  Addr: 0x"));
3212             printf_vma (section->sh_addr);
3213             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
3214                     (unsigned long) section->sh_offset, section->sh_link,
3215                     SECTION_NAME (section_headers + section->sh_link));
3216
3217             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3218                             edefs, Elf_External_Verdef *,
3219                             "version definition section");
3220
3221             for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
3222               {
3223                 char *                 vstart;
3224                 Elf_External_Verdef *  edef;
3225                 Elf_Internal_Verdef    ent;
3226                 Elf_External_Verdaux * eaux;
3227                 Elf_Internal_Verdaux   aux;
3228                 int                    j;
3229                 int                    isum;
3230
3231                 vstart = ((char *) edefs) + idx;
3232
3233                 edef = (Elf_External_Verdef *) vstart;
3234
3235                 ent.vd_version = BYTE_GET (edef->vd_version);
3236                 ent.vd_flags   = BYTE_GET (edef->vd_flags);
3237                 ent.vd_ndx     = BYTE_GET (edef->vd_ndx);
3238                 ent.vd_cnt     = BYTE_GET (edef->vd_cnt);
3239                 ent.vd_hash    = BYTE_GET (edef->vd_hash);
3240                 ent.vd_aux     = BYTE_GET (edef->vd_aux);
3241                 ent.vd_next    = BYTE_GET (edef->vd_next);
3242
3243                 printf (_("  %#06x: Rev: %d  Flags: %s"),
3244                         idx, ent.vd_version, get_ver_flags (ent.vd_flags));
3245
3246                 printf (_("  Index: %d  Cnt: %d  "),
3247                         ent.vd_ndx, ent.vd_cnt);
3248
3249                 vstart += ent.vd_aux;
3250
3251                 eaux = (Elf_External_Verdaux *) vstart;
3252
3253                 aux.vda_name = BYTE_GET (eaux->vda_name);
3254                 aux.vda_next = BYTE_GET (eaux->vda_next);
3255
3256                 if (dynamic_strings)
3257                   printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
3258                 else
3259                   printf (_("Name index: %ld\n"), aux.vda_name);
3260
3261                 isum = idx + ent.vd_aux;
3262
3263                 for (j = 1; j < ent.vd_cnt; j ++)
3264                   {
3265                     isum   += aux.vda_next;
3266                     vstart += aux.vda_next;
3267
3268                     eaux = (Elf_External_Verdaux *) vstart;
3269
3270                     aux.vda_name = BYTE_GET (eaux->vda_name);
3271                     aux.vda_next = BYTE_GET (eaux->vda_next);
3272
3273                     if (dynamic_strings)
3274                       printf (_("  %#06x: Parent %d: %s\n"),
3275                               isum, j, dynamic_strings + aux.vda_name);
3276                     else
3277                       printf (_("  %#06x: Parent %d, name index: %ld\n"),
3278                               isum, j, aux.vda_name);
3279                   }
3280
3281                 idx += ent.vd_next;
3282               }
3283
3284             free (edefs);
3285           }
3286           break;
3287
3288         case SHT_GNU_verneed:
3289           {
3290             Elf_External_Verneed *  eneed;
3291             unsigned int            idx;
3292             unsigned int            cnt;
3293
3294             found = 1;
3295
3296             printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
3297                     SECTION_NAME (section), section->sh_info);
3298
3299             printf (_(" Addr: 0x"));
3300             printf_vma (section->sh_addr);
3301             printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
3302                     (unsigned long) section->sh_offset, section->sh_link,
3303                     SECTION_NAME (section_headers + section->sh_link));
3304
3305             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3306                             eneed, Elf_External_Verneed *,
3307                             "version need section");
3308
3309             for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
3310               {
3311                 Elf_External_Verneed * entry;
3312                 Elf_Internal_Verneed     ent;
3313                 int                      j;
3314                 int                      isum;
3315                 char *                   vstart;
3316
3317                 vstart = ((char *) eneed) + idx;
3318
3319                 entry = (Elf_External_Verneed *) vstart;
3320
3321                 ent.vn_version = BYTE_GET (entry->vn_version);
3322                 ent.vn_cnt     = BYTE_GET (entry->vn_cnt);
3323                 ent.vn_file    = BYTE_GET (entry->vn_file);
3324                 ent.vn_aux     = BYTE_GET (entry->vn_aux);
3325                 ent.vn_next    = BYTE_GET (entry->vn_next);
3326
3327                 printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
3328
3329                 if (dynamic_strings)
3330                   printf (_("  File: %s"), dynamic_strings + ent.vn_file);
3331                 else
3332                   printf (_("  File: %lx"), ent.vn_file);
3333
3334                 printf (_("  Cnt: %d\n"), ent.vn_cnt);
3335
3336                 vstart += ent.vn_aux;
3337
3338                 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
3339                   {
3340                     Elf_External_Vernaux * eaux;
3341                     Elf_Internal_Vernaux   aux;
3342
3343                     eaux = (Elf_External_Vernaux *) vstart;
3344
3345                     aux.vna_hash  = BYTE_GET (eaux->vna_hash);
3346                     aux.vna_flags = BYTE_GET (eaux->vna_flags);
3347                     aux.vna_other = BYTE_GET (eaux->vna_other);
3348                     aux.vna_name  = BYTE_GET (eaux->vna_name);
3349                     aux.vna_next  = BYTE_GET (eaux->vna_next);
3350
3351                     if (dynamic_strings)
3352                       printf (_("  %#06x: Name: %s"),
3353                               isum, dynamic_strings + aux.vna_name);
3354                     else
3355                       printf (_("  %#06x: Name index: %lx"),
3356                               isum, aux.vna_name);
3357
3358                     printf (_("  Flags: %s  Version: %d\n"),
3359                             get_ver_flags (aux.vna_flags), aux.vna_other);
3360
3361                     isum   += aux.vna_next;
3362                     vstart += aux.vna_next;
3363                   }
3364
3365                 idx += ent.vn_next;
3366               }
3367
3368             free (eneed);
3369           }
3370           break;
3371
3372         case SHT_GNU_versym:
3373           {
3374             Elf32_Internal_Shdr *       link_section;
3375             int                         total;
3376             int                         cnt;
3377             unsigned char *             edata;
3378             unsigned short *            data;
3379             char *                      strtab;
3380             Elf_Internal_Sym *          symbols;
3381             Elf32_Internal_Shdr *       string_sec;
3382
3383             link_section = section_headers + section->sh_link;
3384             total = section->sh_size / section->sh_entsize;
3385
3386             found = 1;
3387
3388             symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
3389                                        link_section->sh_size / link_section->sh_entsize);
3390
3391             string_sec = section_headers + link_section->sh_link;
3392
3393             GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3394                             strtab, char *, "version string table");
3395
3396             printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
3397                     SECTION_NAME (section), total);
3398
3399             printf (_(" Addr: "));
3400             printf_vma (section->sh_addr);
3401             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
3402                     (unsigned long) section->sh_offset, section->sh_link,
3403                     SECTION_NAME (link_section));
3404
3405             GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3406                             - loadaddr,
3407                             total * sizeof (short), edata,
3408                             unsigned char *, "version symbol data");
3409
3410             data = (unsigned short *) malloc (total * sizeof (short));
3411
3412             for (cnt = total; cnt --;)
3413               data [cnt] = byte_get (edata + cnt * sizeof (short),
3414                                      sizeof (short));
3415
3416             free (edata);
3417
3418             for (cnt = 0; cnt < total; cnt += 4)
3419               {
3420                 int j, nn;
3421
3422                 printf ("  %03x:", cnt);
3423
3424                 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
3425                   switch (data [cnt + j])
3426                     {
3427                     case 0:
3428                       fputs (_("   0 (*local*)    "), stdout);
3429                       break;
3430
3431                     case 1:
3432                       fputs (_("   1 (*global*)   "), stdout);
3433                       break;
3434
3435                     default:
3436                       nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
3437                                    data [cnt + j] & 0x8000 ? 'h' : ' ');
3438
3439                       if (symbols [cnt + j].st_shndx < SHN_LORESERVE
3440                           && section_headers[symbols [cnt + j].st_shndx].sh_type
3441                           == SHT_NOBITS)
3442                         {
3443                           /* We must test both.  */
3444                           Elf_Internal_Verneed     ivn;
3445                           unsigned long            offset;
3446
3447                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3448                             - loadaddr;
3449
3450                           do
3451                             {
3452                               Elf_External_Verneed   evn;
3453                               Elf_External_Vernaux   evna;
3454                               Elf_Internal_Vernaux     ivna;
3455                               unsigned long            vna_off;
3456
3457                               GET_DATA (offset, evn, "version need");
3458
3459                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
3460                               ivn.vn_next = BYTE_GET (evn.vn_next);
3461
3462                               vna_off = offset + ivn.vn_aux;
3463
3464                               do
3465                                 {
3466                                   GET_DATA (vna_off, evna,
3467                                             "version need aux (1)");
3468
3469                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
3470                                   ivna.vna_other = BYTE_GET (evna.vna_other);
3471
3472                                   vna_off += ivna.vna_next;
3473                                 }
3474                               while (ivna.vna_other != data [cnt + j]
3475                                      && ivna.vna_next != 0);
3476
3477                               if (ivna.vna_other == data [cnt + j])
3478                                 {
3479                                   ivna.vna_name = BYTE_GET (evna.vna_name);
3480
3481                                   nn += printf ("(%s%-*s",
3482                                                 strtab + ivna.vna_name,
3483                                                 12 - strlen (strtab
3484                                                              + ivna.vna_name),
3485                                                 ")");
3486                                   break;
3487                                 }
3488                               else if (ivn.vn_next == 0)
3489                                 {
3490                                   if (data [cnt + j] != 0x8001)
3491                                     {
3492                                       Elf_Internal_Verdef  ivd;
3493                                       Elf_External_Verdef  evd;
3494
3495                                       offset = version_info
3496                                         [DT_VERSIONTAGIDX (DT_VERDEF)]
3497                                         - loadaddr;
3498
3499                                       do
3500                                         {
3501                                           GET_DATA (offset, evd,
3502                                                     "version definition");
3503
3504                                           ivd.vd_next = BYTE_GET (evd.vd_next);
3505                                           ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
3506
3507                                           offset += ivd.vd_next;
3508                                         }
3509                                       while (ivd.vd_ndx
3510                                              != (data [cnt + j] & 0x7fff)
3511                                              && ivd.vd_next != 0);
3512
3513                                       if (ivd.vd_ndx
3514                                           == (data [cnt + j] & 0x7fff))
3515                                         {
3516                                           Elf_External_Verdaux  evda;
3517                                           Elf_Internal_Verdaux  ivda;
3518
3519                                           ivd.vd_aux = BYTE_GET (evd.vd_aux);
3520
3521                                           GET_DATA (offset + ivd.vd_aux, evda,
3522                                                     "version definition aux");
3523
3524                                           ivda.vda_name =
3525                                             BYTE_GET (evda.vda_name);
3526
3527                                           nn +=
3528                                             printf ("(%s%-*s",
3529                                                     strtab + ivda.vda_name,
3530                                                     12
3531                                                     - strlen (strtab
3532                                                               + ivda.vda_name),
3533                                                     ")");
3534                                         }
3535                                     }
3536
3537                                   break;
3538                                 }
3539                               else
3540                                 offset += ivn.vn_next;
3541                             }
3542                           while (ivn.vn_next);
3543                         }
3544                       else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
3545                         {
3546                           Elf_Internal_Verneed     ivn;
3547                           unsigned long            offset;
3548
3549                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3550                             - loadaddr;
3551
3552                           do
3553                             {
3554                               Elf_Internal_Vernaux     ivna;
3555                               Elf_External_Verneed   evn;
3556                               Elf_External_Vernaux   evna;
3557                               unsigned long            a_off;
3558
3559                               GET_DATA (offset, evn, "version need");
3560
3561                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
3562                               ivn.vn_next = BYTE_GET (evn.vn_next);
3563
3564                               a_off = offset + ivn.vn_aux;
3565
3566                               do
3567                                 {
3568                                   GET_DATA (a_off, evna,
3569                                             "version need aux (2)");
3570
3571                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
3572                                   ivna.vna_other = BYTE_GET (evna.vna_other);
3573
3574                                   a_off += ivna.vna_next;
3575                                 }
3576                               while (ivna.vna_other != data [cnt + j]
3577                                      && ivna.vna_next != 0);
3578
3579                               if (ivna.vna_other == data [cnt + j])
3580                                 {
3581                                   ivna.vna_name = BYTE_GET (evna.vna_name);
3582
3583                                   nn += printf ("(%s%-*s",
3584                                                 strtab + ivna.vna_name,
3585                                                 12 - strlen (strtab
3586                                                              + ivna.vna_name),
3587                                                 ")");
3588                                   break;
3589                                 }
3590
3591                               offset += ivn.vn_next;
3592                             }
3593                           while (ivn.vn_next);
3594                         }
3595                       else if (data [cnt + j] != 0x8001)
3596                         {
3597                           Elf_Internal_Verdef  ivd;
3598                           Elf_External_Verdef  evd;
3599                           unsigned long        offset;
3600
3601                           offset = version_info
3602                             [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
3603
3604                           do
3605                             {
3606                               GET_DATA (offset, evd, "version def");
3607
3608                               ivd.vd_next = BYTE_GET (evd.vd_next);
3609                               ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
3610
3611                               offset += ivd.vd_next;
3612                             }
3613                           while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
3614                                  && ivd.vd_next != 0);
3615
3616                           if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
3617                             {
3618                               Elf_External_Verdaux  evda;
3619                               Elf_Internal_Verdaux  ivda;
3620
3621                               ivd.vd_aux = BYTE_GET (evd.vd_aux);
3622
3623                               GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
3624                                         evda, "version def aux");
3625
3626                               ivda.vda_name = BYTE_GET (evda.vda_name);
3627
3628                               nn += printf ("(%s%-*s",
3629                                             strtab + ivda.vda_name,
3630                                             12 - strlen (strtab
3631                                                          + ivda.vda_name),
3632                                             ")");
3633                             }
3634                         }
3635
3636                       if (nn < 18)
3637                         printf ("%*c", 18 - nn, ' ');
3638                     }
3639
3640                 putchar ('\n');
3641               }
3642
3643             free (data);
3644             free (strtab);
3645             free (symbols);
3646           }
3647           break;
3648
3649         default:
3650           break;
3651         }
3652     }
3653
3654   if (! found)
3655     printf (_("\nNo version information found in this file.\n"));
3656
3657   return 1;
3658 }
3659
3660 static char *
3661 get_symbol_binding (binding)
3662      unsigned int binding;
3663 {
3664   static char buff [32];
3665
3666   switch (binding)
3667     {
3668     case STB_LOCAL:  return "LOCAL";
3669     case STB_GLOBAL: return "GLOBAL";
3670     case STB_WEAK:   return "WEAK";
3671     default:
3672       if (binding >= STB_LOPROC && binding <= STB_HIPROC)
3673         sprintf (buff, _("<processor specific>: %d"), binding);
3674       else if (binding >= STB_LOOS && binding <= STB_HIOS)
3675         sprintf (buff, _("<OS specific>: %d"), binding);
3676       else
3677         sprintf (buff, _("<unknown>: %d"), binding);
3678       return buff;
3679     }
3680 }
3681
3682 static char *
3683 get_symbol_type (type)
3684      unsigned int type;
3685 {
3686   static char buff [32];
3687
3688   switch (type)
3689     {
3690     case STT_NOTYPE:   return "NOTYPE";
3691     case STT_OBJECT:   return "OBJECT";
3692     case STT_FUNC:     return "FUNC";
3693     case STT_SECTION:  return "SECTION";
3694     case STT_FILE:     return "FILE";
3695     default:
3696       if (type >= STT_LOPROC && type <= STT_HIPROC)
3697         {
3698           if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3699             return "THUMB_FUNC";
3700
3701           if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
3702             return "REGISTER";
3703
3704           if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
3705             return "PARISC_MILLI";
3706
3707           sprintf (buff, _("<processor specific>: %d"), type);
3708         }
3709       else if (type >= STT_LOOS && type <= STT_HIOS)
3710         {
3711           if (elf_header.e_machine == EM_PARISC)
3712             {
3713               if (type == STT_HP_OPAQUE)
3714                 return "HP_OPAQUE";
3715               if (type == STT_HP_STUB)
3716                 return "HP_STUB";
3717             }
3718
3719           sprintf (buff, _("<OS specific>: %d"), type);
3720         }
3721       else
3722         sprintf (buff, _("<unknown>: %d"), type);
3723       return buff;
3724     }
3725 }
3726
3727 static char *
3728 get_symbol_index_type (type)
3729      unsigned int type;
3730 {
3731   switch (type)
3732     {
3733     case SHN_UNDEF:  return "UND";
3734     case SHN_ABS:    return "ABS";
3735     case SHN_COMMON: return "COM";
3736     default:
3737       if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3738         return "PRC";
3739       else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3740         return "RSV";
3741       else if (type >= SHN_LOOS && type <= SHN_HIOS)
3742         return "OS ";
3743       else
3744         {
3745           static char buff [32];
3746
3747           sprintf (buff, "%3d", type);
3748           return buff;
3749         }
3750     }
3751 }
3752
3753
3754 static int *
3755 get_dynamic_data (file, number)
3756      FILE *       file;
3757      unsigned int number;
3758 {
3759   char * e_data;
3760   int *  i_data;
3761
3762   e_data = (char *) malloc (number * 4);
3763
3764   if (e_data == NULL)
3765     {
3766       error (_("Out of memory\n"));
3767       return NULL;
3768     }
3769
3770   if (fread (e_data, 4, number, file) != number)
3771     {
3772       error (_("Unable to read in dynamic data\n"));
3773       return NULL;
3774     }
3775
3776   i_data = (int *) malloc (number * sizeof (* i_data));
3777
3778   if (i_data == NULL)
3779     {
3780       error (_("Out of memory\n"));
3781       free (e_data);
3782       return NULL;
3783     }
3784
3785   while (number--)
3786     i_data [number] = byte_get (e_data + number * 4, 4);
3787
3788   free (e_data);
3789
3790   return i_data;
3791 }
3792
3793 /* Dump the symbol table */
3794 static int
3795 process_symbol_table (file)
3796      FILE * file;
3797 {
3798   Elf32_Internal_Shdr *   section;
3799   char   nb [4];
3800   char   nc [4];
3801   int    nbuckets = 0;
3802   int    nchains;
3803   int *  buckets = NULL;
3804   int *  chains = NULL;
3805
3806   if (! do_syms && !do_histogram)
3807     return 1;
3808
3809   if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3810                                 || do_histogram))
3811     {
3812       if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3813         {
3814           error (_("Unable to seek to start of dynamic information"));
3815           return 0;
3816         }
3817
3818       if (fread (nb, sizeof (nb), 1, file) != 1)
3819         {
3820           error (_("Failed to read in number of buckets\n"));
3821           return 0;
3822         }
3823
3824       if (fread (nc, sizeof (nc), 1, file) != 1)
3825         {
3826           error (_("Failed to read in number of chains\n"));
3827           return 0;
3828         }
3829
3830       nbuckets = byte_get (nb, 4);
3831       nchains  = byte_get (nc, 4);
3832
3833       buckets = get_dynamic_data (file, nbuckets);
3834       chains  = get_dynamic_data (file, nchains);
3835
3836       if (buckets == NULL || chains == NULL)
3837         return 0;
3838     }
3839
3840   if (do_syms
3841       && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3842     {
3843       int    hn;
3844       int    si;
3845
3846       printf (_("\nSymbol table for image:\n"));
3847       printf (_("  Num Buc:    Value  Size   Type   Bind Ot Ndx Name\n"));
3848
3849       for (hn = 0; hn < nbuckets; hn++)
3850         {
3851           if (! buckets [hn])
3852             continue;
3853
3854           for (si = buckets [hn]; si; si = chains [si])
3855             {
3856               Elf_Internal_Sym * psym;
3857
3858               psym = dynamic_symbols + si;
3859
3860               printf ("  %3d %3d: %8lx %5ld %6s %6s %2d ",
3861                       si, hn,
3862                       (unsigned long) psym->st_value,
3863                       (unsigned long) psym->st_size,
3864                       get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3865                       get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3866                       psym->st_other);
3867
3868               printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3869
3870               printf (" %s\n", dynamic_strings + psym->st_name);
3871             }
3872         }
3873     }
3874   else if (do_syms && !do_using_dynamic)
3875     {
3876       unsigned int     i;
3877
3878       for (i = 0, section = section_headers;
3879            i < elf_header.e_shnum;
3880            i++, section++)
3881         {
3882           unsigned int          si;
3883           char *                strtab;
3884           Elf_Internal_Sym *    symtab;
3885           Elf_Internal_Sym *    psym;
3886
3887
3888           if (   section->sh_type != SHT_SYMTAB
3889               && section->sh_type != SHT_DYNSYM)
3890             continue;
3891
3892           printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3893                   SECTION_NAME (section),
3894                   (unsigned long) (section->sh_size / section->sh_entsize));
3895           fputs (_("  Num:    Value  Size Type    Bind   Ot  Ndx Name\n"),
3896                  stdout);
3897
3898           symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
3899                                     section->sh_size / section->sh_entsize);
3900           if (symtab == NULL)
3901             continue;
3902
3903           if (section->sh_link == elf_header.e_shstrndx)
3904             strtab = string_table;
3905           else
3906             {
3907               Elf32_Internal_Shdr * string_sec;
3908
3909               string_sec = section_headers + section->sh_link;
3910
3911               GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3912                               strtab, char *, "string table");
3913             }
3914
3915           for (si = 0, psym = symtab;
3916                si < section->sh_size / section->sh_entsize;
3917                si ++, psym ++)
3918             {
3919               printf ("  %3d: %8lx %5ld %-7s %-6s %2d ",
3920                       si,
3921                       (unsigned long) psym->st_value,
3922                       (unsigned long) psym->st_size,
3923                       get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3924                       get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3925                       psym->st_other);
3926
3927               printf ("%4s", get_symbol_index_type (psym->st_shndx));
3928
3929               printf (" %s", strtab + psym->st_name);
3930
3931               if (section->sh_type == SHT_DYNSYM &&
3932                   version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3933                 {
3934                   unsigned char   data[2];
3935                   unsigned short  vers_data;
3936                   unsigned long   offset;
3937                   int             is_nobits;
3938                   int             check_def;
3939
3940                   offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3941                     - loadaddr;
3942
3943                   GET_DATA (offset + si * sizeof (vers_data), data,
3944                             "version data");
3945
3946                   vers_data = byte_get (data, 2);
3947
3948                   is_nobits = psym->st_shndx < SHN_LORESERVE ?
3949                     (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3950                     : 0;
3951
3952                   check_def = (psym->st_shndx != SHN_UNDEF);
3953
3954                   if ((vers_data & 0x8000) || vers_data > 1)
3955                     {
3956                       if (is_nobits || ! check_def)
3957                         {
3958                           Elf_External_Verneed  evn;
3959                           Elf_Internal_Verneed  ivn;
3960                           Elf_Internal_Vernaux  ivna;
3961
3962                           /* We must test both.  */
3963                           offset = version_info
3964                             [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3965
3966                           GET_DATA (offset, evn, "version need");
3967
3968                           ivn.vn_aux  = BYTE_GET (evn.vn_aux);
3969                           ivn.vn_next = BYTE_GET (evn.vn_next);
3970
3971                           do
3972                             {
3973                               unsigned long  vna_off;
3974
3975                               vna_off = offset + ivn.vn_aux;
3976
3977                               do
3978                                 {
3979                                   Elf_External_Vernaux  evna;
3980
3981                                   GET_DATA (vna_off, evna,
3982                                             "version need aux (3)");
3983
3984                                   ivna.vna_other = BYTE_GET (evna.vna_other);
3985                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
3986                                   ivna.vna_name  = BYTE_GET (evna.vna_name);
3987
3988                                   vna_off += ivna.vna_next;
3989                                 }
3990                               while (ivna.vna_other != vers_data
3991                                      && ivna.vna_next != 0);
3992
3993                               if (ivna.vna_other == vers_data)
3994                                 break;
3995
3996                               offset += ivn.vn_next;
3997                             }
3998                           while (ivn.vn_next != 0);
3999
4000                           if (ivna.vna_other == vers_data)
4001                             {
4002                               printf ("@%s (%d)",
4003                                       strtab + ivna.vna_name, ivna.vna_other);
4004                               check_def = 0;
4005                             }
4006                           else if (! is_nobits)
4007                             error (_("bad dynamic symbol"));
4008                           else
4009                             check_def = 1;
4010                         }
4011
4012                       if (check_def)
4013                         {
4014                           if (vers_data != 0x8001)
4015                             {
4016                               Elf_Internal_Verdef     ivd;
4017                               Elf_Internal_Verdaux    ivda;
4018                               Elf_External_Verdaux  evda;
4019                               unsigned long           offset;
4020
4021                               offset =
4022                                 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
4023                                 - loadaddr;
4024
4025                               do
4026                                 {
4027                                   Elf_External_Verdef   evd;
4028
4029                                   GET_DATA (offset, evd, "version def");
4030
4031                                   ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
4032                                   ivd.vd_aux  = BYTE_GET (evd.vd_aux);
4033                                   ivd.vd_next = BYTE_GET (evd.vd_next);
4034
4035                                   offset += ivd.vd_next;
4036                                 }
4037                               while (ivd.vd_ndx != (vers_data & 0x7fff)
4038                                      && ivd.vd_next != 0);
4039
4040                               offset -= ivd.vd_next;
4041                               offset += ivd.vd_aux;
4042
4043                               GET_DATA (offset, evda, "version def aux");
4044
4045                               ivda.vda_name = BYTE_GET (evda.vda_name);
4046
4047                               if (psym->st_name != ivda.vda_name)
4048                                 printf ((vers_data & 0x8000)
4049                                         ? "@%s" : "@@%s",
4050                                         strtab + ivda.vda_name);
4051                             }
4052                         }
4053                     }
4054                 }
4055
4056               putchar ('\n');
4057             }
4058
4059           free (symtab);
4060           if (strtab != string_table)
4061             free (strtab);
4062         }
4063     }
4064   else if (do_syms)
4065     printf
4066       (_("\nDynamic symbol information is not available for displaying symbols.\n"));
4067
4068   if (do_histogram && buckets != NULL)
4069     {
4070       int *lengths;
4071       int *counts;
4072       int hn;
4073       int si;
4074       int maxlength = 0;
4075       int nzero_counts = 0;
4076       int nsyms = 0;
4077
4078       printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
4079               nbuckets);
4080       printf (_(" Length  Number     %% of total  Coverage\n"));
4081
4082       lengths = (int *) calloc (nbuckets, sizeof (int));
4083       if (lengths == NULL)
4084         {
4085           error (_("Out of memory"));
4086           return 0;
4087         }
4088       for (hn = 0; hn < nbuckets; ++hn)
4089         {
4090           if (! buckets [hn])
4091             continue;
4092
4093           for (si = buckets[hn]; si; si = chains[si])
4094             {
4095               ++nsyms;
4096               if (maxlength < ++lengths[hn])
4097                 ++maxlength;
4098             }
4099         }
4100
4101       counts = (int *) calloc (maxlength + 1, sizeof (int));
4102       if (counts == NULL)
4103         {
4104           error (_("Out of memory"));
4105           return 0;
4106         }
4107
4108       for (hn = 0; hn < nbuckets; ++hn)
4109         ++counts[lengths [hn]];
4110
4111       if (nbuckets > 0)
4112         {
4113           printf ("      0  %-10d (%5.1f%%)\n",
4114                   counts[0], (counts[0] * 100.0) / nbuckets);
4115           for (si = 1; si <= maxlength; ++si)
4116             {
4117               nzero_counts += counts[si] * si;
4118               printf ("%7d  %-10d (%5.1f%%)    %5.1f%%\n",
4119                       si, counts[si], (counts[si] * 100.0) / nbuckets,
4120                       (nzero_counts * 100.0) / nsyms);
4121             }
4122         }
4123
4124       free (counts);
4125       free (lengths);
4126     }
4127
4128   if (buckets != NULL)
4129     {
4130       free (buckets);
4131       free (chains);
4132     }
4133
4134   return 1;
4135 }
4136
4137 static int
4138 process_syminfo (file)
4139      FILE * file ATTRIBUTE_UNUSED;
4140 {
4141   unsigned int i;
4142
4143   if (dynamic_syminfo == NULL
4144       || !do_dynamic)
4145     /* No syminfo, this is ok.  */
4146     return 1;
4147
4148   /* There better should be a dynamic symbol section.  */
4149   if (dynamic_symbols == NULL || dynamic_strings == NULL)
4150     return 0;
4151
4152   if (dynamic_addr)
4153     printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
4154             dynamic_syminfo_offset, dynamic_syminfo_nent);
4155
4156   printf (_(" Num: Name                           BoundTo     Flags\n"));
4157   for (i = 0; i < dynamic_syminfo_nent; ++i)
4158     {
4159       unsigned short int flags = dynamic_syminfo[i].si_flags;
4160
4161       printf ("%4d: %-30s ", i,
4162               dynamic_strings + dynamic_symbols[i].st_name);
4163
4164       switch (dynamic_syminfo[i].si_boundto)
4165         {
4166         case SYMINFO_BT_SELF:
4167           fputs ("SELF       ", stdout);
4168           break;
4169         case SYMINFO_BT_PARENT:
4170           fputs ("PARENT     ", stdout);
4171           break;
4172         default:
4173           if (dynamic_syminfo[i].si_boundto > 0
4174               && dynamic_syminfo[i].si_boundto < dynamic_size)
4175             printf ("%-10s ",
4176                     dynamic_strings
4177                     + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
4178           else
4179             printf ("%-10d ", dynamic_syminfo[i].si_boundto);
4180           break;
4181         }
4182
4183       if (flags & SYMINFO_FLG_DIRECT)
4184         printf (" DIRECT");
4185       if (flags & SYMINFO_FLG_PASSTHRU)
4186         printf (" PASSTHRU");
4187       if (flags & SYMINFO_FLG_COPY)
4188         printf (" COPY");
4189       if (flags & SYMINFO_FLG_LAZYLOAD)
4190         printf (" LAZYLOAD");
4191
4192       puts ("");
4193     }
4194
4195   return 1;
4196 }
4197
4198 #ifdef SUPPORT_DISASSEMBLY
4199 static void
4200 disassemble_section (section, file)
4201      Elf32_Internal_Shdr * section;
4202      FILE * file;
4203 {
4204   printf (_("\nAssembly dump of section %s\n"),
4205           SECTION_NAME (section));
4206
4207   /* XXX -- to be done --- XXX */
4208
4209   return 1;
4210 }
4211 #endif
4212
4213 static int
4214 dump_section (section, file)
4215      Elf32_Internal_Shdr * section;
4216      FILE * file;
4217 {
4218   bfd_size_type   bytes;
4219   bfd_vma         addr;
4220   unsigned char * data;
4221   unsigned char * start;
4222
4223   bytes = section->sh_size;
4224
4225   if (bytes == 0)
4226     {
4227       printf (_("\nSection '%s' has no data to dump.\n"),
4228               SECTION_NAME (section));
4229       return 0;
4230     }
4231   else
4232     printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
4233
4234   addr = section->sh_addr;
4235
4236   GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
4237                   "section data");
4238
4239   data = start;
4240
4241   while (bytes)
4242     {
4243       int j;
4244       int k;
4245       int lbytes;
4246
4247       lbytes = (bytes > 16 ? 16 : bytes);
4248
4249       printf ("  0x%8.8lx ", (unsigned long) addr);
4250
4251       switch (elf_header.e_ident [EI_DATA])
4252         {
4253         default:
4254         case ELFDATA2LSB:
4255           for (j = 15; j >= 0; j --)
4256             {
4257               if (j < lbytes)
4258                 printf ("%2.2x", data [j]);
4259               else
4260                 printf ("  ");
4261
4262               if (!(j & 0x3))
4263                 printf (" ");
4264             }
4265           break;
4266
4267         case ELFDATA2MSB:
4268           for (j = 0; j < 16; j++)
4269             {
4270               if (j < lbytes)
4271                 printf ("%2.2x", data [j]);
4272               else
4273                 printf ("  ");
4274
4275               if ((j & 3) == 3)
4276                 printf (" ");
4277             }
4278           break;
4279         }
4280
4281       for (j = 0; j < lbytes; j++)
4282         {
4283           k = data [j];
4284           if (k >= ' ' && k < 0x80)
4285             printf ("%c", k);
4286           else
4287             printf (".");
4288         }
4289
4290       putchar ('\n');
4291
4292       data  += lbytes;
4293       addr  += lbytes;
4294       bytes -= lbytes;
4295     }
4296
4297   free (start);
4298
4299   return 1;
4300 }
4301
4302
4303 static unsigned long int
4304 read_leb128 (data, length_return, sign)
4305      unsigned char * data;
4306      int *           length_return;
4307      int             sign;
4308 {
4309   unsigned long int result = 0;
4310   unsigned int      num_read = 0;
4311   int               shift = 0;
4312   unsigned char     byte;
4313
4314   do
4315     {
4316       byte = * data ++;
4317       num_read ++;
4318
4319       result |= (byte & 0x7f) << shift;
4320
4321       shift += 7;
4322
4323     }
4324   while (byte & 0x80);
4325
4326   if (length_return != NULL)
4327     * length_return = num_read;
4328
4329   if (sign && (shift < 32) && (byte & 0x40))
4330     result |= -1 << shift;
4331
4332   return result;
4333 }
4334
4335 typedef struct State_Machine_Registers
4336 {
4337   unsigned long address;
4338   unsigned int  file;
4339   unsigned int  line;
4340   unsigned int  column;
4341   int           is_stmt;
4342   int           basic_block;
4343   int           end_sequence;
4344 /* This variable hold the number of the last entry seen
4345    in the File Table.  */
4346   unsigned int  last_file_entry;
4347 } SMR;
4348
4349 static SMR state_machine_regs;
4350
4351 static void
4352 reset_state_machine (is_stmt)
4353      int is_stmt;
4354 {
4355   state_machine_regs.address = 0;
4356   state_machine_regs.file = 1;
4357   state_machine_regs.line = 1;
4358   state_machine_regs.column = 0;
4359   state_machine_regs.is_stmt = is_stmt;
4360   state_machine_regs.basic_block = 0;
4361   state_machine_regs.end_sequence = 0;
4362   state_machine_regs.last_file_entry = 0;
4363 }
4364
4365 /* Handled an extend line op.  Returns true if this is the end
4366    of sequence.  */
4367 static int
4368 process_extended_line_op (data, is_stmt, pointer_size)
4369      unsigned char * data;
4370      int is_stmt;
4371      int pointer_size;
4372 {
4373   unsigned char   op_code;
4374   int             bytes_read;
4375   unsigned int    len;
4376   unsigned char * name;
4377   unsigned long   adr;
4378
4379   len = read_leb128 (data, & bytes_read, 0);
4380   data += bytes_read;
4381
4382   if (len == 0)
4383     {
4384       warn (_("badly formed extended line op encountered!"));
4385       return bytes_read;
4386     }
4387
4388   len += bytes_read;
4389   op_code = * data ++;
4390
4391   printf (_("  Extended opcode %d: "), op_code);
4392
4393   switch (op_code)
4394     {
4395     case DW_LNE_end_sequence:
4396       printf (_("End of Sequence\n\n"));
4397       reset_state_machine (is_stmt);
4398       break;
4399
4400     case DW_LNE_set_address:
4401       adr = byte_get (data, pointer_size);
4402       printf (_("set Address to 0x%lx\n"), adr);
4403       state_machine_regs.address = adr;
4404       break;
4405
4406     case DW_LNE_define_file:
4407       printf (_("  define new File Table entry\n"));
4408       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
4409
4410       printf (_("   %d\t"), ++ state_machine_regs.last_file_entry);
4411       name = data;
4412       data += strlen (data) + 1;
4413       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4414       data += bytes_read;
4415       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4416       data += bytes_read;
4417       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4418       printf (_("%s\n\n"), name);
4419       break;
4420
4421     default:
4422       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
4423       break;
4424     }
4425
4426   return len;
4427 }
4428
4429 /* Size of pointers in the .debug_line section.  This information is not
4430    really present in that section.  It's obtained before dumping the debug
4431    sections by doing some pre-scan of the .debug_info section.  */
4432 static int debug_line_pointer_size = 4;
4433
4434 static int
4435 display_debug_lines (section, start, file)
4436      Elf32_Internal_Shdr * section;
4437      unsigned char *       start;
4438      FILE *                file ATTRIBUTE_UNUSED;
4439 {
4440   DWARF2_External_LineInfo * external;
4441   DWARF2_Internal_LineInfo   info;
4442   unsigned char *            standard_opcodes;
4443   unsigned char *            data = start;
4444   unsigned char *            end  = start + section->sh_size;
4445   unsigned char *            end_of_sequence;
4446   int                        i;
4447
4448   printf (_("\nDump of debug contents of section %s:\n\n"),
4449           SECTION_NAME (section));
4450
4451   while (data < end)
4452     {
4453       external = (DWARF2_External_LineInfo *) data;
4454
4455       /* Check the length of the block.  */
4456       info.li_length = BYTE_GET (external->li_length);
4457       if (info.li_length > section->sh_size)
4458         {
4459           warn
4460             (_("The line info appears to be corrupt - the section is too small\n"));
4461           return 0;
4462         }
4463
4464       /* Check its version number.  */
4465       info.li_version = BYTE_GET (external->li_version);
4466       if (info.li_version != 2)
4467         {
4468           warn (_("Only DWARF version 2 line info is currently supported.\n"));
4469           return 0;
4470         }
4471
4472       info.li_prologue_length = BYTE_GET (external->li_prologue_length);
4473       info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
4474       info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
4475       info.li_line_base       = BYTE_GET (external->li_line_base);
4476       info.li_line_range      = BYTE_GET (external->li_line_range);
4477       info.li_opcode_base     = BYTE_GET (external->li_opcode_base);
4478
4479       /* Sign extend the line base field.  */
4480       info.li_line_base <<= 24;
4481       info.li_line_base >>= 24;
4482
4483       printf (_("  Length:                      %ld\n"), info.li_length);
4484       printf (_("  DWARF Version:               %d\n"), info.li_version);
4485       printf (_("  Prolgue Length:              %d\n"), info.li_prologue_length);
4486       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
4487       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
4488       printf (_("  Line Base:                   %d\n"), info.li_line_base);
4489       printf (_("  Line Range:                  %d\n"), info.li_line_range);
4490       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
4491
4492       end_of_sequence = data + info.li_length + sizeof (info.li_length);
4493
4494       reset_state_machine (info.li_default_is_stmt);
4495
4496       /* Display the contents of the Opcodes table.  */
4497       standard_opcodes = data + sizeof (* external);
4498
4499       printf (_("\n Opcodes:\n"));
4500
4501       for (i = 1; i < info.li_opcode_base; i++)
4502         printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
4503
4504       /* Display the contents of the Directory table.  */
4505       data = standard_opcodes + info.li_opcode_base - 1;
4506
4507       if (* data == 0)
4508         printf (_("\n The Directory Table is empty.\n"));
4509       else
4510         {
4511           printf (_("\n The Directory Table:\n"));
4512
4513           while (* data != 0)
4514             {
4515               printf (_("  %s\n"), data);
4516
4517               data += strlen (data) + 1;
4518             }
4519         }
4520
4521       /* Skip the NUL at the end of the table.  */
4522       data ++;
4523
4524       /* Display the contents of the File Name table.  */
4525       if (* data == 0)
4526         printf (_("\n The File Name Table is empty.\n"));
4527       else
4528         {
4529           printf (_("\n The File Name Table:\n"));
4530           printf (_("  Entry\tDir\tTime\tSize\tName\n"));
4531
4532           while (* data != 0)
4533             {
4534               char * name;
4535               int bytes_read;
4536
4537               printf (_("  %d\t"), ++ state_machine_regs.last_file_entry);
4538               name = data;
4539
4540               data += strlen (data) + 1;
4541
4542               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4543               data += bytes_read;
4544               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4545               data += bytes_read;
4546               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4547               data += bytes_read;
4548               printf (_("%s\n"), name);
4549             }
4550         }
4551
4552       /* Skip the NUL at the end of the table.  */
4553       data ++;
4554
4555       /* Now display the statements.  */
4556       printf (_("\n Line Number Statements:\n"));
4557
4558
4559       while (data < end_of_sequence)
4560         {
4561           unsigned char op_code;
4562           int           adv;
4563           int           bytes_read;
4564
4565           op_code = * data ++;
4566
4567           switch (op_code)
4568             {
4569             case DW_LNS_extended_op:
4570               data += process_extended_line_op (data, info.li_default_is_stmt,
4571                                                 debug_line_pointer_size);
4572               break;
4573
4574             case DW_LNS_copy:
4575               printf (_("  Copy\n"));
4576               break;
4577
4578             case DW_LNS_advance_pc:
4579               adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
4580               data += bytes_read;
4581               state_machine_regs.address += adv;
4582               printf (_("  Advance PC by %d to %lx\n"), adv,
4583                       state_machine_regs.address);
4584               break;
4585
4586             case DW_LNS_advance_line:
4587               adv = read_leb128 (data, & bytes_read, 1);
4588               data += bytes_read;
4589               state_machine_regs.line += adv;
4590               printf (_("  Advance Line by %d to %d\n"), adv,
4591                       state_machine_regs.line);
4592               break;
4593
4594             case DW_LNS_set_file:
4595               adv = read_leb128 (data, & bytes_read, 0);
4596               data += bytes_read;
4597               printf (_("  Set File Name to entry %d in the File Name Table\n"),
4598                       adv);
4599               state_machine_regs.file = adv;
4600               break;
4601
4602             case DW_LNS_set_column:
4603               adv = read_leb128 (data, & bytes_read, 0);
4604               data += bytes_read;
4605               printf (_("  Set column to %d\n"), adv);
4606               state_machine_regs.column = adv;
4607               break;
4608
4609             case DW_LNS_negate_stmt:
4610               adv = state_machine_regs.is_stmt;
4611               adv = ! adv;
4612               printf (_("  Set is_stmt to %d\n"), adv);
4613               state_machine_regs.is_stmt = adv;
4614               break;
4615
4616             case DW_LNS_set_basic_block:
4617               printf (_("  Set basic block\n"));
4618               state_machine_regs.basic_block = 1;
4619               break;
4620
4621             case DW_LNS_const_add_pc:
4622               adv = (((255 - info.li_opcode_base) / info.li_line_range)
4623                      * info.li_min_insn_length);
4624               state_machine_regs.address += adv;
4625               printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
4626                       state_machine_regs.address);
4627               break;
4628
4629             case DW_LNS_fixed_advance_pc:
4630               adv = byte_get (data, 2);
4631               data += 2;
4632               state_machine_regs.address += adv;
4633               printf (_("  Advance PC by fixed size amount %d to 0x%lx\n"),
4634                       adv, state_machine_regs.address);
4635               break;
4636
4637             default:
4638               op_code -= info.li_opcode_base;
4639               adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
4640               state_machine_regs.address += adv;
4641               printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
4642                       op_code, adv, state_machine_regs.address);
4643               adv = (op_code % info.li_line_range) + info.li_line_base;
4644               state_machine_regs.line += adv;
4645               printf (_(" and Line by %d to %d\n"),
4646                       adv, state_machine_regs.line);
4647               break;
4648             }
4649         }
4650       printf ("\n");
4651     }
4652
4653   return 1;
4654 }
4655
4656 static int
4657 display_debug_pubnames (section, start, file)
4658      Elf32_Internal_Shdr * section;
4659      unsigned char *       start;
4660      FILE *                file ATTRIBUTE_UNUSED;
4661 {
4662   DWARF2_External_PubNames * external;
4663   DWARF2_Internal_PubNames   pubnames;
4664   unsigned char *            end;
4665
4666   end = start + section->sh_size;
4667
4668   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4669
4670   while (start < end)
4671     {
4672       unsigned char * data;
4673       unsigned long   offset;
4674
4675       external = (DWARF2_External_PubNames *) start;
4676
4677       pubnames.pn_length  = BYTE_GET (external->pn_length);
4678       pubnames.pn_version = BYTE_GET (external->pn_version);
4679       pubnames.pn_offset  = BYTE_GET (external->pn_offset);
4680       pubnames.pn_size    = BYTE_GET (external->pn_size);
4681
4682       data   = start + sizeof (* external);
4683       start += pubnames.pn_length + sizeof (external->pn_length);
4684
4685       if (pubnames.pn_version != 2)
4686         {
4687           warn (_("Only DWARF 2 pubnames are currently supported"));
4688           continue;
4689         }
4690
4691       printf (_("  Length:                              %ld\n"),
4692               pubnames.pn_length);
4693       printf (_("  Version:                             %d\n"),
4694               pubnames.pn_version);
4695       printf (_("  Offset into .debug_info section:     %ld\n"),
4696               pubnames.pn_offset);
4697       printf (_("  Size of area in .debug_info section: %ld\n"),
4698               pubnames.pn_size);
4699
4700       printf (_("\n    Offset\tName\n"));
4701
4702       do
4703         {
4704           offset = byte_get (data, 4);
4705
4706           if (offset != 0)
4707             {
4708               data += 4;
4709               printf ("    %ld\t\t%s\n", offset, data);
4710               data += strlen (data) + 1;
4711             }
4712         }
4713       while (offset != 0);
4714     }
4715
4716   printf ("\n");
4717   return 1;
4718 }
4719
4720 static char *
4721 get_TAG_name (tag)
4722      unsigned long tag;
4723 {
4724   switch (tag)
4725     {
4726     case DW_TAG_padding: return "DW_TAG_padding";
4727     case DW_TAG_array_type: return "DW_TAG_array_type";
4728     case DW_TAG_class_type: return "DW_TAG_class_type";
4729     case DW_TAG_entry_point: return "DW_TAG_entry_point";
4730     case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4731     case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4732     case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4733     case DW_TAG_label: return "DW_TAG_label";
4734     case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4735     case DW_TAG_member: return "DW_TAG_member";
4736     case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4737     case DW_TAG_reference_type: return "DW_TAG_reference_type";
4738     case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4739     case DW_TAG_string_type: return "DW_TAG_string_type";
4740     case DW_TAG_structure_type: return "DW_TAG_structure_type";
4741     case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4742     case DW_TAG_typedef: return "DW_TAG_typedef";
4743     case DW_TAG_union_type: return "DW_TAG_union_type";
4744     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4745     case DW_TAG_variant: return "DW_TAG_variant";
4746     case DW_TAG_common_block: return "DW_TAG_common_block";
4747     case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4748     case DW_TAG_inheritance: return "DW_TAG_inheritance";
4749     case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4750     case DW_TAG_module: return "DW_TAG_module";
4751     case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4752     case DW_TAG_set_type: return "DW_TAG_set_type";
4753     case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4754     case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4755     case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4756     case DW_TAG_base_type: return "DW_TAG_base_type";
4757     case DW_TAG_catch_block: return "DW_TAG_catch_block";
4758     case DW_TAG_const_type: return "DW_TAG_const_type";
4759     case DW_TAG_constant: return "DW_TAG_constant";
4760     case DW_TAG_enumerator: return "DW_TAG_enumerator";
4761     case DW_TAG_file_type: return "DW_TAG_file_type";
4762     case DW_TAG_friend: return "DW_TAG_friend";
4763     case DW_TAG_namelist: return "DW_TAG_namelist";
4764     case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4765     case DW_TAG_packed_type: return "DW_TAG_packed_type";
4766     case DW_TAG_subprogram: return "DW_TAG_subprogram";
4767     case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4768     case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4769     case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4770     case DW_TAG_try_block: return "DW_TAG_try_block";
4771     case DW_TAG_variant_part: return "DW_TAG_variant_part";
4772     case DW_TAG_variable: return "DW_TAG_variable";
4773     case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4774     case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4775     case DW_TAG_format_label: return "DW_TAG_format_label";
4776     case DW_TAG_function_template: return "DW_TAG_function_template";
4777     case DW_TAG_class_template: return "DW_TAG_class_template";
4778     default:
4779       {
4780         static char buffer [100];
4781
4782         sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4783         return buffer;
4784       }
4785     }
4786 }
4787
4788 static char *
4789 get_AT_name (attribute)
4790      unsigned long attribute;
4791 {
4792   switch (attribute)
4793     {
4794     case DW_AT_sibling: return "DW_AT_sibling";
4795     case DW_AT_location: return "DW_AT_location";
4796     case DW_AT_name: return "DW_AT_name";
4797     case DW_AT_ordering: return "DW_AT_ordering";
4798     case DW_AT_subscr_data: return "DW_AT_subscr_data";
4799     case DW_AT_byte_size: return "DW_AT_byte_size";
4800     case DW_AT_bit_offset: return "DW_AT_bit_offset";
4801     case DW_AT_bit_size: return "DW_AT_bit_size";
4802     case DW_AT_element_list: return "DW_AT_element_list";
4803     case DW_AT_stmt_list: return "DW_AT_stmt_list";
4804     case DW_AT_low_pc: return "DW_AT_low_pc";
4805     case DW_AT_high_pc: return "DW_AT_high_pc";
4806     case DW_AT_language: return "DW_AT_language";
4807     case DW_AT_member: return "DW_AT_member";
4808     case DW_AT_discr: return "DW_AT_discr";
4809     case DW_AT_discr_value: return "DW_AT_discr_value";
4810     case DW_AT_visibility: return "DW_AT_visibility";
4811     case DW_AT_import: return "DW_AT_import";
4812     case DW_AT_string_length: return "DW_AT_string_length";
4813     case DW_AT_common_reference: return "DW_AT_common_reference";
4814     case DW_AT_comp_dir: return "DW_AT_comp_dir";
4815     case DW_AT_const_value: return "DW_AT_const_value";
4816     case DW_AT_containing_type: return "DW_AT_containing_type";
4817     case DW_AT_default_value: return "DW_AT_default_value";
4818     case DW_AT_inline: return "DW_AT_inline";
4819     case DW_AT_is_optional: return "DW_AT_is_optional";
4820     case DW_AT_lower_bound: return "DW_AT_lower_bound";
4821     case DW_AT_producer: return "DW_AT_producer";
4822     case DW_AT_prototyped: return "DW_AT_prototyped";
4823     case DW_AT_return_addr: return "DW_AT_return_addr";
4824     case DW_AT_start_scope: return "DW_AT_start_scope";
4825     case DW_AT_stride_size: return "DW_AT_stride_size";
4826     case DW_AT_upper_bound: return "DW_AT_upper_bound";
4827     case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4828     case DW_AT_accessibility: return "DW_AT_accessibility";
4829     case DW_AT_address_class: return "DW_AT_address_class";
4830     case DW_AT_artificial: return "DW_AT_artificial";
4831     case DW_AT_base_types: return "DW_AT_base_types";
4832     case DW_AT_calling_convention: return "DW_AT_calling_convention";
4833     case DW_AT_count: return "DW_AT_count";
4834     case DW_AT_data_member_location: return "DW_AT_data_member_location";
4835     case DW_AT_decl_column: return "DW_AT_decl_column";
4836     case DW_AT_decl_file: return "DW_AT_decl_file";
4837     case DW_AT_decl_line: return "DW_AT_decl_line";
4838     case DW_AT_declaration: return "DW_AT_declaration";
4839     case DW_AT_discr_list: return "DW_AT_discr_list";
4840     case DW_AT_encoding: return "DW_AT_encoding";
4841     case DW_AT_external: return "DW_AT_external";
4842     case DW_AT_frame_base: return "DW_AT_frame_base";
4843     case DW_AT_friend: return "DW_AT_friend";
4844     case DW_AT_identifier_case: return "DW_AT_identifier_case";
4845     case DW_AT_macro_info: return "DW_AT_macro_info";
4846     case DW_AT_namelist_items: return "DW_AT_namelist_items";
4847     case DW_AT_priority: return "DW_AT_priority";
4848     case DW_AT_segment: return "DW_AT_segment";
4849     case DW_AT_specification: return "DW_AT_specification";
4850     case DW_AT_static_link: return "DW_AT_static_link";
4851     case DW_AT_type: return "DW_AT_type";
4852     case DW_AT_use_location: return "DW_AT_use_location";
4853     case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4854     case DW_AT_virtuality: return "DW_AT_virtuality";
4855     case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4856     case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4857     case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4858     case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4859     case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4860     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4861     case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4862     case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4863     case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4864     case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4865     case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4866     case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4867     case DW_AT_sf_names: return "DW_AT_sf_names";
4868     case DW_AT_src_info: return "DW_AT_src_info";
4869     case DW_AT_mac_info: return "DW_AT_mac_info";
4870     case DW_AT_src_coords: return "DW_AT_src_coords";
4871     case DW_AT_body_begin: return "DW_AT_body_begin";
4872     case DW_AT_body_end: return "DW_AT_body_end";
4873     default:
4874       {
4875         static char buffer [100];
4876
4877         sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4878         return buffer;
4879       }
4880     }
4881 }
4882
4883 static char *
4884 get_FORM_name (form)
4885      unsigned long form;
4886 {
4887   switch (form)
4888     {
4889     case DW_FORM_addr: return "DW_FORM_addr";
4890     case DW_FORM_block2: return "DW_FORM_block2";
4891     case DW_FORM_block4: return "DW_FORM_block4";
4892     case DW_FORM_data2: return "DW_FORM_data2";
4893     case DW_FORM_data4: return "DW_FORM_data4";
4894     case DW_FORM_data8: return "DW_FORM_data8";
4895     case DW_FORM_string: return "DW_FORM_string";
4896     case DW_FORM_block: return "DW_FORM_block";
4897     case DW_FORM_block1: return "DW_FORM_block1";
4898     case DW_FORM_data1: return "DW_FORM_data1";
4899     case DW_FORM_flag: return "DW_FORM_flag";
4900     case DW_FORM_sdata: return "DW_FORM_sdata";
4901     case DW_FORM_strp: return "DW_FORM_strp";
4902     case DW_FORM_udata: return "DW_FORM_udata";
4903     case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4904     case DW_FORM_ref1: return "DW_FORM_ref1";
4905     case DW_FORM_ref2: return "DW_FORM_ref2";
4906     case DW_FORM_ref4: return "DW_FORM_ref4";
4907     case DW_FORM_ref8: return "DW_FORM_ref8";
4908     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4909     case DW_FORM_indirect: return "DW_FORM_indirect";
4910     default:
4911       {
4912         static char buffer [100];
4913
4914         sprintf (buffer, _("Unknown FORM value: %lx"), form);
4915         return buffer;
4916       }
4917     }
4918 }
4919
4920 /* FIXME:  There are better and more effiecint ways to handle
4921    these structures.  For now though, I just want something that
4922    is simple to implement.  */
4923 typedef struct abbrev_attr
4924 {
4925   unsigned long        attribute;
4926   unsigned long        form;
4927   struct abbrev_attr * next;
4928 }
4929 abbrev_attr;
4930
4931 typedef struct abbrev_entry
4932 {
4933   unsigned long          entry;
4934   unsigned long          tag;
4935   int                    children;
4936   struct abbrev_attr *   first_attr;
4937   struct abbrev_attr *   last_attr;
4938   struct abbrev_entry *  next;
4939 }
4940 abbrev_entry;
4941
4942 static abbrev_entry * first_abbrev = NULL;
4943 static abbrev_entry * last_abbrev = NULL;
4944
4945 static void
4946 free_abbrevs PARAMS ((void))
4947 {
4948   abbrev_entry * abbrev;
4949
4950   for (abbrev = first_abbrev; abbrev;)
4951     {
4952       abbrev_entry * next = abbrev->next;
4953       abbrev_attr  * attr;
4954
4955       for (attr = abbrev->first_attr; attr;)
4956         {
4957           abbrev_attr * next = attr->next;
4958
4959           free (attr);
4960           attr = next;
4961         }
4962
4963       free (abbrev);
4964       abbrev = next;
4965     }
4966
4967   last_abbrev = first_abbrev = NULL;
4968 }
4969
4970 static void
4971 add_abbrev (number, tag, children)
4972      unsigned long number;
4973      unsigned long tag;
4974      int           children;
4975 {
4976   abbrev_entry * entry;
4977
4978   entry = (abbrev_entry *) malloc (sizeof (* entry));
4979
4980   if (entry == NULL)
4981     /* ugg */
4982     return;
4983
4984   entry->entry      = number;
4985   entry->tag        = tag;
4986   entry->children   = children;
4987   entry->first_attr = NULL;
4988   entry->last_attr  = NULL;
4989   entry->next       = NULL;
4990
4991   if (first_abbrev == NULL)
4992     first_abbrev = entry;
4993   else
4994     last_abbrev->next = entry;
4995
4996   last_abbrev = entry;
4997 }
4998
4999 static void
5000 add_abbrev_attr (attribute, form)
5001      unsigned long attribute;
5002      unsigned long form;
5003 {
5004   abbrev_attr * attr;
5005
5006   attr = (abbrev_attr *) malloc (sizeof (* attr));
5007
5008   if (attr == NULL)
5009     /* ugg */
5010     return;
5011
5012   attr->attribute = attribute;
5013   attr->form      = form;
5014   attr->next      = NULL;
5015
5016   if (last_abbrev->first_attr == NULL)
5017     last_abbrev->first_attr = attr;
5018   else
5019     last_abbrev->last_attr->next = attr;
5020
5021   last_abbrev->last_attr = attr;
5022 }
5023
5024 /* Processes the (partial) contents of a .debug_abbrev section.
5025    Returns NULL if the end of the section was encountered.
5026    Returns the address after the last byte read if the end of
5027    an abbreviation set was found.  */
5028
5029 static unsigned char *
5030 process_abbrev_section (start, end)
5031      unsigned char * start;
5032      unsigned char * end;
5033 {
5034   if (first_abbrev != NULL)
5035     return NULL;
5036
5037   while (start < end)
5038     {
5039       int           bytes_read;
5040       unsigned long entry;
5041       unsigned long tag;
5042       unsigned long attribute;
5043       int           children;
5044
5045       entry = read_leb128 (start, & bytes_read, 0);
5046       start += bytes_read;
5047
5048       /* A single zero is supposed to end the section according
5049          to the standard.  If there's more, then signal that to
5050          the caller.  */
5051       if (entry == 0)
5052         return start == end ? NULL : start;
5053
5054       tag = read_leb128 (start, & bytes_read, 0);
5055       start += bytes_read;
5056
5057       children = * start ++;
5058
5059       add_abbrev (entry, tag, children);
5060
5061       do
5062         {
5063           unsigned long form;
5064
5065           attribute = read_leb128 (start, & bytes_read, 0);
5066           start += bytes_read;
5067
5068           form = read_leb128 (start, & bytes_read, 0);
5069           start += bytes_read;
5070
5071           if (attribute != 0)
5072             add_abbrev_attr (attribute, form);
5073         }
5074       while (attribute != 0);
5075     }
5076
5077   return NULL;
5078 }
5079
5080
5081 static int
5082 display_debug_abbrev (section, start, file)
5083      Elf32_Internal_Shdr * section;
5084      unsigned char *       start;
5085      FILE *                file ATTRIBUTE_UNUSED;
5086 {
5087   abbrev_entry * entry;
5088   unsigned char * end = start + section->sh_size;
5089
5090   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5091
5092   do
5093     {
5094       start = process_abbrev_section (start, end);
5095
5096       printf (_("  Number TAG\n"));
5097
5098       for (entry = first_abbrev; entry; entry = entry->next)
5099         {
5100           abbrev_attr * attr;
5101
5102           printf (_("   %ld      %s    [%s]\n"),
5103                   entry->entry,
5104                   get_TAG_name (entry->tag),
5105                   entry->children ? _("has children") : _("no children"));
5106
5107           for (attr = entry->first_attr; attr; attr = attr->next)
5108             {
5109               printf (_("    %-18s %s\n"),
5110                       get_AT_name (attr->attribute),
5111                       get_FORM_name (attr->form));
5112             }
5113         }
5114     }
5115   while (start);
5116
5117   printf ("\n");
5118
5119   return 1;
5120 }
5121
5122
5123 static unsigned char *
5124 display_block (data, length)
5125      unsigned char * data;
5126      unsigned long   length;
5127 {
5128   printf (_(" %lu byte block: "), length);
5129
5130   while (length --)
5131     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
5132
5133   return data;
5134 }
5135
5136 static void
5137 decode_location_expression (data, pointer_size)
5138      unsigned char * data;
5139      unsigned int    pointer_size;
5140 {
5141   unsigned char op;
5142   int           bytes_read;
5143   unsigned long uvalue;
5144
5145   op = * data ++;
5146
5147   switch (op)
5148     {
5149     case DW_OP_addr:
5150       printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
5151       break;
5152     case DW_OP_deref:
5153       printf ("DW_OP_deref");
5154       break;
5155     case DW_OP_const1u:
5156       printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
5157       break;
5158     case DW_OP_const1s:
5159       printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
5160       break;
5161     case DW_OP_const2u:
5162       printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
5163       break;
5164     case DW_OP_const2s:
5165       printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
5166       break;
5167     case DW_OP_const4u:
5168       printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
5169       break;
5170     case DW_OP_const4s:
5171       printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
5172       break;
5173     case DW_OP_const8u:
5174       printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
5175               (unsigned long) byte_get (data + 4, 4));
5176       break;
5177     case DW_OP_const8s:
5178       printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
5179               (long) byte_get (data + 4, 4));
5180       break;
5181     case DW_OP_constu:
5182       printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
5183       break;
5184     case DW_OP_consts:
5185       printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
5186       break;
5187     case DW_OP_dup:
5188       printf ("DW_OP_dup");
5189       break;
5190     case DW_OP_drop:
5191       printf ("DW_OP_drop");
5192       break;
5193     case DW_OP_over:
5194       printf ("DW_OP_over");
5195       break;
5196     case DW_OP_pick:
5197       printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
5198       break;
5199     case DW_OP_swap:
5200       printf ("DW_OP_swap");
5201       break;
5202     case DW_OP_rot:
5203       printf ("DW_OP_rot");
5204       break;
5205     case DW_OP_xderef:
5206       printf ("DW_OP_xderef");
5207       break;
5208     case DW_OP_abs:
5209       printf ("DW_OP_abs");
5210       break;
5211     case DW_OP_and:
5212       printf ("DW_OP_and");
5213       break;
5214     case DW_OP_div:
5215       printf ("DW_OP_div");
5216       break;
5217     case DW_OP_minus:
5218       printf ("DW_OP_minus");
5219       break;
5220     case DW_OP_mod:
5221       printf ("DW_OP_mod");
5222       break;
5223     case DW_OP_mul:
5224       printf ("DW_OP_mul");
5225       break;
5226     case DW_OP_neg:
5227       printf ("DW_OP_neg");
5228       break;
5229     case DW_OP_not:
5230       printf ("DW_OP_not");
5231       break;
5232     case DW_OP_or:
5233       printf ("DW_OP_or");
5234       break;
5235     case DW_OP_plus:
5236       printf ("DW_OP_plus");
5237       break;
5238     case DW_OP_plus_uconst:
5239       printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
5240       break;
5241     case DW_OP_shl:
5242       printf ("DW_OP_shl");
5243       break;
5244     case DW_OP_shr:
5245       printf ("DW_OP_shr");
5246       break;
5247     case DW_OP_shra:
5248       printf ("DW_OP_shra");
5249       break;
5250     case DW_OP_xor:
5251       printf ("DW_OP_xor");
5252       break;
5253     case DW_OP_bra:
5254       printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
5255       break;
5256     case DW_OP_eq:
5257       printf ("DW_OP_eq");
5258       break;
5259     case DW_OP_ge:
5260       printf ("DW_OP_ge");
5261       break;
5262     case DW_OP_gt:
5263       printf ("DW_OP_gt");
5264       break;
5265     case DW_OP_le:
5266       printf ("DW_OP_le");
5267       break;
5268     case DW_OP_lt:
5269       printf ("DW_OP_lt");
5270       break;
5271     case DW_OP_ne:
5272       printf ("DW_OP_ne");
5273       break;
5274     case DW_OP_skip:
5275       printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
5276       break;
5277     case DW_OP_lit0:
5278       printf ("DW_OP_lit0");
5279       break;
5280     case DW_OP_lit1:
5281       printf ("DW_OP_lit1");
5282       break;
5283     case DW_OP_lit2:
5284       printf ("DW_OP_lit2");
5285       break;
5286     case DW_OP_lit3:
5287       printf ("DW_OP_lit3");
5288       break;
5289     case DW_OP_lit4:
5290       printf ("DW_OP_lit4");
5291       break;
5292     case DW_OP_lit5:
5293       printf ("DW_OP_lit5");
5294       break;
5295     case DW_OP_lit6:
5296       printf ("DW_OP_lit6");
5297       break;
5298     case DW_OP_lit7:
5299       printf ("DW_OP_lit7");
5300       break;
5301     case DW_OP_lit8:
5302       printf ("DW_OP_lit8");
5303       break;
5304     case DW_OP_lit9:
5305       printf ("DW_OP_lit9");
5306       break;
5307     case DW_OP_lit10:
5308       printf ("DW_OP_lit10");
5309       break;
5310     case DW_OP_lit11:
5311       printf ("DW_OP_lit11");
5312       break;
5313     case DW_OP_lit12:
5314       printf ("DW_OP_lit12");
5315       break;
5316     case DW_OP_lit13:
5317       printf ("DW_OP_lit13");
5318       break;
5319     case DW_OP_lit14:
5320       printf ("DW_OP_lit14");
5321       break;
5322     case DW_OP_lit15:
5323       printf ("DW_OP_lit15");
5324       break;
5325     case DW_OP_lit16:
5326       printf ("DW_OP_lit16");
5327       break;
5328     case DW_OP_lit17:
5329       printf ("DW_OP_lit17");
5330       break;
5331     case DW_OP_lit18:
5332       printf ("DW_OP_lit18");
5333       break;
5334     case DW_OP_lit19:
5335       printf ("DW_OP_lit19");
5336       break;
5337     case DW_OP_lit20:
5338       printf ("DW_OP_lit20");
5339       break;
5340     case DW_OP_lit21:
5341       printf ("DW_OP_lit21");
5342       break;
5343     case DW_OP_lit22:
5344       printf ("DW_OP_lit22");
5345       break;
5346     case DW_OP_lit23:
5347       printf ("DW_OP_lit23");
5348       break;
5349     case DW_OP_lit24:
5350       printf ("DW_OP_lit24");
5351       break;
5352     case DW_OP_lit25:
5353       printf ("DW_OP_lit25");
5354       break;
5355     case DW_OP_lit26:
5356       printf ("DW_OP_lit26");
5357       break;
5358     case DW_OP_lit27:
5359       printf ("DW_OP_lit27");
5360       break;
5361     case DW_OP_lit28:
5362       printf ("DW_OP_lit28");
5363       break;
5364     case DW_OP_lit29:
5365       printf ("DW_OP_lit29");
5366       break;
5367     case DW_OP_lit30:
5368       printf ("DW_OP_lit30");
5369       break;
5370     case DW_OP_lit31:
5371       printf ("DW_OP_lit31");
5372       break;
5373     case DW_OP_reg0:
5374       printf ("DW_OP_reg0");
5375       break;
5376     case DW_OP_reg1:
5377       printf ("DW_OP_reg1");
5378       break;
5379     case DW_OP_reg2:
5380       printf ("DW_OP_reg2");
5381       break;
5382     case DW_OP_reg3:
5383       printf ("DW_OP_reg3");
5384       break;
5385     case DW_OP_reg4:
5386       printf ("DW_OP_reg4");
5387       break;
5388     case DW_OP_reg5:
5389       printf ("DW_OP_reg5");
5390       break;
5391     case DW_OP_reg6:
5392       printf ("DW_OP_reg6");
5393       break;
5394     case DW_OP_reg7:
5395       printf ("DW_OP_reg7");
5396       break;
5397     case DW_OP_reg8:
5398       printf ("DW_OP_reg8");
5399       break;
5400     case DW_OP_reg9:
5401       printf ("DW_OP_reg9");
5402       break;
5403     case DW_OP_reg10:
5404       printf ("DW_OP_reg10");
5405       break;
5406     case DW_OP_reg11:
5407       printf ("DW_OP_reg11");
5408       break;
5409     case DW_OP_reg12:
5410       printf ("DW_OP_reg12");
5411       break;
5412     case DW_OP_reg13:
5413       printf ("DW_OP_reg13");
5414       break;
5415     case DW_OP_reg14:
5416       printf ("DW_OP_reg14");
5417       break;
5418     case DW_OP_reg15:
5419       printf ("DW_OP_reg15");
5420       break;
5421     case DW_OP_reg16:
5422       printf ("DW_OP_reg16");
5423       break;
5424     case DW_OP_reg17:
5425       printf ("DW_OP_reg17");
5426       break;
5427     case DW_OP_reg18:
5428       printf ("DW_OP_reg18");
5429       break;
5430     case DW_OP_reg19:
5431       printf ("DW_OP_reg19");
5432       break;
5433     case DW_OP_reg20:
5434       printf ("DW_OP_reg20");
5435       break;
5436     case DW_OP_reg21:
5437       printf ("DW_OP_reg21");
5438       break;
5439     case DW_OP_reg22:
5440       printf ("DW_OP_reg22");
5441       break;
5442     case DW_OP_reg23:
5443       printf ("DW_OP_reg23");
5444       break;
5445     case DW_OP_reg24:
5446       printf ("DW_OP_reg24");
5447       break;
5448     case DW_OP_reg25:
5449       printf ("DW_OP_reg25");
5450       break;
5451     case DW_OP_reg26:
5452       printf ("DW_OP_reg26");
5453       break;
5454     case DW_OP_reg27:
5455       printf ("DW_OP_reg27");
5456       break;
5457     case DW_OP_reg28:
5458       printf ("DW_OP_reg28");
5459       break;
5460     case DW_OP_reg29:
5461       printf ("DW_OP_reg29");
5462       break;
5463     case DW_OP_reg30:
5464       printf ("DW_OP_reg30");
5465       break;
5466     case DW_OP_reg31:
5467       printf ("DW_OP_reg31");
5468       break;
5469     case DW_OP_breg0:
5470       printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
5471       break;
5472     case DW_OP_breg1:
5473       printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
5474       break;
5475     case DW_OP_breg2:
5476       printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
5477       break;
5478     case DW_OP_breg3:
5479       printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
5480       break;
5481     case DW_OP_breg4:
5482       printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
5483       break;
5484     case DW_OP_breg5:
5485       printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
5486       break;
5487     case DW_OP_breg6:
5488       printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
5489       break;
5490     case DW_OP_breg7:
5491       printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
5492       break;
5493     case DW_OP_breg8:
5494       printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
5495       break;
5496     case DW_OP_breg9:
5497       printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
5498       break;
5499     case DW_OP_breg10:
5500       printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
5501       break;
5502     case DW_OP_breg11:
5503       printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
5504       break;
5505     case DW_OP_breg12:
5506       printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
5507       break;
5508     case DW_OP_breg13:
5509       printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
5510       break;
5511     case DW_OP_breg14:
5512       printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
5513       break;
5514     case DW_OP_breg15:
5515       printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
5516       break;
5517     case DW_OP_breg16:
5518       printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
5519       break;
5520     case DW_OP_breg17:
5521       printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
5522       break;
5523     case DW_OP_breg18:
5524       printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
5525       break;
5526     case DW_OP_breg19:
5527       printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
5528       break;
5529     case DW_OP_breg20:
5530       printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
5531       break;
5532     case DW_OP_breg21:
5533       printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
5534       break;
5535     case DW_OP_breg22:
5536       printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
5537       break;
5538     case DW_OP_breg23:
5539       printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
5540       break;
5541     case DW_OP_breg24:
5542       printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
5543       break;
5544     case DW_OP_breg25:
5545       printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
5546       break;
5547     case DW_OP_breg26:
5548       printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
5549       break;
5550     case DW_OP_breg27:
5551       printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
5552       break;
5553     case DW_OP_breg28:
5554       printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
5555       break;
5556     case DW_OP_breg29:
5557       printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
5558       break;
5559     case DW_OP_breg30:
5560       printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
5561       break;
5562     case DW_OP_breg31:
5563       printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
5564       break;
5565     case DW_OP_regx:
5566       printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
5567       break;
5568     case DW_OP_fbreg:
5569       printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
5570       break;
5571     case DW_OP_bregx:
5572       uvalue = read_leb128 (data, &bytes_read, 0);
5573       printf ("DW_OP_bregx: %lu %ld", uvalue,
5574               read_leb128 (data + bytes_read, NULL, 1));
5575       break;
5576     case DW_OP_piece:
5577       printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
5578       break;
5579     case DW_OP_deref_size:
5580       printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
5581       break;
5582     case DW_OP_xderef_size:
5583       printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
5584       break;
5585     case DW_OP_nop:
5586       printf ("DW_OP_nop");
5587       break;
5588
5589     default:
5590       if (op >= DW_OP_lo_user
5591           && op <= DW_OP_hi_user)
5592         printf (_("(User defined location op)"));
5593       else
5594         printf (_("(Unknown location op)"));
5595       break;
5596     }
5597 }
5598
5599
5600 static unsigned char *
5601 read_and_display_attr (attribute, form, data, pointer_size)
5602      unsigned long   attribute;
5603      unsigned long   form;
5604      unsigned char * data;
5605      unsigned long   pointer_size;
5606 {
5607   unsigned long   uvalue = 0;
5608   unsigned char * block_start = NULL;
5609   int             bytes_read;
5610   int             is_ref = 0;
5611
5612   printf ("     %-18s:", get_AT_name (attribute));
5613
5614   switch (form)
5615     {
5616     case DW_FORM_ref_addr:
5617     case DW_FORM_ref1:
5618     case DW_FORM_ref2:
5619     case DW_FORM_ref4:
5620     case DW_FORM_ref8:
5621     case DW_FORM_ref_udata:
5622       is_ref = 1;
5623     }
5624
5625   switch (form)
5626     {
5627     case DW_FORM_ref_addr:
5628     case DW_FORM_addr:
5629       uvalue = byte_get (data, pointer_size);
5630       printf (is_ref ? " <%x>" : " %#x", uvalue);
5631       data += pointer_size;
5632       break;
5633
5634     case DW_FORM_ref1:
5635     case DW_FORM_flag:
5636     case DW_FORM_data1:
5637       uvalue = byte_get (data ++, 1);
5638       printf (is_ref ? " <%x>" : " %d", uvalue);
5639       break;
5640
5641     case DW_FORM_ref2:
5642     case DW_FORM_data2:
5643       uvalue = byte_get (data, 2);
5644       data += 2;
5645       printf (is_ref ? " <%x>" : " %d", uvalue);
5646       break;
5647
5648     case DW_FORM_ref4:
5649     case DW_FORM_data4:
5650       uvalue = byte_get (data, 4);
5651       data += 4;
5652       printf (is_ref ? " <%x>" : " %d", uvalue);
5653       break;
5654
5655     case DW_FORM_ref8:
5656     case DW_FORM_data8:
5657       uvalue = byte_get (data, 4);
5658       printf (" %lx", uvalue);
5659       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
5660       data += 8;
5661       break;
5662
5663     case DW_FORM_string:
5664       printf (" %s", data);
5665       data += strlen (data) + 1;
5666       break;
5667
5668     case DW_FORM_sdata:
5669       uvalue = read_leb128 (data, & bytes_read, 1);
5670       data += bytes_read;
5671       printf (" %ld", (long) uvalue);
5672       break;
5673
5674     case DW_FORM_ref_udata:
5675     case DW_FORM_udata:
5676       uvalue = read_leb128 (data, & bytes_read, 0);
5677       data += bytes_read;
5678       printf (is_ref ? " <%lx>" : " %ld", uvalue);
5679       break;
5680
5681     case DW_FORM_block:
5682       uvalue = read_leb128 (data, & bytes_read, 0);
5683       block_start = data + bytes_read;
5684       data = display_block (block_start, uvalue);
5685       uvalue = * block_start;
5686       break;
5687
5688     case DW_FORM_block1:
5689       uvalue = byte_get (data, 1);
5690       block_start = data + 1;
5691       data = display_block (block_start, uvalue);
5692       uvalue = * block_start;
5693       break;
5694
5695     case DW_FORM_block2:
5696       uvalue = byte_get (data, 2);
5697       block_start = data + 2;
5698       data = display_block (block_start, uvalue);
5699       uvalue = * block_start;
5700       break;
5701
5702     case DW_FORM_block4:
5703       uvalue = byte_get (data, 4);
5704       block_start = data + 4;
5705       data = display_block (block_start, uvalue);
5706       uvalue = * block_start;
5707       break;
5708
5709     case DW_FORM_strp:
5710     case DW_FORM_indirect:
5711       warn (_("Unable to handle FORM: %d"), form);
5712       break;
5713
5714     default:
5715       warn (_("Unrecognised form: %d"), form);
5716       break;
5717     }
5718
5719   /* For some attributes we can display futher information.  */
5720
5721   printf ("\t");
5722
5723   switch (attribute)
5724     {
5725     case DW_AT_inline:
5726       switch (uvalue)
5727         {
5728         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
5729         case DW_INL_inlined:              printf (_("(inlined)")); break;
5730         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
5731         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
5732         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
5733         }
5734       break;
5735
5736     case DW_AT_frame_base:
5737       if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
5738         printf ("(reg %ld)", uvalue - DW_OP_reg0);
5739       break;
5740
5741     case DW_AT_language:
5742       switch (uvalue)
5743         {
5744         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
5745         case DW_LANG_C89:            printf ("(ANSI C)"); break;
5746         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
5747         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
5748         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
5749         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
5750         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
5751         case DW_LANG_Ada83:          printf ("(Ada)"); break;
5752         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
5753         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
5754         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
5755         default:                     printf ("(Unknown: %lx)", uvalue); break;
5756         }
5757       break;
5758
5759     case DW_AT_encoding:
5760       switch (uvalue)
5761         {
5762         case DW_ATE_void:            printf ("(void)"); break;
5763         case DW_ATE_address:         printf ("(machine address)"); break;
5764         case DW_ATE_boolean:         printf ("(boolean)"); break;
5765         case DW_ATE_complex_float:   printf ("(complex float)"); break;
5766         case DW_ATE_float:           printf ("(float)"); break;
5767         case DW_ATE_signed:          printf ("(signed)"); break;
5768         case DW_ATE_signed_char:     printf ("(signed char)"); break;
5769         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
5770         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
5771         default:
5772           if (uvalue >= DW_ATE_lo_user
5773               && uvalue <= DW_ATE_hi_user)
5774             printf ("(user defined type)");
5775           else
5776             printf ("(unknown type)");
5777           break;
5778         }
5779       break;
5780
5781     case DW_AT_accessibility:
5782       switch (uvalue)
5783         {
5784         case DW_ACCESS_public:          printf ("(public)"); break;
5785         case DW_ACCESS_protected:       printf ("(protected)"); break;
5786         case DW_ACCESS_private:         printf ("(private)"); break;
5787         default:                        printf ("(unknown accessibility)"); break;
5788         }
5789       break;
5790
5791     case DW_AT_visibility:
5792       switch (uvalue)
5793         {
5794         case DW_VIS_local:      printf ("(local)"); break;
5795         case DW_VIS_exported:   printf ("(exported)"); break;
5796         case DW_VIS_qualified:  printf ("(qualified)"); break;
5797         default:                printf ("(unknown visibility)"); break;
5798         }
5799       break;
5800
5801     case DW_AT_virtuality:
5802       switch (uvalue)
5803         {
5804         case DW_VIRTUALITY_none:        printf ("(none)"); break;
5805         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
5806         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
5807         default:                        printf ("(unknown virtuality)"); break;
5808         }
5809       break;
5810
5811     case DW_AT_identifier_case:
5812       switch (uvalue)
5813         {
5814         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
5815         case DW_ID_up_case:             printf ("(up_case)"); break;
5816         case DW_ID_down_case:           printf ("(down_case)"); break;
5817         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
5818         default:                        printf ("(unknown case)"); break;
5819         }
5820       break;
5821
5822     case DW_AT_calling_convention:
5823       switch (uvalue)
5824         {
5825         case DW_CC_normal:      printf ("(normal)"); break;
5826         case DW_CC_program:     printf ("(program)"); break;
5827         case DW_CC_nocall:      printf ("(nocall)"); break;
5828         default:
5829           if (uvalue >= DW_CC_lo_user
5830               && uvalue <= DW_CC_hi_user)
5831             printf ("(user defined)");
5832           else
5833             printf ("(unknown convention)");
5834         }
5835       break;
5836
5837     case DW_AT_location:
5838     case DW_AT_data_member_location:
5839     case DW_AT_vtable_elem_location:
5840       printf ("(");
5841       decode_location_expression (block_start, pointer_size);
5842       printf (")");
5843       break;
5844
5845     default:
5846       break;
5847     }
5848
5849   printf ("\n");
5850   return data;
5851 }
5852
5853 static int
5854 display_debug_info (section, start, file)
5855      Elf32_Internal_Shdr * section;
5856      unsigned char *       start;
5857      FILE *                file;
5858 {
5859   unsigned char * end = start + section->sh_size;
5860   unsigned char * section_begin = start;
5861
5862   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5863
5864   while (start < end)
5865     {
5866       DWARF2_External_CompUnit * external;
5867       DWARF2_Internal_CompUnit   compunit;
5868       unsigned char *            tags;
5869       int                        i;
5870       int                        level;
5871
5872       external = (DWARF2_External_CompUnit *) start;
5873
5874       compunit.cu_length        = BYTE_GET (external->cu_length);
5875       compunit.cu_version       = BYTE_GET (external->cu_version);
5876       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
5877       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
5878
5879       tags = start + sizeof (* external);
5880       start += compunit.cu_length + sizeof (external->cu_length);
5881
5882       if (compunit.cu_version != 2)
5883         {
5884           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
5885           continue;
5886         }
5887
5888       printf (_("  Compilation Unit:\n"));
5889       printf (_("   Length:        %ld\n"), compunit.cu_length);
5890       printf (_("   Version:       %d\n"), compunit.cu_version);
5891       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
5892       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
5893
5894       if (first_abbrev != NULL)
5895         free_abbrevs ();
5896
5897       /* Read in the abbrevs used by this compilation unit.  */
5898
5899       {
5900         Elf32_Internal_Shdr * sec;
5901         unsigned char *       begin;
5902
5903         /* Locate the .debug_abbrev section and process it.  */
5904         for (i = 0, sec = section_headers;
5905              i < elf_header.e_shnum;
5906              i ++, sec ++)
5907           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
5908             break;
5909
5910         if (i == -1 || sec->sh_size == 0)
5911           {
5912             warn (_("Unable to locate .debug_abbrev section!\n"));
5913             return 0;
5914           }
5915
5916         GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
5917                         "debug_abbrev section data");
5918
5919         process_abbrev_section (begin + compunit.cu_abbrev_offset,
5920                                 begin + sec->sh_size);
5921
5922         free (begin);
5923       }
5924
5925       level = 0;
5926       while (tags < start)
5927         {
5928           int            bytes_read;
5929           unsigned long  abbrev_number;
5930           abbrev_entry * entry;
5931           abbrev_attr  * attr;
5932
5933           abbrev_number = read_leb128 (tags, & bytes_read, 0);
5934           tags += bytes_read;
5935
5936           /* A null DIE marks the end of a list of children.  */
5937           if (abbrev_number == 0)
5938             {
5939               --level;
5940               continue;
5941             }
5942
5943           /* Scan through the abbreviation list until we reach the
5944              correct entry.  */
5945           for (entry = first_abbrev;
5946                entry && entry->entry != abbrev_number;
5947                entry = entry->next)
5948             continue;
5949
5950           if (entry == NULL)
5951             {
5952               warn (_("Unable to locate entry %lu in the abbreviation table\n"),
5953                     abbrev_number);
5954               return 0;
5955             }
5956
5957           printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
5958                   level, tags - section_begin - bytes_read,
5959                   abbrev_number,
5960                   get_TAG_name (entry->tag));
5961
5962           for (attr = entry->first_attr; attr; attr = attr->next)
5963             tags = read_and_display_attr (attr->attribute,
5964                                           attr->form,
5965                                           tags,
5966                                           compunit.cu_pointer_size);
5967
5968           if (entry->children)
5969             ++level;
5970         }
5971     }
5972
5973   printf ("\n");
5974
5975   return 1;
5976 }
5977
5978 static int
5979 display_debug_aranges (section, start, file)
5980      Elf32_Internal_Shdr * section;
5981      unsigned char *       start;
5982      FILE *                file ATTRIBUTE_UNUSED;
5983 {
5984   unsigned char * end = start + section->sh_size;
5985
5986   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5987
5988   while (start < end)
5989     {
5990       DWARF2_External_ARange * external;
5991       DWARF2_Internal_ARange   arange;
5992       unsigned char *          ranges;
5993       unsigned long            length;
5994       unsigned long            address;
5995       int                      excess;
5996
5997       external = (DWARF2_External_ARange *) start;
5998
5999       arange.ar_length       = BYTE_GET (external->ar_length);
6000       arange.ar_version      = BYTE_GET (external->ar_version);
6001       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
6002       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
6003       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
6004
6005       printf (_("  Length:                   %ld\n"), arange.ar_length);
6006       printf (_("  Version:                  %d\n"), arange.ar_version);
6007       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
6008       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
6009       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
6010
6011       printf (_("\n    Address  Length\n"));
6012
6013       ranges = start + sizeof (* external);
6014
6015       /* Must pad to an alignment boundary that is twice the pointer size.  */
6016       excess = sizeof (*external) % (2 * arange.ar_pointer_size);
6017       if (excess)
6018         ranges += (2 * arange.ar_pointer_size) - excess;
6019
6020       for (;;)
6021         {
6022           address = byte_get (ranges, arange.ar_pointer_size);
6023
6024           ranges += arange.ar_pointer_size;
6025
6026           length  = byte_get (ranges, arange.ar_pointer_size);
6027
6028           ranges += arange.ar_pointer_size;
6029
6030           /* A pair of zeros marks the end of the list.  */
6031           if (address == 0 && length == 0)
6032             break;
6033
6034           printf ("    %8.8lx %lu\n", address, length);
6035         }
6036
6037       start += arange.ar_length + sizeof (external->ar_length);
6038     }
6039
6040   printf ("\n");
6041
6042   return 1;
6043 }
6044
6045
6046 static int
6047 display_debug_not_supported (section, start, file)
6048      Elf32_Internal_Shdr * section;
6049      unsigned char *       start ATTRIBUTE_UNUSED;
6050      FILE *                file ATTRIBUTE_UNUSED;
6051 {
6052   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
6053             SECTION_NAME (section));
6054
6055   return 1;
6056 }
6057
6058 /* Pre-scan the .debug_info section to record the size of address.
6059    When dumping the .debug_line, we use that size information, assuming
6060    that all compilation units have the same address size.  */
6061 static int
6062 prescan_debug_info (section, start, file)
6063      Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
6064      unsigned char *       start;
6065      FILE *                file ATTRIBUTE_UNUSED;
6066 {
6067   DWARF2_External_CompUnit * external;
6068
6069   external = (DWARF2_External_CompUnit *) start;
6070
6071   debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
6072   return 0;
6073 }
6074
6075   /* A structure containing the name of a debug section and a pointer
6076      to a function that can decode it.  The third field is a prescan
6077      function to be run over the section before displaying any of the
6078      sections.  */
6079 struct
6080 {
6081   char * name;
6082   int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
6083   int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
6084 }
6085 debug_displays[] =
6086 {
6087   { ".debug_info",        display_debug_info, prescan_debug_info },
6088   { ".debug_abbrev",      display_debug_abbrev, NULL },
6089   { ".debug_line",        display_debug_lines, NULL },
6090   { ".debug_aranges",     display_debug_aranges, NULL },
6091   { ".debug_pubnames",    display_debug_pubnames, NULL },
6092   { ".debug_macinfo",     display_debug_not_supported, NULL },
6093   { ".debug_frame",       display_debug_not_supported, NULL },
6094   { ".debug_str",         display_debug_not_supported, NULL },
6095   { ".debug_static_func", display_debug_not_supported, NULL },
6096   { ".debug_static_vars", display_debug_not_supported, NULL },
6097   { ".debug_types",       display_debug_not_supported, NULL },
6098   { ".debug_weaknames",   display_debug_not_supported, NULL }
6099 };
6100
6101 static int
6102 display_debug_section (section, file)
6103      Elf32_Internal_Shdr * section;
6104      FILE * file;
6105 {
6106   char *          name = SECTION_NAME (section);
6107   bfd_size_type   length;
6108   unsigned char * start;
6109   int             i;
6110
6111   length = section->sh_size;
6112   if (length == 0)
6113     {
6114       printf (_("\nSection '%s' has no debugging data.\n"), name);
6115       return 0;
6116     }
6117
6118   GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
6119                   "debug section data");
6120
6121   /* See if we know how to display the contents of this section.  */
6122   for (i = NUM_ELEM (debug_displays); i--;)
6123     if (strcmp (debug_displays[i].name, name) == 0)
6124       {
6125         debug_displays[i].display (section, start, file);
6126         break;
6127       }
6128
6129   if (i == -1)
6130     printf (_("Unrecognised debug section: %s\n"), name);
6131
6132   free (start);
6133
6134   /* If we loaded in the abbrev section at some point,
6135      we must release it here.  */
6136   if (first_abbrev != NULL)
6137     free_abbrevs ();
6138
6139   return 1;
6140 }
6141
6142 static int
6143 process_section_contents (file)
6144      FILE * file;
6145 {
6146   Elf32_Internal_Shdr * section;
6147   unsigned int          i;
6148
6149   if (! do_dump)
6150     return 1;
6151
6152   /* Pre-scan the debug sections to find some debug information not
6153      present in some of them.  For the .debug_line, we must find out the
6154      size of address (specified in .debug_info and .debug_aranges).  */
6155   for (i = 0, section = section_headers;
6156        i < elf_header.e_shnum && i < num_dump_sects;
6157        i ++, section ++)
6158     {
6159       char *    name = SECTION_NAME (section);
6160       int       j;
6161
6162       if (section->sh_size == 0)
6163         continue;
6164
6165       /* See if there is some pre-scan operation for this section.  */
6166       for (j = NUM_ELEM (debug_displays); j--;)
6167         if (strcmp (debug_displays[j].name, name) == 0)
6168           {
6169             if (debug_displays[j].prescan != NULL)
6170               {
6171                 bfd_size_type   length;
6172                 unsigned char * start;
6173
6174                 length = section->sh_size;
6175                 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
6176                                 "debug section data");
6177
6178                 debug_displays[j].prescan (section, start, file);
6179                 free (start);
6180               }
6181
6182             break;
6183           }
6184     }
6185
6186   for (i = 0, section = section_headers;
6187        i < elf_header.e_shnum && i < num_dump_sects;
6188        i ++, section ++)
6189     {
6190 #ifdef SUPPORT_DISASSEMBLY
6191       if (dump_sects[i] & DISASS_DUMP)
6192         disassemble_section (section, file);
6193 #endif
6194       if (dump_sects[i] & HEX_DUMP)
6195         dump_section (section, file);
6196
6197       if (dump_sects[i] & DEBUG_DUMP)
6198         display_debug_section (section, file);
6199     }
6200
6201   if (i < num_dump_sects)
6202     warn (_("Some sections were not dumped because they do not exist!\n"));
6203
6204   return 1;
6205 }
6206
6207 static void
6208 process_mips_fpe_exception (mask)
6209      int mask;
6210 {
6211   if (mask)
6212     {
6213       int first = 1;
6214       if (mask & OEX_FPU_INEX)
6215         fputs ("INEX", stdout), first = 0;
6216       if (mask & OEX_FPU_UFLO)
6217         printf ("%sUFLO", first ? "" : "|"), first = 0;
6218       if (mask & OEX_FPU_OFLO)
6219         printf ("%sOFLO", first ? "" : "|"), first = 0;
6220       if (mask & OEX_FPU_DIV0)
6221         printf ("%sDIV0", first ? "" : "|"), first = 0;
6222       if (mask & OEX_FPU_INVAL)
6223         printf ("%sINVAL", first ? "" : "|");
6224     }
6225   else
6226     fputs ("0", stdout);
6227 }
6228
6229 static int
6230 process_mips_specific (file)
6231      FILE * file;
6232 {
6233   Elf_Internal_Dyn * entry;
6234   size_t liblist_offset = 0;
6235   size_t liblistno = 0;
6236   size_t conflictsno = 0;
6237   size_t options_offset = 0;
6238   size_t conflicts_offset = 0;
6239
6240   /* We have a lot of special sections.  Thanks SGI!  */
6241   if (dynamic_segment == NULL)
6242     /* No information available.  */
6243     return 0;
6244
6245   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
6246     switch (entry->d_tag)
6247       {
6248       case DT_MIPS_LIBLIST:
6249         liblist_offset = entry->d_un.d_val - loadaddr;
6250         break;
6251       case DT_MIPS_LIBLISTNO:
6252         liblistno = entry->d_un.d_val;
6253         break;
6254       case DT_MIPS_OPTIONS:
6255         options_offset = entry->d_un.d_val - loadaddr;
6256         break;
6257       case DT_MIPS_CONFLICT:
6258         conflicts_offset = entry->d_un.d_val - loadaddr;
6259         break;
6260       case DT_MIPS_CONFLICTNO:
6261         conflictsno = entry->d_un.d_val;
6262         break;
6263       default:
6264         break;
6265       }
6266
6267   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
6268     {
6269       Elf32_External_Lib * elib;
6270       size_t cnt;
6271
6272       GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
6273                       elib, Elf32_External_Lib *, "liblist");
6274
6275       printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
6276       fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
6277              stdout);
6278
6279       for (cnt = 0; cnt < liblistno; ++cnt)
6280         {
6281           Elf32_Lib liblist;
6282           time_t time;
6283           char timebuf[20];
6284
6285           liblist.l_name = BYTE_GET (elib[cnt].l_name);
6286           time = BYTE_GET (elib[cnt].l_time_stamp);
6287           liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
6288           liblist.l_version = BYTE_GET (elib[cnt].l_version);
6289           liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
6290
6291           strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
6292
6293           printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
6294                   dynamic_strings + liblist.l_name, timebuf,
6295                   liblist.l_checksum, liblist.l_version);
6296
6297           if (liblist.l_flags == 0)
6298             puts (" NONE");
6299           else
6300             {
6301               static const struct
6302               {
6303                 const char *name;
6304                 int bit;
6305               } l_flags_vals[] =
6306                 {
6307                   { " EXACT_MATCH", LL_EXACT_MATCH },
6308                   { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
6309                   { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
6310                   { " EXPORTS", LL_EXPORTS },
6311                   { " DELAY_LOAD", LL_DELAY_LOAD },
6312                   { " DELTA", LL_DELTA }
6313                 };
6314               int flags = liblist.l_flags;
6315               size_t fcnt;
6316
6317               for (fcnt = 0;
6318                    fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
6319                    ++fcnt)
6320                 if ((flags & l_flags_vals[fcnt].bit) != 0)
6321                   {
6322                     fputs (l_flags_vals[fcnt].name, stdout);
6323                     flags ^= l_flags_vals[fcnt].bit;
6324                   }
6325               if (flags != 0)
6326                 printf (" %#x", (unsigned int) flags);
6327
6328               puts ("");
6329             }
6330         }
6331
6332       free (elib);
6333     }
6334
6335   if (options_offset != 0)
6336     {
6337       Elf_External_Options * eopt;
6338       Elf_Internal_Shdr * sect = section_headers;
6339       Elf_Internal_Options * iopt;
6340       Elf_Internal_Options * option;
6341       size_t offset;
6342       int cnt;
6343
6344       /* Find the section header so that we get the size.  */
6345       while (sect->sh_type != SHT_MIPS_OPTIONS)
6346         ++sect;
6347
6348       GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
6349                       Elf_External_Options *, "options");
6350
6351       iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
6352                                               * sizeof (*iopt));
6353       if (iopt == NULL)
6354         {
6355           error (_("Out of memory"));
6356           return 0;
6357         }
6358
6359       offset = cnt = 0;
6360       option = iopt;
6361       while (offset < sect->sh_size)
6362         {
6363           Elf_External_Options * eoption;
6364
6365           eoption = (Elf_External_Options *) ((char *) eopt + offset);
6366
6367           option->kind = BYTE_GET (eoption->kind);
6368           option->size = BYTE_GET (eoption->size);
6369           option->section = BYTE_GET (eoption->section);
6370           option->info = BYTE_GET (eoption->info);
6371
6372           offset += option->size;
6373           ++option;
6374           ++cnt;
6375         }
6376
6377       printf (_("\nSection '%s' contains %d entries:\n"),
6378               string_table + sect->sh_name, cnt);
6379
6380       option = iopt;
6381       while (cnt-- > 0)
6382         {
6383           size_t len;
6384
6385           switch (option->kind)
6386             {
6387             case ODK_NULL:
6388               /* This shouldn't happen.  */
6389               printf (" NULL       %d %lx", option->section, option->info);
6390               break;
6391             case ODK_REGINFO:
6392               printf (" REGINFO    ");
6393               if (elf_header.e_machine == EM_MIPS)
6394                 {
6395                   /* 32bit form.  */
6396                   Elf32_External_RegInfo *ereg;
6397                   Elf32_RegInfo reginfo;
6398
6399                   ereg = (Elf32_External_RegInfo *) (option + 1);
6400                   reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
6401                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6402                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6403                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6404                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6405                   reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
6406
6407                   printf ("GPR %08lx  GP 0x%lx\n",
6408                           reginfo.ri_gprmask,
6409                           (unsigned long) reginfo.ri_gp_value);
6410                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
6411                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6412                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6413                 }
6414               else
6415                 {
6416                   /* 64 bit form.  */
6417                   Elf64_External_RegInfo * ereg;
6418                   Elf64_Internal_RegInfo reginfo;
6419
6420                   ereg = (Elf64_External_RegInfo *) (option + 1);
6421                   reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
6422                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6423                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6424                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6425                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6426                   reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
6427
6428                   printf ("GPR %08lx  GP 0x",
6429                           reginfo.ri_gprmask);
6430                   printf_vma (reginfo.ri_gp_value);
6431                   printf ("\n");
6432
6433                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
6434                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6435                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6436                 }
6437               ++option;
6438               continue;
6439             case ODK_EXCEPTIONS:
6440               fputs (" EXCEPTIONS fpe_min(", stdout);
6441               process_mips_fpe_exception (option->info & OEX_FPU_MIN);
6442               fputs (") fpe_max(", stdout);
6443               process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
6444               fputs (")", stdout);
6445
6446               if (option->info & OEX_PAGE0)
6447                 fputs (" PAGE0", stdout);
6448               if (option->info & OEX_SMM)
6449                 fputs (" SMM", stdout);
6450               if (option->info & OEX_FPDBUG)
6451                 fputs (" FPDBUG", stdout);
6452               if (option->info & OEX_DISMISS)
6453                 fputs (" DISMISS", stdout);
6454               break;
6455             case ODK_PAD:
6456               fputs (" PAD       ", stdout);
6457               if (option->info & OPAD_PREFIX)
6458                 fputs (" PREFIX", stdout);
6459               if (option->info & OPAD_POSTFIX)
6460                 fputs (" POSTFIX", stdout);
6461               if (option->info & OPAD_SYMBOL)
6462                 fputs (" SYMBOL", stdout);
6463               break;
6464             case ODK_HWPATCH:
6465               fputs (" HWPATCH   ", stdout);
6466               if (option->info & OHW_R4KEOP)
6467                 fputs (" R4KEOP", stdout);
6468               if (option->info & OHW_R8KPFETCH)
6469                 fputs (" R8KPFETCH", stdout);
6470               if (option->info & OHW_R5KEOP)
6471                 fputs (" R5KEOP", stdout);
6472               if (option->info & OHW_R5KCVTL)
6473                 fputs (" R5KCVTL", stdout);
6474               break;
6475             case ODK_FILL:
6476               fputs (" FILL       ", stdout);
6477               /* XXX Print content of info word?  */
6478               break;
6479             case ODK_TAGS:
6480               fputs (" TAGS       ", stdout);
6481               /* XXX Print content of info word?  */
6482               break;
6483             case ODK_HWAND:
6484               fputs (" HWAND     ", stdout);
6485               if (option->info & OHWA0_R4KEOP_CHECKED)
6486                 fputs (" R4KEOP_CHECKED", stdout);
6487               if (option->info & OHWA0_R4KEOP_CLEAN)
6488                 fputs (" R4KEOP_CLEAN", stdout);
6489               break;
6490             case ODK_HWOR:
6491               fputs (" HWOR      ", stdout);
6492               if (option->info & OHWA0_R4KEOP_CHECKED)
6493                 fputs (" R4KEOP_CHECKED", stdout);
6494               if (option->info & OHWA0_R4KEOP_CLEAN)
6495                 fputs (" R4KEOP_CLEAN", stdout);
6496               break;
6497             case ODK_GP_GROUP:
6498               printf (" GP_GROUP  %#06lx  self-contained %#06lx",
6499                       option->info & OGP_GROUP,
6500                       (option->info & OGP_SELF) >> 16);
6501               break;
6502             case ODK_IDENT:
6503               printf (" IDENT     %#06lx  self-contained %#06lx",
6504                       option->info & OGP_GROUP,
6505                       (option->info & OGP_SELF) >> 16);
6506               break;
6507             default:
6508               /* This shouldn't happen.  */
6509               printf (" %3d ???     %d %lx",
6510                       option->kind, option->section, option->info);
6511               break;
6512             }
6513
6514           len = sizeof (*eopt);
6515           while (len < option->size)
6516             if (((char *) option)[len] >= ' '
6517                 && ((char *) option)[len] < 0x7f)
6518               printf ("%c", ((char *) option)[len++]);
6519             else
6520               printf ("\\%03o", ((char *) option)[len++]);
6521
6522           fputs ("\n", stdout);
6523           ++option;
6524         }
6525
6526       free (eopt);
6527     }
6528
6529   if (conflicts_offset != 0 && conflictsno != 0)
6530     {
6531       Elf32_External_Conflict * econf32;
6532       Elf64_External_Conflict * econf64;
6533       Elf32_Conflict * iconf;
6534       size_t cnt;
6535
6536       if (dynamic_symbols == NULL)
6537         {
6538           error (_("conflict list with without table"));
6539           return 0;
6540         }
6541
6542       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
6543       if (iconf == NULL)
6544         {
6545           error (_("Out of memory"));
6546           return 0;
6547         }
6548
6549       if (is_32bit_elf)
6550         {
6551           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
6552                           econf32, Elf32_External_Conflict *, "conflict");
6553
6554           for (cnt = 0; cnt < conflictsno; ++cnt)
6555             iconf[cnt] = BYTE_GET (econf32[cnt]);
6556         }
6557       else
6558         {
6559           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
6560                           econf64, Elf64_External_Conflict *, "conflict");
6561
6562           for (cnt = 0; cnt < conflictsno; ++cnt)
6563             iconf[cnt] = BYTE_GET (econf64[cnt]);
6564         }
6565
6566       printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
6567       puts (_("  Num:    Index       Value  Name"));
6568
6569       for (cnt = 0; cnt < conflictsno; ++cnt)
6570         {
6571           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
6572
6573           printf ("%5u: %8lu  %#10lx  %s\n",
6574                   cnt, iconf[cnt], (unsigned long) psym->st_value,
6575                   dynamic_strings + psym->st_name);
6576         }
6577
6578
6579       free (iconf);
6580     }
6581
6582   return 1;
6583 }
6584
6585 static char *
6586 get_note_type (e_type)
6587      unsigned e_type;
6588 {
6589   static char buff[64];
6590
6591   switch (e_type)
6592     {
6593     case NT_PRSTATUS:   return _("NT_PRSTATUS (prstatus structure)");
6594     case NT_FPREGSET:   return _("NT_FPREGSET (floating point registers)");
6595     case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
6596     case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
6597     case NT_PSTATUS:    return _("NT_PSTATUS (pstatus structure)");
6598     case NT_FPREGS:     return _("NT_FPREGS (floating point registers)");
6599     case NT_PSINFO:     return _("NT_PSINFO (psinfo structure)");
6600     case NT_LWPSTATUS:  return _("NT_LWPSTATUS (lwpstatus_t structure)");
6601     case NT_LWPSINFO:   return _("NT_LWPSINFO (lwpsinfo_t structure)");
6602     default:
6603       sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
6604       return buff;
6605     }
6606 }
6607
6608 static int
6609 process_note (pnote)
6610   Elf_External_Note * pnote;
6611 {
6612   Elf32_Internal_Note * internal;
6613   char * pname;
6614
6615   internal = (Elf32_Internal_Note *) pnote;
6616   pname = malloc (internal->namesz + 1);
6617
6618   if (pname == NULL)
6619     {
6620       error (_("Out of memory\n"));
6621       return 0;
6622     }
6623
6624   memcpy (pname, pnote->name, internal->namesz);
6625   pname[internal->namesz] = '\0';
6626
6627   printf ("  %s\t\t0x%08lx\t%s\n",
6628           pname, internal->descsz, get_note_type (internal->type));
6629
6630   free (pname);
6631
6632   return 1;
6633 }
6634
6635 static int
6636 process_corefile_note_segment (file, offset, length)
6637      FILE * file;
6638      unsigned long offset;
6639      unsigned long length;
6640 {
6641   Elf_External_Note *  pnotes;
6642   Elf_External_Note *  external;
6643   Elf32_Internal_Note* internal;
6644   unsigned int         notesz;
6645   unsigned int         nlength;
6646   unsigned char *      p;
6647   int                  res = 1;
6648
6649   if (length <= 0)
6650     return 0;
6651
6652   GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
6653
6654   external = pnotes;
6655   p = (unsigned char *) pnotes;
6656   nlength = length;
6657
6658   printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length);
6659   printf (_("  Owner\t\tData size\tDescription\n"));
6660
6661   while (nlength > 0)
6662     {
6663       res &= process_note (external);
6664
6665       internal = (Elf32_Internal_Note *) p;
6666       notesz   = 3 * sizeof(unsigned long) + internal->namesz + internal->descsz;
6667       nlength -= notesz;
6668       p       += notesz;
6669       external = (Elf_External_Note *) p;
6670     }
6671
6672   free (pnotes);
6673
6674   return res;
6675 }
6676
6677 static int
6678 process_corefile_note_segments (file)
6679      FILE * file;
6680 {
6681   Elf_Internal_Phdr * program_headers;
6682   Elf_Internal_Phdr * segment;
6683   unsigned int        i;
6684   int                 res = 1;
6685
6686   program_headers = (Elf_Internal_Phdr *) malloc
6687     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
6688
6689   if (program_headers == NULL)
6690     {
6691       error (_("Out of memory\n"));
6692       return 0;
6693     }
6694
6695   if (is_32bit_elf)
6696     i = get_32bit_program_headers (file, program_headers);
6697   else
6698     i = get_64bit_program_headers (file, program_headers);
6699
6700   if (i == 0)
6701     {
6702       free (program_headers);
6703       return 0;
6704     }
6705
6706   for (i = 0, segment = program_headers;
6707        i < elf_header.e_phnum;
6708        i ++, segment ++)
6709     {
6710       if (segment->p_type == PT_NOTE)
6711         res &= process_corefile_note_segment (file,
6712                                               (unsigned long)segment->p_offset,
6713                                               (unsigned long)segment->p_filesz);
6714     }
6715
6716   free (program_headers);
6717
6718   return res;
6719 }
6720
6721 static int
6722 process_corefile_contents (file)
6723      FILE * file;
6724 {
6725   /* If we have not been asked to display the notes then do nothing.  */
6726   if (! do_notes)
6727     return 1;
6728
6729   /* If file is not a core file then exit.  */
6730   if (elf_header.e_type != ET_CORE)
6731     return 1;
6732
6733   /* No program headers means no NOTE segment.  */
6734   if (elf_header.e_phnum == 0)
6735     {
6736       printf (_("No note segments present in the core file.\n"));
6737       return 1;
6738    }
6739
6740   return process_corefile_note_segments (file);
6741 }
6742
6743 static int
6744 process_arch_specific (file)
6745      FILE * file;
6746 {
6747   if (! do_arch)
6748     return 1;
6749
6750   switch (elf_header.e_machine)
6751     {
6752     case EM_MIPS:
6753     case EM_MIPS_RS4_BE:
6754       return process_mips_specific (file);
6755       break;
6756     default:
6757       break;
6758     }
6759   return 1;
6760 }
6761
6762 static int
6763 get_file_header (file)
6764      FILE * file;
6765 {
6766   /* Read in the identity array.  */
6767   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
6768     return 0;
6769
6770   /* Determine how to read the rest of the header.  */
6771   switch (elf_header.e_ident [EI_DATA])
6772     {
6773     default: /* fall through */
6774     case ELFDATANONE: /* fall through */
6775     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
6776     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
6777     }
6778
6779   /* For now we only support 32 bit and 64 bit ELF files.  */
6780   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
6781
6782   /* Read in the rest of the header.  */
6783   if (is_32bit_elf)
6784     {
6785       Elf32_External_Ehdr ehdr32;
6786
6787       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
6788         return 0;
6789
6790       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
6791       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
6792       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
6793       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
6794       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
6795       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
6796       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
6797       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
6798       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
6799       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
6800       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
6801       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
6802       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
6803     }
6804   else
6805     {
6806       Elf64_External_Ehdr ehdr64;
6807
6808       /* If we have been compiled with sizeof (bfd_vma) == 4, then
6809          we will not be able to cope with the 64bit data found in
6810          64 ELF files.  Detect this now and abort before we start
6811          overwritting things.  */
6812       if (sizeof (bfd_vma) < 8)
6813         {
6814           error (_("This instance of readelf has been built without support for a\n"));
6815           error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
6816           return 0;
6817         }
6818
6819       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
6820         return 0;
6821
6822       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
6823       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
6824       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
6825       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
6826       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
6827       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
6828       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
6829       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
6830       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
6831       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
6832       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
6833       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
6834       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
6835     }
6836
6837   return 1;
6838 }
6839
6840 static void
6841 process_file (file_name)
6842      char * file_name;
6843 {
6844   FILE *       file;
6845   struct stat  statbuf;
6846   unsigned int i;
6847
6848   if (stat (file_name, & statbuf) < 0)
6849     {
6850       error (_("Cannot stat input file %s.\n"), file_name);
6851       return;
6852     }
6853
6854   file = fopen (file_name, "rb");
6855   if (file == NULL)
6856     {
6857       error (_("Input file %s not found.\n"), file_name);
6858       return;
6859     }
6860
6861   if (! get_file_header (file))
6862     {
6863       error (_("%s: Failed to read file header\n"), file_name);
6864       fclose (file);
6865       return;
6866     }
6867
6868   /* Initialise per file variables.  */
6869   for (i = NUM_ELEM (version_info); i--;)
6870     version_info[i] = 0;
6871
6872   for (i = NUM_ELEM (dynamic_info); i--;)
6873     dynamic_info[i] = 0;
6874
6875   /* Process the file.  */
6876   if (show_name)
6877     printf (_("\nFile: %s\n"), file_name);
6878
6879   if (! process_file_header ())
6880     {
6881       fclose (file);
6882       return;
6883     }
6884
6885   process_section_headers (file);
6886
6887   process_program_headers (file);
6888
6889   process_dynamic_segment (file);
6890
6891   process_relocs (file);
6892
6893   process_symbol_table (file);
6894
6895   process_syminfo (file);
6896
6897   process_version_sections (file);
6898
6899   process_section_contents (file);
6900
6901   process_corefile_contents (file);
6902
6903   process_arch_specific (file);
6904
6905   fclose (file);
6906
6907   if (section_headers)
6908     {
6909       free (section_headers);
6910       section_headers = NULL;
6911     }
6912
6913   if (string_table)
6914     {
6915       free (string_table);
6916       string_table = NULL;
6917     }
6918
6919   if (dynamic_strings)
6920     {
6921       free (dynamic_strings);
6922       dynamic_strings = NULL;
6923     }
6924
6925   if (dynamic_symbols)
6926     {
6927       free (dynamic_symbols);
6928       dynamic_symbols = NULL;
6929       num_dynamic_syms = 0;
6930     }
6931
6932   if (dynamic_syminfo)
6933     {
6934       free (dynamic_syminfo);
6935       dynamic_syminfo = NULL;
6936     }
6937 }
6938
6939 #ifdef SUPPORT_DISASSEMBLY
6940 /* Needed by the i386 disassembler.  For extra credit, someone could
6941    fix this so that we insert symbolic addresses here, esp for GOT/PLT
6942    symbols */
6943
6944 void
6945 print_address (unsigned int addr, FILE * outfile)
6946 {
6947   fprintf (outfile,"0x%8.8x", addr);
6948 }
6949
6950 /* Needed by the i386 disassembler. */
6951 void
6952 db_task_printsym (unsigned int addr)
6953 {
6954   print_address (addr, stderr);
6955 }
6956 #endif
6957
6958 int
6959 main (argc, argv)
6960      int     argc;
6961      char ** argv;
6962 {
6963 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
6964   setlocale (LC_MESSAGES, "");
6965 #endif
6966   bindtextdomain (PACKAGE, LOCALEDIR);
6967   textdomain (PACKAGE);
6968
6969   parse_args (argc, argv);
6970
6971   if (optind < (argc - 1))
6972     show_name = 1;
6973
6974   while (optind < argc)
6975     process_file (argv [optind ++]);
6976
6977   if (dump_sects != NULL)
6978     free (dump_sects);
6979
6980   return 0;
6981 }