OSDN Git Service

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