]> Git Repo - binutils.git/blob - binutils/readelf.c
m
[binutils.git] / binutils / readelf.c
1 /* readelf.c -- display contents of an ELF format file
2    Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
4    Originally developed by Eric Youngdale <[email protected]>
5    Modifications by Nick Clifton <[email protected]>
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 [email protected]\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: %x>"), 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: %x>"), 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: %x>"), 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
1567                ? "(current)"
1568                : (elf_header.e_ident [EI_VERSION] != EV_NONE
1569                   ? "<unknown: %lx>"
1570                   : "")));
1571       printf (_("  OS/ABI:                            %s\n"),
1572               get_osabi_name (elf_header.e_ident [EI_OSABI]));
1573       printf (_("  ABI Version:                       %d\n"),
1574               elf_header.e_ident [EI_ABIVERSION]);
1575       printf (_("  Type:                              %s\n"),
1576               get_file_type (elf_header.e_type));
1577       printf (_("  Machine:                           %s\n"),
1578               get_machine_name (elf_header.e_machine));
1579       printf (_("  Version:                           0x%lx\n"),
1580               (unsigned long) elf_header.e_version);
1581       printf (_("  Entry point address:               0x%lx\n"),
1582               (unsigned long) elf_header.e_entry);
1583       printf (_("  Start of program headers:          %ld (bytes into file)\n"),
1584               (long) elf_header.e_phoff);
1585       printf (_("  Start of section headers:          %ld (bytes into file)\n"),
1586               (long) elf_header.e_shoff);
1587       printf (_("  Flags:                             0x%lx%s\n"),
1588               (unsigned long) elf_header.e_flags,
1589               get_machine_flags (elf_header.e_flags, elf_header.e_machine));
1590       printf (_("  Size of this header:               %ld (bytes)\n"),
1591               (long) elf_header.e_ehsize);
1592       printf (_("  Size of program headers:           %ld (bytes)\n"),
1593               (long) elf_header.e_phentsize);
1594       printf (_("  Number of program headers:         %ld\n"),
1595               (long) elf_header.e_phnum);
1596       printf (_("  Size of section headers:           %ld (bytes)\n"),
1597               (long) elf_header.e_shentsize);
1598       printf (_("  Number of section headers:         %ld\n"),
1599               (long) elf_header.e_shnum);
1600       printf (_("  Section header string table index: %ld\n"),
1601               (long) elf_header.e_shstrndx);
1602     }
1603   
1604   return 1;
1605 }
1606
1607
1608 static int
1609 get_32bit_program_headers (file, program_headers)
1610      FILE * file;
1611      Elf_Internal_Phdr * program_headers;
1612 {
1613   Elf32_External_Phdr * phdrs;
1614   Elf32_External_Phdr * external;
1615   Elf32_Internal_Phdr * internal;
1616   unsigned int          i;
1617   
1618   GET_DATA_ALLOC (elf_header.e_phoff,
1619                   elf_header.e_phentsize * elf_header.e_phnum,
1620                   phdrs, Elf32_External_Phdr *, "program headers");
1621
1622   for (i = 0, internal = program_headers, external = phdrs;
1623        i < elf_header.e_phnum;
1624        i ++, internal ++, external ++)
1625     {
1626       internal->p_type   = BYTE_GET (external->p_type);
1627       internal->p_offset = BYTE_GET (external->p_offset);
1628       internal->p_vaddr  = BYTE_GET (external->p_vaddr);
1629       internal->p_paddr  = BYTE_GET (external->p_paddr);
1630       internal->p_filesz = BYTE_GET (external->p_filesz);
1631       internal->p_memsz  = BYTE_GET (external->p_memsz);
1632       internal->p_flags  = BYTE_GET (external->p_flags);
1633       internal->p_align  = BYTE_GET (external->p_align);
1634     }
1635
1636   free (phdrs);
1637
1638   return 1;
1639 }
1640
1641 static int
1642 get_64bit_program_headers (file, program_headers)
1643      FILE * file;
1644      Elf_Internal_Phdr * program_headers;
1645 {
1646   Elf64_External_Phdr * phdrs;
1647   Elf64_External_Phdr * external;
1648   Elf64_Internal_Phdr * internal;
1649   unsigned int          i;
1650   
1651   GET_DATA_ALLOC (elf_header.e_phoff,
1652                   elf_header.e_phentsize * elf_header.e_phnum,
1653                   phdrs, Elf64_External_Phdr *, "program headers");
1654
1655   for (i = 0, internal = program_headers, external = phdrs;
1656        i < elf_header.e_phnum;
1657        i ++, internal ++, external ++)
1658     {
1659       internal->p_type   = BYTE_GET (external->p_type);
1660       internal->p_flags  = BYTE_GET (external->p_flags);
1661       internal->p_offset = BYTE_GET8 (external->p_offset);
1662       internal->p_vaddr  = BYTE_GET8 (external->p_vaddr);
1663       internal->p_paddr  = BYTE_GET8 (external->p_paddr);
1664       internal->p_filesz = BYTE_GET8 (external->p_filesz);
1665       internal->p_memsz  = BYTE_GET8 (external->p_memsz);
1666       internal->p_align  = BYTE_GET8 (external->p_align);
1667     }
1668
1669   free (phdrs);
1670
1671   return 1;
1672 }
1673
1674 static int
1675 process_program_headers (file)
1676      FILE * file;
1677 {
1678   Elf_Internal_Phdr * program_headers;
1679   Elf_Internal_Phdr * segment;
1680   unsigned int        i;
1681
1682   if (elf_header.e_phnum == 0)
1683     {
1684       if (do_segments)
1685         printf (_("\nThere are no program headers in this file.\n"));
1686       return 1;
1687     }
1688
1689   if (do_segments && !do_header)
1690     {
1691       printf (_("\nElf file is %s\n"), get_file_type (elf_header.e_type));
1692       printf (_("Entry point 0x%lx\n"), (unsigned long) elf_header.e_entry);
1693       printf (_("There are %d program headers, starting at offset %lx:\n"),
1694               elf_header.e_phnum, (unsigned long) elf_header.e_phoff);
1695     }
1696
1697   program_headers = (Elf_Internal_Phdr *) malloc
1698     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
1699
1700   if (program_headers == NULL)
1701     {
1702       error (_("Out of memory\n"));
1703       return 0;
1704     }
1705
1706   if (is_32bit_elf)
1707     i = get_32bit_program_headers (file, program_headers);
1708   else
1709     i = get_64bit_program_headers (file, program_headers);
1710
1711   if (i == 0)
1712     {
1713       free (program_headers);
1714       return 0;
1715     }
1716   
1717   if (do_segments)
1718     {
1719       printf
1720         (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
1721       printf
1722         (_("  Type        Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align\n"));
1723     }
1724
1725   loadaddr = -1;
1726   dynamic_addr = 0;
1727   dynamic_size = 0;
1728
1729   for (i = 0, segment = program_headers;
1730        i < elf_header.e_phnum;
1731        i ++, segment ++)
1732     {
1733       if (do_segments)
1734         {
1735           printf ("  %-11.11s ", get_segment_type (segment->p_type));
1736           printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
1737           printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
1738           printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
1739           printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
1740           printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
1741           printf ("%c%c%c ",
1742                   (segment->p_flags & PF_R ? 'R' : ' '),
1743                   (segment->p_flags & PF_W ? 'W' : ' '),
1744                   (segment->p_flags & PF_X ? 'E' : ' '));
1745           printf ("%#lx", (unsigned long) segment->p_align);
1746         }
1747
1748       switch (segment->p_type)
1749         {
1750         case PT_LOAD:
1751           if (loadaddr == -1)
1752             loadaddr = (segment->p_vaddr & 0xfffff000)
1753               - (segment->p_offset & 0xfffff000);
1754           break;
1755
1756         case PT_DYNAMIC:
1757           if (dynamic_addr)
1758             error (_("more than one dynamic segment\n"));
1759
1760           dynamic_addr = segment->p_offset;
1761           dynamic_size = segment->p_filesz;
1762           break;
1763
1764         case PT_INTERP:
1765           if (fseek (file, segment->p_offset, SEEK_SET))
1766             error (_("Unable to find program interpreter name\n"));
1767           else
1768             {
1769               program_interpreter[0] = 0;
1770               fscanf (file, "%63s", program_interpreter);
1771
1772               if (do_segments)
1773                 printf (_("\n      [Requesting program interpreter: %s]"),
1774                     program_interpreter);
1775             }
1776           break;
1777         }
1778
1779       if (do_segments)
1780         putc ('\n', stdout);
1781     }
1782
1783   if (loadaddr == -1)
1784     {
1785       /* Very strange. */
1786       loadaddr = 0;
1787     }
1788
1789   if (do_segments && section_headers != NULL)
1790     {
1791       printf (_("\n Section to Segment mapping:\n"));
1792       printf (_("  Segment Sections...\n"));
1793
1794       assert (string_table != NULL);
1795
1796       for (i = 0; i < elf_header.e_phnum; i++)
1797         {
1798           int                 j;
1799           Elf_Internal_Shdr * section;
1800
1801           segment = program_headers + i;
1802           section = section_headers;
1803
1804           printf ("   %2.2d     ", i);
1805
1806           for (j = 0; j < elf_header.e_shnum; j++, section ++)
1807             {
1808               if (section->sh_size > 0
1809                   /* Compare allocated sections by VMA, unallocated
1810                      sections by file offset.  */
1811                   && (section->sh_flags & SHF_ALLOC
1812                       ? (section->sh_addr >= segment->p_vaddr
1813                          && section->sh_addr + section->sh_size
1814                          <= segment->p_vaddr + segment->p_memsz)
1815                       : (section->sh_offset >= segment->p_offset
1816                          && (section->sh_offset + section->sh_size
1817                              <= segment->p_offset + segment->p_filesz))))
1818                 printf ("%s ", SECTION_NAME (section));
1819             }
1820
1821           putc ('\n',stdout);
1822         }
1823     }
1824
1825   free (program_headers);
1826
1827   return 1;
1828 }
1829
1830
1831 static int
1832 get_32bit_section_headers (file)
1833      FILE * file;
1834 {
1835   Elf32_External_Shdr * shdrs;
1836   Elf32_Internal_Shdr * internal;
1837   unsigned int          i;
1838
1839   GET_DATA_ALLOC (elf_header.e_shoff,
1840                   elf_header.e_shentsize * elf_header.e_shnum,
1841                   shdrs, Elf32_External_Shdr *, "section headers");
1842
1843   section_headers = (Elf_Internal_Shdr *) malloc
1844     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
1845
1846   if (section_headers == NULL)
1847     {
1848       error (_("Out of memory\n"));
1849       return 0;
1850     }
1851
1852   for (i = 0, internal = section_headers;
1853        i < elf_header.e_shnum;
1854        i ++, internal ++)
1855     {
1856       internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
1857       internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
1858       internal->sh_flags     = BYTE_GET (shdrs[i].sh_flags);
1859       internal->sh_addr      = BYTE_GET (shdrs[i].sh_addr);
1860       internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
1861       internal->sh_size      = BYTE_GET (shdrs[i].sh_size);
1862       internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
1863       internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
1864       internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1865       internal->sh_entsize   = BYTE_GET (shdrs[i].sh_entsize);
1866     }
1867
1868   free (shdrs);
1869
1870   return 1;
1871 }
1872
1873 static int
1874 get_64bit_section_headers (file)
1875      FILE * file;
1876 {
1877   Elf64_External_Shdr * shdrs;
1878   Elf64_Internal_Shdr * internal;
1879   unsigned int          i;
1880
1881   GET_DATA_ALLOC (elf_header.e_shoff,
1882                   elf_header.e_shentsize * elf_header.e_shnum,
1883                   shdrs, Elf64_External_Shdr *, "section headers");
1884
1885   section_headers = (Elf_Internal_Shdr *) malloc
1886     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
1887
1888   if (section_headers == NULL)
1889     {
1890       error (_("Out of memory\n"));
1891       return 0;
1892     }
1893
1894   for (i = 0, internal = section_headers;
1895        i < elf_header.e_shnum;
1896        i ++, internal ++)
1897     {
1898       internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
1899       internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
1900       internal->sh_flags     = BYTE_GET8 (shdrs[i].sh_flags);
1901       internal->sh_addr      = BYTE_GET8 (shdrs[i].sh_addr);
1902       internal->sh_size      = BYTE_GET8 (shdrs[i].sh_size);
1903       internal->sh_entsize   = BYTE_GET8 (shdrs[i].sh_entsize);
1904       internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
1905       internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
1906       internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
1907       internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
1908     }
1909
1910   free (shdrs);
1911
1912   return 1;
1913 }
1914
1915 static Elf_Internal_Sym *
1916 get_32bit_elf_symbols (file, offset, number)
1917      FILE * file;
1918      unsigned long offset;
1919      unsigned long number;
1920 {
1921   Elf32_External_Sym * esyms;
1922   Elf_Internal_Sym *   isyms;
1923   Elf_Internal_Sym *   psym;
1924   unsigned int         j;
1925
1926   GET_DATA_ALLOC (offset, number * sizeof (Elf32_External_Sym),
1927                   esyms, Elf32_External_Sym *, "symbols");
1928
1929   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1930
1931   if (isyms == NULL)
1932     {
1933       error (_("Out of memory\n"));
1934       free (esyms);
1935
1936       return NULL;
1937     }
1938
1939   for (j = 0, psym = isyms;
1940        j < number;
1941        j ++, psym ++)
1942     {
1943       psym->st_name  = BYTE_GET (esyms[j].st_name);
1944       psym->st_value = BYTE_GET (esyms[j].st_value);
1945       psym->st_size  = BYTE_GET (esyms[j].st_size);
1946       psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1947       psym->st_info  = BYTE_GET (esyms[j].st_info);
1948       psym->st_other = BYTE_GET (esyms[j].st_other);
1949     }
1950
1951   free (esyms);
1952
1953   return isyms;
1954 }
1955
1956 static Elf_Internal_Sym *
1957 get_64bit_elf_symbols (file, offset, number)
1958      FILE * file;
1959      unsigned long offset;
1960      unsigned long number;
1961 {
1962   Elf64_External_Sym * esyms;
1963   Elf_Internal_Sym *   isyms;
1964   Elf_Internal_Sym *   psym;
1965   unsigned int         j;
1966
1967   GET_DATA_ALLOC (offset, number * sizeof (Elf64_External_Sym),
1968                   esyms, Elf64_External_Sym *, "symbols");
1969
1970   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
1971
1972   if (isyms == NULL)
1973     {
1974       error (_("Out of memory\n"));
1975       free (esyms);
1976
1977       return NULL;
1978     }
1979
1980   for (j = 0, psym = isyms;
1981        j < number;
1982        j ++, psym ++)
1983     {
1984       psym->st_name  = BYTE_GET (esyms[j].st_name);
1985       psym->st_info  = BYTE_GET (esyms[j].st_info);
1986       psym->st_other = BYTE_GET (esyms[j].st_other);
1987       psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
1988       psym->st_value = BYTE_GET8 (esyms[j].st_value);
1989       psym->st_size  = BYTE_GET8 (esyms[j].st_size);
1990     }
1991
1992   free (esyms);
1993
1994   return isyms;
1995 }
1996
1997 static int
1998 process_section_headers (file)
1999      FILE * file;
2000 {
2001   Elf_Internal_Shdr * section;
2002   int                 i;
2003
2004   section_headers = NULL;
2005
2006   if (elf_header.e_shnum == 0)
2007     {
2008       if (do_sections)
2009         printf (_("\nThere are no sections in this file.\n"));
2010
2011       return 1;
2012     }
2013
2014   if (do_sections && !do_header)
2015     printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
2016             elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
2017
2018   if (is_32bit_elf)
2019     {
2020       if (! get_32bit_section_headers (file))
2021         return 0;
2022     }
2023   else if (! get_64bit_section_headers (file))
2024     return 0;
2025
2026   /* Read in the string table, so that we have names to display.  */
2027   section = section_headers + elf_header.e_shstrndx;
2028
2029   if (section->sh_size != 0)
2030     {
2031       unsigned long string_table_offset;
2032
2033       string_table_offset = section->sh_offset;
2034
2035       GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2036                       string_table, char *, "string table");
2037     }
2038
2039   /* Scan the sections for the dynamic symbol table
2040      and dynamic string table and debug sections. */
2041   dynamic_symbols = NULL;
2042   dynamic_strings = NULL;
2043   dynamic_syminfo = NULL;
2044   
2045   for (i = 0, section = section_headers;
2046        i < elf_header.e_shnum;
2047        i ++, section ++)
2048     {
2049       char * name = SECTION_NAME (section);
2050
2051       if (section->sh_type == SHT_DYNSYM)
2052         {
2053           if (dynamic_symbols != NULL)
2054             {
2055               error (_("File contains multiple dynamic symbol tables\n"));
2056               continue;
2057             }
2058
2059           num_dynamic_syms = section->sh_size / section->sh_entsize;
2060           dynamic_symbols =
2061             GET_ELF_SYMBOLS (file, section->sh_offset, num_dynamic_syms);
2062         }
2063       else if (section->sh_type == SHT_STRTAB
2064                && strcmp (name, ".dynstr") == 0)
2065         {
2066           if (dynamic_strings != NULL)
2067             {
2068               error (_("File contains multiple dynamic string tables\n"));
2069               continue;
2070             }
2071
2072           GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2073                           dynamic_strings, char *, "dynamic strings");
2074         }
2075       else if ((do_debugging || do_debug_info || do_debug_abbrevs
2076                 || do_debug_lines || do_debug_pubnames || do_debug_aranges)
2077                && strncmp (name, ".debug_", 7) == 0)
2078         {
2079           name += 7;
2080
2081           if (do_debugging
2082               || (do_debug_info     && (strcmp (name, "info") == 0))
2083               || (do_debug_abbrevs  && (strcmp (name, "abbrev") == 0))
2084               || (do_debug_lines    && (strcmp (name, "line") == 0))
2085               || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
2086               || (do_debug_aranges  && (strcmp (name, "aranges") == 0))
2087               )
2088             request_dump (i, DEBUG_DUMP);
2089         }
2090     }
2091
2092   if (! do_sections)
2093     return 1;
2094
2095   printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2096   printf
2097     (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
2098
2099   for (i = 0, section = section_headers;
2100        i < elf_header.e_shnum;
2101        i ++, section ++)
2102     {
2103       printf ("  [%2d] %-17.17s %-15.15s ",
2104               i,
2105               SECTION_NAME (section),
2106               get_section_type_name (section->sh_type));
2107
2108       printf ( "%8.8lx %6.6lx %6.6lx %2.2lx",
2109                (unsigned long) section->sh_addr,
2110                (unsigned long) section->sh_offset,
2111                (unsigned long) section->sh_size,
2112                (unsigned long) section->sh_entsize);
2113
2114       printf (" %c%c%c %2ld %3lx %ld\n",
2115               (section->sh_flags & SHF_WRITE ? 'W' : ' '),
2116               (section->sh_flags & SHF_ALLOC ? 'A' : ' '),
2117               (section->sh_flags & SHF_EXECINSTR ? 'X' : ' '),
2118               (unsigned long) section->sh_link,
2119               (unsigned long) section->sh_info,
2120               (unsigned long) section->sh_addralign);
2121     }
2122
2123   return 1;
2124 }
2125
2126 /* Process the reloc section.  */
2127 static int
2128 process_relocs (file)
2129      FILE * file;
2130 {
2131   unsigned long    rel_size;
2132   unsigned long    rel_offset;
2133
2134
2135   if (!do_reloc)
2136     return 1;
2137
2138   if (do_using_dynamic)
2139     {
2140       int is_rela;
2141
2142       rel_size   = 0;
2143       rel_offset = 0;
2144
2145       if (dynamic_info[DT_REL])
2146         {
2147           rel_offset = dynamic_info[DT_REL];
2148           rel_size   = dynamic_info[DT_RELSZ];
2149           is_rela    = FALSE;
2150         }
2151       else if (dynamic_info [DT_RELA])
2152         {
2153           rel_offset = dynamic_info[DT_RELA];
2154           rel_size   = dynamic_info[DT_RELASZ];
2155           is_rela    = TRUE;
2156         }
2157       else if (dynamic_info[DT_JMPREL])
2158         {
2159           rel_offset = dynamic_info[DT_JMPREL];
2160           rel_size   = dynamic_info[DT_PLTRELSZ];
2161           
2162           switch (dynamic_info[DT_PLTREL])
2163             {
2164             case DT_REL:
2165               is_rela = FALSE;
2166               break;
2167             case DT_RELA:
2168               is_rela = TRUE;
2169               break;
2170             default:
2171               is_rela = UNKNOWN;
2172               break;
2173             }
2174         }
2175
2176       if (rel_size)
2177         {
2178           printf
2179             (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
2180              rel_offset, rel_size);
2181
2182           dump_relocations (file, rel_offset - loadaddr, rel_size,
2183                             dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
2184         }
2185       else
2186         printf (_("\nThere are no dynamic relocations in this file.\n"));
2187     }
2188   else
2189     {
2190       Elf32_Internal_Shdr *     section;
2191       unsigned long             i;
2192       int                       found = 0;
2193
2194       for (i = 0, section = section_headers;
2195            i < elf_header.e_shnum;
2196            i++, section ++)
2197         {
2198           if (   section->sh_type != SHT_RELA
2199               && section->sh_type != SHT_REL)
2200             continue;
2201
2202           rel_offset = section->sh_offset;
2203           rel_size   = section->sh_size;
2204
2205           if (rel_size)
2206             {
2207               Elf32_Internal_Shdr * strsec;
2208               Elf32_Internal_Shdr * symsec;
2209               Elf_Internal_Sym *    symtab;
2210               char *                strtab;
2211               int                   is_rela;
2212               unsigned long         nsyms;
2213               
2214               printf (_("\nRelocation section "));
2215
2216               if (string_table == NULL)
2217                 printf ("%d", section->sh_name);
2218               else
2219                 printf ("'%s'", SECTION_NAME (section));
2220
2221               printf (_(" at offset 0x%lx contains %lu entries:\n"),
2222                  rel_offset, (unsigned long) (rel_size / section->sh_entsize));
2223
2224               symsec = section_headers + section->sh_link;
2225
2226               nsyms = symsec->sh_size / symsec->sh_entsize;
2227               symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
2228
2229               if (symtab == NULL)
2230                 continue;
2231
2232               strsec = section_headers + symsec->sh_link;
2233
2234               GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
2235                               char *, "string table");
2236               
2237               is_rela = section->sh_type == SHT_RELA;
2238
2239               dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela);
2240
2241               free (strtab);
2242               free (symtab);
2243
2244               found = 1;
2245             }
2246         }
2247
2248       if (! found)
2249         printf (_("\nThere are no relocations in this file.\n"));
2250     }
2251
2252   return 1;
2253 }
2254
2255
2256 static void
2257 dynamic_segment_mips_val (entry)
2258      Elf_Internal_Dyn * entry;
2259 {
2260   switch (entry->d_tag)
2261     {
2262     case DT_MIPS_FLAGS:
2263       if (entry->d_un.d_val == 0)
2264         printf ("NONE\n");
2265       else
2266         {
2267           static const char * opts[] =
2268           {
2269             "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2270             "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2271             "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2272             "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2273             "RLD_ORDER_SAFE"
2274           };
2275           unsigned int cnt;
2276           int first = 1;
2277           for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2278             if (entry->d_un.d_val & (1 << cnt))
2279               {
2280                 printf ("%s%s", first ? "" : " ", opts[cnt]);
2281                 first = 0;
2282               }
2283           puts ("");
2284         }
2285       break;
2286       
2287     case DT_MIPS_IVERSION:
2288       if (dynamic_strings != NULL)
2289         printf ("Interface Version: %s\n",
2290                 dynamic_strings + entry->d_un.d_val);
2291       else
2292         printf ("%ld\n", (long) entry->d_un.d_ptr);
2293       break;
2294       
2295     case DT_MIPS_TIME_STAMP:
2296       {
2297         char timebuf[20];
2298         time_t time = entry->d_un.d_val;
2299         strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
2300         printf ("Time Stamp: %s\n", timebuf);
2301       }
2302       break;
2303       
2304     case DT_MIPS_RLD_VERSION:
2305     case DT_MIPS_LOCAL_GOTNO:
2306     case DT_MIPS_CONFLICTNO:
2307     case DT_MIPS_LIBLISTNO:
2308     case DT_MIPS_SYMTABNO:
2309     case DT_MIPS_UNREFEXTNO:
2310     case DT_MIPS_HIPAGENO:
2311     case DT_MIPS_DELTA_CLASS_NO:
2312     case DT_MIPS_DELTA_INSTANCE_NO:
2313     case DT_MIPS_DELTA_RELOC_NO:
2314     case DT_MIPS_DELTA_SYM_NO:
2315     case DT_MIPS_DELTA_CLASSSYM_NO:
2316     case DT_MIPS_COMPACT_SIZE:
2317       printf ("%ld\n", (long) entry->d_un.d_ptr);
2318       break;
2319       
2320     default:
2321       printf ("%#lx\n", (long) entry->d_un.d_ptr);
2322     }
2323 }
2324
2325 static int
2326 get_32bit_dynamic_segment (file)
2327      FILE * file;
2328 {
2329   Elf32_External_Dyn * edyn;
2330   Elf_Internal_Dyn *   entry;
2331   bfd_size_type        i;
2332   
2333   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2334                   edyn, Elf32_External_Dyn *, "dynamic segment");
2335   
2336   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
2337      how large this .dynamic is now.  We can do this even before the byte
2338      swapping since the DT_NULL tag is recognizable.  */
2339   dynamic_size = 0;
2340   while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
2341     ;
2342
2343   dynamic_segment = (Elf_Internal_Dyn *)
2344     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2345
2346   if (dynamic_segment == NULL)
2347     {
2348       error (_("Out of memory\n"));
2349       free (edyn);
2350       return 0;
2351     }
2352
2353   for (i = 0, entry = dynamic_segment;
2354        i < dynamic_size;
2355        i ++, entry ++)
2356     {
2357       entry->d_tag      = BYTE_GET (edyn [i].d_tag);
2358       entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
2359     }
2360
2361   free (edyn);
2362
2363   return 1;
2364 }
2365
2366 static int
2367 get_64bit_dynamic_segment (file)
2368      FILE * file;
2369 {
2370   Elf64_External_Dyn * edyn;
2371   Elf_Internal_Dyn *   entry;
2372   bfd_size_type        i;
2373   
2374   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
2375                   edyn, Elf64_External_Dyn *, "dynamic segment");
2376   
2377   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
2378      how large this .dynamic is now.  We can do this even before the byte
2379      swapping since the DT_NULL tag is recognizable.  */
2380   dynamic_size = 0;
2381   while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
2382     ;
2383
2384   dynamic_segment = (Elf_Internal_Dyn *)
2385     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
2386
2387   if (dynamic_segment == NULL)
2388     {
2389       error (_("Out of memory\n"));
2390       free (edyn);
2391       return 0;
2392     }
2393
2394   for (i = 0, entry = dynamic_segment;
2395        i < dynamic_size;
2396        i ++, entry ++)
2397     {
2398       entry->d_tag      = BYTE_GET8 (edyn [i].d_tag);
2399       entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
2400     }
2401
2402   free (edyn);
2403
2404   return 1;
2405 }
2406
2407 /* Parse and display the contents of the dynamic segment.  */
2408 static int
2409 process_dynamic_segment (file)
2410      FILE * file;
2411 {
2412   Elf_Internal_Dyn * entry;
2413   bfd_size_type      i;
2414
2415   if (dynamic_size == 0)
2416     {
2417       if (do_dynamic)
2418         printf (_("\nThere is no dynamic segment in this file.\n"));
2419
2420       return 1;
2421     }
2422
2423   if (is_32bit_elf)
2424     {
2425       if (! get_32bit_dynamic_segment (file))
2426         return 0;
2427     }
2428   else if (! get_64bit_dynamic_segment (file))
2429     return 0;
2430
2431   /* Find the appropriate symbol table.  */
2432   if (dynamic_symbols == NULL)
2433     {
2434       for (i = 0, entry = dynamic_segment;
2435            i < dynamic_size;
2436            ++i, ++ entry)
2437         {
2438           unsigned long        offset;
2439
2440           if (entry->d_tag != DT_SYMTAB)
2441             continue;
2442
2443           dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
2444
2445           /* Since we do not know how big the symbol table is,
2446              we default to reading in the entire file (!) and
2447              processing that.  This is overkill, I know, but it
2448              should work. */
2449           offset = entry->d_un.d_val - loadaddr;
2450
2451           if (fseek (file, 0, SEEK_END))
2452             error (_("Unable to seek to end of file!"));
2453
2454           if (is_32bit_elf)
2455             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
2456           else
2457             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
2458
2459           if (num_dynamic_syms < 1)
2460             {
2461               error (_("Unable to determine the number of symbols to load\n"));
2462               continue;
2463             }
2464
2465           dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
2466         }
2467     }
2468
2469   /* Similarly find a string table.  */
2470   if (dynamic_strings == NULL)
2471     {
2472       for (i = 0, entry = dynamic_segment;
2473            i < dynamic_size;
2474            ++i, ++ entry)
2475         {
2476           unsigned long offset;
2477           long          str_tab_len;
2478
2479           if (entry->d_tag != DT_STRTAB)
2480             continue;
2481
2482           dynamic_info[DT_STRTAB] = entry->d_un.d_val;
2483
2484           /* Since we do not know how big the string table is,
2485              we default to reading in the entire file (!) and
2486              processing that.  This is overkill, I know, but it
2487              should work. */
2488
2489           offset = entry->d_un.d_val - loadaddr;
2490           if (fseek (file, 0, SEEK_END))
2491             error (_("Unable to seek to end of file\n"));
2492           str_tab_len = ftell (file) - offset;
2493
2494           if (str_tab_len < 1)
2495             {
2496               error
2497                 (_("Unable to determine the length of the dynamic string table\n"));
2498               continue;
2499             }
2500
2501           GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
2502                           "dynamic string table");
2503
2504           break;
2505         }
2506     }
2507
2508   /* And find the syminfo section if available.  */
2509   if (dynamic_syminfo == NULL)
2510     {
2511       unsigned int syminsz = 0;
2512
2513       for (i = 0, entry = dynamic_segment;
2514            i < dynamic_size;
2515            ++i, ++ entry)
2516         {
2517           if (entry->d_tag == DT_SYMINENT)
2518             {
2519               /* Note: these braces are necessary to avoid a syntax
2520                  error from the SunOS4 C compiler.  */
2521               assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
2522             }
2523           else if (entry->d_tag == DT_SYMINSZ)
2524             syminsz = entry->d_un.d_val;
2525           else if (entry->d_tag == DT_SYMINFO)
2526             dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
2527         }
2528
2529       if (dynamic_syminfo_offset != 0 && syminsz != 0)
2530         {
2531           Elf_External_Syminfo * extsyminfo;
2532           Elf_Internal_Syminfo * syminfo;
2533
2534           /* There is a syminfo section.  Read the data.  */
2535           GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
2536                           Elf_External_Syminfo *, "symbol information");
2537
2538           dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
2539           if (dynamic_syminfo == NULL)
2540             {
2541               error (_("Out of memory\n"));
2542               return 0;
2543             }
2544
2545           dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
2546           for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
2547                ++i, ++syminfo)
2548             {
2549               syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
2550               syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
2551             }
2552
2553           free (extsyminfo);
2554         }
2555     }
2556
2557   if (do_dynamic && dynamic_addr)
2558     printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
2559             dynamic_addr, (long) dynamic_size);
2560   if (do_dynamic)
2561     printf (_("  Tag        Type                         Name/Value\n"));
2562
2563   for (i = 0, entry = dynamic_segment;
2564        i < dynamic_size;
2565        i++, entry ++)
2566     {
2567       if (do_dynamic)
2568         printf (_("  0x%-8.8lx (%s)%*s"),
2569                 (unsigned long) entry->d_tag,
2570                 get_dynamic_type (entry->d_tag),
2571                 27 - strlen (get_dynamic_type (entry->d_tag)),
2572                 " ");
2573
2574       switch (entry->d_tag)
2575         {
2576         case DT_AUXILIARY:
2577         case DT_FILTER:
2578           if (do_dynamic)
2579             {
2580               if (entry->d_tag == DT_AUXILIARY)
2581                 printf (_("Auxiliary library"));
2582               else
2583                 printf (_("Filter library"));
2584
2585               if (dynamic_strings)
2586                 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
2587               else
2588                 printf (": %#lx\n", (long) entry->d_un.d_val);
2589             }
2590           break;
2591
2592         case DT_FEATURE_1:
2593           if (do_dynamic)
2594             {
2595               printf (_("Flags:"));
2596               if (entry->d_un.d_val == 0)
2597                 printf (_(" None\n"));
2598               else
2599                 {
2600                   unsigned long int val = entry->d_un.d_val;
2601                   if (val & DTF_1_PARINIT)
2602                     {
2603                       printf (" PARINIT");
2604                       val ^= DTF_1_PARINIT;
2605                     }
2606                   if (val != 0)
2607                     printf (" %lx", val);
2608                   puts ("");
2609                 }
2610             }
2611           break;
2612
2613         case DT_POSFLAG_1:
2614           if (do_dynamic)
2615             {
2616               printf (_("Flags:"));
2617               if (entry->d_un.d_val == 0)
2618                 printf (_(" None\n"));
2619               else
2620                 {
2621                   unsigned long int val = entry->d_un.d_val;
2622                   if (val & DF_P1_LAZYLOAD)
2623                     {
2624                       printf (" LAZYLOAD");
2625                       val ^= DF_P1_LAZYLOAD;
2626                     }
2627                   if (val & DF_P1_GROUPPERM)
2628                     {
2629                       printf (" GROUPPERM");
2630                       val ^= DF_P1_GROUPPERM;
2631                     }
2632                   if (val != 0)
2633                     printf (" %lx", val);
2634                   puts ("");
2635                 }
2636             }
2637           break;
2638
2639         case DT_FLAGS_1:
2640           if (do_dynamic)
2641             {
2642               printf (_("Flags:"));
2643               if (entry->d_un.d_val == 0)
2644                 printf (_(" None\n"));
2645               else
2646                 {
2647                   unsigned long int val = entry->d_un.d_val;
2648                   if (val & DF_1_NOW)
2649                     {
2650                       printf (" NOW");
2651                       val ^= DF_1_NOW;
2652                     }
2653                   if (val & DF_1_GLOBAL)
2654                     {
2655                       printf (" GLOBAL");
2656                       val ^= DF_1_GLOBAL;
2657                     }
2658                   if (val & DF_1_GROUP)
2659                     {
2660                       printf (" GROUP");
2661                       val ^= DF_1_GROUP;
2662                     }
2663                   if (val & DF_1_NODELETE)
2664                     {
2665                       printf (" NODELETE");
2666                       val ^= DF_1_NODELETE;
2667                     }
2668                   if (val & DF_1_LOADFLTR)
2669                     {
2670                       printf (" LOADFLTR");
2671                       val ^= DF_1_LOADFLTR;
2672                     }
2673                   if (val & DF_1_INITFIRST)
2674                     {
2675                       printf (" INITFIRST");
2676                       val ^= DF_1_INITFIRST;
2677                     }
2678                   if (val & DF_1_NOOPEN)
2679                     {
2680                       printf (" NOOPEN");
2681                       val ^= DF_1_NOOPEN;
2682                     }
2683                   if (val & DF_1_ORIGIN)
2684                     {
2685                       printf (" ORIGIN");
2686                       val ^= DF_1_ORIGIN;
2687                     }
2688                   if (val & DF_1_DIRECT)
2689                     {
2690                       printf (" DIRECT");
2691                       val ^= DF_1_DIRECT;
2692                     }
2693                   if (val & DF_1_TRANS)
2694                     {
2695                       printf (" TRANS");
2696                       val ^= DF_1_TRANS;
2697                     }
2698                   if (val & DF_1_INTERPOSE)
2699                     {
2700                       printf (" INTERPOSE");
2701                       val ^= DF_1_INTERPOSE;
2702                     }
2703                   if (val != 0)
2704                     printf (" %lx", val);
2705                   puts ("");
2706                 }
2707             }
2708           break;
2709
2710         case DT_PLTREL:
2711           if (do_dynamic)
2712             puts (get_dynamic_type (entry->d_un.d_val));
2713           break;
2714
2715         case DT_NULL    :
2716         case DT_NEEDED  :
2717         case DT_PLTGOT  :
2718         case DT_HASH    :
2719         case DT_STRTAB  :
2720         case DT_SYMTAB  :
2721         case DT_RELA    :
2722         case DT_INIT    :
2723         case DT_FINI    :
2724         case DT_SONAME  :
2725         case DT_RPATH   :
2726         case DT_SYMBOLIC:
2727         case DT_REL     :
2728         case DT_DEBUG   :
2729         case DT_TEXTREL :
2730         case DT_JMPREL  :
2731           dynamic_info[entry->d_tag] = entry->d_un.d_val;
2732
2733           if (do_dynamic)
2734             {
2735               char * name;
2736
2737               if (dynamic_strings == NULL)
2738                 name = NULL;
2739               else
2740                 name = dynamic_strings + entry->d_un.d_val;
2741
2742               if (name)
2743                 {
2744                   switch (entry->d_tag)
2745                     {
2746                     case DT_NEEDED:
2747                       printf (_("Shared library: [%s]"), name);
2748
2749                       if (strcmp (name, program_interpreter))
2750                         printf ("\n");
2751                       else
2752                         printf (_(" program interpreter\n"));
2753                       break;
2754
2755                     case DT_SONAME:
2756                       printf (_("Library soname: [%s]\n"), name);
2757                       break;
2758
2759                     case DT_RPATH:
2760                       printf (_("Library rpath: [%s]\n"), name);
2761                       break;
2762
2763                     default:
2764                       printf ("%#lx\n", (long) entry->d_un.d_val);
2765                     }
2766                 }
2767               else
2768                 printf ("%#lx\n", (long) entry->d_un.d_val);
2769             }
2770           break;
2771
2772         case DT_PLTRELSZ:
2773         case DT_RELASZ  :
2774         case DT_STRSZ   :
2775         case DT_RELSZ   :
2776         case DT_RELAENT :
2777         case DT_SYMENT  :
2778         case DT_RELENT  :
2779         case DT_PLTPADSZ:
2780         case DT_MOVEENT :
2781         case DT_MOVESZ  :
2782         case DT_INIT_ARRAYSZ:
2783         case DT_FINI_ARRAYSZ:
2784           if (do_dynamic)
2785             printf ("%lu (bytes)\n", (unsigned long) entry->d_un.d_val);
2786           break;
2787
2788         case DT_VERDEFNUM:
2789         case DT_VERNEEDNUM:
2790         case DT_RELACOUNT:
2791         case DT_RELCOUNT:
2792           if (do_dynamic)
2793             printf ("%lu\n", (unsigned long) entry->d_un.d_val);
2794           break;
2795
2796         case DT_SYMINSZ:
2797         case DT_SYMINENT:
2798         case DT_SYMINFO:
2799         case DT_USED:
2800         case DT_INIT_ARRAY:
2801         case DT_FINI_ARRAY:
2802           if (do_dynamic)
2803             {
2804               if (dynamic_strings != NULL && entry->d_tag == DT_USED)
2805                 {
2806                   char * name;
2807
2808                   name = dynamic_strings + entry->d_un.d_val;
2809
2810                   if (* name)
2811                     {
2812                       printf (_("Not needed object: [%s]\n"), name);
2813                       break;
2814                     }
2815                 }
2816               
2817               printf ("%#lx\n", (long) entry->d_un.d_val);
2818             }
2819           break;
2820
2821         case DT_BIND_NOW:
2822           /* The value of this entry is ignored.  */
2823           break;
2824           
2825         default:
2826           if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
2827             version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
2828               entry->d_un.d_val;
2829
2830           if (do_dynamic)
2831             {
2832               switch (elf_header.e_machine)
2833                 {
2834                 case EM_MIPS:
2835                 case EM_MIPS_RS4_BE:
2836                   dynamic_segment_mips_val (entry);
2837                   break;
2838                 default:
2839                   printf ("%#lx\n", (long) entry->d_un.d_ptr);
2840                 }
2841             }
2842           break;
2843         }
2844     }
2845
2846   return 1;
2847 }
2848
2849 static char *
2850 get_ver_flags (flags)
2851      unsigned int flags;
2852 {
2853   static char buff [32];
2854
2855   buff[0] = 0;
2856
2857   if (flags == 0)
2858     return _("none");
2859
2860   if (flags & VER_FLG_BASE)
2861     strcat (buff, "BASE ");
2862
2863   if (flags & VER_FLG_WEAK)
2864     {
2865       if (flags & VER_FLG_BASE)
2866         strcat (buff, "| ");
2867
2868       strcat (buff, "WEAK ");
2869     }
2870
2871   if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
2872     strcat (buff, "| <unknown>");
2873
2874   return buff;
2875 }
2876
2877 /* Display the contents of the version sections.  */
2878 static int
2879 process_version_sections (file)
2880      FILE * file;
2881 {
2882   Elf32_Internal_Shdr * section;
2883   unsigned   i;
2884   int        found = 0;
2885
2886   if (! do_version)
2887     return 1;
2888
2889   for (i = 0, section = section_headers;
2890        i < elf_header.e_shnum;
2891        i++, section ++)
2892     {
2893       switch (section->sh_type)
2894         {
2895         case SHT_GNU_verdef:
2896           {
2897             Elf_External_Verdef * edefs;
2898             unsigned int          idx;
2899             unsigned int          cnt;
2900
2901             found = 1;
2902
2903             printf
2904               (_("\nVersion definition section '%s' contains %ld entries:\n"),
2905                SECTION_NAME (section), section->sh_info);
2906
2907             printf (_("  Addr: 0x"));
2908             printf_vma (section->sh_addr);
2909             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
2910                     (unsigned long) section->sh_offset, section->sh_link,
2911                     SECTION_NAME (section_headers + section->sh_link));
2912
2913             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
2914                             edefs, Elf_External_Verdef *,
2915                             "version definition section");
2916
2917             for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
2918               {
2919                 char *                 vstart;
2920                 Elf_External_Verdef *  edef;
2921                 Elf_Internal_Verdef    ent;
2922                 Elf_External_Verdaux * eaux;
2923                 Elf_Internal_Verdaux   aux;
2924                 int                    j;
2925                 int                    isum;
2926                 
2927                 vstart = ((char *) edefs) + idx;
2928
2929                 edef = (Elf_External_Verdef *) vstart;
2930
2931                 ent.vd_version = BYTE_GET (edef->vd_version);
2932                 ent.vd_flags   = BYTE_GET (edef->vd_flags);
2933                 ent.vd_ndx     = BYTE_GET (edef->vd_ndx);
2934                 ent.vd_cnt     = BYTE_GET (edef->vd_cnt);
2935                 ent.vd_hash    = BYTE_GET (edef->vd_hash);
2936                 ent.vd_aux     = BYTE_GET (edef->vd_aux);
2937                 ent.vd_next    = BYTE_GET (edef->vd_next);
2938
2939                 printf (_("  %#06x: Rev: %d  Flags: %s"),
2940                         idx, ent.vd_version, get_ver_flags (ent.vd_flags));
2941
2942                 printf (_("  Index: %d  Cnt: %d  "),
2943                         ent.vd_ndx, ent.vd_cnt);
2944
2945                 vstart += ent.vd_aux;
2946
2947                 eaux = (Elf_External_Verdaux *) vstart;
2948
2949                 aux.vda_name = BYTE_GET (eaux->vda_name);
2950                 aux.vda_next = BYTE_GET (eaux->vda_next);
2951
2952                 if (dynamic_strings)
2953                   printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
2954                 else
2955                   printf (_("Name index: %ld\n"), aux.vda_name);
2956
2957                 isum = idx + ent.vd_aux;
2958
2959                 for (j = 1; j < ent.vd_cnt; j ++)
2960                   {
2961                     isum   += aux.vda_next;
2962                     vstart += aux.vda_next;
2963
2964                     eaux = (Elf_External_Verdaux *) vstart;
2965
2966                     aux.vda_name = BYTE_GET (eaux->vda_name);
2967                     aux.vda_next = BYTE_GET (eaux->vda_next);
2968
2969                     if (dynamic_strings)
2970                       printf (_("  %#06x: Parent %d: %s\n"),
2971                               isum, j, dynamic_strings + aux.vda_name);
2972                     else
2973                       printf (_("  %#06x: Parent %d, name index: %ld\n"),
2974                               isum, j, aux.vda_name);
2975                   }
2976
2977                 idx += ent.vd_next;
2978               }
2979
2980             free (edefs);
2981           }
2982           break;
2983           
2984         case SHT_GNU_verneed:
2985           {
2986             Elf_External_Verneed *  eneed;
2987             unsigned int            idx;
2988             unsigned int            cnt;
2989
2990             found = 1;
2991
2992             printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
2993                     SECTION_NAME (section), section->sh_info);
2994
2995             printf (_(" Addr: 0x"));
2996             printf_vma (section->sh_addr);
2997             printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
2998                     (unsigned long) section->sh_offset, section->sh_link,
2999                     SECTION_NAME (section_headers + section->sh_link));
3000
3001             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3002                             eneed, Elf_External_Verneed *,
3003                             "version need section");
3004
3005             for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
3006               {
3007                 Elf_External_Verneed * entry;
3008                 Elf_Internal_Verneed     ent;
3009                 int                      j;
3010                 int                      isum;
3011                 char *                   vstart;
3012
3013                 vstart = ((char *) eneed) + idx;
3014
3015                 entry = (Elf_External_Verneed *) vstart;
3016
3017                 ent.vn_version = BYTE_GET (entry->vn_version);
3018                 ent.vn_cnt     = BYTE_GET (entry->vn_cnt);
3019                 ent.vn_file    = BYTE_GET (entry->vn_file);
3020                 ent.vn_aux     = BYTE_GET (entry->vn_aux);
3021                 ent.vn_next    = BYTE_GET (entry->vn_next);
3022
3023                 printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
3024
3025                 if (dynamic_strings)
3026                   printf (_("  File: %s"), dynamic_strings + ent.vn_file);
3027                 else
3028                   printf (_("  File: %lx"), ent.vn_file);
3029
3030                 printf (_("  Cnt: %d\n"), ent.vn_cnt);
3031
3032                 vstart += ent.vn_aux;
3033
3034                 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
3035                   {
3036                     Elf_External_Vernaux * eaux;
3037                     Elf_Internal_Vernaux   aux;
3038
3039                     eaux = (Elf_External_Vernaux *) vstart;
3040
3041                     aux.vna_hash  = BYTE_GET (eaux->vna_hash);
3042                     aux.vna_flags = BYTE_GET (eaux->vna_flags);
3043                     aux.vna_other = BYTE_GET (eaux->vna_other);
3044                     aux.vna_name  = BYTE_GET (eaux->vna_name);
3045                     aux.vna_next  = BYTE_GET (eaux->vna_next);
3046
3047                     if (dynamic_strings)
3048                       printf (_("  %#06x: Name: %s"),
3049                               isum, dynamic_strings + aux.vna_name);
3050                     else
3051                       printf (_("  %#06x: Name index: %lx"),
3052                               isum, aux.vna_name);
3053
3054                     printf (_("  Flags: %s  Version: %d\n"),
3055                             get_ver_flags (aux.vna_flags), aux.vna_other);
3056
3057                     isum   += aux.vna_next;
3058                     vstart += aux.vna_next;
3059                   }
3060
3061                 idx += ent.vn_next;
3062               }
3063             
3064             free (eneed);
3065           }
3066           break;
3067
3068         case SHT_GNU_versym:
3069           {
3070             Elf32_Internal_Shdr *       link_section;
3071             int                         total;
3072             int                         cnt;
3073             unsigned char *             edata;
3074             unsigned short *            data;
3075             char *                      strtab;
3076             Elf_Internal_Sym *          symbols;
3077             Elf32_Internal_Shdr *       string_sec;
3078
3079             link_section = section_headers + section->sh_link;
3080             total = section->sh_size / section->sh_entsize;
3081
3082             found = 1;
3083
3084             symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
3085                                        link_section->sh_size / link_section->sh_entsize);
3086
3087             string_sec = section_headers + link_section->sh_link;
3088
3089             GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3090                             strtab, char *, "version string table");
3091
3092             printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
3093                     SECTION_NAME (section), total);
3094
3095             printf (_(" Addr: "));
3096             printf_vma (section->sh_addr);
3097             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
3098                     (unsigned long) section->sh_offset, section->sh_link,
3099                     SECTION_NAME (link_section));
3100
3101             GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3102                             - loadaddr,
3103                             total * sizeof (short), edata,
3104                             unsigned char *, "version symbol data");
3105
3106             data = (unsigned short *) malloc (total * sizeof (short));
3107
3108             for (cnt = total; cnt --;)
3109               data [cnt] = byte_get (edata + cnt * sizeof (short),
3110                                      sizeof (short));
3111
3112             free (edata);
3113
3114             for (cnt = 0; cnt < total; cnt += 4)
3115               {
3116                 int j, nn;
3117
3118                 printf ("  %03x:", cnt);
3119
3120                 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
3121                   switch (data [cnt + j])
3122                     {
3123                     case 0:
3124                       fputs (_("   0 (*local*)    "), stdout);
3125                       break;
3126
3127                     case 1:
3128                       fputs (_("   1 (*global*)   "), stdout);
3129                       break;
3130
3131                     default:
3132                       nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
3133                                    data [cnt + j] & 0x8000 ? 'h' : ' ');
3134
3135                       if (symbols [cnt + j].st_shndx < SHN_LORESERVE
3136                           && section_headers[symbols [cnt + j].st_shndx].sh_type
3137                           == SHT_NOBITS)
3138                         {
3139                           /* We must test both.  */
3140                           Elf_Internal_Verneed     ivn;
3141                           unsigned long            offset;
3142
3143                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3144                             - loadaddr;
3145
3146                           do
3147                             {
3148                               Elf_External_Verneed   evn;
3149                               Elf_External_Vernaux   evna;
3150                               Elf_Internal_Vernaux     ivna;
3151                               unsigned long            vna_off;
3152
3153                               GET_DATA (offset, evn, "version need");
3154
3155                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
3156                               ivn.vn_next = BYTE_GET (evn.vn_next);
3157
3158                               vna_off = offset + ivn.vn_aux;
3159
3160                               do
3161                                 {
3162                                   GET_DATA (vna_off, evna,
3163                                             "version need aux (1)");
3164
3165                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
3166                                   ivna.vna_other = BYTE_GET (evna.vna_other);
3167
3168                                   vna_off += ivna.vna_next;
3169                                 }
3170                               while (ivna.vna_other != data [cnt + j]
3171                                      && ivna.vna_next != 0);
3172
3173                               if (ivna.vna_other == data [cnt + j])
3174                                 {
3175                                   ivna.vna_name = BYTE_GET (evna.vna_name);
3176
3177                                   nn += printf ("(%s%-*s",
3178                                                 strtab + ivna.vna_name,
3179                                                 12 - strlen (strtab
3180                                                              + ivna.vna_name),
3181                                                 ")");
3182                                   break;
3183                                 }
3184                               else if (ivn.vn_next == 0)
3185                                 {
3186                                   if (data [cnt + j] != 0x8001)
3187                                     {
3188                                       Elf_Internal_Verdef  ivd;
3189                                       Elf_External_Verdef  evd;
3190
3191                                       offset = version_info
3192                                         [DT_VERSIONTAGIDX (DT_VERDEF)]
3193                                         - loadaddr;
3194
3195                                       do
3196                                         {
3197                                           GET_DATA (offset, evd,
3198                                                     "version definition");
3199
3200                                           ivd.vd_next = BYTE_GET (evd.vd_next);
3201                                           ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
3202
3203                                           offset += ivd.vd_next;
3204                                         }
3205                                       while (ivd.vd_ndx
3206                                              != (data [cnt + j] & 0x7fff)
3207                                              && ivd.vd_next != 0);
3208
3209                                       if (ivd.vd_ndx
3210                                           == (data [cnt + j] & 0x7fff))
3211                                         {
3212                                           Elf_External_Verdaux  evda;
3213                                           Elf_Internal_Verdaux  ivda;
3214
3215                                           ivd.vd_aux = BYTE_GET (evd.vd_aux);
3216
3217                                           GET_DATA (offset + ivd.vd_aux, evda,
3218                                                     "version definition aux");
3219
3220                                           ivda.vda_name =
3221                                             BYTE_GET (evda.vda_name);
3222
3223                                           nn +=
3224                                             printf ("(%s%-*s",
3225                                                     strtab + ivda.vda_name,
3226                                                     12
3227                                                     - strlen (strtab
3228                                                               + ivda.vda_name),
3229                                                     ")");
3230                                         }
3231                                     }
3232
3233                                   break;
3234                                 }
3235                               else
3236                                 offset += ivn.vn_next;
3237                             }
3238                           while (ivn.vn_next);
3239                         }
3240                       else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
3241                         {
3242                           Elf_Internal_Verneed     ivn;
3243                           unsigned long            offset;
3244
3245                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
3246                             - loadaddr;
3247
3248                           do
3249                             {
3250                               Elf_Internal_Vernaux     ivna;
3251                               Elf_External_Verneed   evn;
3252                               Elf_External_Vernaux   evna;
3253                               unsigned long            a_off;
3254
3255                               GET_DATA (offset, evn, "version need");
3256
3257                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
3258                               ivn.vn_next = BYTE_GET (evn.vn_next);
3259
3260                               a_off = offset + ivn.vn_aux;
3261
3262                               do
3263                                 {
3264                                   GET_DATA (a_off, evna,
3265                                             "version need aux (2)");
3266
3267                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
3268                                   ivna.vna_other = BYTE_GET (evna.vna_other);
3269
3270                                   a_off += ivna.vna_next;
3271                                 }
3272                               while (ivna.vna_other != data [cnt + j]
3273                                      && ivna.vna_next != 0);
3274
3275                               if (ivna.vna_other == data [cnt + j])
3276                                 {
3277                                   ivna.vna_name = BYTE_GET (evna.vna_name);
3278
3279                                   nn += printf ("(%s%-*s",
3280                                                 strtab + ivna.vna_name,
3281                                                 12 - strlen (strtab
3282                                                              + ivna.vna_name),
3283                                                 ")");
3284                                   break;
3285                                 }
3286
3287                               offset += ivn.vn_next;
3288                             }
3289                           while (ivn.vn_next);
3290                         }
3291                       else if (data [cnt + j] != 0x8001)
3292                         {
3293                           Elf_Internal_Verdef  ivd;
3294                           Elf_External_Verdef  evd;
3295                           unsigned long        offset;
3296
3297                           offset = version_info
3298                             [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
3299
3300                           do
3301                             {
3302                               GET_DATA (offset, evd, "version def");
3303
3304                               ivd.vd_next = BYTE_GET (evd.vd_next);
3305                               ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
3306
3307                               offset += ivd.vd_next;
3308                             }
3309                           while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
3310                                  && ivd.vd_next != 0);
3311
3312                           if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
3313                             {
3314                               Elf_External_Verdaux  evda;
3315                               Elf_Internal_Verdaux  ivda;
3316
3317                               ivd.vd_aux = BYTE_GET (evd.vd_aux);
3318
3319                               GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
3320                                         evda, "version def aux");
3321
3322                               ivda.vda_name = BYTE_GET (evda.vda_name);
3323
3324                               nn += printf ("(%s%-*s",
3325                                             strtab + ivda.vda_name,
3326                                             12 - strlen (strtab
3327                                                          + ivda.vda_name),
3328                                             ")");
3329                             }
3330                         }
3331
3332                       if (nn < 18)
3333                         printf ("%*c", 18 - nn, ' ');
3334                     }
3335
3336                 putchar ('\n');
3337               }
3338
3339             free (data);
3340             free (strtab);
3341             free (symbols);
3342           }
3343           break;
3344         
3345         default:
3346           break;
3347         }
3348     }
3349
3350   if (! found)
3351     printf (_("\nNo version information found in this file.\n"));
3352
3353   return 1;
3354 }
3355
3356 static char *
3357 get_symbol_binding (binding)
3358      unsigned int binding;
3359 {
3360   static char buff [32];
3361
3362   switch (binding)
3363     {
3364     case STB_LOCAL:  return _("LOCAL");
3365     case STB_GLOBAL: return _("GLOBAL");
3366     case STB_WEAK:   return _("WEAK");
3367     default:
3368       if (binding >= STB_LOPROC && binding <= STB_HIPROC)
3369         sprintf (buff, _("<processor specific>: %d"), binding);
3370       else if (binding >= STB_LOOS && binding <= STB_HIOS)
3371         sprintf (buff, _("<OS specific>: %d"), binding);
3372       else
3373         sprintf (buff, _("<unknown>: %d"), binding);
3374       return buff;
3375     }
3376 }
3377
3378 static char *
3379 get_symbol_type (type)
3380      unsigned int type;
3381 {
3382   static char buff [32];
3383
3384   switch (type)
3385     {
3386     case STT_NOTYPE:   return _("NOTYPE");
3387     case STT_OBJECT:   return _("OBJECT");
3388     case STT_FUNC:     return _("FUNC");
3389     case STT_SECTION:  return _("SECTION");
3390     case STT_FILE:     return _("FILE");
3391     default:
3392       if (type >= STT_LOPROC && type <= STT_HIPROC)
3393         {
3394           if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3395             return _("THUMB_FUNC");
3396           
3397           sprintf (buff, _("<processor specific>: %d"), type);
3398         }
3399       else if (type >= STT_LOOS && type <= STT_HIOS)
3400         sprintf (buff, _("<OS specific>: %d"), type);
3401       else
3402         sprintf (buff, _("<unknown>: %d"), type);
3403       return buff;
3404     }
3405 }
3406
3407 static char *
3408 get_symbol_index_type (type)
3409      unsigned int type;
3410 {
3411   switch (type)
3412     {
3413     case SHN_UNDEF:  return "UND";
3414     case SHN_ABS:    return "ABS";
3415     case SHN_COMMON: return "COM";
3416     default:
3417       if (type >= SHN_LOPROC && type <= SHN_HIPROC)
3418         return "PRC";
3419       else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
3420         return "RSV";
3421       else if (type >= SHN_LOOS && type <= SHN_HIOS)
3422         return "OS ";
3423       else
3424         {
3425           static char buff [32];
3426
3427           sprintf (buff, "%3d", type);
3428           return buff;
3429         }
3430     }
3431 }
3432
3433
3434 static int *
3435 get_dynamic_data (file, number)
3436      FILE *       file;
3437      unsigned int number;
3438 {
3439   char * e_data;
3440   int *  i_data;
3441
3442   e_data = (char *) malloc (number * 4);
3443
3444   if (e_data == NULL)
3445     {
3446       error (_("Out of memory\n"));
3447       return NULL;
3448     }
3449
3450   if (fread (e_data, 4, number, file) != number)
3451     {
3452       error (_("Unable to read in dynamic data\n"));
3453       return NULL;
3454     }
3455
3456   i_data = (int *) malloc (number * sizeof (* i_data));
3457
3458   if (i_data == NULL)
3459     {
3460       error (_("Out of memory\n"));
3461       free (e_data);
3462       return NULL;
3463     }
3464
3465   while (number--)
3466     i_data [number] = byte_get (e_data + number * 4, 4);
3467
3468   free (e_data);
3469
3470   return i_data;
3471 }
3472
3473 /* Dump the symbol table */
3474 static int
3475 process_symbol_table (file)
3476      FILE * file;
3477 {
3478   Elf32_Internal_Shdr *   section;
3479   char   nb [4];
3480   char   nc [4];
3481   int    nbuckets;
3482   int    nchains;
3483   int *  buckets = NULL;
3484   int *  chains = NULL;
3485
3486   if (! do_syms && !do_histogram)
3487     return 1;
3488
3489   if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
3490                                 || do_histogram))
3491     {
3492       if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
3493         {
3494           error (_("Unable to seek to start of dynamic information"));
3495           return 0;
3496         }
3497
3498       if (fread (nb, sizeof (nb), 1, file) != 1)
3499         {
3500           error (_("Failed to read in number of buckets\n"));
3501           return 0;
3502         }
3503
3504       if (fread (nc, sizeof (nc), 1, file) != 1)
3505         {
3506           error (_("Failed to read in number of chains\n"));
3507           return 0;
3508         }
3509
3510       nbuckets = byte_get (nb, 4);
3511       nchains  = byte_get (nc, 4);
3512
3513       buckets = get_dynamic_data (file, nbuckets);
3514       chains  = get_dynamic_data (file, nchains);
3515
3516       if (buckets == NULL || chains == NULL)
3517         return 0;
3518     }
3519
3520   if (do_syms
3521       && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
3522     {
3523       int    hn;
3524       int    si;
3525
3526       printf (_("\nSymbol table for image:\n"));
3527       printf (_("  Num Buc:    Value  Size   Type   Bind Ot Ndx Name\n"));
3528
3529       for (hn = 0; hn < nbuckets; hn++)
3530         {
3531           if (! buckets [hn])
3532             continue;
3533
3534           for (si = buckets [hn]; si; si = chains [si])
3535             {
3536               Elf_Internal_Sym * psym;
3537
3538               psym = dynamic_symbols + si;
3539
3540               printf ("  %3d %3d: %8lx %5ld %6s %6s %2d ",
3541                       si, hn,
3542                       (unsigned long) psym->st_value,
3543                       (unsigned long) psym->st_size,
3544                       get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3545                       get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3546                       psym->st_other);
3547
3548               printf ("%3.3s", get_symbol_index_type (psym->st_shndx));
3549
3550               printf (" %s\n", dynamic_strings + psym->st_name);
3551             }
3552         }
3553     }
3554   else if (do_syms && !do_using_dynamic)
3555     {
3556       unsigned int     i;
3557
3558       for (i = 0, section = section_headers;
3559            i < elf_header.e_shnum;
3560            i++, section++)
3561         {
3562           unsigned int          si;
3563           char *                strtab;
3564           Elf_Internal_Sym *    symtab;
3565           Elf_Internal_Sym *    psym;
3566
3567
3568           if (   section->sh_type != SHT_SYMTAB
3569               && section->sh_type != SHT_DYNSYM)
3570             continue;
3571
3572           printf (_("\nSymbol table '%s' contains %lu entries:\n"),
3573                   SECTION_NAME (section),
3574                   (unsigned long) (section->sh_size / section->sh_entsize));
3575           fputs (_("  Num:    Value  Size Type    Bind   Ot  Ndx Name\n"),
3576                  stdout);
3577
3578           symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
3579                                     section->sh_size / section->sh_entsize);
3580           if (symtab == NULL)
3581             continue;
3582
3583           if (section->sh_link == elf_header.e_shstrndx)
3584             strtab = string_table;
3585           else
3586             {
3587               Elf32_Internal_Shdr * string_sec;
3588
3589               string_sec = section_headers + section->sh_link;
3590
3591               GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3592                               strtab, char *, "string table");
3593             }
3594
3595           for (si = 0, psym = symtab;
3596                si < section->sh_size / section->sh_entsize;
3597                si ++, psym ++)
3598             {
3599               printf ("  %3d: %8lx %5ld %-7s %-6s %2d ",
3600                       si,
3601                       (unsigned long) psym->st_value,
3602                       (unsigned long) psym->st_size,
3603                       get_symbol_type (ELF_ST_TYPE (psym->st_info)),
3604                       get_symbol_binding (ELF_ST_BIND (psym->st_info)),
3605                       psym->st_other);
3606
3607               printf ("%4s", get_symbol_index_type (psym->st_shndx));
3608
3609               printf (" %s", strtab + psym->st_name);
3610
3611               if (section->sh_type == SHT_DYNSYM &&
3612                   version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
3613                 {
3614                   unsigned char   data[2];
3615                   unsigned short  vers_data;
3616                   unsigned long   offset;
3617                   int             is_nobits;
3618                   int             check_def;
3619
3620                   offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3621                     - loadaddr;
3622
3623                   GET_DATA (offset + si * sizeof (vers_data), data,
3624                             "version data");
3625
3626                   vers_data = byte_get (data, 2);
3627
3628                   is_nobits = psym->st_shndx < SHN_LORESERVE ?
3629                     (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
3630                     : 0;
3631
3632                   check_def = (psym->st_shndx != SHN_UNDEF);
3633
3634                   if ((vers_data & 0x8000) || vers_data > 1)
3635                     {
3636                       if (is_nobits || ! check_def)
3637                         {
3638                           Elf_External_Verneed  evn;
3639                           Elf_Internal_Verneed  ivn;
3640                           Elf_Internal_Vernaux  ivna;
3641
3642                           /* We must test both.  */
3643                           offset = version_info
3644                             [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
3645
3646                           GET_DATA (offset, evn, "version need");
3647
3648                           ivn.vn_aux  = BYTE_GET (evn.vn_aux);
3649                           ivn.vn_next = BYTE_GET (evn.vn_next);
3650
3651                           do
3652                             {
3653                               unsigned long  vna_off;
3654
3655                               vna_off = offset + ivn.vn_aux;
3656
3657                               do
3658                                 {
3659                                   Elf_External_Vernaux  evna;
3660
3661                                   GET_DATA (vna_off, evna,
3662                                             "version need aux (3)");
3663
3664                                   ivna.vna_other = BYTE_GET (evna.vna_other);
3665                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
3666                                   ivna.vna_name  = BYTE_GET (evna.vna_name);
3667
3668                                   vna_off += ivna.vna_next;
3669                                 }
3670                               while (ivna.vna_other != vers_data
3671                                      && ivna.vna_next != 0);
3672
3673                               if (ivna.vna_other == vers_data)
3674                                 break;
3675
3676                               offset += ivn.vn_next;
3677                             }
3678                           while (ivn.vn_next != 0);
3679
3680                           if (ivna.vna_other == vers_data)
3681                             {
3682                               printf ("@%s (%d)",
3683                                       strtab + ivna.vna_name, ivna.vna_other);
3684                               check_def = 0;
3685                             }
3686                           else if (! is_nobits)
3687                             error (_("bad dynamic symbol"));
3688                           else
3689                             check_def = 1;
3690                         }
3691
3692                       if (check_def)
3693                         {
3694                           if (vers_data != 0x8001)
3695                             {
3696                               Elf_Internal_Verdef     ivd;
3697                               Elf_Internal_Verdaux    ivda;
3698                               Elf_External_Verdaux  evda;
3699                               unsigned long           offset;
3700
3701                               offset =
3702                                 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
3703                                 - loadaddr;
3704
3705                               do
3706                                 {
3707                                   Elf_External_Verdef   evd;
3708
3709                                   GET_DATA (offset, evd, "version def");
3710
3711                                   ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
3712                                   ivd.vd_aux  = BYTE_GET (evd.vd_aux);
3713                                   ivd.vd_next = BYTE_GET (evd.vd_next);
3714
3715                                   offset += ivd.vd_next;
3716                                 }
3717                               while (ivd.vd_ndx != (vers_data & 0x7fff)
3718                                      && ivd.vd_next != 0);
3719
3720                               offset -= ivd.vd_next;
3721                               offset += ivd.vd_aux;
3722
3723                               GET_DATA (offset, evda, "version def aux");
3724
3725                               ivda.vda_name = BYTE_GET (evda.vda_name);
3726
3727                               if (psym->st_name != ivda.vda_name)
3728                                 printf ((vers_data & 0x8000)
3729                                         ? "@%s" : "@@%s",
3730                                         strtab + ivda.vda_name);
3731                             }
3732                         }
3733                     }
3734                 }
3735
3736               putchar ('\n');
3737             }
3738
3739           free (symtab);
3740           if (strtab != string_table)
3741             free (strtab);
3742         }
3743     }
3744   else if (do_syms)
3745     printf
3746       (_("\nDynamic symbol information is not available for displaying symbols.\n"));
3747
3748   if (do_histogram && buckets != NULL)
3749     {
3750       int *lengths;
3751       int *counts;
3752       int hn;
3753       int si;
3754       int maxlength = 0;
3755       int nzero_counts = 0;
3756       int nsyms = 0;
3757
3758       printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
3759               nbuckets);
3760       printf (_(" Length  Number     %% of total  Coverage\n"));
3761
3762       lengths = (int *) calloc (nbuckets, sizeof (int));
3763       if (lengths == NULL)
3764         {
3765           error (_("Out of memory"));
3766           return 0;
3767         }
3768       for (hn = 0; hn < nbuckets; ++hn)
3769         {
3770           if (! buckets [hn])
3771             continue;
3772
3773           for (si = buckets[hn]; si; si = chains[si])
3774             {
3775               ++nsyms;
3776               if (maxlength < ++lengths[hn])
3777                 ++maxlength;
3778             }
3779         }
3780
3781       counts = (int *) calloc (maxlength + 1, sizeof (int));
3782       if (counts == NULL)
3783         {
3784           error (_("Out of memory"));
3785           return 0;
3786         }
3787
3788       for (hn = 0; hn < nbuckets; ++hn)
3789         ++ counts [lengths [hn]];
3790
3791       printf ("      0  %-10d (%5.1f%%)\n",
3792               counts[0], (counts[0] * 100.0) / nbuckets);
3793       for (si = 1; si <= maxlength; ++si)
3794         {
3795           nzero_counts += counts[si] * si;
3796           printf ("%7d  %-10d (%5.1f%%)    %5.1f%%\n",
3797                   si, counts[si], (counts[si] * 100.0) / nbuckets,
3798                   (nzero_counts * 100.0) / nsyms);
3799         }
3800
3801       free (counts);
3802       free (lengths);
3803     }
3804
3805   if (buckets != NULL)
3806     {
3807       free (buckets);
3808       free (chains);
3809     }
3810
3811   return 1;
3812 }
3813
3814 static int
3815 process_syminfo (file)
3816      FILE * file;
3817 {
3818   int i;
3819
3820   if (dynamic_syminfo == NULL
3821       || !do_dynamic)
3822     /* No syminfo, this is ok.  */
3823     return 1;
3824
3825   /* There better should be a dynamic symbol section.  */
3826   if (dynamic_symbols == NULL || dynamic_strings == NULL)
3827     return 0;
3828
3829   if (dynamic_addr)
3830     printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
3831             dynamic_syminfo_offset, dynamic_syminfo_nent);
3832
3833   printf (_(" Num: Name                           BoundTo     Flags\n"));
3834   for (i = 0; i < dynamic_syminfo_nent; ++i)
3835     {
3836       unsigned short int flags = dynamic_syminfo[i].si_flags;
3837
3838       printf ("%4d: %-30s ", i,
3839               dynamic_strings + dynamic_symbols[i].st_name);
3840
3841       switch (dynamic_syminfo[i].si_boundto)
3842         {
3843         case SYMINFO_BT_SELF:
3844           fputs ("SELF       ", stdout);
3845           break;
3846         case SYMINFO_BT_PARENT:
3847           fputs ("PARENT     ", stdout);
3848           break;
3849         default:
3850           if (dynamic_syminfo[i].si_boundto > 0
3851               && dynamic_syminfo[i].si_boundto < dynamic_size)
3852             printf ("%-10s ",
3853                     dynamic_strings
3854                     + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
3855           else
3856             printf ("%-10d ", dynamic_syminfo[i].si_boundto);
3857           break;
3858         }
3859
3860       if (flags & SYMINFO_FLG_DIRECT)
3861         printf (" DIRECT");
3862       if (flags & SYMINFO_FLG_PASSTHRU)
3863         printf (" PASSTHRU");
3864       if (flags & SYMINFO_FLG_COPY)
3865         printf (" COPY");
3866       if (flags & SYMINFO_FLG_LAZYLOAD)
3867         printf (" LAZYLOAD");
3868
3869       puts ("");
3870     }
3871
3872   return 1;
3873 }
3874
3875 #ifdef SUPPORT_DISASSEMBLY
3876 static void
3877 disassemble_section (section, file)
3878      Elf32_Internal_Shdr * section;
3879      FILE * file;
3880 {
3881   printf (_("\nAssembly dump of section %s\n"),
3882           SECTION_NAME (section));
3883
3884   /* XXX -- to be done --- XXX */
3885
3886   return 1;
3887 }
3888 #endif
3889
3890 static int
3891 dump_section (section, file)
3892      Elf32_Internal_Shdr * section;
3893      FILE * file;
3894 {
3895   bfd_size_type   bytes;
3896   bfd_vma         addr;
3897   unsigned char * data;
3898   unsigned char * start;
3899
3900   bytes = section->sh_size;
3901
3902   if (bytes == 0)
3903     {
3904       printf (_("\nSection '%s' has no data to dump.\n"),
3905               SECTION_NAME (section));
3906       return 0;
3907     }
3908   else
3909     printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
3910
3911   addr = section->sh_addr;
3912
3913   GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
3914                   "section data");
3915
3916   data = start;
3917
3918   while (bytes)
3919     {
3920       int j;
3921       int k;
3922       int lbytes;
3923
3924       lbytes = (bytes > 16 ? 16 : bytes);
3925
3926       printf ("  0x%8.8lx ", (unsigned long) addr);
3927
3928       switch (elf_header.e_ident [EI_DATA])
3929         {
3930         default:
3931         case ELFDATA2LSB:
3932           for (j = 15; j >= 0; j --)
3933             {
3934               if (j < lbytes)
3935                 printf ("%2.2x", data [j]);
3936               else
3937                 printf ("  ");
3938
3939               if (!(j & 0x3))
3940                 printf (" ");
3941             }
3942           break;
3943
3944         case ELFDATA2MSB:
3945           for (j = 0; j < 16; j++)
3946             {
3947               if (j < lbytes)
3948                 printf ("%2.2x", data [j]);
3949               else
3950                 printf ("  ");
3951
3952               if ((j & 3) == 3)
3953                 printf (" ");
3954             }
3955           break;
3956         }
3957
3958       for (j = 0; j < lbytes; j++)
3959         {
3960           k = data [j];
3961           if (k >= ' ' && k < 0x80)
3962             printf ("%c", k);
3963           else
3964             printf (".");
3965         }
3966
3967       putchar ('\n');
3968
3969       data  += lbytes;
3970       addr  += lbytes;
3971       bytes -= lbytes;
3972     }
3973
3974   free (start);
3975
3976   return 1;
3977 }
3978
3979
3980 static unsigned long int
3981 read_leb128 (data, length_return, sign)
3982      unsigned char * data;
3983      int *           length_return;
3984      int             sign;
3985 {
3986   unsigned long int result = 0;
3987   unsigned int      num_read = 0;
3988   int               shift = 0;
3989   unsigned char     byte;
3990
3991   do
3992     {
3993       byte = * data ++;
3994       num_read ++;
3995
3996       result |= (byte & 0x7f) << shift;
3997
3998       shift += 7;
3999
4000     }
4001   while (byte & 0x80);
4002
4003   if (length_return != NULL)
4004     * length_return = num_read;
4005
4006   if (sign && (shift < 32) && (byte & 0x40))
4007     result |= -1 << shift;
4008
4009   return result;
4010 }
4011
4012 typedef struct State_Machine_Registers
4013 {
4014   unsigned long address;
4015   unsigned int  file;
4016   unsigned int  line;
4017   unsigned int  column;
4018   int           is_stmt;
4019   int           basic_block;
4020   int           end_sequence;
4021 /* This variable hold the number of the last entry seen
4022    in the File Table.  */
4023   unsigned int  last_file_entry;
4024 } SMR;
4025
4026 static SMR state_machine_regs;
4027
4028 static void
4029 reset_state_machine (is_stmt)
4030      int is_stmt;
4031 {
4032   state_machine_regs.address = 0;
4033   state_machine_regs.file = 1;
4034   state_machine_regs.line = 1;
4035   state_machine_regs.column = 0;
4036   state_machine_regs.is_stmt = is_stmt;
4037   state_machine_regs.basic_block = 0;
4038   state_machine_regs.end_sequence = 0;
4039   state_machine_regs.last_file_entry = 0;
4040 }
4041
4042 /* Handled an extend line op.  Returns true if this is the end
4043    of sequence.  */
4044 static int
4045 process_extended_line_op (data, is_stmt)
4046      unsigned char * data;
4047      int is_stmt;
4048 {
4049   unsigned char   op_code;
4050   int             bytes_read;
4051   unsigned int    len;
4052   unsigned char * name;
4053   unsigned long   adr;
4054   
4055   len = read_leb128 (data, & bytes_read, 0);
4056   data += bytes_read;
4057
4058   if (len == 0)
4059     {
4060       warn (_("badly formed extended line op encountered!"));
4061       return bytes_read;
4062     }
4063
4064   len += bytes_read;
4065   op_code = * data ++;
4066
4067   printf (_("  Extended opcode %d: "), op_code);
4068   
4069   switch (op_code)
4070     {
4071     case DW_LNE_end_sequence:
4072       printf (_("End of Sequence\n\n"));
4073       reset_state_machine (is_stmt);
4074       break;
4075
4076     case DW_LNE_set_address:
4077       /* XXX - assumption here that address size is 4! */
4078       adr = byte_get (data, 4);
4079       printf (_("set Address to 0x%lx\n"), adr);
4080       state_machine_regs.address = adr;
4081       break;
4082
4083     case DW_LNE_define_file:
4084       printf (_("  define new File Table entry\n"));
4085       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
4086          
4087       printf (_("   %d\t"), ++ state_machine_regs.last_file_entry);
4088       name = data;
4089       data += strlen (data) + 1;
4090       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4091       data += bytes_read;
4092       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4093       data += bytes_read;
4094       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4095       printf (_("%s\n\n"), name);
4096       break;
4097
4098     default:
4099       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
4100       break;
4101     }
4102
4103   return len;
4104 }
4105
4106
4107 static int
4108 display_debug_lines (section, start, file)
4109      Elf32_Internal_Shdr * section;
4110      unsigned char *       start;
4111      FILE *                file;
4112 {
4113   DWARF2_External_LineInfo * external;
4114   DWARF2_Internal_LineInfo   info;
4115   unsigned char *            standard_opcodes;
4116   unsigned char *            data = start;
4117   unsigned char *            end  = start + section->sh_size;
4118   unsigned char *            end_of_sequence;
4119   int                        i;
4120
4121   printf (_("\nDump of debug contents of section %s:\n\n"),
4122           SECTION_NAME (section));
4123
4124   while (data < end)
4125     {
4126       external = (DWARF2_External_LineInfo *) data;
4127
4128       /* Check the length of the block.  */
4129       info.li_length = BYTE_GET (external->li_length);
4130       if (info.li_length > section->sh_size)
4131         {
4132           warn
4133             (_("The line info appears to be corrupt - the section is too small\n"));
4134           return 0;
4135         }
4136       
4137       /* Check its version number.  */
4138       info.li_version = BYTE_GET (external->li_version);
4139       if (info.li_version != 2)
4140         {
4141           warn (_("Only DWARF version 2 line info is currently supported.\n"));
4142           return 0;
4143         }
4144       
4145       info.li_prologue_length = BYTE_GET (external->li_prologue_length);
4146       info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
4147       info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
4148       info.li_line_base       = BYTE_GET (external->li_line_base);
4149       info.li_line_range      = BYTE_GET (external->li_line_range);
4150       info.li_opcode_base     = BYTE_GET (external->li_opcode_base);
4151       
4152       /* Sign extend the line base field.  */
4153       info.li_line_base <<= 24;
4154       info.li_line_base >>= 24;
4155       
4156       printf (_("  Length:                      %ld\n"), info.li_length);
4157       printf (_("  DWARF Version:               %d\n"), info.li_version);
4158       printf (_("  Prolgue Length:              %d\n"), info.li_prologue_length);
4159       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
4160       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
4161       printf (_("  Line Base:                   %d\n"), info.li_line_base);
4162       printf (_("  Line Range:                  %d\n"), info.li_line_range);
4163       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
4164
4165       end_of_sequence = data + info.li_length + sizeof (info.li_length);
4166
4167       reset_state_machine (info.li_default_is_stmt);
4168       
4169       /* Display the contents of the Opcodes table.  */
4170       standard_opcodes = data + sizeof (* external);
4171       
4172       printf (_("\n Opcodes:\n"));
4173       
4174       for (i = 1; i < info.li_opcode_base; i++)
4175         printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i]);
4176       
4177       /* Display the contents of the Directory table.  */
4178       data = standard_opcodes + info.li_opcode_base - 1;
4179       
4180       if (* data == 0)
4181         printf (_("\n The Directory Table is empty.\n"));
4182       else
4183         {
4184           printf (_("\n The Directory Table:\n"));
4185           
4186           while (* data != 0)
4187             {
4188               printf (_("  %s\n"), data);
4189               
4190               data += strlen (data) + 1;
4191             }
4192         }
4193       
4194       /* Skip the NUL at the end of the table.  */
4195       data ++;
4196       
4197       /* Display the contents of the File Name table.  */
4198       if (* data == 0)
4199         printf (_("\n The File Name Table is empty.\n"));
4200       else
4201         {
4202           printf (_("\n The File Name Table:\n"));
4203           printf (_("  Entry\tDir\tTime\tSize\tName\n"));
4204           
4205           while (* data != 0)
4206             {
4207               char * name;
4208               int bytes_read;
4209               
4210               printf (_("  %d\t"), ++ state_machine_regs.last_file_entry);
4211               name = data;
4212               
4213               data += strlen (data) + 1;
4214               
4215               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4216               data += bytes_read;
4217               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4218               data += bytes_read;
4219               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4220               data += bytes_read;
4221               printf (_("%s\n"), name);
4222             }
4223         }
4224       
4225       /* Skip the NUL at the end of the table.  */
4226       data ++;
4227       
4228       /* Now display the statements.  */
4229       printf (_("\n Line Number Statements:\n"));
4230       
4231       
4232       while (data < end_of_sequence)
4233         {
4234           unsigned char op_code;
4235           int           adv;
4236           int           bytes_read;
4237           
4238           op_code = * data ++;
4239           
4240           switch (op_code)
4241             {
4242             case DW_LNS_extended_op:
4243               data += process_extended_line_op (data, info.li_default_is_stmt);
4244               break;
4245               
4246             case DW_LNS_copy:
4247               printf (_("  Copy\n"));
4248               break;
4249               
4250             case DW_LNS_advance_pc:
4251               adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
4252               data += bytes_read;
4253               state_machine_regs.address += adv;
4254               printf (_("  Advance PC by %d to %lx\n"), adv,
4255                       state_machine_regs.address);
4256               break;
4257               
4258             case DW_LNS_advance_line:
4259               adv = read_leb128 (data, & bytes_read, 1);
4260               data += bytes_read;
4261               state_machine_regs.line += adv;
4262               printf (_("  Advance Line by %d to %d\n"), adv,
4263                       state_machine_regs.line);
4264               break;
4265               
4266             case DW_LNS_set_file:
4267               adv = read_leb128 (data, & bytes_read, 0);
4268               data += bytes_read;
4269               printf (_("  Set File Name to entry %d in the File Name Table\n"),
4270                       adv);
4271               state_machine_regs.file = adv;
4272               break;
4273               
4274             case DW_LNS_set_column:
4275               adv = read_leb128 (data, & bytes_read, 0);
4276               data += bytes_read;
4277               printf (_("  Set column to %d\n"), adv);
4278               state_machine_regs.column = adv;
4279               break;
4280               
4281             case DW_LNS_negate_stmt:
4282               adv = state_machine_regs.is_stmt;
4283               adv = ! adv;
4284               printf (_("  Set is_stmt to %d\n"), adv);
4285               state_machine_regs.is_stmt = adv;
4286               break;
4287               
4288             case DW_LNS_set_basic_block:
4289               printf (_("  Set basic block\n"));
4290               state_machine_regs.basic_block = 1;
4291               break;
4292               
4293             case DW_LNS_const_add_pc:
4294               adv = (255 - info.li_opcode_base) / info.li_line_range;
4295               state_machine_regs.address += adv;
4296               printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
4297                       state_machine_regs.address);
4298               break;
4299               
4300             case DW_LNS_fixed_advance_pc:
4301               adv = byte_get (data, 2);
4302               data += 2;
4303               state_machine_regs.address += adv;
4304               printf (_("  Advance PC by fixed size amount %d to 0x%lx\n"),
4305                       adv, state_machine_regs.address);
4306               break;
4307               
4308             default:
4309               op_code -= info.li_opcode_base;
4310               adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
4311               state_machine_regs.address += adv;
4312               printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
4313                       op_code, adv, state_machine_regs.address);
4314               adv    += (op_code % info.li_line_range) + info.li_line_base;
4315               state_machine_regs.line += adv;
4316               printf (_(" and Line by %d to %d\n"),
4317                       adv, state_machine_regs.line);
4318               break;
4319             }
4320         }
4321       printf ("\n");
4322     }
4323   
4324   return 1;
4325 }
4326
4327 static int
4328 display_debug_pubnames (section, start, file)
4329      Elf32_Internal_Shdr * section;
4330      unsigned char *       start;
4331      FILE *                file;
4332 {
4333   DWARF2_External_PubNames * external;
4334   DWARF2_Internal_PubNames   pubnames;
4335   unsigned char *            end;
4336
4337   end = start + section->sh_size;
4338
4339   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4340
4341   while (start < end)
4342     {
4343       unsigned char * data;
4344       unsigned long   offset;
4345
4346       external = (DWARF2_External_PubNames *) start;
4347
4348       pubnames.pn_length  = BYTE_GET (external->pn_length);
4349       pubnames.pn_version = BYTE_GET (external->pn_version);
4350       pubnames.pn_offset  = BYTE_GET (external->pn_offset);
4351       pubnames.pn_size    = BYTE_GET (external->pn_size);
4352
4353       data   = start + sizeof (* external);
4354       start += pubnames.pn_length + sizeof (external->pn_length);
4355
4356       if (pubnames.pn_version != 2)
4357         {
4358           warn (_("Only DWARF 2 pubnames are currently supported"));
4359           continue;
4360         }
4361
4362       printf (_("  Length:                              %ld\n"),
4363               pubnames.pn_length);
4364       printf (_("  Version:                             %d\n"),
4365               pubnames.pn_version);
4366       printf (_("  Offset into .debug_info section:     %ld\n"),
4367               pubnames.pn_offset);
4368       printf (_("  Size of area in .debug_info section: %ld\n"),
4369               pubnames.pn_size);
4370
4371       printf (_("\n    Offset\tName\n"));
4372
4373       do
4374         {
4375           offset = byte_get (data, 4);
4376
4377           if (offset != 0)
4378             {
4379               data += 4;
4380               printf ("    %ld\t\t%s\n", offset, data);
4381               data += strlen (data) + 1;
4382             }
4383         }
4384       while (offset != 0);
4385     }
4386
4387   printf ("\n");
4388   return 1;
4389 }
4390
4391 static char *
4392 get_TAG_name (tag)
4393      unsigned long tag;
4394 {
4395   switch (tag)
4396     {
4397     case DW_TAG_padding: return "DW_TAG_padding";
4398     case DW_TAG_array_type: return "DW_TAG_array_type";
4399     case DW_TAG_class_type: return "DW_TAG_class_type";
4400     case DW_TAG_entry_point: return "DW_TAG_entry_point";
4401     case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
4402     case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
4403     case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
4404     case DW_TAG_label: return "DW_TAG_label";
4405     case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
4406     case DW_TAG_member: return "DW_TAG_member";
4407     case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
4408     case DW_TAG_reference_type: return "DW_TAG_reference_type";
4409     case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
4410     case DW_TAG_string_type: return "DW_TAG_string_type";
4411     case DW_TAG_structure_type: return "DW_TAG_structure_type";
4412     case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
4413     case DW_TAG_typedef: return "DW_TAG_typedef";
4414     case DW_TAG_union_type: return "DW_TAG_union_type";
4415     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4416     case DW_TAG_variant: return "DW_TAG_variant";
4417     case DW_TAG_common_block: return "DW_TAG_common_block";
4418     case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
4419     case DW_TAG_inheritance: return "DW_TAG_inheritance";
4420     case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
4421     case DW_TAG_module: return "DW_TAG_module";
4422     case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
4423     case DW_TAG_set_type: return "DW_TAG_set_type";
4424     case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
4425     case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
4426     case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
4427     case DW_TAG_base_type: return "DW_TAG_base_type";
4428     case DW_TAG_catch_block: return "DW_TAG_catch_block";
4429     case DW_TAG_const_type: return "DW_TAG_const_type";
4430     case DW_TAG_constant: return "DW_TAG_constant";
4431     case DW_TAG_enumerator: return "DW_TAG_enumerator";
4432     case DW_TAG_file_type: return "DW_TAG_file_type";
4433     case DW_TAG_friend: return "DW_TAG_friend";
4434     case DW_TAG_namelist: return "DW_TAG_namelist";
4435     case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
4436     case DW_TAG_packed_type: return "DW_TAG_packed_type";
4437     case DW_TAG_subprogram: return "DW_TAG_subprogram";
4438     case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
4439     case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
4440     case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
4441     case DW_TAG_try_block: return "DW_TAG_try_block";
4442     case DW_TAG_variant_part: return "DW_TAG_variant_part";
4443     case DW_TAG_variable: return "DW_TAG_variable";
4444     case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
4445     case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
4446     case DW_TAG_format_label: return "DW_TAG_format_label";
4447     case DW_TAG_function_template: return "DW_TAG_function_template";
4448     case DW_TAG_class_template: return "DW_TAG_class_template";
4449     default:
4450       {
4451         static char buffer [100];
4452
4453         sprintf (buffer, _("Unknown TAG value: %lx"), tag);
4454         return buffer;
4455       }
4456     }
4457 }
4458
4459 static char *
4460 get_AT_name (attribute)
4461      unsigned long attribute;
4462 {
4463   switch (attribute)
4464     {
4465     case DW_AT_sibling: return "DW_AT_sibling";
4466     case DW_AT_location: return "DW_AT_location";
4467     case DW_AT_name: return "DW_AT_name";
4468     case DW_AT_ordering: return "DW_AT_ordering";
4469     case DW_AT_subscr_data: return "DW_AT_subscr_data";
4470     case DW_AT_byte_size: return "DW_AT_byte_size";
4471     case DW_AT_bit_offset: return "DW_AT_bit_offset";
4472     case DW_AT_bit_size: return "DW_AT_bit_size";
4473     case DW_AT_element_list: return "DW_AT_element_list";
4474     case DW_AT_stmt_list: return "DW_AT_stmt_list";
4475     case DW_AT_low_pc: return "DW_AT_low_pc";
4476     case DW_AT_high_pc: return "DW_AT_high_pc";
4477     case DW_AT_language: return "DW_AT_language";
4478     case DW_AT_member: return "DW_AT_member";
4479     case DW_AT_discr: return "DW_AT_discr";
4480     case DW_AT_discr_value: return "DW_AT_discr_value";
4481     case DW_AT_visibility: return "DW_AT_visibility";
4482     case DW_AT_import: return "DW_AT_import";
4483     case DW_AT_string_length: return "DW_AT_string_length";
4484     case DW_AT_common_reference: return "DW_AT_common_reference";
4485     case DW_AT_comp_dir: return "DW_AT_comp_dir";
4486     case DW_AT_const_value: return "DW_AT_const_value";
4487     case DW_AT_containing_type: return "DW_AT_containing_type";
4488     case DW_AT_default_value: return "DW_AT_default_value";
4489     case DW_AT_inline: return "DW_AT_inline";
4490     case DW_AT_is_optional: return "DW_AT_is_optional";
4491     case DW_AT_lower_bound: return "DW_AT_lower_bound";
4492     case DW_AT_producer: return "DW_AT_producer";
4493     case DW_AT_prototyped: return "DW_AT_prototyped";
4494     case DW_AT_return_addr: return "DW_AT_return_addr";
4495     case DW_AT_start_scope: return "DW_AT_start_scope";
4496     case DW_AT_stride_size: return "DW_AT_stride_size";
4497     case DW_AT_upper_bound: return "DW_AT_upper_bound";
4498     case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
4499     case DW_AT_accessibility: return "DW_AT_accessibility";
4500     case DW_AT_address_class: return "DW_AT_address_class";
4501     case DW_AT_artificial: return "DW_AT_artificial";
4502     case DW_AT_base_types: return "DW_AT_base_types";
4503     case DW_AT_calling_convention: return "DW_AT_calling_convention";
4504     case DW_AT_count: return "DW_AT_count";
4505     case DW_AT_data_member_location: return "DW_AT_data_member_location";
4506     case DW_AT_decl_column: return "DW_AT_decl_column";
4507     case DW_AT_decl_file: return "DW_AT_decl_file";
4508     case DW_AT_decl_line: return "DW_AT_decl_line";
4509     case DW_AT_declaration: return "DW_AT_declaration";
4510     case DW_AT_discr_list: return "DW_AT_discr_list";
4511     case DW_AT_encoding: return "DW_AT_encoding";
4512     case DW_AT_external: return "DW_AT_external";
4513     case DW_AT_frame_base: return "DW_AT_frame_base";
4514     case DW_AT_friend: return "DW_AT_friend";
4515     case DW_AT_identifier_case: return "DW_AT_identifier_case";
4516     case DW_AT_macro_info: return "DW_AT_macro_info";
4517     case DW_AT_namelist_items: return "DW_AT_namelist_items";
4518     case DW_AT_priority: return "DW_AT_priority";
4519     case DW_AT_segment: return "DW_AT_segment";
4520     case DW_AT_specification: return "DW_AT_specification";
4521     case DW_AT_static_link: return "DW_AT_static_link";
4522     case DW_AT_type: return "DW_AT_type";
4523     case DW_AT_use_location: return "DW_AT_use_location";
4524     case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
4525     case DW_AT_virtuality: return "DW_AT_virtuality";
4526     case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
4527     case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
4528     case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
4529     case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
4530     case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
4531     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
4532     case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
4533     case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
4534     case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
4535     case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
4536     case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
4537     case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
4538     case DW_AT_sf_names: return "DW_AT_sf_names";
4539     case DW_AT_src_info: return "DW_AT_src_info";
4540     case DW_AT_mac_info: return "DW_AT_mac_info";
4541     case DW_AT_src_coords: return "DW_AT_src_coords";
4542     case DW_AT_body_begin: return "DW_AT_body_begin";
4543     case DW_AT_body_end: return "DW_AT_body_end";
4544     default:
4545       {
4546         static char buffer [100];
4547
4548         sprintf (buffer, _("Unknown AT value: %lx"), attribute);
4549         return buffer;
4550       }
4551     }
4552 }
4553
4554 static char *
4555 get_FORM_name (form)
4556      unsigned long form;
4557 {
4558   switch (form)
4559     {
4560     case DW_FORM_addr: return "DW_FORM_addr";
4561     case DW_FORM_block2: return "DW_FORM_block2";
4562     case DW_FORM_block4: return "DW_FORM_block4";
4563     case DW_FORM_data2: return "DW_FORM_data2";
4564     case DW_FORM_data4: return "DW_FORM_data4";
4565     case DW_FORM_data8: return "DW_FORM_data8";
4566     case DW_FORM_string: return "DW_FORM_string";
4567     case DW_FORM_block: return "DW_FORM_block";
4568     case DW_FORM_block1: return "DW_FORM_block1";
4569     case DW_FORM_data1: return "DW_FORM_data1";
4570     case DW_FORM_flag: return "DW_FORM_flag";
4571     case DW_FORM_sdata: return "DW_FORM_sdata";
4572     case DW_FORM_strp: return "DW_FORM_strp";
4573     case DW_FORM_udata: return "DW_FORM_udata";
4574     case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
4575     case DW_FORM_ref1: return "DW_FORM_ref1";
4576     case DW_FORM_ref2: return "DW_FORM_ref2";
4577     case DW_FORM_ref4: return "DW_FORM_ref4";
4578     case DW_FORM_ref8: return "DW_FORM_ref8";
4579     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
4580     case DW_FORM_indirect: return "DW_FORM_indirect";
4581     default:
4582       {
4583         static char buffer [100];
4584
4585         sprintf (buffer, _("Unknown FORM value: %lx"), form);
4586         return buffer;
4587       }
4588     }
4589 }
4590
4591 /* FIXME:  There are better and more effiecint ways to handle
4592    these structures.  For now though, I just want something that
4593    is simple to implement.  */
4594 typedef struct abbrev_attr
4595 {
4596   unsigned long        attribute;
4597   unsigned long        form;
4598   struct abbrev_attr * next;
4599 }
4600 abbrev_attr;
4601
4602 typedef struct abbrev_entry
4603 {
4604   unsigned long          entry;
4605   unsigned long          tag;
4606   int                    children;
4607   struct abbrev_attr *   first_attr;
4608   struct abbrev_attr *   last_attr;
4609   struct abbrev_entry *  next;
4610 }
4611 abbrev_entry;
4612
4613 static abbrev_entry * first_abbrev = NULL;
4614 static abbrev_entry * last_abbrev = NULL;
4615
4616 static void
4617 free_abbrevs PARAMS ((void))
4618 {
4619   abbrev_entry * abbrev;
4620
4621   for (abbrev = first_abbrev; abbrev;)
4622     {
4623       abbrev_entry * next = abbrev->next;
4624       abbrev_attr  * attr;
4625
4626       for (attr = abbrev->first_attr; attr;)
4627         {
4628           abbrev_attr * next = attr->next;
4629
4630           free (attr);
4631           attr = next;
4632         }
4633
4634       free (abbrev);
4635       abbrev = next;
4636     }
4637
4638   last_abbrev = first_abbrev = NULL;
4639 }
4640
4641 static void
4642 add_abbrev (number, tag, children)
4643      unsigned long number;
4644      unsigned long tag;
4645      int           children;
4646 {
4647   abbrev_entry * entry;
4648
4649   entry = (abbrev_entry *) malloc (sizeof (* entry));
4650
4651   if (entry == NULL)
4652     /* ugg */
4653     return;
4654
4655   entry->entry      = number;
4656   entry->tag        = tag;
4657   entry->children   = children;
4658   entry->first_attr = NULL;
4659   entry->last_attr  = NULL;
4660   entry->next       = NULL;
4661
4662   if (first_abbrev == NULL)
4663     first_abbrev = entry;
4664   else
4665     last_abbrev->next = entry;
4666
4667   last_abbrev = entry;
4668 }
4669
4670 static void
4671 add_abbrev_attr (attribute, form)
4672      unsigned long attribute;
4673      unsigned long form;
4674 {
4675   abbrev_attr * attr;
4676
4677   attr = (abbrev_attr *) malloc (sizeof (* attr));
4678
4679   if (attr == NULL)
4680     /* ugg */
4681     return;
4682
4683   attr->attribute = attribute;
4684   attr->form      = form;
4685   attr->next      = NULL;
4686
4687   if (last_abbrev->first_attr == NULL)
4688     last_abbrev->first_attr = attr;
4689   else
4690     last_abbrev->last_attr->next = attr;
4691
4692   last_abbrev->last_attr = attr;
4693 }
4694
4695 /* Processes the (partial) contents of a .debug_abbrev section.
4696    Returns NULL if the end of the section was encountered.
4697    Returns the address after the last byte read if the end of
4698    an abbreviation set was found.  */
4699
4700 static unsigned char *
4701 process_abbrev_section (start, end)
4702      unsigned char * start;
4703      unsigned char * end;
4704 {
4705   if (first_abbrev != NULL)
4706     return NULL;
4707
4708   while (start < end)
4709     {
4710       int           bytes_read;
4711       unsigned long entry;
4712       unsigned long tag;
4713       unsigned long attribute;
4714       int           children;
4715
4716       entry = read_leb128 (start, & bytes_read, 0);
4717       start += bytes_read;
4718
4719       if (entry == 0)
4720         return start;
4721
4722       tag = read_leb128 (start, & bytes_read, 0);
4723       start += bytes_read;
4724
4725       children = * start ++;
4726
4727       add_abbrev (entry, tag, children);
4728
4729       do
4730         {
4731           unsigned long form;
4732
4733           attribute = read_leb128 (start, & bytes_read, 0);
4734           start += bytes_read;
4735
4736           form = read_leb128 (start, & bytes_read, 0);
4737           start += bytes_read;
4738
4739           if (attribute != 0)
4740             add_abbrev_attr (attribute, form);
4741         }
4742       while (attribute != 0);
4743     }
4744
4745   return NULL;
4746 }
4747
4748
4749 static int
4750 display_debug_abbrev (section, start, file)
4751      Elf32_Internal_Shdr * section;
4752      unsigned char *       start;
4753      FILE *                file;
4754 {
4755   abbrev_entry * entry;
4756   unsigned char * end = start + section->sh_size;
4757
4758   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
4759
4760   do
4761     {
4762       start = process_abbrev_section (start, end);
4763
4764       printf (_("  Number TAG\n"));
4765
4766       for (entry = first_abbrev; entry; entry = entry->next)
4767         {
4768           abbrev_attr * attr;
4769
4770           printf (_("   %ld      %s    [%s]\n"),
4771                   entry->entry,
4772                   get_TAG_name (entry->tag),
4773                   entry->children ? _("has children") : _("no children"));
4774
4775           for (attr = entry->first_attr; attr; attr = attr->next)
4776             {
4777               printf (_("    %-18s %s\n"),
4778                       get_AT_name (attr->attribute),
4779                       get_FORM_name (attr->form));
4780             }
4781         }
4782     }
4783   while (start);
4784
4785   printf ("\n");
4786
4787   return 1;
4788 }
4789
4790
4791 static unsigned char *
4792 display_block (data, length)
4793      unsigned char * data;
4794      unsigned long   length;
4795 {
4796   printf (_(" %lu byte block: "), length);
4797
4798   while (length --)
4799     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
4800
4801   return data;
4802 }
4803
4804 static void
4805 decode_location_expression (data, pointer_size)
4806      unsigned char * data;
4807      unsigned int    pointer_size;
4808 {
4809   unsigned char op;
4810   int           bytes_read;
4811   unsigned long uvalue;
4812
4813   op = * data ++;
4814
4815   switch (op)
4816     {
4817     case DW_OP_addr:
4818       printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
4819       break;
4820     case DW_OP_deref:
4821       printf ("DW_OP_deref");
4822       break;
4823     case DW_OP_const1u:
4824       printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
4825       break;
4826     case DW_OP_const1s:
4827       printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
4828       break;
4829     case DW_OP_const2u:
4830       printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
4831       break;
4832     case DW_OP_const2s:
4833       printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
4834       break;
4835     case DW_OP_const4u:
4836       printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
4837       break;
4838     case DW_OP_const4s:
4839       printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
4840       break;
4841     case DW_OP_const8u:
4842       printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
4843               (unsigned long) byte_get (data + 4, 4));
4844       break;
4845     case DW_OP_const8s:
4846       printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
4847               (long) byte_get (data + 4, 4));
4848       break;
4849     case DW_OP_constu:
4850       printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
4851       break;
4852     case DW_OP_consts:
4853       printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
4854       break;
4855     case DW_OP_dup:
4856       printf ("DW_OP_dup");
4857       break;
4858     case DW_OP_drop:
4859       printf ("DW_OP_drop");
4860       break;
4861     case DW_OP_over:
4862       printf ("DW_OP_over");
4863       break;
4864     case DW_OP_pick:
4865       printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
4866       break;
4867     case DW_OP_swap:
4868       printf ("DW_OP_swap");
4869       break;
4870     case DW_OP_rot:
4871       printf ("DW_OP_rot");
4872       break;
4873     case DW_OP_xderef:
4874       printf ("DW_OP_xderef");
4875       break;
4876     case DW_OP_abs:
4877       printf ("DW_OP_abs");
4878       break;
4879     case DW_OP_and:
4880       printf ("DW_OP_and");
4881       break;
4882     case DW_OP_div:
4883       printf ("DW_OP_div");
4884       break;
4885     case DW_OP_minus:
4886       printf ("DW_OP_minus");
4887       break;
4888     case DW_OP_mod:
4889       printf ("DW_OP_mod");
4890       break;
4891     case DW_OP_mul:
4892       printf ("DW_OP_mul");
4893       break;
4894     case DW_OP_neg:
4895       printf ("DW_OP_neg");
4896       break;
4897     case DW_OP_not:
4898       printf ("DW_OP_not");
4899       break;
4900     case DW_OP_or:
4901       printf ("DW_OP_or");
4902       break;
4903     case DW_OP_plus:
4904       printf ("DW_OP_plus");
4905       break;
4906     case DW_OP_plus_uconst:
4907       printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
4908       break;
4909     case DW_OP_shl:
4910       printf ("DW_OP_shl");
4911       break;
4912     case DW_OP_shr:
4913       printf ("DW_OP_shr");
4914       break;
4915     case DW_OP_shra:
4916       printf ("DW_OP_shra");
4917       break;
4918     case DW_OP_xor:
4919       printf ("DW_OP_xor");
4920       break;
4921     case DW_OP_bra:
4922       printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
4923       break;
4924     case DW_OP_eq:
4925       printf ("DW_OP_eq");
4926       break;
4927     case DW_OP_ge:
4928       printf ("DW_OP_ge");
4929       break;
4930     case DW_OP_gt:
4931       printf ("DW_OP_gt");
4932       break;
4933     case DW_OP_le:
4934       printf ("DW_OP_le");
4935       break;
4936     case DW_OP_lt:
4937       printf ("DW_OP_lt");
4938       break;
4939     case DW_OP_ne:
4940       printf ("DW_OP_ne");
4941       break;
4942     case DW_OP_skip:
4943       printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
4944       break;
4945     case DW_OP_lit0:
4946       printf ("DW_OP_lit0");
4947       break;
4948     case DW_OP_lit1:
4949       printf ("DW_OP_lit1");
4950       break;
4951     case DW_OP_lit2:
4952       printf ("DW_OP_lit2");
4953       break;
4954     case DW_OP_lit3:
4955       printf ("DW_OP_lit3");
4956       break;
4957     case DW_OP_lit4:
4958       printf ("DW_OP_lit4");
4959       break;
4960     case DW_OP_lit5:
4961       printf ("DW_OP_lit5");
4962       break;
4963     case DW_OP_lit6:
4964       printf ("DW_OP_lit6");
4965       break;
4966     case DW_OP_lit7:
4967       printf ("DW_OP_lit7");
4968       break;
4969     case DW_OP_lit8:
4970       printf ("DW_OP_lit8");
4971       break;
4972     case DW_OP_lit9:
4973       printf ("DW_OP_lit9");
4974       break;
4975     case DW_OP_lit10:
4976       printf ("DW_OP_lit10");
4977       break;
4978     case DW_OP_lit11:
4979       printf ("DW_OP_lit11");
4980       break;
4981     case DW_OP_lit12:
4982       printf ("DW_OP_lit12");
4983       break;
4984     case DW_OP_lit13:
4985       printf ("DW_OP_lit13");
4986       break;
4987     case DW_OP_lit14:
4988       printf ("DW_OP_lit14");
4989       break;
4990     case DW_OP_lit15:
4991       printf ("DW_OP_lit15");
4992       break;
4993     case DW_OP_lit16:
4994       printf ("DW_OP_lit16");
4995       break;
4996     case DW_OP_lit17:
4997       printf ("DW_OP_lit17");
4998       break;
4999     case DW_OP_lit18:
5000       printf ("DW_OP_lit18");
5001       break;
5002     case DW_OP_lit19:
5003       printf ("DW_OP_lit19");
5004       break;
5005     case DW_OP_lit20:
5006       printf ("DW_OP_lit20");
5007       break;
5008     case DW_OP_lit21:
5009       printf ("DW_OP_lit21");
5010       break;
5011     case DW_OP_lit22:
5012       printf ("DW_OP_lit22");
5013       break;
5014     case DW_OP_lit23:
5015       printf ("DW_OP_lit23");
5016       break;
5017     case DW_OP_lit24:
5018       printf ("DW_OP_lit24");
5019       break;
5020     case DW_OP_lit25:
5021       printf ("DW_OP_lit25");
5022       break;
5023     case DW_OP_lit26:
5024       printf ("DW_OP_lit26");
5025       break;
5026     case DW_OP_lit27:
5027       printf ("DW_OP_lit27");
5028       break;
5029     case DW_OP_lit28:
5030       printf ("DW_OP_lit28");
5031       break;
5032     case DW_OP_lit29:
5033       printf ("DW_OP_lit29");
5034       break;
5035     case DW_OP_lit30:
5036       printf ("DW_OP_lit30");
5037       break;
5038     case DW_OP_lit31:
5039       printf ("DW_OP_lit31");
5040       break;
5041     case DW_OP_reg0:
5042       printf ("DW_OP_reg0");
5043       break;
5044     case DW_OP_reg1:
5045       printf ("DW_OP_reg1");
5046       break;
5047     case DW_OP_reg2:
5048       printf ("DW_OP_reg2");
5049       break;
5050     case DW_OP_reg3:
5051       printf ("DW_OP_reg3");
5052       break;
5053     case DW_OP_reg4:
5054       printf ("DW_OP_reg4");
5055       break;
5056     case DW_OP_reg5:
5057       printf ("DW_OP_reg5");
5058       break;
5059     case DW_OP_reg6:
5060       printf ("DW_OP_reg6");
5061       break;
5062     case DW_OP_reg7:
5063       printf ("DW_OP_reg7");
5064       break;
5065     case DW_OP_reg8:
5066       printf ("DW_OP_reg8");
5067       break;
5068     case DW_OP_reg9:
5069       printf ("DW_OP_reg9");
5070       break;
5071     case DW_OP_reg10:
5072       printf ("DW_OP_reg10");
5073       break;
5074     case DW_OP_reg11:
5075       printf ("DW_OP_reg11");
5076       break;
5077     case DW_OP_reg12:
5078       printf ("DW_OP_reg12");
5079       break;
5080     case DW_OP_reg13:
5081       printf ("DW_OP_reg13");
5082       break;
5083     case DW_OP_reg14:
5084       printf ("DW_OP_reg14");
5085       break;
5086     case DW_OP_reg15:
5087       printf ("DW_OP_reg15");
5088       break;
5089     case DW_OP_reg16:
5090       printf ("DW_OP_reg16");
5091       break;
5092     case DW_OP_reg17:
5093       printf ("DW_OP_reg17");
5094       break;
5095     case DW_OP_reg18:
5096       printf ("DW_OP_reg18");
5097       break;
5098     case DW_OP_reg19:
5099       printf ("DW_OP_reg19");
5100       break;
5101     case DW_OP_reg20:
5102       printf ("DW_OP_reg20");
5103       break;
5104     case DW_OP_reg21:
5105       printf ("DW_OP_reg21");
5106       break;
5107     case DW_OP_reg22:
5108       printf ("DW_OP_reg22");
5109       break;
5110     case DW_OP_reg23:
5111       printf ("DW_OP_reg23");
5112       break;
5113     case DW_OP_reg24:
5114       printf ("DW_OP_reg24");
5115       break;
5116     case DW_OP_reg25:
5117       printf ("DW_OP_reg25");
5118       break;
5119     case DW_OP_reg26:
5120       printf ("DW_OP_reg26");
5121       break;
5122     case DW_OP_reg27:
5123       printf ("DW_OP_reg27");
5124       break;
5125     case DW_OP_reg28:
5126       printf ("DW_OP_reg28");
5127       break;
5128     case DW_OP_reg29:
5129       printf ("DW_OP_reg29");
5130       break;
5131     case DW_OP_reg30:
5132       printf ("DW_OP_reg30");
5133       break;
5134     case DW_OP_reg31:
5135       printf ("DW_OP_reg31");
5136       break;
5137     case DW_OP_breg0:
5138       printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
5139       break;
5140     case DW_OP_breg1:
5141       printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
5142       break;
5143     case DW_OP_breg2:
5144       printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
5145       break;
5146     case DW_OP_breg3:
5147       printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
5148       break;
5149     case DW_OP_breg4:
5150       printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
5151       break;
5152     case DW_OP_breg5:
5153       printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
5154       break;
5155     case DW_OP_breg6:
5156       printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
5157       break;
5158     case DW_OP_breg7:
5159       printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
5160       break;
5161     case DW_OP_breg8:
5162       printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
5163       break;
5164     case DW_OP_breg9:
5165       printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
5166       break;
5167     case DW_OP_breg10:
5168       printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
5169       break;
5170     case DW_OP_breg11:
5171       printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
5172       break;
5173     case DW_OP_breg12:
5174       printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
5175       break;
5176     case DW_OP_breg13:
5177       printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
5178       break;
5179     case DW_OP_breg14:
5180       printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
5181       break;
5182     case DW_OP_breg15:
5183       printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
5184       break;
5185     case DW_OP_breg16:
5186       printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
5187       break;
5188     case DW_OP_breg17:
5189       printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
5190       break;
5191     case DW_OP_breg18:
5192       printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
5193       break;
5194     case DW_OP_breg19:
5195       printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
5196       break;
5197     case DW_OP_breg20:
5198       printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
5199       break;
5200     case DW_OP_breg21:
5201       printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
5202       break;
5203     case DW_OP_breg22:
5204       printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
5205       break;
5206     case DW_OP_breg23:
5207       printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
5208       break;
5209     case DW_OP_breg24:
5210       printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
5211       break;
5212     case DW_OP_breg25:
5213       printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
5214       break;
5215     case DW_OP_breg26:
5216       printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
5217       break;
5218     case DW_OP_breg27:
5219       printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
5220       break;
5221     case DW_OP_breg28:
5222       printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
5223       break;
5224     case DW_OP_breg29:
5225       printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
5226       break;
5227     case DW_OP_breg30:
5228       printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
5229       break;
5230     case DW_OP_breg31:
5231       printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
5232       break;
5233     case DW_OP_regx:
5234       printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
5235       break;
5236     case DW_OP_fbreg:
5237       printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
5238       break;
5239     case DW_OP_bregx:
5240       uvalue = read_leb128 (data, &bytes_read, 0);
5241       printf ("DW_OP_bregx: %lu %ld", uvalue,
5242               read_leb128 (data + bytes_read, NULL, 1));
5243       break;
5244     case DW_OP_piece:
5245       printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
5246       break;
5247     case DW_OP_deref_size:
5248       printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
5249       break;
5250     case DW_OP_xderef_size:
5251       printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
5252       break;
5253     case DW_OP_nop:
5254       printf ("DW_OP_nop");
5255       break;
5256
5257     default:
5258       if (op >= DW_OP_lo_user
5259           && op <= DW_OP_hi_user)
5260         printf (_("(User defined location op)"));
5261       else
5262         printf (_("(Unknown location op)"));
5263       break;
5264     }
5265 }
5266
5267
5268 static unsigned char *
5269 read_and_display_attr (attribute, form, data, pointer_size)
5270      unsigned long   attribute;
5271      unsigned long   form;
5272      unsigned char * data;
5273      unsigned long   pointer_size;
5274 {
5275   unsigned long   uvalue;
5276   unsigned char * block_start;
5277   int             bytes_read;
5278   int             is_ref = 0;
5279
5280   printf ("     %-18s:", get_AT_name (attribute));
5281
5282   switch (form)
5283     {
5284     case DW_FORM_ref_addr:
5285     case DW_FORM_ref1:
5286     case DW_FORM_ref2:
5287     case DW_FORM_ref4:
5288     case DW_FORM_ref8:
5289     case DW_FORM_ref_udata:
5290       is_ref = 1;
5291     }
5292
5293   switch (form)
5294     {
5295     case DW_FORM_ref_addr:
5296     case DW_FORM_addr:
5297       uvalue = byte_get (data, pointer_size);
5298       printf (is_ref ? " <%x>" : " %#x", uvalue);
5299       data += pointer_size;
5300       break;
5301
5302     case DW_FORM_ref1:
5303     case DW_FORM_flag:
5304     case DW_FORM_data1:
5305       uvalue = byte_get (data ++, 1);
5306       printf (is_ref ? " <%x>" : " %d", uvalue);
5307       break;
5308
5309     case DW_FORM_ref2:
5310     case DW_FORM_data2:
5311       uvalue = byte_get (data, 2);
5312       data += 2;
5313       printf (is_ref ? " <%x>" : " %d", uvalue);
5314       break;
5315
5316     case DW_FORM_ref4:
5317     case DW_FORM_data4:
5318       uvalue = byte_get (data, 4);
5319       data += 4;
5320       printf (is_ref ? " <%x>" : " %d", uvalue);
5321       break;
5322
5323     case DW_FORM_ref8:
5324     case DW_FORM_data8:
5325       uvalue = byte_get (data, 4);
5326       printf (" %lx", uvalue);
5327       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
5328       data += 8;
5329       break;
5330
5331     case DW_FORM_string:
5332       printf (" %s", data);
5333       data += strlen (data) + 1;
5334       break;
5335
5336     case DW_FORM_sdata:
5337       uvalue = read_leb128 (data, & bytes_read, 1);
5338       data += bytes_read;
5339       printf (" %ld", (long) uvalue);
5340       break;
5341
5342     case DW_FORM_ref_udata:
5343     case DW_FORM_udata:
5344       uvalue = read_leb128 (data, & bytes_read, 0);
5345       data += bytes_read;
5346       printf (is_ref ? " <%lx>" : " %ld", uvalue);
5347       break;
5348
5349     case DW_FORM_block:
5350       uvalue = read_leb128 (data, & bytes_read, 0);
5351       block_start = data + bytes_read;
5352       data = display_block (block_start, uvalue);
5353       uvalue = * block_start;
5354       break;
5355
5356     case DW_FORM_block1:
5357       uvalue = byte_get (data, 1);
5358       block_start = data + 1;
5359       data = display_block (block_start, uvalue);
5360       uvalue = * block_start;
5361       break;
5362
5363     case DW_FORM_block2:
5364       uvalue = byte_get (data, 2);
5365       block_start = data + 2;
5366       data = display_block (block_start, uvalue);
5367       uvalue = * block_start;
5368       break;
5369
5370     case DW_FORM_block4:
5371       uvalue = byte_get (data, 4);
5372       block_start = data + 4;
5373       data = display_block (block_start, uvalue);
5374       uvalue = * block_start;
5375       break;
5376
5377     case DW_FORM_strp:
5378     case DW_FORM_indirect:
5379       warn (_("Unable to handle FORM: %d"), form);
5380       break;
5381
5382     default:
5383       warn (_("Unrecognised form: %d"), form);
5384       break;
5385     }
5386
5387   /* For some attributes we can display futher information.  */
5388
5389   printf ("\t");
5390
5391   switch (attribute)
5392     {
5393     case DW_AT_inline:
5394       switch (uvalue)
5395         {
5396         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
5397         case DW_INL_inlined:              printf (_("(inlined)")); break;
5398         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
5399         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
5400         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
5401         }
5402       break;
5403
5404     case DW_AT_frame_base:
5405       if (uvalue >= DW_OP_reg0 && uvalue <= DW_OP_reg31)
5406         printf ("(reg %ld)", uvalue - DW_OP_reg0);
5407       break;
5408
5409     case DW_AT_language:
5410       switch (uvalue)
5411         {
5412         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
5413         case DW_LANG_C89:            printf ("(ANSI C)"); break;
5414         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
5415         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
5416         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
5417         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
5418         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
5419         case DW_LANG_Ada83:          printf ("(Ada)"); break;
5420         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
5421         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
5422         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
5423         default:                     printf ("(Unknown: %lx)", uvalue); break;
5424         }
5425       break;
5426
5427     case DW_AT_encoding:
5428       switch (uvalue)
5429         {
5430         case DW_ATE_void:            printf ("(void)"); break;
5431         case DW_ATE_address:         printf ("(machine address)"); break;
5432         case DW_ATE_boolean:         printf ("(boolean)"); break;
5433         case DW_ATE_complex_float:   printf ("(complex float)"); break;
5434         case DW_ATE_float:           printf ("(float)"); break;
5435         case DW_ATE_signed:          printf ("(signed)"); break;
5436         case DW_ATE_signed_char:     printf ("(signed char)"); break;
5437         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
5438         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
5439         default:
5440           if (uvalue >= DW_ATE_lo_user
5441               && uvalue <= DW_ATE_hi_user)
5442             printf ("(user defined type)");
5443           else
5444             printf ("(unknown type)");
5445           break;
5446         }
5447       break;
5448
5449     case DW_AT_accessibility:
5450       switch (uvalue)
5451         {
5452         case DW_ACCESS_public:          printf ("(public)"); break;
5453         case DW_ACCESS_protected:       printf ("(protected)"); break;
5454         case DW_ACCESS_private:         printf ("(private)"); break;
5455         default:                        printf ("(unknown accessibility)"); break;
5456         }
5457       break;
5458
5459     case DW_AT_visibility:
5460       switch (uvalue)
5461         {
5462         case DW_VIS_local:      printf ("(local)"); break;
5463         case DW_VIS_exported:   printf ("(exported)"); break;
5464         case DW_VIS_qualified:  printf ("(qualified)"); break;
5465         default:                printf ("(unknown visibility)"); break;
5466         }
5467       break;
5468
5469     case DW_AT_virtuality:
5470       switch (uvalue)
5471         {
5472         case DW_VIRTUALITY_none:        printf ("(none)"); break;
5473         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
5474         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
5475         default:                        printf ("(unknown virtuality)"); break;
5476         }
5477       break;
5478
5479     case DW_AT_identifier_case:
5480       switch (uvalue)
5481         {
5482         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
5483         case DW_ID_up_case:             printf ("(up_case)"); break;
5484         case DW_ID_down_case:           printf ("(down_case)"); break;
5485         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
5486         default:                        printf ("(unknown case)"); break;
5487         }
5488       break;
5489
5490     case DW_AT_calling_convention:
5491       switch (uvalue)
5492         {
5493         case DW_CC_normal:      printf ("(normal)"); break;
5494         case DW_CC_program:     printf ("(program)"); break;
5495         case DW_CC_nocall:      printf ("(nocall)"); break;
5496         default:
5497           if (uvalue >= DW_CC_lo_user
5498               && uvalue <= DW_CC_hi_user)
5499             printf ("(user defined)");
5500           else
5501             printf ("(unknown convention)");
5502         }
5503       break;
5504
5505     case DW_AT_location:
5506     case DW_AT_data_member_location:
5507     case DW_AT_vtable_elem_location:
5508       printf ("(");
5509       decode_location_expression (block_start, pointer_size);
5510       printf (")");
5511       break;
5512
5513     default:
5514       break;
5515     }
5516
5517   printf ("\n");
5518   return data;
5519 }
5520
5521 static int
5522 display_debug_info (section, start, file)
5523      Elf32_Internal_Shdr * section;
5524      unsigned char *       start;
5525      FILE *                file;
5526 {
5527   unsigned char * end = start + section->sh_size;
5528   unsigned char * section_begin = start;
5529
5530   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5531
5532   while (start < end)
5533     {
5534       DWARF2_External_CompUnit * external;
5535       DWARF2_Internal_CompUnit   compunit;
5536       unsigned char *            tags;
5537       int                        i;
5538       int                        level;
5539
5540       external = (DWARF2_External_CompUnit *) start;
5541
5542       compunit.cu_length        = BYTE_GET (external->cu_length);
5543       compunit.cu_version       = BYTE_GET (external->cu_version);
5544       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
5545       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
5546
5547       tags = start + sizeof (* external);
5548       start += compunit.cu_length + sizeof (external->cu_length);
5549
5550       if (compunit.cu_version != 2)
5551         {
5552           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
5553           continue;
5554         }
5555
5556       printf (_("  Compilation Unit:\n"));
5557       printf (_("   Length:        %ld\n"), compunit.cu_length);
5558       printf (_("   Version:       %d\n"), compunit.cu_version);
5559       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
5560       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
5561
5562       if (first_abbrev != NULL)
5563         free_abbrevs ();
5564
5565       /* Read in the abbrevs used by this compilation unit.  */
5566
5567       {
5568         Elf32_Internal_Shdr * sec;
5569         unsigned char *       begin;
5570
5571         /* Locate the .debug_abbrev section and process it.  */
5572         for (i = 0, sec = section_headers;
5573              i < elf_header.e_shnum;
5574              i ++, sec ++)
5575           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
5576             break;
5577
5578         if (i == -1 || sec->sh_size == 0)
5579           {
5580             warn (_("Unable to locate .debug_abbrev section!\n"));
5581             return 0;
5582           }
5583
5584         GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
5585                         "debug_abbrev section data");
5586
5587         process_abbrev_section (begin + compunit.cu_abbrev_offset,
5588                                 begin + sec->sh_size);
5589
5590         free (begin);
5591       }
5592
5593       level = 0;
5594       while (tags < start)
5595         {
5596           int            bytes_read;
5597           int            abbrev_number;
5598           abbrev_entry * entry;
5599           abbrev_attr  * attr;
5600
5601           abbrev_number = read_leb128 (tags, & bytes_read, 0);
5602           tags += bytes_read;
5603
5604           /* A null DIE marks the end of a list of children.  */
5605           if (abbrev_number == 0)
5606             {
5607               --level;
5608               continue;
5609             }
5610
5611           /* Scan through the abbreviation list until we reach the
5612              correct entry.  */
5613           for (entry = first_abbrev;
5614                entry && entry->entry != abbrev_number;
5615                entry = entry->next)
5616             continue;
5617
5618           if (entry == NULL)
5619             {
5620               warn (_("Unable to locate entry %d in the abbreviation table\n"),
5621                     abbrev_number);
5622               return 0;
5623             }
5624
5625           printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
5626                   level, tags - section_begin - bytes_read,
5627                   abbrev_number,
5628                   get_TAG_name (entry->tag));
5629
5630           for (attr = entry->first_attr; attr; attr = attr->next)
5631             tags = read_and_display_attr (attr->attribute,
5632                                           attr->form,
5633                                           tags,
5634                                           compunit.cu_pointer_size);
5635
5636           if (entry->children)
5637             ++level;
5638         }
5639     }
5640
5641   printf ("\n");
5642
5643   return 1;
5644 }
5645
5646 static int
5647 display_debug_aranges (section, start, file)
5648      Elf32_Internal_Shdr * section;
5649      unsigned char *       start;
5650      FILE *                file;
5651 {
5652   unsigned char * end = start + section->sh_size;
5653
5654   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
5655
5656   while (start < end)
5657     {
5658       DWARF2_External_ARange * external;
5659       DWARF2_Internal_ARange   arange;
5660       unsigned char *          ranges;
5661       unsigned long            length;
5662       unsigned long            address;
5663
5664       external = (DWARF2_External_ARange *) start;
5665
5666       arange.ar_length       = BYTE_GET (external->ar_length);
5667       arange.ar_version      = BYTE_GET (external->ar_version);
5668       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
5669       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
5670       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
5671
5672       printf (_("  Length:                   %ld\n"), arange.ar_length);
5673       printf (_("  Version:                  %d\n"), arange.ar_version);
5674       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
5675       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
5676       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
5677
5678       printf (_("\n    Address  Length\n"));
5679
5680       ranges = start + sizeof (* external);
5681
5682       for (;;)
5683         {
5684           address = byte_get (ranges, arange.ar_pointer_size);
5685
5686           if (address == 0)
5687             break;
5688
5689           ranges += arange.ar_pointer_size;
5690
5691           length  = byte_get (ranges, arange.ar_pointer_size);
5692
5693           ranges += arange.ar_pointer_size;
5694
5695           printf ("    %8.8lx %lu\n", address, length);
5696         }
5697
5698       start += arange.ar_length + sizeof (external->ar_length);
5699     }
5700
5701   printf ("\n");
5702
5703   return 1;
5704 }
5705
5706
5707 static int
5708 display_debug_not_supported (section, start, file)
5709      Elf32_Internal_Shdr * section;
5710      unsigned char *       start;
5711      FILE *                file;
5712 {
5713   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
5714             SECTION_NAME (section));
5715
5716   return 1;
5717 }
5718
5719   /* A structure containing the name of a debug section and a pointer
5720      to a function that can decode it.  */
5721 struct
5722 {
5723   char * name;
5724   int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
5725 }
5726 debug_displays[] =
5727 {
5728   { ".debug_info",        display_debug_info },
5729   { ".debug_abbrev",      display_debug_abbrev },
5730   { ".debug_line",        display_debug_lines },
5731   { ".debug_aranges",     display_debug_aranges },
5732   { ".debug_pubnames",    display_debug_pubnames },
5733   { ".debug_macinfo",     display_debug_not_supported },
5734   { ".debug_frame",       display_debug_not_supported },
5735   { ".debug_str",         display_debug_not_supported },
5736   { ".debug_static_func", display_debug_not_supported },
5737   { ".debug_static_vars", display_debug_not_supported },
5738   { ".debug_types",       display_debug_not_supported },
5739   { ".debug_weaknames",   display_debug_not_supported }
5740 };
5741
5742 static int
5743 display_debug_section (section, file)
5744      Elf32_Internal_Shdr * section;
5745      FILE * file;
5746 {
5747   char *          name = SECTION_NAME (section);
5748   bfd_size_type   length;
5749   unsigned char * start;
5750   int             i;
5751
5752   length = section->sh_size;
5753   if (length == 0)
5754     {
5755       printf (_("\nSection '%s' has no debugging data.\n"), name);
5756       return 0;
5757     }
5758
5759   GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
5760                   "debug section data");
5761
5762   /* See if we know how to display the contents of this section.  */
5763   for (i = NUM_ELEM (debug_displays); i--;)
5764     if (strcmp (debug_displays[i].name, name) == 0)
5765       {
5766         debug_displays[i].display (section, start, file);
5767         break;
5768       }
5769
5770   if (i == -1)
5771     printf (_("Unrecognised debug section: %s\n"), name);
5772
5773   free (start);
5774
5775   /* If we loaded in the abbrev section at some point,
5776      we must release it here.  */
5777   if (first_abbrev != NULL)
5778     free_abbrevs ();
5779
5780   return 1;
5781 }
5782
5783 static int
5784 process_section_contents (file)
5785      FILE * file;
5786 {
5787   Elf32_Internal_Shdr *    section;
5788   unsigned int  i;
5789
5790   if (! do_dump)
5791     return 1;
5792
5793   for (i = 0, section = section_headers;
5794        i < elf_header.e_shnum
5795        && i < num_dump_sects;
5796        i ++, section ++)
5797     {
5798 #ifdef SUPPORT_DISASSEMBLY
5799       if (dump_sects[i] & DISASS_DUMP)
5800         disassemble_section (section, file);
5801 #endif
5802       if (dump_sects[i] & HEX_DUMP)
5803         dump_section (section, file);
5804
5805       if (dump_sects[i] & DEBUG_DUMP)
5806         display_debug_section (section, file);
5807     }
5808
5809   if (i < num_dump_sects)
5810     warn (_("Some sections were not dumped because they do not exist!\n"));
5811
5812   return 1;
5813 }
5814
5815 static void
5816 process_mips_fpe_exception (mask)
5817      int mask;
5818 {
5819   if (mask)
5820     {
5821       int first = 1;
5822       if (mask & OEX_FPU_INEX)
5823         fputs ("INEX", stdout), first = 0;
5824       if (mask & OEX_FPU_UFLO)
5825         printf ("%sUFLO", first ? "" : "|"), first = 0;
5826       if (mask & OEX_FPU_OFLO)
5827         printf ("%sOFLO", first ? "" : "|"), first = 0;
5828       if (mask & OEX_FPU_DIV0)
5829         printf ("%sDIV0", first ? "" : "|"), first = 0;
5830       if (mask & OEX_FPU_INVAL)
5831         printf ("%sINVAL", first ? "" : "|");
5832     }
5833   else
5834     fputs ("0", stdout);
5835 }
5836
5837 static int
5838 process_mips_specific (file)
5839      FILE * file;
5840 {
5841   Elf_Internal_Dyn * entry;
5842   size_t liblist_offset = 0;
5843   size_t liblistno = 0;
5844   size_t conflictsno = 0;
5845   size_t options_offset = 0;
5846   size_t conflicts_offset = 0;
5847
5848   /* We have a lot of special sections.  Thanks SGI!  */
5849   if (dynamic_segment == NULL)
5850     /* No information available.  */
5851     return 0;
5852
5853   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
5854     switch (entry->d_tag)
5855       {
5856       case DT_MIPS_LIBLIST:
5857         liblist_offset = entry->d_un.d_val - loadaddr;
5858         break;
5859       case DT_MIPS_LIBLISTNO:
5860         liblistno = entry->d_un.d_val;
5861         break;
5862       case DT_MIPS_OPTIONS:
5863         options_offset = entry->d_un.d_val - loadaddr;
5864         break;
5865       case DT_MIPS_CONFLICT:
5866         conflicts_offset = entry->d_un.d_val - loadaddr;
5867         break;
5868       case DT_MIPS_CONFLICTNO:
5869         conflictsno = entry->d_un.d_val;
5870         break;
5871       default:
5872         break;
5873       }
5874
5875   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
5876     {
5877       Elf32_External_Lib * elib;
5878       size_t cnt;
5879
5880       GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
5881                       elib, Elf32_External_Lib *, "liblist");
5882
5883       printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
5884       fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
5885              stdout);
5886
5887       for (cnt = 0; cnt < liblistno; ++cnt)
5888         {
5889           Elf32_Lib liblist;
5890           time_t time;
5891           char timebuf[20];
5892
5893           liblist.l_name = BYTE_GET (elib[cnt].l_name);
5894           time = BYTE_GET (elib[cnt].l_time_stamp);
5895           liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
5896           liblist.l_version = BYTE_GET (elib[cnt].l_version);
5897           liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
5898
5899           strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
5900
5901           printf ("%3d: %-20s %s %#10lx %-7ld", cnt,
5902                   dynamic_strings + liblist.l_name, timebuf,
5903                   liblist.l_checksum, liblist.l_version);
5904
5905           if (liblist.l_flags == 0)
5906             puts (" NONE");
5907           else
5908             {
5909               static const struct
5910               {
5911                 const char *name;
5912                 int bit;
5913               } l_flags_vals[] =
5914                 {
5915                   { " EXACT_MATCH", LL_EXACT_MATCH },
5916                   { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
5917                   { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
5918                   { " EXPORTS", LL_EXPORTS },
5919                   { " DELAY_LOAD", LL_DELAY_LOAD },
5920                   { " DELTA", LL_DELTA }
5921                 };
5922               int flags = liblist.l_flags;
5923               int fcnt;
5924
5925               for (fcnt = 0;
5926                    fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
5927                    ++fcnt)
5928                 if ((flags & l_flags_vals[fcnt].bit) != 0)
5929                   {
5930                     fputs (l_flags_vals[fcnt].name, stdout);
5931                     flags ^= l_flags_vals[fcnt].bit;
5932                   }
5933               if (flags != 0)
5934                 printf (" %#x", (unsigned int) flags);
5935
5936               puts ("");
5937             }
5938         }
5939
5940       free (elib);
5941     }
5942
5943   if (options_offset != 0)
5944     {
5945       Elf_External_Options * eopt;
5946       Elf_Internal_Shdr * sect = section_headers;
5947       Elf_Internal_Options * iopt;
5948       Elf_Internal_Options * option;
5949       size_t offset;
5950       int cnt;
5951
5952       /* Find the section header so that we get the size.  */
5953       while (sect->sh_type != SHT_MIPS_OPTIONS)
5954         ++sect;
5955
5956       GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
5957                       Elf_External_Options *, "options");
5958
5959       iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
5960                                               * sizeof (*iopt));
5961       if (iopt == NULL)
5962         {
5963           error (_("Out of memory"));
5964           return 0;
5965         }
5966
5967       offset = cnt = 0;
5968       option = iopt;
5969       while (offset < sect->sh_size)
5970         {
5971           Elf_External_Options * eoption;
5972
5973           eoption = (Elf_External_Options *) ((char *) eopt + offset);
5974
5975           option->kind = BYTE_GET (eoption->kind);
5976           option->size = BYTE_GET (eoption->size);
5977           option->section = BYTE_GET (eoption->section);
5978           option->info = BYTE_GET (eoption->info);
5979
5980           offset += option->size;
5981           ++option;
5982           ++cnt;
5983         }
5984
5985       printf (_("\nSection '%s' contains %d entries:\n"),
5986               string_table + sect->sh_name, cnt);
5987
5988       option = iopt;
5989       while (cnt-- > 0)
5990         {
5991           size_t len;
5992
5993           switch (option->kind)
5994             {
5995             case ODK_NULL:
5996               /* This shouldn't happen.  */
5997               printf (" NULL       %d %lx", option->section, option->info);
5998               break;
5999             case ODK_REGINFO:
6000               printf (" REGINFO    ");
6001               if (elf_header.e_machine == EM_MIPS)
6002                 {
6003                   /* 32bit form.  */
6004                   Elf32_External_RegInfo *ereg;
6005                   Elf32_RegInfo reginfo;
6006
6007                   ereg = (Elf32_External_RegInfo *) (option + 1);
6008                   reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
6009                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6010                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6011                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6012                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6013                   reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
6014
6015                   printf ("GPR %08lx  GP 0x%lx\n",
6016                           reginfo.ri_gprmask,
6017                           (unsigned long) reginfo.ri_gp_value);
6018                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
6019                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6020                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6021                 }
6022               else
6023                 {
6024                   /* 64 bit form.  */
6025                   Elf64_External_RegInfo * ereg;
6026                   Elf64_Internal_RegInfo reginfo;
6027
6028                   ereg = (Elf64_External_RegInfo *) (option + 1);
6029                   reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
6030                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
6031                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
6032                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
6033                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
6034                   reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
6035
6036                   printf ("GPR %08lx  GP 0x",
6037                           reginfo.ri_gprmask);
6038                   printf_vma (reginfo.ri_gp_value);
6039                   printf ("\n");
6040
6041                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
6042                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
6043                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
6044                 }
6045               ++option;
6046               continue;
6047             case ODK_EXCEPTIONS:
6048               fputs (" EXCEPTIONS fpe_min(", stdout);
6049               process_mips_fpe_exception (option->info & OEX_FPU_MIN);
6050               fputs (") fpe_max(", stdout);
6051               process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
6052               fputs (")", stdout);
6053
6054               if (option->info & OEX_PAGE0)
6055                 fputs (" PAGE0", stdout);
6056               if (option->info & OEX_SMM)
6057                 fputs (" SMM", stdout);
6058               if (option->info & OEX_FPDBUG)
6059                 fputs (" FPDBUG", stdout);
6060               if (option->info & OEX_DISMISS)
6061                 fputs (" DISMISS", stdout);
6062               break;
6063             case ODK_PAD:
6064               fputs (" PAD       ", stdout);
6065               if (option->info & OPAD_PREFIX)
6066                 fputs (" PREFIX", stdout);
6067               if (option->info & OPAD_POSTFIX)
6068                 fputs (" POSTFIX", stdout);
6069               if (option->info & OPAD_SYMBOL)
6070                 fputs (" SYMBOL", stdout);
6071               break;
6072             case ODK_HWPATCH:
6073               fputs (" HWPATCH   ", stdout);
6074               if (option->info & OHW_R4KEOP)
6075                 fputs (" R4KEOP", stdout);
6076               if (option->info & OHW_R8KPFETCH)
6077                 fputs (" R8KPFETCH", stdout);
6078               if (option->info & OHW_R5KEOP)
6079                 fputs (" R5KEOP", stdout);
6080               if (option->info & OHW_R5KCVTL)
6081                 fputs (" R5KCVTL", stdout);
6082               break;
6083             case ODK_FILL:
6084               fputs (" FILL       ", stdout);
6085               /* XXX Print content of info word?  */
6086               break;
6087             case ODK_TAGS:
6088               fputs (" TAGS       ", stdout);
6089               /* XXX Print content of info word?  */
6090               break;
6091             case ODK_HWAND:
6092               fputs (" HWAND     ", 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_HWOR:
6099               fputs (" HWOR      ", stdout);
6100               if (option->info & OHWA0_R4KEOP_CHECKED)
6101                 fputs (" R4KEOP_CHECKED", stdout);
6102               if (option->info & OHWA0_R4KEOP_CLEAN)
6103                 fputs (" R4KEOP_CLEAN", stdout);
6104               break;
6105             case ODK_GP_GROUP:
6106               printf (" GP_GROUP  %#06lx  self-contained %#06lx",
6107                       option->info & OGP_GROUP,
6108                       (option->info & OGP_SELF) >> 16);
6109               break;
6110             case ODK_IDENT:
6111               printf (" IDENT     %#06lx  self-contained %#06lx",
6112                       option->info & OGP_GROUP,
6113                       (option->info & OGP_SELF) >> 16);
6114               break;
6115             default:
6116               /* This shouldn't happen.  */
6117               printf (" %3d ???     %d %lx",
6118                       option->kind, option->section, option->info);
6119               break;
6120             }
6121
6122           len = sizeof (*eopt);
6123           while (len < option->size)
6124             if (((char *) option)[len] >= ' '
6125                 && ((char *) option)[len] < 0x7f)
6126               printf ("%c", ((char *) option)[len++]);
6127             else
6128               printf ("\\%03o", ((char *) option)[len++]);
6129
6130           fputs ("\n", stdout);
6131           ++option;
6132         }
6133
6134       free (eopt);
6135     }
6136
6137   if (conflicts_offset != 0 && conflictsno != 0)
6138     {
6139       Elf32_External_Conflict * econf32;
6140       Elf64_External_Conflict * econf64;
6141       Elf32_Conflict * iconf;
6142       size_t cnt;
6143
6144       if (dynamic_symbols == NULL)
6145         {
6146           error (_("conflict list with without table"));
6147           return 0;
6148         }
6149
6150       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
6151       if (iconf == NULL)
6152         {
6153           error (_("Out of memory"));
6154           return 0;
6155         }
6156
6157       if (is_32bit_elf)
6158         {
6159           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
6160                           econf32, Elf32_External_Conflict *, "conflict");
6161
6162           for (cnt = 0; cnt < conflictsno; ++cnt)
6163             iconf[cnt] = BYTE_GET (econf32[cnt]);
6164         }
6165       else
6166         {
6167           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
6168                           econf64, Elf64_External_Conflict *, "conflict");
6169
6170           for (cnt = 0; cnt < conflictsno; ++cnt)
6171             iconf[cnt] = BYTE_GET (econf64[cnt]);
6172         }
6173
6174       printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
6175       puts (_("  Num:    Index       Value  Name"));
6176
6177       for (cnt = 0; cnt < conflictsno; ++cnt)
6178         {
6179           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
6180
6181           printf ("%5u: %8lu  %#10lx  %s\n",
6182                   cnt, iconf[cnt], (unsigned long) psym->st_value,
6183                   dynamic_strings + psym->st_name);
6184         }
6185
6186
6187       free (iconf);
6188     }
6189
6190   return 1;
6191 }
6192
6193 static int
6194 process_arch_specific (file)
6195      FILE * file;
6196 {
6197   switch (elf_header.e_machine)
6198     {
6199     case EM_MIPS:
6200     case EM_MIPS_RS4_BE:
6201       return process_mips_specific (file);
6202       break;
6203     default:
6204       break;
6205     }
6206   return 1;
6207 }
6208
6209 static int
6210 get_file_header (file)
6211      FILE * file;
6212 {
6213   /* Read in the identity array.  */
6214   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
6215     return 0;
6216
6217   /* Determine how to read the rest of the header.  */
6218   switch (elf_header.e_ident [EI_DATA])
6219     {
6220     default: /* fall through */
6221     case ELFDATANONE: /* fall through */
6222     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
6223     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
6224     }
6225
6226   /* For now we only support 32 bit and 64 bit ELF files.  */
6227   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
6228
6229   /* Read in the rest of the header.  */
6230   if (is_32bit_elf)
6231     {
6232       Elf32_External_Ehdr ehdr32;
6233
6234       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
6235         return 0;
6236       
6237       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
6238       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
6239       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
6240       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
6241       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
6242       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
6243       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
6244       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
6245       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
6246       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
6247       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
6248       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
6249       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
6250     }
6251   else
6252     {
6253       Elf64_External_Ehdr ehdr64;
6254       
6255       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
6256         return 0;
6257       
6258       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
6259       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
6260       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
6261       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
6262       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
6263       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
6264       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
6265       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
6266       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
6267       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
6268       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
6269       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
6270       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
6271     }
6272
6273   return 1;
6274 }
6275
6276 static void
6277 process_file (file_name)
6278      char * file_name;
6279 {
6280   FILE *       file;
6281   struct stat  statbuf;
6282   unsigned int i;
6283
6284   if (stat (file_name, & statbuf) < 0)
6285     {
6286       error (_("Cannot stat input file %s.\n"), file_name);
6287       return;
6288     }
6289
6290   file = fopen (file_name, "rb");
6291   if (file == NULL)
6292     {
6293       error (_("Input file %s not found.\n"), file_name);
6294       return;
6295     }
6296
6297   if (! get_file_header (file))
6298     {
6299       error (_("%s: Failed to read file header\n"), file_name);
6300       fclose (file);
6301       return;
6302     }
6303
6304   /* Initialise per file variables.  */
6305   for (i = NUM_ELEM (version_info); i--;)
6306     version_info[i] = 0;
6307
6308   for (i = NUM_ELEM (dynamic_info); i--;)
6309     dynamic_info[i] = 0;
6310
6311   /* Process the file.  */
6312   if (show_name)
6313     printf (_("\nFile: %s\n"), file_name);
6314
6315   if (! process_file_header ())
6316     {
6317       fclose (file);
6318       return;
6319     }
6320
6321   process_section_headers (file);
6322
6323   process_program_headers (file);
6324
6325   process_dynamic_segment (file);
6326
6327   process_relocs (file);
6328
6329   process_symbol_table (file);
6330
6331   process_syminfo (file);
6332
6333   process_version_sections (file);
6334
6335   process_section_contents (file);
6336
6337   process_arch_specific (file);
6338
6339   fclose (file);
6340
6341   if (section_headers)
6342     {
6343       free (section_headers);
6344       section_headers = NULL;
6345     }
6346
6347   if (string_table)
6348     {
6349       free (string_table);
6350       string_table = NULL;
6351     }
6352
6353   if (dynamic_strings)
6354     {
6355       free (dynamic_strings);
6356       dynamic_strings = NULL;
6357     }
6358
6359   if (dynamic_symbols)
6360     {
6361       free (dynamic_symbols);
6362       dynamic_symbols = NULL;
6363       num_dynamic_syms = 0;
6364     }
6365
6366   if (dynamic_syminfo)
6367     {
6368       free (dynamic_syminfo);
6369       dynamic_syminfo = NULL;
6370     }
6371 }
6372
6373 #ifdef SUPPORT_DISASSEMBLY
6374 /* Needed by the i386 disassembler.  For extra credit, someone could
6375    fix this so that we insert symbolic addresses here, esp for GOT/PLT
6376    symbols */
6377
6378 void
6379 print_address (unsigned int addr, FILE * outfile)
6380 {
6381   fprintf (outfile,"0x%8.8x", addr);
6382 }
6383
6384 /* Needed by the i386 disassembler. */
6385 void
6386 db_task_printsym (unsigned int addr)
6387 {
6388   print_address (addr, stderr);
6389 }
6390 #endif
6391
6392 int
6393 main (argc, argv)
6394      int     argc;
6395      char ** argv;
6396 {
6397 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
6398   setlocale (LC_MESSAGES, "");
6399 #endif
6400   bindtextdomain (PACKAGE, LOCALEDIR);
6401   textdomain (PACKAGE);
6402
6403   parse_args (argc, argv);
6404
6405   if (optind < (argc - 1))
6406     show_name = 1;
6407
6408   while (optind < argc)
6409     process_file (argv [optind ++]);
6410
6411   if (dump_sects != NULL)
6412     free (dump_sects);
6413
6414   return 0;
6415 }
This page took 0.379216 seconds and 4 git commands to generate.