Support DWARF 2.1 tags, encodings, languages.
[external/binutils.git] / binutils / readelf.c
1 /* readelf.c -- display contents of an ELF format file
2    Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4    Originally developed by Eric Youngdale <eric@andante.jic.com>
5    Modifications by Nick Clifton <nickc@redhat.com>
6
7    This file is part of GNU Binutils.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22    02111-1307, USA.  */
23 \f
24
25 #include <assert.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <time.h>
30
31 #if __GNUC__ >= 2
32 /* Define BFD64 here, even if our default architecture is 32 bit ELF
33    as this will allow us to read in and parse 64bit and 32bit ELF files.
34    Only do this if we belive that the compiler can support a 64 bit
35    data type.  For now we only rely on GCC being able to do this.  */
36 #define BFD64
37 #endif
38
39 #include "bfd.h"
40
41 #include "elf/common.h"
42 #include "elf/external.h"
43 #include "elf/internal.h"
44 #include "elf/dwarf2.h"
45
46 /* The following headers use the elf/reloc-macros.h file to
47    automatically generate relocation recognition functions
48    such as elf_mips_reloc_type()  */
49
50 #define RELOC_MACROS_GEN_FUNC
51
52 #include "elf/i386.h"
53 #include "elf/v850.h"
54 #include "elf/ppc.h"
55 #include "elf/mips.h"
56 #include "elf/alpha.h"
57 #include "elf/arm.h"
58 #include "elf/m68k.h"
59 #include "elf/sparc.h"
60 #include "elf/m32r.h"
61 #include "elf/d10v.h"
62 #include "elf/d30v.h"
63 #include "elf/sh.h"
64 #include "elf/mn10200.h"
65 #include "elf/mn10300.h"
66 #include "elf/hppa.h"
67 #include "elf/arc.h"
68 #include "elf/fr30.h"
69 #include "elf/mcore.h"
70 #include "elf/i960.h"
71 #include "elf/pj.h"
72 #include "elf/avr.h"
73 #include "elf/ia64.h"
74 #include "elf/cris.h"
75 #include "elf/i860.h"
76 #include "elf/x86-64.h"
77 #include "elf/s390.h"
78
79 #include "bucomm.h"
80 #include "getopt.h"
81
82 char *                  program_name = "readelf";
83 unsigned int            dynamic_addr;
84 bfd_size_type           dynamic_size;
85 unsigned int            rela_addr;
86 unsigned int            rela_size;
87 char *                  dynamic_strings;
88 char *                  string_table;
89 unsigned long           string_table_length;
90 unsigned long           num_dynamic_syms;
91 Elf_Internal_Sym *      dynamic_symbols;
92 Elf_Internal_Syminfo *  dynamic_syminfo;
93 unsigned long           dynamic_syminfo_offset;
94 unsigned int            dynamic_syminfo_nent;
95 char                    program_interpreter [64];
96 int                     dynamic_info[DT_JMPREL + 1];
97 int                     version_info[16];
98 int                     loadaddr = 0;
99 Elf_Internal_Ehdr       elf_header;
100 Elf_Internal_Shdr *     section_headers;
101 Elf_Internal_Dyn *      dynamic_segment;
102 int                     show_name;
103 int                     do_dynamic;
104 int                     do_syms;
105 int                     do_reloc;
106 int                     do_sections;
107 int                     do_segments;
108 int                     do_unwind;
109 int                     do_using_dynamic;
110 int                     do_header;
111 int                     do_dump;
112 int                     do_version;
113 int                     do_histogram;
114 int                     do_debugging;
115 int                     do_debug_info;
116 int                     do_debug_abbrevs;
117 int                     do_debug_lines;
118 int                     do_debug_pubnames;
119 int                     do_debug_aranges;
120 int                     do_debug_frames;
121 int                     do_debug_frames_interp;
122 int                     do_arch;
123 int                     do_notes;
124 int                     is_32bit_elf;
125
126 /* A dynamic array of flags indicating which sections require dumping.  */
127 char *                  dump_sects = NULL;
128 unsigned int            num_dump_sects = 0;
129
130 #define HEX_DUMP        (1 << 0)
131 #define DISASS_DUMP     (1 << 1)
132 #define DEBUG_DUMP      (1 << 2)
133
134 /* How to rpint a vma value.  */
135 typedef enum print_mode
136 {
137   HEX,
138   DEC,
139   DEC_5,
140   UNSIGNED,
141   PREFIX_HEX,
142   FULL_HEX,
143   LONG_HEX
144 }
145 print_mode;
146
147 /* Forward declarations for dumb compilers.  */
148 static void               print_vma                   PARAMS ((bfd_vma, print_mode));
149 static bfd_vma (*         byte_get)                   PARAMS ((unsigned char *, int));
150 static bfd_vma            byte_get_little_endian      PARAMS ((unsigned char *, int));
151 static bfd_vma            byte_get_big_endian         PARAMS ((unsigned char *, int));
152 static const char *       get_mips_dynamic_type       PARAMS ((unsigned long));
153 static const char *       get_sparc64_dynamic_type    PARAMS ((unsigned long));
154 static const char *       get_parisc_dynamic_type     PARAMS ((unsigned long));
155 static const char *       get_dynamic_type            PARAMS ((unsigned long));
156 static int                slurp_rela_relocs           PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rela **, unsigned long *));
157 static int                slurp_rel_relocs            PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Rel **, unsigned long *));
158 static int                dump_relocations            PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
159 static char *             get_file_type               PARAMS ((unsigned));
160 static char *             get_machine_name            PARAMS ((unsigned));
161 static void               decode_ARM_machine_flags    PARAMS ((unsigned, char []));
162 static char *             get_machine_flags           PARAMS ((unsigned, unsigned));
163 static const char *       get_mips_segment_type       PARAMS ((unsigned long));
164 static const char *       get_parisc_segment_type     PARAMS ((unsigned long));
165 static const char *       get_ia64_segment_type       PARAMS ((unsigned long));
166 static const char *       get_segment_type            PARAMS ((unsigned long));
167 static const char *       get_mips_section_type_name  PARAMS ((unsigned int));
168 static const char *       get_parisc_section_type_name PARAMS ((unsigned int));
169 static const char *       get_ia64_section_type_name  PARAMS ((unsigned int));
170 static const char *       get_section_type_name       PARAMS ((unsigned int));
171 static const char *       get_symbol_binding          PARAMS ((unsigned int));
172 static const char *       get_symbol_type             PARAMS ((unsigned int));
173 static const char *       get_symbol_visibility       PARAMS ((unsigned int));
174 static const char *       get_symbol_index_type       PARAMS ((unsigned int));
175 static const char *       get_dynamic_flags           PARAMS ((bfd_vma));
176 static void               usage                       PARAMS ((void));
177 static void               parse_args                  PARAMS ((int, char **));
178 static int                process_file_header         PARAMS ((void));
179 static int                process_program_headers     PARAMS ((FILE *));
180 static int                process_section_headers     PARAMS ((FILE *));
181 static int                process_unwind              PARAMS ((FILE *));
182 static void               dynamic_segment_mips_val    PARAMS ((Elf_Internal_Dyn *));
183 static void               dynamic_segment_parisc_val  PARAMS ((Elf_Internal_Dyn *));
184 static int                process_dynamic_segment     PARAMS ((FILE *));
185 static int                process_symbol_table        PARAMS ((FILE *));
186 static int                process_section_contents    PARAMS ((FILE *));
187 static void               process_file                PARAMS ((char *));
188 static int                process_relocs              PARAMS ((FILE *));
189 static int                process_version_sections    PARAMS ((FILE *));
190 static char *             get_ver_flags               PARAMS ((unsigned int));
191 static int                get_32bit_section_headers   PARAMS ((FILE *));
192 static int                get_64bit_section_headers   PARAMS ((FILE *));
193 static int                get_32bit_program_headers   PARAMS ((FILE *, Elf_Internal_Phdr *));
194 static int                get_64bit_program_headers   PARAMS ((FILE *, Elf_Internal_Phdr *));
195 static int                get_file_header             PARAMS ((FILE *));
196 static Elf_Internal_Sym * get_32bit_elf_symbols       PARAMS ((FILE *, unsigned long, unsigned long));
197 static Elf_Internal_Sym * get_64bit_elf_symbols       PARAMS ((FILE *, unsigned long, unsigned long));
198 static const char *       get_elf_section_flags       PARAMS ((bfd_vma));
199 static int *              get_dynamic_data            PARAMS ((FILE *, unsigned int));
200 static int                get_32bit_dynamic_segment   PARAMS ((FILE *));
201 static int                get_64bit_dynamic_segment   PARAMS ((FILE *));
202 #ifdef SUPPORT_DISASSEMBLY
203 static int                disassemble_section         PARAMS ((Elf32_Internal_Shdr *, FILE *));
204 #endif
205 static int                dump_section                PARAMS ((Elf32_Internal_Shdr *, FILE *));
206 static int                display_debug_section       PARAMS ((Elf32_Internal_Shdr *, FILE *));
207 static int                display_debug_info          PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
208 static int                display_debug_not_supported PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
209 static int                display_debug_lines         PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
210 static int                display_debug_abbrev        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
211 static int                display_debug_aranges       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
212 static int                display_debug_frames        PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
213 static unsigned char *    process_abbrev_section      PARAMS ((unsigned char *, unsigned char *));
214 static unsigned long      read_leb128                 PARAMS ((unsigned char *, int *, int));
215 static int                process_extended_line_op    PARAMS ((unsigned char *, int, int));
216 static void               reset_state_machine         PARAMS ((int));
217 static char *             get_TAG_name                PARAMS ((unsigned long));
218 static char *             get_AT_name                 PARAMS ((unsigned long));
219 static char *             get_FORM_name               PARAMS ((unsigned long));
220 static void               free_abbrevs                PARAMS ((void));
221 static void               add_abbrev                  PARAMS ((unsigned long, unsigned long, int));
222 static void               add_abbrev_attr             PARAMS ((unsigned long, unsigned long));
223 static unsigned char *    read_and_display_attr       PARAMS ((unsigned long, unsigned long, unsigned char *, unsigned long, unsigned long));
224 static unsigned char *    display_block               PARAMS ((unsigned char *, unsigned long));
225 static void               decode_location_expression  PARAMS ((unsigned char *, unsigned int, unsigned long));
226 static void               request_dump                PARAMS ((unsigned int, char));
227 static const char *       get_elf_class               PARAMS ((unsigned char));
228 static const char *       get_data_encoding           PARAMS ((unsigned char));
229 static const char *       get_osabi_name              PARAMS ((unsigned char));
230 static int                guess_is_rela               PARAMS ((unsigned long));
231 static char *             get_note_type                  PARAMS ((unsigned int));
232 static int                process_note                   PARAMS ((Elf32_Internal_Note *));
233 static int                process_corefile_note_segment  PARAMS ((FILE *, bfd_vma, bfd_vma));
234 static int                process_corefile_note_segments PARAMS ((FILE *));
235 static int                process_corefile_contents      PARAMS ((FILE *));
236
237 typedef int Elf32_Word;
238
239 #ifndef TRUE
240 #define TRUE     1
241 #define FALSE    0
242 #endif
243 #define UNKNOWN -1
244
245 #define SECTION_NAME(X) ((X) == NULL ? "<none>" : \
246                                  ((X)->sh_name >= string_table_length \
247                                   ? "<corrupt>" : string_table + (X)->sh_name))
248
249 #define DT_VERSIONTAGIDX(tag)   (DT_VERNEEDNUM - (tag)) /* Reverse order! */
250
251 #define BYTE_GET(field) byte_get (field, sizeof (field))
252
253 /* If we can support a 64 bit data type then BFD64 should be defined
254    and sizeof (bfd_vma) == 8.  In this case when translating from an
255    external 8 byte field to an internal field, we can assume that the
256    internal field is also 8 bytes wide and so we can extract all the data.
257    If, however, BFD64 is not defined, then we must assume that the
258    internal data structure only has 4 byte wide fields that are the
259    equivalent of the 8 byte wide external counterparts, and so we must
260    truncate the data.  */
261 #ifdef  BFD64
262 #define BYTE_GET8(field)        byte_get (field, -8)
263 #else
264 #define BYTE_GET8(field)        byte_get (field, 8)
265 #endif
266
267 #define NUM_ELEM(array) (sizeof (array) / sizeof ((array)[0]))
268
269 #define GET_ELF_SYMBOLS(file, offset, size)                     \
270   (is_32bit_elf ? get_32bit_elf_symbols (file, offset, size)    \
271    : get_64bit_elf_symbols (file, offset, size))
272
273
274 #ifdef ANSI_PROTOTYPES
275 static void
276 error (const char * message, ...)
277 {
278   va_list args;
279
280   fprintf (stderr, _("%s: Error: "), program_name);
281   va_start (args, message);
282   vfprintf (stderr, message, args);
283   va_end (args);
284   return;
285 }
286
287 static void
288 warn (const char * message, ...)
289 {
290   va_list args;
291
292   fprintf (stderr, _("%s: Warning: "), program_name);
293   va_start (args, message);
294   vfprintf (stderr, message, args);
295   va_end (args);
296   return;
297 }
298 #else
299 static void
300 error (va_alist)
301      va_dcl
302 {
303   char * message;
304   va_list args;
305
306   fprintf (stderr, _("%s: Error: "), program_name);
307   va_start (args);
308   message = va_arg (args, char *);
309   vfprintf (stderr, message, args);
310   va_end (args);
311   return;
312 }
313
314 static void
315 warn (va_alist)
316      va_dcl
317 {
318   char * message;
319   va_list args;
320
321   fprintf (stderr, _("%s: Warning: "), program_name);
322   va_start (args);
323   message = va_arg (args, char *);
324   vfprintf (stderr, message, args);
325   va_end (args);
326   return;
327 }
328 #endif
329
330 static PTR get_data PARAMS ((PTR, FILE *, long, size_t, const char *));
331
332 static PTR
333 get_data (var, file, offset, size, reason)
334      PTR var;
335      FILE *file;
336      long offset;
337      size_t size;
338      const char *reason;
339 {
340   PTR mvar;
341
342   if (size == 0)
343     return NULL;
344
345   if (fseek (file, offset, SEEK_SET))
346     {
347       error (_("Unable to seek to %x for %s\n"), offset, reason);
348       return NULL;
349     }
350
351   mvar = var;
352   if (mvar == NULL)
353     {
354       mvar = (PTR) malloc (size);
355
356       if (mvar == NULL)
357         {
358           error (_("Out of memory allocating %d bytes for %s\n"),
359                  size, reason);
360           return NULL;
361         }
362     }
363
364   if (fread (mvar, size, 1, file) != 1)
365     {
366       error (_("Unable to read in %d bytes of %s\n"), size, reason);
367       if (mvar != var)
368         free (mvar);
369       return NULL;
370     }
371
372   return mvar;
373 }
374
375 static bfd_vma
376 byte_get_little_endian (field, size)
377      unsigned char * field;
378      int             size;
379 {
380   switch (size)
381     {
382     case 1:
383       return * field;
384
385     case 2:
386       return  ((unsigned int) (field [0]))
387         |    (((unsigned int) (field [1])) << 8);
388
389 #ifndef BFD64
390     case 8:
391       /* We want to extract data from an 8 byte wide field and
392          place it into a 4 byte wide field.  Since this is a little
393          endian source we can juts use the 4 byte extraction code.  */
394       /* Fall through.  */
395 #endif
396     case 4:
397       return  ((unsigned long) (field [0]))
398         |    (((unsigned long) (field [1])) << 8)
399         |    (((unsigned long) (field [2])) << 16)
400         |    (((unsigned long) (field [3])) << 24);
401
402 #ifdef BFD64
403     case 8:
404     case -8:
405       /* This is a special case, generated by the BYTE_GET8 macro.
406          It means that we are loading an 8 byte value from a field
407          in an external structure into an 8 byte value in a field
408          in an internal strcuture.  */
409       return  ((bfd_vma) (field [0]))
410         |    (((bfd_vma) (field [1])) << 8)
411         |    (((bfd_vma) (field [2])) << 16)
412         |    (((bfd_vma) (field [3])) << 24)
413         |    (((bfd_vma) (field [4])) << 32)
414         |    (((bfd_vma) (field [5])) << 40)
415         |    (((bfd_vma) (field [6])) << 48)
416         |    (((bfd_vma) (field [7])) << 56);
417 #endif
418     default:
419       error (_("Unhandled data length: %d\n"), size);
420       abort ();
421     }
422 }
423
424 /* Print a VMA value.  */
425 static void
426 print_vma (vma, mode)
427      bfd_vma vma;
428      print_mode mode;
429 {
430 #ifdef BFD64
431   if (is_32bit_elf)
432 #endif
433     {
434       switch (mode)
435         {
436         case FULL_HEX: printf ("0x"); /* drop through */
437         case LONG_HEX: printf ("%8.8lx", (unsigned long) vma); break;
438         case PREFIX_HEX: printf ("0x"); /* drop through */
439         case HEX: printf ("%lx", (unsigned long) vma); break;
440         case DEC: printf ("%ld", (unsigned long) vma); break;
441         case DEC_5: printf ("%5ld", (long) vma); break;
442         case UNSIGNED: printf ("%lu", (unsigned long) vma); break;
443         }
444     }
445 #ifdef BFD64
446   else
447     {
448       switch (mode)
449         {
450         case FULL_HEX:
451           printf ("0x");
452           /* drop through */
453
454         case LONG_HEX:
455           printf_vma (vma);
456           break;
457
458         case PREFIX_HEX:
459           printf ("0x");
460           /* drop through */
461
462         case HEX:
463 #if BFD_HOST_64BIT_LONG
464           printf ("%lx", vma);
465 #else
466           if (_bfd_int64_high (vma))
467             printf ("%lx%lx", _bfd_int64_high (vma), _bfd_int64_low (vma));
468           else
469             printf ("%lx", _bfd_int64_low (vma));
470 #endif
471           break;
472
473         case DEC:
474 #if BFD_HOST_64BIT_LONG
475           printf ("%ld", vma);
476 #else
477           if (_bfd_int64_high (vma))
478             /* ugg */
479             printf ("++%ld", _bfd_int64_low (vma));
480           else
481             printf ("%ld", _bfd_int64_low (vma));
482 #endif
483           break;
484
485         case DEC_5:
486 #if BFD_HOST_64BIT_LONG
487           printf ("%5ld", vma);
488 #else
489           if (_bfd_int64_high (vma))
490             /* ugg */
491             printf ("++%ld", _bfd_int64_low (vma));
492           else
493             printf ("%5ld", _bfd_int64_low (vma));
494 #endif
495           break;
496
497         case UNSIGNED:
498 #if BFD_HOST_64BIT_LONG
499           printf ("%lu", vma);
500 #else
501           if (_bfd_int64_high (vma))
502             /* ugg */
503             printf ("++%lu", _bfd_int64_low (vma));
504           else
505             printf ("%lu", _bfd_int64_low (vma));
506 #endif
507           break;
508         }
509     }
510 #endif
511 }
512
513 static bfd_vma
514 byte_get_big_endian (field, size)
515      unsigned char * field;
516      int             size;
517 {
518   switch (size)
519     {
520     case 1:
521       return * field;
522
523     case 2:
524       return ((unsigned int) (field [1])) | (((int) (field [0])) << 8);
525
526     case 4:
527       return ((unsigned long) (field [3]))
528         |   (((unsigned long) (field [2])) << 8)
529         |   (((unsigned long) (field [1])) << 16)
530         |   (((unsigned long) (field [0])) << 24);
531
532 #ifndef BFD64
533     case 8:
534       /* Although we are extracing data from an 8 byte wide field, we
535          are returning only 4 bytes of data.  */
536       return ((unsigned long) (field [7]))
537         |   (((unsigned long) (field [6])) << 8)
538         |   (((unsigned long) (field [5])) << 16)
539         |   (((unsigned long) (field [4])) << 24);
540 #else
541     case 8:
542     case -8:
543       /* This is a special case, generated by the BYTE_GET8 macro.
544          It means that we are loading an 8 byte value from a field
545          in an external structure into an 8 byte value in a field
546          in an internal strcuture.  */
547       return ((bfd_vma) (field [7]))
548         |   (((bfd_vma) (field [6])) << 8)
549         |   (((bfd_vma) (field [5])) << 16)
550         |   (((bfd_vma) (field [4])) << 24)
551         |   (((bfd_vma) (field [3])) << 32)
552         |   (((bfd_vma) (field [2])) << 40)
553         |   (((bfd_vma) (field [1])) << 48)
554         |   (((bfd_vma) (field [0])) << 56);
555 #endif
556
557     default:
558       error (_("Unhandled data length: %d\n"), size);
559       abort ();
560     }
561 }
562
563 /* Guess the relocation size commonly used by the specific machines.  */
564
565 static int
566 guess_is_rela (e_machine)
567      unsigned long e_machine;
568 {
569   switch (e_machine)
570     {
571       /* Targets that use REL relocations.  */
572     case EM_ARM:
573     case EM_386:
574     case EM_486:
575     case EM_960:
576     case EM_CYGNUS_M32R:
577     case EM_CYGNUS_D10V:
578     case EM_MIPS:
579     case EM_MIPS_RS3_LE:
580       return FALSE;
581
582       /* Targets that use RELA relocations.  */
583     case EM_68K:
584     case EM_SPARC32PLUS:
585     case EM_SPARCV9:
586     case EM_SPARC:
587     case EM_PPC:
588     case EM_CYGNUS_V850:
589     case EM_CYGNUS_D30V:
590     case EM_CYGNUS_MN10200:
591     case EM_CYGNUS_MN10300:
592     case EM_CYGNUS_FR30:
593     case EM_SH:
594     case EM_ALPHA:
595     case EM_MCORE:
596     case EM_IA_64:
597     case EM_AVR:
598     case EM_CRIS:
599     case EM_860:
600     case EM_X86_64:
601     case EM_S390:
602     case EM_S390_OLD:
603       return TRUE;
604
605     case EM_MMA:
606     case EM_PCP:
607     case EM_NCPU:
608     case EM_NDR1:
609     case EM_STARCORE:
610     case EM_ME16:
611     case EM_ST100:
612     case EM_TINYJ:
613     case EM_FX66:
614     case EM_ST9PLUS:
615     case EM_ST7:
616     case EM_68HC16:
617     case EM_68HC11:
618     case EM_68HC08:
619     case EM_68HC05:
620     case EM_SVX:
621     case EM_ST19:
622     case EM_VAX:
623     default:
624       warn (_("Don't know about relocations on this machine architecture\n"));
625       return FALSE;
626     }
627 }
628
629 static int
630 slurp_rela_relocs (file, rel_offset, rel_size, relasp, nrelasp)
631      FILE *file;
632      unsigned long rel_offset;
633      unsigned long rel_size;
634      Elf_Internal_Rela **relasp;
635      unsigned long *nrelasp;
636 {
637   Elf_Internal_Rela *relas;
638   unsigned long nrelas;
639   unsigned int i;
640
641   if (is_32bit_elf)
642     {
643       Elf32_External_Rela * erelas;
644
645       erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset,
646                                                  rel_size, _("relocs"));
647       if (!erelas)
648         return 0;
649
650       nrelas = rel_size / sizeof (Elf32_External_Rela);
651
652       relas = (Elf_Internal_Rela *)
653         malloc (nrelas * sizeof (Elf_Internal_Rela));
654
655       if (relas == NULL)
656         {
657           error(_("out of memory parsing relocs"));
658           return 0;
659         }
660
661       for (i = 0; i < nrelas; i++)
662         {
663           relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
664           relas[i].r_info   = BYTE_GET (erelas[i].r_info);
665           relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
666         }
667
668       free (erelas);
669     }
670   else
671     {
672       Elf64_External_Rela * erelas;
673
674       erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset,
675                                                  rel_size, _("relocs"));
676       if (!erelas)
677         return 0;
678
679       nrelas = rel_size / sizeof (Elf64_External_Rela);
680
681       relas = (Elf_Internal_Rela *)
682         malloc (nrelas * sizeof (Elf_Internal_Rela));
683
684       if (relas == NULL)
685         {
686           error(_("out of memory parsing relocs"));
687           return 0;
688         }
689
690       for (i = 0; i < nrelas; i++)
691         {
692           relas[i].r_offset = BYTE_GET8 (erelas[i].r_offset);
693           relas[i].r_info   = BYTE_GET8 (erelas[i].r_info);
694           relas[i].r_addend = BYTE_GET8 (erelas[i].r_addend);
695         }
696
697       free (erelas);
698     }
699   *relasp = relas;
700   *nrelasp = nrelas;
701   return 1;
702 }
703
704 static int
705 slurp_rel_relocs (file, rel_offset, rel_size, relsp, nrelsp)
706      FILE *file;
707      unsigned long rel_offset;
708      unsigned long rel_size;
709      Elf_Internal_Rel **relsp;
710      unsigned long *nrelsp;
711 {
712   Elf_Internal_Rel *rels;
713   unsigned long nrels;
714   unsigned int i;
715
716   if (is_32bit_elf)
717     {
718       Elf32_External_Rel * erels;
719
720       erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset,
721                                                rel_size, _("relocs"));
722       if (!erels)
723         return 0;
724
725       nrels = rel_size / sizeof (Elf32_External_Rel);
726
727       rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel));
728
729       if (rels == NULL)
730         {
731           error(_("out of memory parsing relocs"));
732           return 0;
733         }
734
735       for (i = 0; i < nrels; i++)
736         {
737           rels[i].r_offset = BYTE_GET (erels[i].r_offset);
738           rels[i].r_info   = BYTE_GET (erels[i].r_info);
739         }
740
741       free (erels);
742     }
743   else
744     {
745       Elf64_External_Rel * erels;
746
747       erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset,
748                                                rel_size, _("relocs"));
749       if (!erels)
750         return 0;
751
752       nrels = rel_size / sizeof (Elf64_External_Rel);
753
754       rels = (Elf_Internal_Rel *) malloc (nrels * sizeof (Elf_Internal_Rel));
755
756       if (rels == NULL)
757         {
758           error(_("out of memory parsing relocs"));
759           return 0;
760         }
761
762       for (i = 0; i < nrels; i++)
763         {
764           rels[i].r_offset = BYTE_GET8 (erels[i].r_offset);
765           rels[i].r_info   = BYTE_GET8 (erels[i].r_info);
766         }
767
768       free (erels);
769     }
770   *relsp = rels;
771   *nrelsp = nrels;
772   return 1;
773 }
774
775 /* Display the contents of the relocation data found at the specified offset.  */
776 static int
777 dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
778      FILE *             file;
779      unsigned long      rel_offset;
780      unsigned long      rel_size;
781      Elf_Internal_Sym * symtab;
782      unsigned long      nsyms;
783      char *             strtab;
784      int                is_rela;
785 {
786   unsigned int        i;
787   Elf_Internal_Rel *  rels;
788   Elf_Internal_Rela * relas;
789
790
791   if (is_rela == UNKNOWN)
792     is_rela = guess_is_rela (elf_header.e_machine);
793
794   if (is_rela)
795     {
796       if (!slurp_rela_relocs (file, rel_offset, rel_size, &relas, &rel_size))
797         return 0;
798     }
799   else
800     {
801       if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
802         return 0;
803     }
804
805   if (is_rela)
806     printf
807       (_("  Offset    Info  Type            Symbol's Value  Symbol's Name          Addend\n"));
808   else
809     printf
810       (_("  Offset    Info  Type            Symbol's Value  Symbol's Name\n"));
811
812   for (i = 0; i < rel_size; i++)
813     {
814       const char * rtype;
815       bfd_vma      offset;
816       bfd_vma      info;
817       bfd_vma      symtab_index;
818       bfd_vma      type;
819
820       if (is_rela)
821         {
822           offset = relas [i].r_offset;
823           info   = relas [i].r_info;
824         }
825       else
826         {
827           offset = rels [i].r_offset;
828           info   = rels [i].r_info;
829         }
830
831       if (is_32bit_elf)
832         {
833           type         = ELF32_R_TYPE (info);
834           symtab_index = ELF32_R_SYM  (info);
835         }
836       else
837         {
838           if (elf_header.e_machine == EM_SPARCV9)
839             type       = ELF64_R_TYPE_ID (info);
840           else
841             type       = ELF64_R_TYPE (info);
842           /* The #ifdef BFD64 below is to prevent a compile time warning.
843              We know that if we do not have a 64 bit data type that we
844              will never execute this code anyway.  */
845 #ifdef BFD64
846           symtab_index = ELF64_R_SYM  (info);
847 #endif
848         }
849
850 #ifdef _bfd_int64_low
851       printf ("  %8.8lx  %5.5lx ", _bfd_int64_low (offset), _bfd_int64_low (info));
852 #else
853       printf ("  %8.8lx  %5.5lx ", offset, info);
854 #endif
855
856       switch (elf_header.e_machine)
857         {
858         default:
859           rtype = NULL;
860           break;
861
862         case EM_CYGNUS_M32R:
863           rtype = elf_m32r_reloc_type (type);
864           break;
865
866         case EM_386:
867         case EM_486:
868           rtype = elf_i386_reloc_type (type);
869           break;
870
871         case EM_68K:
872           rtype = elf_m68k_reloc_type (type);
873           break;
874
875         case EM_960:
876           rtype = elf_i960_reloc_type (type);
877           break;
878
879         case EM_AVR:
880           rtype = elf_avr_reloc_type (type);
881           break;
882
883         case EM_OLD_SPARCV9:
884         case EM_SPARC32PLUS:
885         case EM_SPARCV9:
886         case EM_SPARC:
887           rtype = elf_sparc_reloc_type (type);
888           break;
889
890         case EM_CYGNUS_V850:
891           rtype = v850_reloc_type (type);
892           break;
893
894         case EM_CYGNUS_D10V:
895           rtype = elf_d10v_reloc_type (type);
896           break;
897
898         case EM_CYGNUS_D30V:
899           rtype = elf_d30v_reloc_type (type);
900           break;
901
902         case EM_SH:
903           rtype = elf_sh_reloc_type (type);
904           break;
905
906         case EM_CYGNUS_MN10300:
907           rtype = elf_mn10300_reloc_type (type);
908           break;
909
910         case EM_CYGNUS_MN10200:
911           rtype = elf_mn10200_reloc_type (type);
912           break;
913
914         case EM_CYGNUS_FR30:
915           rtype = elf_fr30_reloc_type (type);
916           break;
917
918         case EM_MCORE:
919           rtype = elf_mcore_reloc_type (type);
920           break;
921
922         case EM_PPC:
923           rtype = elf_ppc_reloc_type (type);
924           break;
925
926         case EM_MIPS:
927         case EM_MIPS_RS3_LE:
928           rtype = elf_mips_reloc_type (type);
929           break;
930
931         case EM_ALPHA:
932           rtype = elf_alpha_reloc_type (type);
933           break;
934
935         case EM_ARM:
936           rtype = elf_arm_reloc_type (type);
937           break;
938
939         case EM_CYGNUS_ARC:
940         case EM_ARC:
941           rtype = elf_arc_reloc_type (type);
942           break;
943
944         case EM_PARISC:
945           rtype = elf_hppa_reloc_type (type);
946           break;
947
948         case EM_PJ:
949           rtype = elf_pj_reloc_type (type);
950           break;
951         case EM_IA_64:
952           rtype = elf_ia64_reloc_type (type);
953           break;
954
955         case EM_CRIS:
956           rtype = elf_cris_reloc_type (type);
957           break;
958
959         case EM_860:
960           rtype = elf_i860_reloc_type (type);
961           break;
962
963         case EM_X86_64:
964           rtype = elf_x86_64_reloc_type (type);
965           break;
966
967         case EM_S390_OLD:
968         case EM_S390:
969           rtype = elf_s390_reloc_type (type);
970           break;
971         }
972
973       if (rtype == NULL)
974 #ifdef _bfd_int64_low
975         printf (_("unrecognised: %-7lx"), _bfd_int64_low (type));
976 #else
977         printf (_("unrecognised: %-7lx"), type);
978 #endif
979       else
980         printf ("%-21.21s", rtype);
981
982       if (symtab_index)
983         {
984           if (symtab == NULL || symtab_index >= nsyms)
985             printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
986           else
987             {
988               Elf_Internal_Sym * psym;
989
990               psym = symtab + symtab_index;
991
992               printf (" ");
993               print_vma (psym->st_value, LONG_HEX);
994               printf ("  ");
995
996               if (psym->st_name == 0)
997                 printf ("%-25.25s",
998                         SECTION_NAME (section_headers + psym->st_shndx));
999               else if (strtab == NULL)
1000                 printf (_("<string table index %3ld>"), psym->st_name);
1001               else
1002                 printf ("%-25.25s", strtab + psym->st_name);
1003
1004               if (is_rela)
1005                 printf (" + %lx", (unsigned long) relas [i].r_addend);
1006             }
1007         }
1008       else if (is_rela)
1009         {
1010           printf ("%*c", is_32bit_elf ? 34 : 26, ' ');
1011           print_vma (relas[i].r_addend, LONG_HEX);
1012         }
1013
1014       if (elf_header.e_machine == EM_SPARCV9
1015           && !strcmp (rtype, "R_SPARC_OLO10"))
1016         printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
1017
1018       putchar ('\n');
1019     }
1020
1021   if (is_rela)
1022     free (relas);
1023   else
1024     free (rels);
1025
1026   return 1;
1027 }
1028
1029 static const char *
1030 get_mips_dynamic_type (type)
1031      unsigned long type;
1032 {
1033   switch (type)
1034     {
1035     case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1036     case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1037     case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1038     case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1039     case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1040     case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1041     case DT_MIPS_MSYM: return "MIPS_MSYM";
1042     case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1043     case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1044     case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1045     case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1046     case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1047     case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1048     case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1049     case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1050     case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1051     case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1052     case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1053     case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1054     case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1055     case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1056     case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1057     case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1058     case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1059     case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1060     case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1061     case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1062     case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1063     case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1064     case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1065     case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1066     case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1067     case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1068     case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1069     case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1070     case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1071     case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1072     case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1073     case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1074     case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1075     case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1076     case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1077     case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
1078     default:
1079       return NULL;
1080     }
1081 }
1082
1083 static const char *
1084 get_sparc64_dynamic_type (type)
1085      unsigned long type;
1086 {
1087   switch (type)
1088     {
1089     case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1090     default:
1091       return NULL;
1092     }
1093 }
1094
1095 static const char *
1096 get_parisc_dynamic_type (type)
1097      unsigned long type;
1098 {
1099   switch (type)
1100     {
1101     case DT_HP_LOAD_MAP:        return "HP_LOAD_MAP";
1102     case DT_HP_DLD_FLAGS:       return "HP_DLD_FLAGS";
1103     case DT_HP_DLD_HOOK:        return "HP_DLD_HOOK";
1104     case DT_HP_UX10_INIT:       return "HP_UX10_INIT";
1105     case DT_HP_UX10_INITSZ:     return "HP_UX10_INITSZ";
1106     case DT_HP_PREINIT:         return "HP_PREINIT";
1107     case DT_HP_PREINITSZ:       return "HP_PREINITSZ";
1108     case DT_HP_NEEDED:          return "HP_NEEDED";
1109     case DT_HP_TIME_STAMP:      return "HP_TIME_STAMP";
1110     case DT_HP_CHECKSUM:        return "HP_CHECKSUM";
1111     case DT_HP_GST_SIZE:        return "HP_GST_SIZE";
1112     case DT_HP_GST_VERSION:     return "HP_GST_VERSION";
1113     case DT_HP_GST_HASHVAL:     return "HP_GST_HASHVAL";
1114     default:
1115       return NULL;
1116     }
1117 }
1118
1119 static const char *
1120 get_dynamic_type (type)
1121      unsigned long type;
1122 {
1123   static char buff [32];
1124
1125   switch (type)
1126     {
1127     case DT_NULL:       return "NULL";
1128     case DT_NEEDED:     return "NEEDED";
1129     case DT_PLTRELSZ:   return "PLTRELSZ";
1130     case DT_PLTGOT:     return "PLTGOT";
1131     case DT_HASH:       return "HASH";
1132     case DT_STRTAB:     return "STRTAB";
1133     case DT_SYMTAB:     return "SYMTAB";
1134     case DT_RELA:       return "RELA";
1135     case DT_RELASZ:     return "RELASZ";
1136     case DT_RELAENT:    return "RELAENT";
1137     case DT_STRSZ:      return "STRSZ";
1138     case DT_SYMENT:     return "SYMENT";
1139     case DT_INIT:       return "INIT";
1140     case DT_FINI:       return "FINI";
1141     case DT_SONAME:     return "SONAME";
1142     case DT_RPATH:      return "RPATH";
1143     case DT_SYMBOLIC:   return "SYMBOLIC";
1144     case DT_REL:        return "REL";
1145     case DT_RELSZ:      return "RELSZ";
1146     case DT_RELENT:     return "RELENT";
1147     case DT_PLTREL:     return "PLTREL";
1148     case DT_DEBUG:      return "DEBUG";
1149     case DT_TEXTREL:    return "TEXTREL";
1150     case DT_JMPREL:     return "JMPREL";
1151     case DT_BIND_NOW:   return "BIND_NOW";
1152     case DT_INIT_ARRAY: return "INIT_ARRAY";
1153     case DT_FINI_ARRAY: return "FINI_ARRAY";
1154     case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1155     case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
1156     case DT_RUNPATH:    return "RUNPATH";
1157     case DT_FLAGS:      return "FLAGS";
1158
1159     case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1160     case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
1161
1162     case DT_CHECKSUM:   return "CHECKSUM";
1163     case DT_PLTPADSZ:   return "PLTPADSZ";
1164     case DT_MOVEENT:    return "MOVEENT";
1165     case DT_MOVESZ:     return "MOVESZ";
1166     case DT_FEATURE:    return "FEATURE";
1167     case DT_POSFLAG_1:  return "POSFLAG_1";
1168     case DT_SYMINSZ:    return "SYMINSZ";
1169     case DT_SYMINENT:   return "SYMINENT"; /* aka VALRNGHI */
1170
1171     case DT_ADDRRNGLO:  return "ADDRRNGLO";
1172     case DT_CONFIG:     return "CONFIG";
1173     case DT_DEPAUDIT:   return "DEPAUDIT";
1174     case DT_AUDIT:      return "AUDIT";
1175     case DT_PLTPAD:     return "PLTPAD";
1176     case DT_MOVETAB:    return "MOVETAB";
1177     case DT_SYMINFO:    return "SYMINFO"; /* aka ADDRRNGHI */
1178
1179     case DT_VERSYM:     return "VERSYM";
1180
1181     case DT_RELACOUNT:  return "RELACOUNT";
1182     case DT_RELCOUNT:   return "RELCOUNT";
1183     case DT_FLAGS_1:    return "FLAGS_1";
1184     case DT_VERDEF:     return "VERDEF";
1185     case DT_VERDEFNUM:  return "VERDEFNUM";
1186     case DT_VERNEED:    return "VERNEED";
1187     case DT_VERNEEDNUM: return "VERNEEDNUM";
1188
1189     case DT_AUXILIARY:  return "AUXILIARY";
1190     case DT_USED:       return "USED";
1191     case DT_FILTER:     return "FILTER";
1192
1193     default:
1194       if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1195         {
1196           const char * result;
1197
1198           switch (elf_header.e_machine)
1199             {
1200             case EM_MIPS:
1201             case EM_MIPS_RS3_LE:
1202               result = get_mips_dynamic_type (type);
1203               break;
1204             case EM_SPARCV9:
1205               result = get_sparc64_dynamic_type (type);
1206               break;
1207             default:
1208               result = NULL;
1209               break;
1210             }
1211
1212           if (result != NULL)
1213             return result;
1214
1215           sprintf (buff, _("Processor Specific: %lx"), type);
1216         }
1217       else if ((type >= DT_LOOS) && (type <= DT_HIOS))
1218         {
1219           const char * result;
1220
1221           switch (elf_header.e_machine)
1222             {
1223             case EM_PARISC:
1224               result = get_parisc_dynamic_type (type);
1225               break;
1226             default:
1227               result = NULL;
1228               break;
1229             }
1230
1231           if (result != NULL)
1232             return result;
1233
1234           sprintf (buff, _("Operating System specific: %lx"), type);
1235         }
1236       else
1237         sprintf (buff, _("<unknown>: %lx"), type);
1238
1239       return buff;
1240     }
1241 }
1242
1243 static char *
1244 get_file_type (e_type)
1245      unsigned e_type;
1246 {
1247   static char buff [32];
1248
1249   switch (e_type)
1250     {
1251     case ET_NONE:       return _("NONE (None)");
1252     case ET_REL:        return _("REL (Relocatable file)");
1253     case ET_EXEC:       return _("EXEC (Executable file)");
1254     case ET_DYN:        return _("DYN (Shared object file)");
1255     case ET_CORE:       return _("CORE (Core file)");
1256
1257     default:
1258       if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
1259         sprintf (buff, _("Processor Specific: (%x)"), e_type);
1260       else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
1261         sprintf (buff, _("OS Specific: (%x)"), e_type);
1262       else
1263         sprintf (buff, _("<unknown>: %x"), e_type);
1264       return buff;
1265     }
1266 }
1267
1268 static char *
1269 get_machine_name (e_machine)
1270      unsigned e_machine;
1271 {
1272   static char buff [64]; /* XXX */
1273
1274   switch (e_machine)
1275     {
1276     case EM_NONE:               return _("None");
1277     case EM_M32:                return "WE32100";
1278     case EM_SPARC:              return "Sparc";
1279     case EM_386:                return "Intel 80386";
1280     case EM_68K:                return "MC68000";
1281     case EM_88K:                return "MC88000";
1282     case EM_486:                return "Intel 80486";
1283     case EM_860:                return "Intel 80860";
1284     case EM_MIPS:               return "MIPS R3000";
1285     case EM_S370:               return "IBM System/370";
1286     case EM_MIPS_RS3_LE:        return "MIPS R4000 big-endian";
1287     case EM_OLD_SPARCV9:        return "Sparc v9 (old)";
1288     case EM_PARISC:             return "HPPA";
1289     case EM_PPC_OLD:            return "Power PC (old)";
1290     case EM_SPARC32PLUS:        return "Sparc v8+" ;
1291     case EM_960:                return "Intel 90860";
1292     case EM_PPC:                return "PowerPC";
1293     case EM_V800:               return "NEC V800";
1294     case EM_FR20:               return "Fujitsu FR20";
1295     case EM_RH32:               return "TRW RH32";
1296     case EM_MCORE:              return "MCORE";
1297     case EM_ARM:                return "ARM";
1298     case EM_OLD_ALPHA:          return "Digital Alpha (old)";
1299     case EM_SH:                 return "Hitachi SH";
1300     case EM_SPARCV9:            return "Sparc v9";
1301     case EM_TRICORE:            return "Siemens Tricore";
1302     case EM_ARC:                return "ARC";
1303     case EM_H8_300:             return "Hitachi H8/300";
1304     case EM_H8_300H:            return "Hitachi H8/300H";
1305     case EM_H8S:                return "Hitachi H8S";
1306     case EM_H8_500:             return "Hitachi H8/500";
1307     case EM_IA_64:              return "Intel IA-64";
1308     case EM_MIPS_X:             return "Stanford MIPS-X";
1309     case EM_COLDFIRE:           return "Motorola Coldfire";
1310     case EM_68HC12:             return "Motorola M68HC12";
1311     case EM_ALPHA:              return "Alpha";
1312     case EM_CYGNUS_D10V:        return "d10v";
1313     case EM_CYGNUS_D30V:        return "d30v";
1314     case EM_CYGNUS_ARC:         return "ARC";
1315     case EM_CYGNUS_M32R:        return "Mitsubishi M32r";
1316     case EM_CYGNUS_V850:        return "NEC v850";
1317     case EM_CYGNUS_MN10300:     return "mn10300";
1318     case EM_CYGNUS_MN10200:     return "mn10200";
1319     case EM_CYGNUS_FR30:        return "Fujitsu FR30";
1320     case EM_PJ:                 return "picoJava";
1321     case EM_MMA:                return "Fujitsu Multimedia Accelerator";
1322     case EM_PCP:                return "Siemens PCP";
1323     case EM_NCPU:               return "Sony nCPU embedded RISC processor";
1324     case EM_NDR1:               return "Denso NDR1 microprocesspr";
1325     case EM_STARCORE:           return "Motorola Star*Core processor";
1326     case EM_ME16:               return "Toyota ME16 processor";
1327     case EM_ST100:              return "STMicroelectronics ST100 processor";
1328     case EM_TINYJ:              return "Advanced Logic Corp. TinyJ embedded processor";
1329     case EM_FX66:               return "Siemens FX66 microcontroller";
1330     case EM_ST9PLUS:            return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1331     case EM_ST7:                return "STMicroelectronics ST7 8-bit microcontroller";
1332     case EM_68HC16:             return "Motorola MC68HC16 Microcontroller";
1333     case EM_68HC11:             return "Motorola MC68HC11 Microcontroller";
1334     case EM_68HC08:             return "Motorola MC68HC08 Microcontroller";
1335     case EM_68HC05:             return "Motorola MC68HC05 Microcontroller";
1336     case EM_SVX:                return "Silicon Graphics SVx";
1337     case EM_ST19:               return "STMicroelectronics ST19 8-bit microcontroller";
1338     case EM_VAX:                return "Digital VAX";
1339     case EM_AVR:                return "Atmel AVR 8-bit microcontroller";
1340     case EM_CRIS:               return "Axis Communications 32-bit embedded processor";
1341     case EM_JAVELIN:            return "Infineon Technologies 32-bit embedded cpu";
1342     case EM_FIREPATH:           return "Element 14 64-bit DSP processor";
1343     case EM_ZSP:                return "LSI Logic's 16-bit DSP processor";
1344     case EM_MMIX:               return "Donald Knuth's educational 64-bit processor";
1345     case EM_HUANY:              return "Harvard Universitys's machine-independent object format";
1346     case EM_PRISM:              return "SiTera Prism";
1347     case EM_X86_64:             return "Advanced Micro Devices X86-64";
1348     case EM_S390_OLD:
1349     case EM_S390:               return "IBM S/390";
1350     default:
1351       sprintf (buff, _("<unknown>: %x"), e_machine);
1352       return buff;
1353     }
1354 }
1355
1356 static void
1357 decode_ARM_machine_flags (e_flags, buf)
1358      unsigned e_flags;
1359      char buf[];
1360 {
1361   unsigned eabi;
1362   int unknown = 0;
1363
1364   eabi = EF_ARM_EABI_VERSION (e_flags);
1365   e_flags &= ~ EF_ARM_EABIMASK;
1366
1367   /* Handle "generic" ARM flags.  */
1368   if (e_flags & EF_ARM_RELEXEC)
1369     {
1370       strcat (buf, ", relocatable executable");
1371       e_flags &= ~ EF_ARM_RELEXEC;
1372     }
1373
1374   if (e_flags & EF_ARM_HASENTRY)
1375     {
1376       strcat (buf, ", has entry point");
1377       e_flags &= ~ EF_ARM_HASENTRY;
1378     }
1379
1380   /* Now handle EABI specific flags.  */
1381   switch (eabi)
1382     {
1383     default:
1384       strcat (buf, ", <unrecognised EABI>");
1385       if (e_flags)
1386         unknown = 1;
1387       break;
1388
1389     case EF_ARM_EABI_VER1:
1390       strcat (buf, ", Version1 EABI");
1391       while (e_flags)
1392         {
1393           unsigned flag;
1394
1395           /* Process flags one bit at a time.  */
1396           flag = e_flags & - e_flags;
1397           e_flags &= ~ flag;
1398
1399           switch (flag)
1400             {
1401             case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK.  */
1402               strcat (buf, ", sorted symbol tables");
1403               break;
1404
1405             default:
1406               unknown = 1;
1407               break;
1408             }
1409         }
1410       break;
1411
1412     case EF_ARM_EABI_VER2:
1413       strcat (buf, ", Version2 EABI");
1414       while (e_flags)
1415         {
1416           unsigned flag;
1417
1418           /* Process flags one bit at a time.  */
1419           flag = e_flags & - e_flags;
1420           e_flags &= ~ flag;
1421
1422           switch (flag)
1423             {
1424             case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK.  */
1425               strcat (buf, ", sorted symbol tables");
1426               break;
1427
1428             case EF_ARM_DYNSYMSUSESEGIDX:
1429               strcat (buf, ", dynamic symbols use segment index");
1430               break;
1431
1432             case EF_ARM_MAPSYMSFIRST:
1433               strcat (buf, ", mapping symbols precede others");
1434               break;
1435
1436             default:
1437               unknown = 1;
1438               break;
1439             }
1440         }
1441       break;
1442
1443     case EF_ARM_EABI_UNKNOWN:
1444       strcat (buf, ", GNU EABI");
1445       while (e_flags)
1446         {
1447           unsigned flag;
1448
1449           /* Process flags one bit at a time.  */
1450           flag = e_flags & - e_flags;
1451           e_flags &= ~ flag;
1452
1453           switch (flag)
1454             {
1455             case EF_ARM_INTERWORK:
1456               strcat (buf, ", interworking enabled");
1457               break;
1458
1459             case EF_ARM_APCS_26:
1460               strcat (buf, ", uses APCS/26");
1461               break;
1462
1463             case EF_ARM_APCS_FLOAT:
1464               strcat (buf, ", uses APCS/float");
1465               break;
1466
1467             case EF_ARM_PIC:
1468               strcat (buf, ", position independent");
1469               break;
1470
1471             case EF_ARM_ALIGN8:
1472               strcat (buf, ", 8 bit structure alignment");
1473               break;
1474
1475             case EF_ARM_NEW_ABI:
1476               strcat (buf, ", uses new ABI");
1477               break;
1478
1479             case EF_ARM_OLD_ABI:
1480               strcat (buf, ", uses old ABI");
1481               break;
1482
1483             case EF_ARM_SOFT_FLOAT:
1484               strcat (buf, ", software FP");
1485               break;
1486
1487             default:
1488               unknown = 1;
1489               break;
1490             }
1491         }
1492     }
1493
1494   if (unknown)
1495     strcat (buf,", <unknown>");
1496 }
1497
1498 static char *
1499 get_machine_flags (e_flags, e_machine)
1500      unsigned e_flags;
1501      unsigned e_machine;
1502 {
1503   static char buf [1024];
1504
1505   buf[0] = '\0';
1506
1507   if (e_flags)
1508     {
1509       switch (e_machine)
1510         {
1511         default:
1512           break;
1513
1514         case EM_ARM:
1515           decode_ARM_machine_flags (e_flags, buf);
1516           break;
1517
1518         case EM_68K:
1519           if (e_flags & EF_CPU32)
1520             strcat (buf, ", cpu32");
1521           break;
1522
1523         case EM_PPC:
1524           if (e_flags & EF_PPC_EMB)
1525             strcat (buf, ", emb");
1526
1527           if (e_flags & EF_PPC_RELOCATABLE)
1528             strcat (buf, ", relocatable");
1529
1530           if (e_flags & EF_PPC_RELOCATABLE_LIB)
1531             strcat (buf, ", relocatable-lib");
1532           break;
1533
1534         case EM_CYGNUS_V850:
1535           switch (e_flags & EF_V850_ARCH)
1536             {
1537             case E_V850E_ARCH:
1538               strcat (buf, ", v850e");
1539               break;
1540             case E_V850EA_ARCH:
1541               strcat (buf, ", v850ea");
1542               break;
1543             case E_V850_ARCH:
1544               strcat (buf, ", v850");
1545               break;
1546             default:
1547               strcat (buf, ", unknown v850 architecture variant");
1548               break;
1549             }
1550           break;
1551
1552         case EM_CYGNUS_M32R:
1553           if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
1554             strcat (buf, ", m32r");
1555
1556           break;
1557
1558         case EM_MIPS:
1559         case EM_MIPS_RS3_LE:
1560           if (e_flags & EF_MIPS_NOREORDER)
1561             strcat (buf, ", noreorder");
1562
1563           if (e_flags & EF_MIPS_PIC)
1564             strcat (buf, ", pic");
1565
1566           if (e_flags & EF_MIPS_CPIC)
1567             strcat (buf, ", cpic");
1568
1569           if (e_flags & EF_MIPS_ABI2)
1570             strcat (buf, ", abi2");
1571
1572           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_1)
1573             strcat (buf, ", mips1");
1574
1575           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_2)
1576             strcat (buf, ", mips2");
1577
1578           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_3)
1579             strcat (buf, ", mips3");
1580
1581           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
1582             strcat (buf, ", mips4");
1583
1584           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_5)
1585             strcat (buf, ", mips5");
1586
1587           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32)
1588             strcat (buf, ", mips32");
1589
1590           if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64)
1591             strcat (buf, ", mips64");
1592
1593           switch ((e_flags & EF_MIPS_MACH))
1594             {
1595             case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
1596             case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
1597             case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
1598             case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
1599             case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
1600             case E_MIPS_MACH_MIPS32_4K: strcat (buf, ", mips32-4k"); break;
1601             case E_MIPS_MACH_SB1:  strcat (buf, ", sb1");  break;
1602             default: strcat (buf, " UNKNOWN"); break;
1603             }
1604           break;
1605
1606         case EM_SPARCV9:
1607           if (e_flags & EF_SPARC_32PLUS)
1608             strcat (buf, ", v8+");
1609
1610           if (e_flags & EF_SPARC_SUN_US1)
1611             strcat (buf, ", ultrasparcI");
1612
1613           if (e_flags & EF_SPARC_SUN_US3)
1614             strcat (buf, ", ultrasparcIII");
1615
1616           if (e_flags & EF_SPARC_HAL_R1)
1617             strcat (buf, ", halr1");
1618
1619           if (e_flags & EF_SPARC_LEDATA)
1620             strcat (buf, ", ledata");
1621
1622           if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
1623             strcat (buf, ", tso");
1624
1625           if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
1626             strcat (buf, ", pso");
1627
1628           if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
1629             strcat (buf, ", rmo");
1630           break;
1631
1632         case EM_PARISC:
1633           switch (e_flags & EF_PARISC_ARCH)
1634             {
1635             case EFA_PARISC_1_0:
1636               strcpy (buf, ", PA-RISC 1.0");
1637               break;
1638             case EFA_PARISC_1_1:
1639               strcpy (buf, ", PA-RISC 1.1");
1640               break;
1641             case EFA_PARISC_2_0:
1642               strcpy (buf, ", PA-RISC 2.0");
1643               break;
1644             default:
1645               break;
1646             }
1647           if (e_flags & EF_PARISC_TRAPNIL)
1648             strcat (buf, ", trapnil");
1649           if (e_flags & EF_PARISC_EXT)
1650             strcat (buf, ", ext");
1651           if (e_flags & EF_PARISC_LSB)
1652             strcat (buf, ", lsb");
1653           if (e_flags & EF_PARISC_WIDE)
1654             strcat (buf, ", wide");
1655           if (e_flags & EF_PARISC_NO_KABP)
1656             strcat (buf, ", no kabp");
1657           if (e_flags & EF_PARISC_LAZYSWAP)
1658             strcat (buf, ", lazyswap");
1659           break;
1660
1661         case EM_PJ:
1662           if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
1663             strcat (buf, ", new calling convention");
1664
1665           if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
1666             strcat (buf, ", gnu calling convention");
1667           break;
1668
1669         case EM_IA_64:
1670           if ((e_flags & EF_IA_64_ABI64))
1671             strcat (buf, ", 64-bit");
1672           else
1673             strcat (buf, ", 32-bit");
1674           if ((e_flags & EF_IA_64_REDUCEDFP))
1675             strcat (buf, ", reduced fp model");
1676           if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
1677             strcat (buf, ", no function descriptors, constant gp");
1678           else if ((e_flags & EF_IA_64_CONS_GP))
1679             strcat (buf, ", constant gp");
1680           if ((e_flags & EF_IA_64_ABSOLUTE))
1681             strcat (buf, ", absolute");
1682           break;
1683         }
1684     }
1685
1686   return buf;
1687 }
1688
1689 static const char *
1690 get_mips_segment_type (type)
1691      unsigned long type;
1692 {
1693   switch (type)
1694     {
1695     case PT_MIPS_REGINFO:
1696       return "REGINFO";
1697     case PT_MIPS_RTPROC:
1698       return "RTPROC";
1699     case PT_MIPS_OPTIONS:
1700       return "OPTIONS";
1701     default:
1702       break;
1703     }
1704
1705   return NULL;
1706 }
1707
1708 static const char *
1709 get_parisc_segment_type (type)
1710      unsigned long type;
1711 {
1712   switch (type)
1713     {
1714     case PT_HP_TLS:             return "HP_TLS";
1715     case PT_HP_CORE_NONE:       return "HP_CORE_NONE";
1716     case PT_HP_CORE_VERSION:    return "HP_CORE_VERSION";
1717     case PT_HP_CORE_KERNEL:     return "HP_CORE_KERNEL";
1718     case PT_HP_CORE_COMM:       return "HP_CORE_COMM";
1719     case PT_HP_CORE_PROC:       return "HP_CORE_PROC";
1720     case PT_HP_CORE_LOADABLE:   return "HP_CORE_LOADABLE";
1721     case PT_HP_CORE_STACK:      return "HP_CORE_STACK";
1722     case PT_HP_CORE_SHM:        return "HP_CORE_SHM";
1723     case PT_HP_CORE_MMF:        return "HP_CORE_MMF";
1724     case PT_HP_PARALLEL:        return "HP_PARALLEL";
1725     case PT_HP_FASTBIND:        return "HP_FASTBIND";
1726     case PT_PARISC_ARCHEXT:     return "PARISC_ARCHEXT";
1727     case PT_PARISC_UNWIND:      return "PARISC_UNWIND";
1728     default:
1729       break;
1730     }
1731
1732   return NULL;
1733 }
1734
1735 static const char *
1736 get_ia64_segment_type (type)
1737      unsigned long type;
1738 {
1739   switch (type)
1740     {
1741     case PT_IA_64_ARCHEXT:      return "IA_64_ARCHEXT";
1742     case PT_IA_64_UNWIND:       return "IA_64_UNWIND";
1743     default:
1744       break;
1745     }
1746
1747   return NULL;
1748 }
1749
1750 static const char *
1751 get_segment_type (p_type)
1752      unsigned long p_type;
1753 {
1754   static char buff [32];
1755
1756   switch (p_type)
1757     {
1758     case PT_NULL:       return "NULL";
1759     case PT_LOAD:       return "LOAD";
1760     case PT_DYNAMIC:    return "DYNAMIC";
1761     case PT_INTERP:     return "INTERP";
1762     case PT_NOTE:       return "NOTE";
1763     case PT_SHLIB:      return "SHLIB";
1764     case PT_PHDR:       return "PHDR";
1765
1766     default:
1767       if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
1768         {
1769           const char * result;
1770
1771           switch (elf_header.e_machine)
1772             {
1773             case EM_MIPS:
1774             case EM_MIPS_RS3_LE:
1775               result = get_mips_segment_type (p_type);
1776               break;
1777             case EM_PARISC:
1778               result = get_parisc_segment_type (p_type);
1779               break;
1780             case EM_IA_64:
1781               result = get_ia64_segment_type (p_type);
1782               break;
1783             default:
1784               result = NULL;
1785               break;
1786             }
1787
1788           if (result != NULL)
1789             return result;
1790
1791           sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
1792         }
1793       else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
1794         {
1795           const char * result;
1796
1797           switch (elf_header.e_machine)
1798             {
1799             case EM_PARISC:
1800               result = get_parisc_segment_type (p_type);
1801               break;
1802             default:
1803               result = NULL;
1804               break;
1805             }
1806
1807           if (result != NULL)
1808             return result;
1809
1810           sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
1811         }
1812       else
1813         sprintf (buff, _("<unknown>: %lx"), p_type);
1814
1815       return buff;
1816     }
1817 }
1818
1819 static const char *
1820 get_mips_section_type_name (sh_type)
1821      unsigned int sh_type;
1822 {
1823   switch (sh_type)
1824     {
1825     case SHT_MIPS_LIBLIST:       return "MIPS_LIBLIST";
1826     case SHT_MIPS_MSYM:          return "MIPS_MSYM";
1827     case SHT_MIPS_CONFLICT:      return "MIPS_CONFLICT";
1828     case SHT_MIPS_GPTAB:         return "MIPS_GPTAB";
1829     case SHT_MIPS_UCODE:         return "MIPS_UCODE";
1830     case SHT_MIPS_DEBUG:         return "MIPS_DEBUG";
1831     case SHT_MIPS_REGINFO:       return "MIPS_REGINFO";
1832     case SHT_MIPS_PACKAGE:       return "MIPS_PACKAGE";
1833     case SHT_MIPS_PACKSYM:       return "MIPS_PACKSYM";
1834     case SHT_MIPS_RELD:          return "MIPS_RELD";
1835     case SHT_MIPS_IFACE:         return "MIPS_IFACE";
1836     case SHT_MIPS_CONTENT:       return "MIPS_CONTENT";
1837     case SHT_MIPS_OPTIONS:       return "MIPS_OPTIONS";
1838     case SHT_MIPS_SHDR:          return "MIPS_SHDR";
1839     case SHT_MIPS_FDESC:         return "MIPS_FDESC";
1840     case SHT_MIPS_EXTSYM:        return "MIPS_EXTSYM";
1841     case SHT_MIPS_DENSE:         return "MIPS_DENSE";
1842     case SHT_MIPS_PDESC:         return "MIPS_PDESC";
1843     case SHT_MIPS_LOCSYM:        return "MIPS_LOCSYM";
1844     case SHT_MIPS_AUXSYM:        return "MIPS_AUXSYM";
1845     case SHT_MIPS_OPTSYM:        return "MIPS_OPTSYM";
1846     case SHT_MIPS_LOCSTR:        return "MIPS_LOCSTR";
1847     case SHT_MIPS_LINE:          return "MIPS_LINE";
1848     case SHT_MIPS_RFDESC:        return "MIPS_RFDESC";
1849     case SHT_MIPS_DELTASYM:      return "MIPS_DELTASYM";
1850     case SHT_MIPS_DELTAINST:     return "MIPS_DELTAINST";
1851     case SHT_MIPS_DELTACLASS:    return "MIPS_DELTACLASS";
1852     case SHT_MIPS_DWARF:         return "MIPS_DWARF";
1853     case SHT_MIPS_DELTADECL:     return "MIPS_DELTADECL";
1854     case SHT_MIPS_SYMBOL_LIB:    return "MIPS_SYMBOL_LIB";
1855     case SHT_MIPS_EVENTS:        return "MIPS_EVENTS";
1856     case SHT_MIPS_TRANSLATE:     return "MIPS_TRANSLATE";
1857     case SHT_MIPS_PIXIE:         return "MIPS_PIXIE";
1858     case SHT_MIPS_XLATE:         return "MIPS_XLATE";
1859     case SHT_MIPS_XLATE_DEBUG:   return "MIPS_XLATE_DEBUG";
1860     case SHT_MIPS_WHIRL:         return "MIPS_WHIRL";
1861     case SHT_MIPS_EH_REGION:     return "MIPS_EH_REGION";
1862     case SHT_MIPS_XLATE_OLD:     return "MIPS_XLATE_OLD";
1863     case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
1864     default:
1865       break;
1866     }
1867   return NULL;
1868 }
1869
1870 static const char *
1871 get_parisc_section_type_name (sh_type)
1872      unsigned int sh_type;
1873 {
1874   switch (sh_type)
1875     {
1876     case SHT_PARISC_EXT:        return "PARISC_EXT";
1877     case SHT_PARISC_UNWIND:     return "PARISC_UNWIND";
1878     case SHT_PARISC_DOC:        return "PARISC_DOC";
1879     default:
1880       break;
1881     }
1882   return NULL;
1883 }
1884
1885 static const char *
1886 get_ia64_section_type_name (sh_type)
1887      unsigned int sh_type;
1888 {
1889   switch (sh_type)
1890     {
1891     case SHT_IA_64_EXT:         return "IA_64_EXT";
1892     case SHT_IA_64_UNWIND:      return "IA_64_UNWIND";
1893     default:
1894       break;
1895     }
1896   return NULL;
1897 }
1898
1899 static const char *
1900 get_section_type_name (sh_type)
1901      unsigned int sh_type;
1902 {
1903   static char buff [32];
1904
1905   switch (sh_type)
1906     {
1907     case SHT_NULL:              return "NULL";
1908     case SHT_PROGBITS:          return "PROGBITS";
1909     case SHT_SYMTAB:            return "SYMTAB";
1910     case SHT_STRTAB:            return "STRTAB";
1911     case SHT_RELA:              return "RELA";
1912     case SHT_HASH:              return "HASH";
1913     case SHT_DYNAMIC:           return "DYNAMIC";
1914     case SHT_NOTE:              return "NOTE";
1915     case SHT_NOBITS:            return "NOBITS";
1916     case SHT_REL:               return "REL";
1917     case SHT_SHLIB:             return "SHLIB";
1918     case SHT_DYNSYM:            return "DYNSYM";
1919     case SHT_INIT_ARRAY:        return "INIT_ARRAY";
1920     case SHT_FINI_ARRAY:        return "FINI_ARRAY";
1921     case SHT_PREINIT_ARRAY:     return "PREINIT_ARRAY";
1922     case SHT_GROUP:             return "GROUP";
1923     case SHT_SYMTAB_SHNDX:      return "SYMTAB SECTION INDICIES";
1924     case SHT_GNU_verdef:        return "VERDEF";
1925     case SHT_GNU_verneed:       return "VERNEED";
1926     case SHT_GNU_versym:        return "VERSYM";
1927     case 0x6ffffff0:            return "VERSYM";
1928     case 0x6ffffffc:            return "VERDEF";
1929     case 0x7ffffffd:            return "AUXILIARY";
1930     case 0x7fffffff:            return "FILTER";
1931
1932     default:
1933       if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
1934         {
1935           const char * result;
1936
1937           switch (elf_header.e_machine)
1938             {
1939             case EM_MIPS:
1940             case EM_MIPS_RS3_LE:
1941               result = get_mips_section_type_name (sh_type);
1942               break;
1943             case EM_PARISC:
1944               result = get_parisc_section_type_name (sh_type);
1945               break;
1946             case EM_IA_64:
1947               result = get_ia64_section_type_name (sh_type);
1948               break;
1949             default:
1950               result = NULL;
1951               break;
1952             }
1953
1954           if (result != NULL)
1955             return result;
1956
1957           sprintf (buff, "SHT_LOPROC+%x", sh_type - SHT_LOPROC);
1958         }
1959       else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
1960         sprintf (buff, "SHT_LOOS+%x", sh_type - SHT_LOOS);
1961       else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
1962         sprintf (buff, "SHT_LOUSER+%x", sh_type - SHT_LOUSER);
1963       else
1964         sprintf (buff, _("<unknown>: %x"), sh_type);
1965
1966       return buff;
1967     }
1968 }
1969
1970 struct option options [] =
1971 {
1972   {"all",              no_argument, 0, 'a'},
1973   {"file-header",      no_argument, 0, 'h'},
1974   {"program-headers",  no_argument, 0, 'l'},
1975   {"headers",          no_argument, 0, 'e'},
1976   {"histogram",        no_argument, 0, 'I'},
1977   {"segments",         no_argument, 0, 'l'},
1978   {"sections",         no_argument, 0, 'S'},
1979   {"section-headers",  no_argument, 0, 'S'},
1980   {"symbols",          no_argument, 0, 's'},
1981   {"syms",             no_argument, 0, 's'},
1982   {"relocs",           no_argument, 0, 'r'},
1983   {"notes",            no_argument, 0, 'n'},
1984   {"dynamic",          no_argument, 0, 'd'},
1985   {"arch-specific",    no_argument, 0, 'A'},
1986   {"version-info",     no_argument, 0, 'V'},
1987   {"use-dynamic",      no_argument, 0, 'D'},
1988   {"hex-dump",         required_argument, 0, 'x'},
1989   {"debug-dump",       optional_argument, 0, 'w'},
1990   {"unwind",           no_argument, 0, 'u'},
1991 #ifdef SUPPORT_DISASSEMBLY
1992   {"instruction-dump", required_argument, 0, 'i'},
1993 #endif
1994
1995   {"version",          no_argument, 0, 'v'},
1996   {"help",             no_argument, 0, 'H'},
1997   {0,                  no_argument, 0, 0}
1998 };
1999
2000 static void
2001 usage ()
2002 {
2003   fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n"));
2004   fprintf (stdout, _("  Options are:\n"));
2005   fprintf (stdout, _("  -a or --all               Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
2006   fprintf (stdout, _("  -h or --file-header       Display the ELF file header\n"));
2007   fprintf (stdout, _("  -l or --program-headers or --segments\n"));
2008   fprintf (stdout, _("                            Display the program headers\n"));
2009   fprintf (stdout, _("  -S or --section-headers or --sections\n"));
2010   fprintf (stdout, _("                            Display the sections' header\n"));
2011   fprintf (stdout, _("  -e or --headers           Equivalent to: -h -l -S\n"));
2012   fprintf (stdout, _("  -s or --syms or --symbols Display the symbol table\n"));
2013   fprintf (stdout, _("  -n or --notes             Display the core notes (if present)\n"));
2014   fprintf (stdout, _("  -r or --relocs            Display the relocations (if present)\n"));
2015   fprintf (stdout, _("  -u or --unwind            Display the unwind info (if present)\n"));
2016   fprintf (stdout, _("  -d or --dynamic           Display the dynamic segment (if present)\n"));
2017   fprintf (stdout, _("  -V or --version-info      Display the version sections (if present)\n"));
2018   fprintf (stdout, _("  -A or --arch-specific     Display architecture specific information (if any).\n"));
2019   fprintf (stdout, _("  -D or --use-dynamic       Use the dynamic section info when displaying symbols\n"));
2020   fprintf (stdout, _("  -x <number> or --hex-dump=<number>\n"));
2021   fprintf (stdout, _("                            Dump the contents of section <number>\n"));
2022   fprintf (stdout, _("  -w[liaprf] or --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=frames]\n"));
2023   fprintf (stdout, _("                            Display the contents of DWARF2 debug sections\n"));
2024 #ifdef SUPPORT_DISASSEMBLY
2025   fprintf (stdout, _("  -i <number> or --instruction-dump=<number>\n"));
2026   fprintf (stdout, _("                            Disassemble the contents of section <number>\n"));
2027 #endif
2028   fprintf (stdout, _("  -I or --histogram         Display histogram of bucket list lengths\n"));
2029   fprintf (stdout, _("  -v or --version           Display the version number of readelf\n"));
2030   fprintf (stdout, _("  -H or --help              Display this information\n"));
2031   fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
2032
2033   exit (0);
2034 }
2035
2036 static void
2037 request_dump (section, type)
2038      unsigned int section;
2039      char         type;
2040 {
2041   if (section >= num_dump_sects)
2042     {
2043       char * new_dump_sects;
2044
2045       new_dump_sects = (char *) calloc (section + 1, 1);
2046
2047       if (new_dump_sects == NULL)
2048         error (_("Out of memory allocating dump request table."));
2049       else
2050         {
2051           /* Copy current flag settings.  */
2052           memcpy (new_dump_sects, dump_sects, num_dump_sects);
2053
2054           free (dump_sects);
2055
2056           dump_sects = new_dump_sects;
2057           num_dump_sects = section + 1;
2058         }
2059     }
2060
2061   if (dump_sects)
2062     dump_sects [section] |= type;
2063
2064   return;
2065 }
2066
2067 static void
2068 parse_args (argc, argv)
2069      int argc;
2070      char ** argv;
2071 {
2072   int c;
2073
2074   if (argc < 2)
2075     usage ();
2076
2077   while ((c = getopt_long
2078           (argc, argv, "ersuahnldSDAIw::x:i:vV", options, NULL)) != EOF)
2079     {
2080       char *    cp;
2081       int       section;
2082
2083       switch (c)
2084         {
2085         case 0:
2086           /* Long options.  */
2087           break;
2088         case 'H':
2089           usage ();
2090           break;
2091
2092         case 'a':
2093           do_syms ++;
2094           do_reloc ++;
2095           do_unwind ++;
2096           do_dynamic ++;
2097           do_header ++;
2098           do_sections ++;
2099           do_segments ++;
2100           do_version ++;
2101           do_histogram ++;
2102           do_arch ++;
2103           do_notes ++;
2104           break;
2105         case 'e':
2106           do_header ++;
2107           do_sections ++;
2108           do_segments ++;
2109           break;
2110         case 'A':
2111           do_arch ++;
2112           break;
2113         case 'D':
2114           do_using_dynamic ++;
2115           break;
2116         case 'r':
2117           do_reloc ++;
2118           break;
2119         case 'u':
2120           do_unwind ++;
2121           break;
2122         case 'h':
2123           do_header ++;
2124           break;
2125         case 'l':
2126           do_segments ++;
2127           break;
2128         case 's':
2129           do_syms ++;
2130           break;
2131         case 'S':
2132           do_sections ++;
2133           break;
2134         case 'd':
2135           do_dynamic ++;
2136           break;
2137         case 'I':
2138           do_histogram ++;
2139           break;
2140         case 'n':
2141           do_notes ++;
2142           break;
2143         case 'x':
2144           do_dump ++;
2145           section = strtoul (optarg, & cp, 0);
2146           if (! * cp && section >= 0)
2147             {
2148               request_dump (section, HEX_DUMP);
2149               break;
2150             }
2151           goto oops;
2152         case 'w':
2153           do_dump ++;
2154           if (optarg == 0)
2155             do_debugging = 1;
2156           else
2157             {
2158               do_debugging = 0;
2159               switch (optarg[0])
2160                 {
2161                 case 'i':
2162                 case 'I':
2163                   do_debug_info = 1;
2164                   break;
2165
2166                 case 'a':
2167                 case 'A':
2168                   do_debug_abbrevs = 1;
2169                   break;
2170
2171                 case 'l':
2172                 case 'L':
2173                   do_debug_lines = 1;
2174                   break;
2175
2176                 case 'p':
2177                 case 'P':
2178                   do_debug_pubnames = 1;
2179                   break;
2180
2181                 case 'r':
2182                 case 'R':
2183                   do_debug_aranges = 1;
2184                   break;
2185
2186                 case 'F':
2187                   do_debug_frames_interp = 1;
2188                 case 'f':
2189                   do_debug_frames = 1;
2190                   break;
2191
2192                 default:
2193                   warn (_("Unrecognised debug option '%s'\n"), optarg);
2194                   break;
2195                 }
2196             }
2197           break;
2198 #ifdef SUPPORT_DISASSEMBLY
2199         case 'i':
2200           do_dump ++;
2201           section = strtoul (optarg, & cp, 0);
2202           if (! * cp && section >= 0)
2203             {
2204               request_dump (section, DISASS_DUMP);
2205               break;
2206             }
2207           goto oops;
2208 #endif
2209         case 'v':
2210           print_version (program_name);
2211           break;
2212         case 'V':
2213           do_version ++;
2214           break;
2215         default:
2216         oops:
2217           /* xgettext:c-format */
2218           error (_("Invalid option '-%c'\n"), c);
2219           /* Drop through.  */
2220         case '?':
2221           usage ();
2222         }
2223     }
2224
2225   if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
2226       && !do_segments && !do_header && !do_dump && !do_version
2227       && !do_histogram && !do_debugging && !do_arch && !do_notes)
2228     usage ();
2229   else if (argc < 3)
2230     {
2231       warn (_("Nothing to do.\n"));
2232       usage();
2233     }
2234 }
2235
2236 static const char *
2237 get_elf_class (elf_class)
2238      unsigned char elf_class;
2239 {
2240   static char buff [32];
2241
2242   switch (elf_class)
2243     {
2244     case ELFCLASSNONE: return _("none");
2245     case ELFCLASS32:   return _("ELF32");
2246     case ELFCLASS64:   return _("ELF64");
2247     default:
2248       sprintf (buff, _("<unknown: %x>"), elf_class);
2249       return buff;
2250     }
2251 }
2252
2253 static const char *
2254 get_data_encoding (encoding)
2255      unsigned char encoding;
2256 {
2257   static char buff [32];
2258
2259   switch (encoding)
2260     {
2261     case ELFDATANONE: return _("none");
2262     case ELFDATA2LSB: return _("2's complement, little endian");
2263     case ELFDATA2MSB: return _("2's complement, big endian");
2264     default:
2265       sprintf (buff, _("<unknown: %x>"), encoding);
2266       return buff;
2267     }
2268 }
2269
2270 static const char *
2271 get_osabi_name (osabi)
2272      unsigned char osabi;
2273 {
2274   static char buff [32];
2275
2276   switch (osabi)
2277     {
2278     case ELFOSABI_NONE:       return _("UNIX - System V");
2279     case ELFOSABI_HPUX:       return _("UNIX - HP-UX");
2280     case ELFOSABI_NETBSD:     return _("UNIX - NetBSD");
2281     case ELFOSABI_LINUX:      return _("UNIX - Linux");
2282     case ELFOSABI_HURD:       return _("GNU/Hurd");
2283     case ELFOSABI_SOLARIS:    return _("UNIX - Solaris");
2284     case ELFOSABI_AIX:        return _("UNIX - AIX");
2285     case ELFOSABI_IRIX:       return _("UNIX - IRIX");
2286     case ELFOSABI_FREEBSD:    return _("UNIX - FreeBSD");
2287     case ELFOSABI_TRU64:      return _("UNIX - TRU64");
2288     case ELFOSABI_MODESTO:    return _("Novell - Modesto");
2289     case ELFOSABI_OPENBSD:    return _("UNIX - OpenBSD");
2290     case ELFOSABI_STANDALONE: return _("Standalone App");
2291     case ELFOSABI_ARM:        return _("ARM");
2292     default:
2293       sprintf (buff, _("<unknown: %x>"), osabi);
2294       return buff;
2295     }
2296 }
2297
2298 /* Decode the data held in 'elf_header'.  */
2299 static int
2300 process_file_header ()
2301 {
2302   if (   elf_header.e_ident [EI_MAG0] != ELFMAG0
2303       || elf_header.e_ident [EI_MAG1] != ELFMAG1
2304       || elf_header.e_ident [EI_MAG2] != ELFMAG2
2305       || elf_header.e_ident [EI_MAG3] != ELFMAG3)
2306     {
2307       error
2308         (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
2309       return 0;
2310     }
2311
2312   if (do_header)
2313     {
2314       int i;
2315
2316       printf (_("ELF Header:\n"));
2317       printf (_("  Magic:   "));
2318       for (i = 0; i < EI_NIDENT; i ++)
2319         printf ("%2.2x ", elf_header.e_ident [i]);
2320       printf ("\n");
2321       printf (_("  Class:                             %s\n"),
2322               get_elf_class (elf_header.e_ident [EI_CLASS]));
2323       printf (_("  Data:                              %s\n"),
2324               get_data_encoding (elf_header.e_ident [EI_DATA]));
2325       printf (_("  Version:                           %d %s\n"),
2326               elf_header.e_ident [EI_VERSION],
2327               (elf_header.e_ident [EI_VERSION] == EV_CURRENT
2328                ? "(current)"
2329                : (elf_header.e_ident [EI_VERSION] != EV_NONE
2330                   ? "<unknown: %lx>"
2331                   : "")));
2332       printf (_("  OS/ABI:                            %s\n"),
2333               get_osabi_name (elf_header.e_ident [EI_OSABI]));
2334       printf (_("  ABI Version:                       %d\n"),
2335               elf_header.e_ident [EI_ABIVERSION]);
2336       printf (_("  Type:                              %s\n"),
2337               get_file_type (elf_header.e_type));
2338       printf (_("  Machine:                           %s\n"),
2339               get_machine_name (elf_header.e_machine));
2340       printf (_("  Version:                           0x%lx\n"),
2341               (unsigned long) elf_header.e_version);
2342
2343       printf (_("  Entry point address:               "));
2344       print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
2345       printf (_("\n  Start of program headers:          "));
2346       print_vma ((bfd_vma) elf_header.e_phoff, DEC);
2347       printf (_(" (bytes into file)\n  Start of section headers:          "));
2348       print_vma ((bfd_vma) elf_header.e_shoff, DEC);
2349       printf (_(" (bytes into file)\n"));
2350
2351       printf (_("  Flags:                             0x%lx%s\n"),
2352               (unsigned long) elf_header.e_flags,
2353               get_machine_flags (elf_header.e_flags, elf_header.e_machine));
2354       printf (_("  Size of this header:               %ld (bytes)\n"),
2355               (long) elf_header.e_ehsize);
2356       printf (_("  Size of program headers:           %ld (bytes)\n"),
2357               (long) elf_header.e_phentsize);
2358       printf (_("  Number of program headers:         %ld\n"),
2359               (long) elf_header.e_phnum);
2360       printf (_("  Size of section headers:           %ld (bytes)\n"),
2361               (long) elf_header.e_shentsize);
2362       printf (_("  Number of section headers:         %ld\n"),
2363               (long) elf_header.e_shnum);
2364       printf (_("  Section header string table index: %ld\n"),
2365               (long) elf_header.e_shstrndx);
2366     }
2367
2368   return 1;
2369 }
2370
2371
2372 static int
2373 get_32bit_program_headers (file, program_headers)
2374      FILE * file;
2375      Elf_Internal_Phdr * program_headers;
2376 {
2377   Elf32_External_Phdr * phdrs;
2378   Elf32_External_Phdr * external;
2379   Elf32_Internal_Phdr * internal;
2380   unsigned int          i;
2381
2382   phdrs = ((Elf32_External_Phdr *)
2383            get_data (NULL, file, elf_header.e_phoff,
2384                      elf_header.e_phentsize * elf_header.e_phnum,
2385                      _("program headers")));
2386   if (!phdrs)
2387     return 0;
2388
2389   for (i = 0, internal = program_headers, external = phdrs;
2390        i < elf_header.e_phnum;
2391        i ++, internal ++, external ++)
2392     {
2393       internal->p_type   = BYTE_GET (external->p_type);
2394       internal->p_offset = BYTE_GET (external->p_offset);
2395       internal->p_vaddr  = BYTE_GET (external->p_vaddr);
2396       internal->p_paddr  = BYTE_GET (external->p_paddr);
2397       internal->p_filesz = BYTE_GET (external->p_filesz);
2398       internal->p_memsz  = BYTE_GET (external->p_memsz);
2399       internal->p_flags  = BYTE_GET (external->p_flags);
2400       internal->p_align  = BYTE_GET (external->p_align);
2401     }
2402
2403   free (phdrs);
2404
2405   return 1;
2406 }
2407
2408 static int
2409 get_64bit_program_headers (file, program_headers)
2410      FILE * file;
2411      Elf_Internal_Phdr * program_headers;
2412 {
2413   Elf64_External_Phdr * phdrs;
2414   Elf64_External_Phdr * external;
2415   Elf64_Internal_Phdr * internal;
2416   unsigned int          i;
2417
2418   phdrs = ((Elf64_External_Phdr *)
2419            get_data (NULL, file, elf_header.e_phoff,
2420                      elf_header.e_phentsize * elf_header.e_phnum,
2421                      _("program headers")));
2422   if (!phdrs)
2423     return 0;
2424
2425   for (i = 0, internal = program_headers, external = phdrs;
2426        i < elf_header.e_phnum;
2427        i ++, internal ++, external ++)
2428     {
2429       internal->p_type   = BYTE_GET (external->p_type);
2430       internal->p_flags  = BYTE_GET (external->p_flags);
2431       internal->p_offset = BYTE_GET8 (external->p_offset);
2432       internal->p_vaddr  = BYTE_GET8 (external->p_vaddr);
2433       internal->p_paddr  = BYTE_GET8 (external->p_paddr);
2434       internal->p_filesz = BYTE_GET8 (external->p_filesz);
2435       internal->p_memsz  = BYTE_GET8 (external->p_memsz);
2436       internal->p_align  = BYTE_GET8 (external->p_align);
2437     }
2438
2439   free (phdrs);
2440
2441   return 1;
2442 }
2443
2444 static int
2445 process_program_headers (file)
2446      FILE * file;
2447 {
2448   Elf_Internal_Phdr * program_headers;
2449   Elf_Internal_Phdr * segment;
2450   unsigned int        i;
2451
2452   if (elf_header.e_phnum == 0)
2453     {
2454       if (do_segments)
2455         printf (_("\nThere are no program headers in this file.\n"));
2456       return 1;
2457     }
2458
2459   if (do_segments && !do_header)
2460     {
2461       printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
2462       printf (_("Entry point "));
2463       print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
2464       printf (_("\nThere are %d program headers, starting at offset "),
2465               elf_header.e_phnum);
2466       print_vma ((bfd_vma) elf_header.e_phoff, DEC);
2467       printf ("\n");
2468     }
2469
2470   program_headers = (Elf_Internal_Phdr *) malloc
2471     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
2472
2473   if (program_headers == NULL)
2474     {
2475       error (_("Out of memory\n"));
2476       return 0;
2477     }
2478
2479   if (is_32bit_elf)
2480     i = get_32bit_program_headers (file, program_headers);
2481   else
2482     i = get_64bit_program_headers (file, program_headers);
2483
2484   if (i == 0)
2485     {
2486       free (program_headers);
2487       return 0;
2488     }
2489
2490   if (do_segments)
2491     {
2492       printf
2493         (_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
2494
2495       if (is_32bit_elf)
2496         printf
2497           (_("  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align\n"));
2498       else
2499         {
2500           printf
2501             (_("  Type           Offset             VirtAddr           PhysAddr\n"));
2502           printf
2503             (_("                 FileSiz            MemSiz              Flags  Align\n"));
2504         }
2505     }
2506
2507   loadaddr = -1;
2508   dynamic_addr = 0;
2509   dynamic_size = 0;
2510
2511   for (i = 0, segment = program_headers;
2512        i < elf_header.e_phnum;
2513        i ++, segment ++)
2514     {
2515       if (do_segments)
2516         {
2517           printf ("  %-14.14s ", get_segment_type (segment->p_type));
2518
2519           if (is_32bit_elf)
2520             {
2521               printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
2522               printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
2523               printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
2524               printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
2525               printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
2526               printf ("%c%c%c ",
2527                       (segment->p_flags & PF_R ? 'R' : ' '),
2528                       (segment->p_flags & PF_W ? 'W' : ' '),
2529                       (segment->p_flags & PF_X ? 'E' : ' '));
2530               printf ("%#lx", (unsigned long) segment->p_align);
2531             }
2532           else
2533             {
2534               print_vma (segment->p_offset, FULL_HEX);
2535               putchar (' ');
2536               print_vma (segment->p_vaddr, FULL_HEX);
2537               putchar (' ');
2538               print_vma (segment->p_paddr, FULL_HEX);
2539               printf ("\n                 ");
2540               print_vma (segment->p_filesz, FULL_HEX);
2541               putchar (' ');
2542               print_vma (segment->p_memsz, FULL_HEX);
2543               printf ("  %c%c%c    ",
2544                       (segment->p_flags & PF_R ? 'R' : ' '),
2545                       (segment->p_flags & PF_W ? 'W' : ' '),
2546                       (segment->p_flags & PF_X ? 'E' : ' '));
2547               print_vma (segment->p_align, HEX);
2548             }
2549         }
2550
2551       switch (segment->p_type)
2552         {
2553         case PT_LOAD:
2554           if (loadaddr == -1)
2555             loadaddr = (segment->p_vaddr & 0xfffff000)
2556               - (segment->p_offset & 0xfffff000);
2557           break;
2558
2559         case PT_DYNAMIC:
2560           if (dynamic_addr)
2561             error (_("more than one dynamic segment\n"));
2562
2563           dynamic_addr = segment->p_offset;
2564           dynamic_size = segment->p_filesz;
2565           break;
2566
2567         case PT_INTERP:
2568           if (fseek (file, (long) segment->p_offset, SEEK_SET))
2569             error (_("Unable to find program interpreter name\n"));
2570           else
2571             {
2572               program_interpreter[0] = 0;
2573               fscanf (file, "%63s", program_interpreter);
2574
2575               if (do_segments)
2576                 printf (_("\n      [Requesting program interpreter: %s]"),
2577                     program_interpreter);
2578             }
2579           break;
2580         }
2581
2582       if (do_segments)
2583         putc ('\n', stdout);
2584     }
2585
2586   if (loadaddr == -1)
2587     {
2588       /* Very strange. */
2589       loadaddr = 0;
2590     }
2591
2592   if (do_segments && section_headers != NULL)
2593     {
2594       printf (_("\n Section to Segment mapping:\n"));
2595       printf (_("  Segment Sections...\n"));
2596
2597       assert (string_table != NULL);
2598
2599       for (i = 0; i < elf_header.e_phnum; i++)
2600         {
2601           int                 j;
2602           Elf_Internal_Shdr * section;
2603
2604           segment = program_headers + i;
2605           section = section_headers;
2606
2607           printf ("   %2.2d     ", i);
2608
2609           for (j = 0; j < elf_header.e_shnum; j++, section ++)
2610             {
2611               if (section->sh_size > 0
2612                   /* Compare allocated sections by VMA, unallocated
2613                      sections by file offset.  */
2614                   && (section->sh_flags & SHF_ALLOC
2615                       ? (section->sh_addr >= segment->p_vaddr
2616                          && section->sh_addr + section->sh_size
2617                          <= segment->p_vaddr + segment->p_memsz)
2618                       : ((bfd_vma) section->sh_offset >= segment->p_offset
2619                          && (section->sh_offset + section->sh_size
2620                              <= segment->p_offset + segment->p_filesz))))
2621                 printf ("%s ", SECTION_NAME (section));
2622             }
2623
2624           putc ('\n',stdout);
2625         }
2626     }
2627
2628   free (program_headers);
2629
2630   return 1;
2631 }
2632
2633
2634 static int
2635 get_32bit_section_headers (file)
2636      FILE * file;
2637 {
2638   Elf32_External_Shdr * shdrs;
2639   Elf32_Internal_Shdr * internal;
2640   unsigned int          i;
2641
2642   shdrs = ((Elf32_External_Shdr *)
2643            get_data (NULL, file, elf_header.e_shoff,
2644                      elf_header.e_shentsize * elf_header.e_shnum,
2645                      _("section headers")));
2646   if (!shdrs)
2647     return 0;
2648
2649   section_headers = (Elf_Internal_Shdr *) malloc
2650     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
2651
2652   if (section_headers == NULL)
2653     {
2654       error (_("Out of memory\n"));
2655       return 0;
2656     }
2657
2658   for (i = 0, internal = section_headers;
2659        i < elf_header.e_shnum;
2660        i ++, internal ++)
2661     {
2662       internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
2663       internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
2664       internal->sh_flags     = BYTE_GET (shdrs[i].sh_flags);
2665       internal->sh_addr      = BYTE_GET (shdrs[i].sh_addr);
2666       internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
2667       internal->sh_size      = BYTE_GET (shdrs[i].sh_size);
2668       internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
2669       internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
2670       internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
2671       internal->sh_entsize   = BYTE_GET (shdrs[i].sh_entsize);
2672     }
2673
2674   free (shdrs);
2675
2676   return 1;
2677 }
2678
2679 static int
2680 get_64bit_section_headers (file)
2681      FILE * file;
2682 {
2683   Elf64_External_Shdr * shdrs;
2684   Elf64_Internal_Shdr * internal;
2685   unsigned int          i;
2686
2687   shdrs = ((Elf64_External_Shdr *)
2688            get_data (NULL, file, elf_header.e_shoff,
2689                      elf_header.e_shentsize * elf_header.e_shnum,
2690                      _("section headers")));
2691   if (!shdrs)
2692     return 0;
2693
2694   section_headers = (Elf_Internal_Shdr *) malloc
2695     (elf_header.e_shnum * sizeof (Elf_Internal_Shdr));
2696
2697   if (section_headers == NULL)
2698     {
2699       error (_("Out of memory\n"));
2700       return 0;
2701     }
2702
2703   for (i = 0, internal = section_headers;
2704        i < elf_header.e_shnum;
2705        i ++, internal ++)
2706     {
2707       internal->sh_name      = BYTE_GET (shdrs[i].sh_name);
2708       internal->sh_type      = BYTE_GET (shdrs[i].sh_type);
2709       internal->sh_flags     = BYTE_GET8 (shdrs[i].sh_flags);
2710       internal->sh_addr      = BYTE_GET8 (shdrs[i].sh_addr);
2711       internal->sh_size      = BYTE_GET8 (shdrs[i].sh_size);
2712       internal->sh_entsize   = BYTE_GET8 (shdrs[i].sh_entsize);
2713       internal->sh_link      = BYTE_GET (shdrs[i].sh_link);
2714       internal->sh_info      = BYTE_GET (shdrs[i].sh_info);
2715       internal->sh_offset    = BYTE_GET (shdrs[i].sh_offset);
2716       internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
2717     }
2718
2719   free (shdrs);
2720
2721   return 1;
2722 }
2723
2724 static Elf_Internal_Sym *
2725 get_32bit_elf_symbols (file, offset, number)
2726      FILE * file;
2727      unsigned long offset;
2728      unsigned long number;
2729 {
2730   Elf32_External_Sym * esyms;
2731   Elf_Internal_Sym *   isyms;
2732   Elf_Internal_Sym *   psym;
2733   unsigned int         j;
2734
2735   esyms = ((Elf32_External_Sym *)
2736            get_data (NULL, file, offset,
2737                      number * sizeof (Elf32_External_Sym), _("symbols")));
2738   if (!esyms)
2739     return NULL;
2740
2741   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
2742
2743   if (isyms == NULL)
2744     {
2745       error (_("Out of memory\n"));
2746       free (esyms);
2747
2748       return NULL;
2749     }
2750
2751   for (j = 0, psym = isyms;
2752        j < number;
2753        j ++, psym ++)
2754     {
2755       psym->st_name  = BYTE_GET (esyms[j].st_name);
2756       psym->st_value = BYTE_GET (esyms[j].st_value);
2757       psym->st_size  = BYTE_GET (esyms[j].st_size);
2758       psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
2759       psym->st_info  = BYTE_GET (esyms[j].st_info);
2760       psym->st_other = BYTE_GET (esyms[j].st_other);
2761     }
2762
2763   free (esyms);
2764
2765   return isyms;
2766 }
2767
2768 static Elf_Internal_Sym *
2769 get_64bit_elf_symbols (file, offset, number)
2770      FILE * file;
2771      unsigned long offset;
2772      unsigned long number;
2773 {
2774   Elf64_External_Sym * esyms;
2775   Elf_Internal_Sym *   isyms;
2776   Elf_Internal_Sym *   psym;
2777   unsigned int         j;
2778
2779   esyms = ((Elf64_External_Sym *)
2780            get_data (NULL, file, offset,
2781                      number * sizeof (Elf64_External_Sym), _("symbols")));
2782   if (!esyms)
2783     return NULL;
2784
2785   isyms = (Elf_Internal_Sym *) malloc (number * sizeof (Elf_Internal_Sym));
2786
2787   if (isyms == NULL)
2788     {
2789       error (_("Out of memory\n"));
2790       free (esyms);
2791
2792       return NULL;
2793     }
2794
2795   for (j = 0, psym = isyms;
2796        j < number;
2797        j ++, psym ++)
2798     {
2799       psym->st_name  = BYTE_GET (esyms[j].st_name);
2800       psym->st_info  = BYTE_GET (esyms[j].st_info);
2801       psym->st_other = BYTE_GET (esyms[j].st_other);
2802       psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
2803       psym->st_value = BYTE_GET8 (esyms[j].st_value);
2804       psym->st_size  = BYTE_GET8 (esyms[j].st_size);
2805     }
2806
2807   free (esyms);
2808
2809   return isyms;
2810 }
2811
2812 static const char *
2813 get_elf_section_flags (sh_flags)
2814      bfd_vma sh_flags;
2815 {
2816   static char buff [32];
2817
2818   * buff = 0;
2819
2820   while (sh_flags)
2821     {
2822       bfd_vma flag;
2823
2824       flag = sh_flags & - sh_flags;
2825       sh_flags &= ~ flag;
2826
2827       switch (flag)
2828         {
2829         case SHF_WRITE:            strcat (buff, "W"); break;
2830         case SHF_ALLOC:            strcat (buff, "A"); break;
2831         case SHF_EXECINSTR:        strcat (buff, "X"); break;
2832         case SHF_MERGE:            strcat (buff, "M"); break;
2833         case SHF_STRINGS:          strcat (buff, "S"); break;
2834         case SHF_INFO_LINK:        strcat (buff, "I"); break;
2835         case SHF_LINK_ORDER:       strcat (buff, "L"); break;
2836         case SHF_OS_NONCONFORMING: strcat (buff, "O"); break;
2837         case SHF_GROUP:            strcat (buff, "G"); break;
2838
2839         default:
2840           if (flag & SHF_MASKOS)
2841             {
2842               strcat (buff, "o");
2843               sh_flags &= ~ SHF_MASKOS;
2844             }
2845           else if (flag & SHF_MASKPROC)
2846             {
2847               strcat (buff, "p");
2848               sh_flags &= ~ SHF_MASKPROC;
2849             }
2850           else
2851             strcat (buff, "x");
2852           break;
2853         }
2854     }
2855
2856   return buff;
2857 }
2858
2859 static int
2860 process_section_headers (file)
2861      FILE * file;
2862 {
2863   Elf_Internal_Shdr * section;
2864   int                 i;
2865
2866   section_headers = NULL;
2867
2868   if (elf_header.e_shnum == 0)
2869     {
2870       if (do_sections)
2871         printf (_("\nThere are no sections in this file.\n"));
2872
2873       return 1;
2874     }
2875
2876   if (do_sections && !do_header)
2877     printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
2878             elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
2879
2880   if (is_32bit_elf)
2881     {
2882       if (! get_32bit_section_headers (file))
2883         return 0;
2884     }
2885   else if (! get_64bit_section_headers (file))
2886     return 0;
2887
2888   /* Read in the string table, so that we have names to display.  */
2889   section = section_headers + elf_header.e_shstrndx;
2890
2891   if (section->sh_size != 0)
2892     {
2893       string_table = (char *) get_data (NULL, file, section->sh_offset,
2894                                         section->sh_size, _("string table"));
2895
2896       string_table_length = section->sh_size;
2897     }
2898
2899   /* Scan the sections for the dynamic symbol table
2900      and dynamic string table and debug sections. */
2901   dynamic_symbols = NULL;
2902   dynamic_strings = NULL;
2903   dynamic_syminfo = NULL;
2904
2905   for (i = 0, section = section_headers;
2906        i < elf_header.e_shnum;
2907        i ++, section ++)
2908     {
2909       char * name = SECTION_NAME (section);
2910
2911       if (section->sh_type == SHT_DYNSYM)
2912         {
2913           if (dynamic_symbols != NULL)
2914             {
2915               error (_("File contains multiple dynamic symbol tables\n"));
2916               continue;
2917             }
2918
2919           num_dynamic_syms = section->sh_size / section->sh_entsize;
2920           dynamic_symbols =
2921             GET_ELF_SYMBOLS (file, section->sh_offset, num_dynamic_syms);
2922         }
2923       else if (section->sh_type == SHT_STRTAB
2924                && strcmp (name, ".dynstr") == 0)
2925         {
2926           if (dynamic_strings != NULL)
2927             {
2928               error (_("File contains multiple dynamic string tables\n"));
2929               continue;
2930             }
2931
2932           dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
2933                                                section->sh_size,
2934                                                _("dynamic strings"));
2935         }
2936       else if ((do_debugging || do_debug_info || do_debug_abbrevs
2937                 || do_debug_lines || do_debug_pubnames || do_debug_aranges
2938                 || do_debug_frames)
2939                && strncmp (name, ".debug_", 7) == 0)
2940         {
2941           name += 7;
2942
2943           if (do_debugging
2944               || (do_debug_info     && (strcmp (name, "info") == 0))
2945               || (do_debug_abbrevs  && (strcmp (name, "abbrev") == 0))
2946               || (do_debug_lines    && (strcmp (name, "line") == 0))
2947               || (do_debug_pubnames && (strcmp (name, "pubnames") == 0))
2948               || (do_debug_aranges  && (strcmp (name, "aranges") == 0))
2949               || (do_debug_frames   && (strcmp (name, "frame") == 0))
2950               )
2951             request_dump (i, DEBUG_DUMP);
2952         }
2953       /* linkonce section to be combined with .debug_info at link time.  */
2954       else if ((do_debugging || do_debug_info)
2955                && strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
2956         request_dump (i, DEBUG_DUMP);
2957       else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
2958         request_dump (i, DEBUG_DUMP);
2959     }
2960
2961   if (! do_sections)
2962     return 1;
2963
2964   printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2965
2966   if (is_32bit_elf)
2967     printf
2968       (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
2969   else
2970     {
2971       printf (_("  [Nr] Name              Type             Address           Offset\n"));
2972       printf (_("       Size              EntSize          Flags  Link  Info  Align\n"));
2973     }
2974
2975   for (i = 0, section = section_headers;
2976        i < elf_header.e_shnum;
2977        i ++, section ++)
2978     {
2979       printf ("  [%2d] %-17.17s %-15.15s ",
2980               i,
2981               SECTION_NAME (section),
2982               get_section_type_name (section->sh_type));
2983
2984       if (is_32bit_elf)
2985         {
2986           print_vma (section->sh_addr, LONG_HEX);
2987
2988           printf ( " %6.6lx %6.6lx %2.2lx",
2989                    (unsigned long) section->sh_offset,
2990                    (unsigned long) section->sh_size,
2991                    (unsigned long) section->sh_entsize);
2992
2993           printf (" %3s ", get_elf_section_flags (section->sh_flags));
2994
2995           printf ("%2ld %3lx %2ld\n",
2996                   (unsigned long) section->sh_link,
2997                   (unsigned long) section->sh_info,
2998                   (unsigned long) section->sh_addralign);
2999         }
3000       else
3001         {
3002           putchar (' ');
3003           print_vma (section->sh_addr, LONG_HEX);
3004           printf ("  %8.8lx", section->sh_offset);
3005           printf ("\n       ");
3006           print_vma (section->sh_size, LONG_HEX);
3007           printf ("  ");
3008           print_vma (section->sh_entsize, LONG_HEX);
3009
3010           printf (" %3s ", get_elf_section_flags (section->sh_flags));
3011
3012           printf ("     %2ld   %3lx     %ld\n",
3013                   (unsigned long) section->sh_link,
3014                   (unsigned long) section->sh_info,
3015                   (unsigned long) section->sh_addralign);
3016         }
3017     }
3018
3019   printf (_("Key to Flags:\n"));
3020   printf (_("  W (write), A (alloc), X (execute), M (merge), S (strings)\n"));
3021   printf (_("  I (info), L (link order), G (group), x (unknown)\n"));
3022   printf (_("  O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3023
3024   return 1;
3025 }
3026
3027 /* Process the reloc section.  */
3028 static int
3029 process_relocs (file)
3030      FILE * file;
3031 {
3032   unsigned long    rel_size;
3033   unsigned long    rel_offset;
3034
3035
3036   if (!do_reloc)
3037     return 1;
3038
3039   if (do_using_dynamic)
3040     {
3041       int is_rela = FALSE;
3042
3043       rel_size   = 0;
3044       rel_offset = 0;
3045
3046       if (dynamic_info[DT_REL])
3047         {
3048           rel_offset = dynamic_info[DT_REL];
3049           rel_size   = dynamic_info[DT_RELSZ];
3050           is_rela    = FALSE;
3051         }
3052       else if (dynamic_info [DT_RELA])
3053         {
3054           rel_offset = dynamic_info[DT_RELA];
3055           rel_size   = dynamic_info[DT_RELASZ];
3056           is_rela    = TRUE;
3057         }
3058       else if (dynamic_info[DT_JMPREL])
3059         {
3060           rel_offset = dynamic_info[DT_JMPREL];
3061           rel_size   = dynamic_info[DT_PLTRELSZ];
3062
3063           switch (dynamic_info[DT_PLTREL])
3064             {
3065             case DT_REL:
3066               is_rela = FALSE;
3067               break;
3068             case DT_RELA:
3069               is_rela = TRUE;
3070               break;
3071             default:
3072               is_rela = UNKNOWN;
3073               break;
3074             }
3075         }
3076
3077       if (rel_size)
3078         {
3079           printf
3080             (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
3081              rel_offset, rel_size);
3082
3083           dump_relocations (file, rel_offset - loadaddr, rel_size,
3084                             dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
3085         }
3086       else
3087         printf (_("\nThere are no dynamic relocations in this file.\n"));
3088     }
3089   else
3090     {
3091       Elf32_Internal_Shdr *     section;
3092       unsigned long             i;
3093       int               found = 0;
3094
3095       for (i = 0, section = section_headers;
3096            i < elf_header.e_shnum;
3097            i++, section ++)
3098         {
3099           if (   section->sh_type != SHT_RELA
3100               && section->sh_type != SHT_REL)
3101             continue;
3102
3103           rel_offset = section->sh_offset;
3104           rel_size   = section->sh_size;
3105
3106           if (rel_size)
3107             {
3108               Elf32_Internal_Shdr * strsec;
3109               Elf_Internal_Sym *    symtab;
3110               char *                strtab;
3111               int                   is_rela;
3112               unsigned long         nsyms;
3113
3114               printf (_("\nRelocation section "));
3115
3116               if (string_table == NULL)
3117                 printf ("%d", section->sh_name);
3118               else
3119                 printf ("'%s'", SECTION_NAME (section));
3120
3121               printf (_(" at offset 0x%lx contains %lu entries:\n"),
3122                  rel_offset, (unsigned long) (rel_size / section->sh_entsize));
3123
3124               symtab = NULL;
3125               strtab = NULL;
3126               nsyms = 0;
3127               if (section->sh_link)
3128                 {
3129                   Elf32_Internal_Shdr * symsec;
3130
3131                   symsec = section_headers + section->sh_link;
3132                   nsyms = symsec->sh_size / symsec->sh_entsize;
3133                   symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
3134
3135                   if (symtab == NULL)
3136                     continue;
3137
3138                   strsec = section_headers + symsec->sh_link;
3139
3140                   strtab = (char *) get_data (NULL, file, strsec->sh_offset,
3141                                               strsec->sh_size,
3142                                               _("string table"));
3143                 }
3144               is_rela = section->sh_type == SHT_RELA;
3145
3146               dump_relocations (file, rel_offset, rel_size,
3147                                 symtab, nsyms, strtab, is_rela);
3148
3149               if (strtab)
3150                 free (strtab);
3151               if (symtab)
3152                 free (symtab);
3153
3154               found = 1;
3155             }
3156         }
3157
3158       if (! found)
3159         printf (_("\nThere are no relocations in this file.\n"));
3160     }
3161
3162   return 1;
3163 }
3164
3165 #include "unwind-ia64.h"
3166
3167 /* An absolute address consists of a section and an offset.  If the
3168    section is NULL, the offset itself is the address, otherwise, the
3169    address equals to LOAD_ADDRESS(section) + offset.  */
3170
3171 struct absaddr
3172   {
3173     unsigned short section;
3174     bfd_vma offset;
3175   };
3176
3177 struct unw_aux_info
3178   {
3179     struct unw_table_entry
3180       {
3181         struct absaddr    start;
3182         struct absaddr    end;
3183         struct absaddr    info;
3184       }
3185     *table;                             /* Unwind table.  */
3186     unsigned long         table_len;    /* Length of unwind table.  */
3187     unsigned char *       info;         /* Unwind info.  */
3188     unsigned long         info_size;    /* Size of unwind info.  */
3189     bfd_vma               info_addr;    /* starting address of unwind info.  */
3190     bfd_vma               seg_base;     /* Starting address of segment.  */
3191     Elf_Internal_Sym *    symtab;       /* The symbol table.  */
3192     unsigned              long nsyms;   /* Number of symbols.  */
3193     char *                strtab;       /* The string table.  */
3194     unsigned long         strtab_size;  /* Size of string table.  */
3195   };
3196
3197 static void find_symbol_for_address PARAMS ((struct unw_aux_info *,
3198                                              struct absaddr, const char **,
3199                                              bfd_vma *));
3200 static void dump_ia64_unwind PARAMS ((struct unw_aux_info *));
3201 static int  slurp_ia64_unwind_table PARAMS ((FILE *, struct unw_aux_info *,
3202                                             Elf32_Internal_Shdr *));
3203
3204 static void
3205 find_symbol_for_address (aux, addr, symname, offset)
3206      struct unw_aux_info *aux;
3207      struct absaddr addr;
3208      const char **symname;
3209      bfd_vma *offset;
3210 {
3211   bfd_vma dist = (bfd_vma) 0x100000;
3212   Elf_Internal_Sym *sym, *best = NULL;
3213   unsigned long i;
3214
3215   for (i = 0, sym = aux->symtab; i < aux->nsyms; ++i, ++sym)
3216     {
3217       if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
3218           && sym->st_name != 0
3219           && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
3220           && addr.offset >= sym->st_value
3221           && addr.offset - sym->st_value < dist)
3222         {
3223           best = sym;
3224           dist = addr.offset - sym->st_value;
3225           if (!dist)
3226             break;
3227         }
3228     }
3229   if (best)
3230     {
3231       *symname = (best->st_name >= aux->strtab_size
3232                   ? "<corrupt>" : aux->strtab + best->st_name);
3233       *offset = dist;
3234       return;
3235     }
3236   *symname = NULL;
3237   *offset = addr.offset;
3238 }
3239
3240 static void
3241 dump_ia64_unwind (aux)
3242      struct unw_aux_info *aux;
3243 {
3244   bfd_vma addr_size;
3245   struct unw_table_entry * tp;
3246   int in_body;
3247
3248   addr_size = is_32bit_elf ? 4 : 8;
3249
3250   for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
3251     {
3252       bfd_vma stamp;
3253       bfd_vma offset;
3254       const unsigned char * dp;
3255       const unsigned char * head;
3256       const char * procname;
3257
3258       find_symbol_for_address (aux, tp->start, &procname, &offset);
3259
3260       fputs ("\n<", stdout);
3261
3262       if (procname)
3263         {
3264           fputs (procname, stdout);
3265
3266           if (offset)
3267             printf ("+%lx", (unsigned long) offset);
3268         }
3269
3270       fputs (">: [", stdout);
3271       print_vma (tp->start.offset, PREFIX_HEX);
3272       fputc ('-', stdout);
3273       print_vma (tp->end.offset, PREFIX_HEX);
3274       printf ("), info at +0x%lx\n",
3275               (unsigned long) (tp->info.offset - aux->seg_base));
3276
3277       head = aux->info + (tp->info.offset - aux->info_addr);
3278       stamp = BYTE_GET8 ((unsigned char *) head);
3279
3280       printf ("  v%u, flags=0x%lx (%s%s ), len=%lu bytes\n",
3281               (unsigned) UNW_VER (stamp),
3282               (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
3283               UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
3284               UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
3285               (unsigned long) (addr_size * UNW_LENGTH (stamp)));
3286
3287       if (UNW_VER (stamp) != 1)
3288         {
3289           printf ("\tUnknown version.\n");
3290           continue;
3291         }
3292
3293       in_body = 0;
3294       for (dp = head + 8; dp < head + 8 + addr_size * UNW_LENGTH (stamp);)
3295         dp = unw_decode (dp, in_body, & in_body);
3296     }
3297 }
3298
3299 static int
3300 slurp_ia64_unwind_table (file, aux, sec)
3301      FILE *file;
3302      struct unw_aux_info *aux;
3303      Elf32_Internal_Shdr *sec;
3304 {
3305   unsigned long size, addr_size, nrelas, i;
3306   Elf_Internal_Phdr *prog_hdrs, *seg;
3307   struct unw_table_entry *tep;
3308   Elf32_Internal_Shdr *relsec;
3309   Elf_Internal_Rela *rela, *rp;
3310   unsigned char *table, *tp;
3311   Elf_Internal_Sym *sym;
3312   const char *relname;
3313   int result;
3314
3315   addr_size = is_32bit_elf ? 4 : 8;
3316
3317   /* First, find the starting address of the segment that includes
3318      this section: */
3319
3320   if (elf_header.e_phnum)
3321     {
3322       prog_hdrs = (Elf_Internal_Phdr *)
3323         xmalloc (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
3324
3325       if (is_32bit_elf)
3326         result = get_32bit_program_headers (file, prog_hdrs);
3327       else
3328         result = get_64bit_program_headers (file, prog_hdrs);
3329
3330       if (!result)
3331         {
3332           free (prog_hdrs);
3333           return 0;
3334         }
3335
3336       for (seg = prog_hdrs; seg < prog_hdrs + elf_header.e_phnum; ++seg)
3337         {
3338           if (seg->p_type != PT_LOAD)
3339             continue;
3340
3341           if (sec->sh_addr >= seg->p_vaddr
3342               && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
3343             {
3344               aux->seg_base = seg->p_vaddr;
3345               break;
3346             }
3347         }
3348
3349       free (prog_hdrs);
3350     }
3351
3352   /* Second, build the unwind table from the contents of the unwind section:  */
3353   size = sec->sh_size;
3354   table = (char *) get_data (NULL, file, sec->sh_offset,
3355                              size, _("unwind table"));
3356   if (!table)
3357     return 0;
3358
3359   tep = aux->table = xmalloc (size / (3 * addr_size) * sizeof (aux->table[0]));
3360   for (tp = table; tp < table + size; tp += 3 * addr_size, ++ tep)
3361     {
3362       tep->start.section = SHN_UNDEF;
3363       tep->end.section   = SHN_UNDEF;
3364       tep->info.section  = SHN_UNDEF;
3365       if (is_32bit_elf)
3366         {
3367           tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
3368           tep->end.offset   = byte_get ((unsigned char *) tp + 4, 4);
3369           tep->info.offset  = byte_get ((unsigned char *) tp + 8, 4);
3370         }
3371       else
3372         {
3373           tep->start.offset = BYTE_GET8 ((unsigned char *) tp +  0);
3374           tep->end.offset   = BYTE_GET8 ((unsigned char *) tp +  8);
3375           tep->info.offset  = BYTE_GET8 ((unsigned char *) tp + 16);
3376         }
3377       tep->start.offset += aux->seg_base;
3378       tep->end.offset   += aux->seg_base;
3379       tep->info.offset  += aux->seg_base;
3380     }
3381   free (table);
3382
3383   /* Third, apply any relocations to the unwind table: */
3384
3385   for (relsec = section_headers;
3386        relsec < section_headers + elf_header.e_shnum;
3387        ++relsec)
3388     {
3389       if (relsec->sh_type != SHT_RELA
3390           || section_headers + relsec->sh_info != sec)
3391         continue;
3392
3393       if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
3394                               & rela, & nrelas))
3395         return 0;
3396
3397       for (rp = rela; rp < rela + nrelas; ++rp)
3398         {
3399           if (is_32bit_elf)
3400             {
3401               relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
3402               sym = aux->symtab + ELF32_R_SYM (rp->r_info);
3403
3404               if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
3405                 {
3406                   warn (_("Skipping unexpected symbol type %u"),
3407                         ELF32_ST_TYPE (sym->st_info));
3408                   continue;
3409                 }
3410             }
3411           else
3412             {
3413               relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
3414               sym = aux->symtab + ELF64_R_SYM (rp->r_info);
3415
3416               if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
3417                 {
3418                   warn (_("Skipping unexpected symbol type %u"),
3419                         ELF64_ST_TYPE (sym->st_info));
3420                   continue;
3421                 }
3422             }
3423
3424           if (strncmp (relname, "R_IA64_SEGREL", 13) != 0)
3425             {
3426               warn (_("Skipping unexpected relocation type %s"), relname);
3427               continue;
3428             }
3429
3430           i = rp->r_offset / (3 * addr_size);
3431
3432           switch (rp->r_offset/addr_size % 3)
3433             {
3434             case 0:
3435               aux->table[i].start.section = sym->st_shndx;
3436               aux->table[i].start.offset += rp->r_addend;
3437               break;
3438             case 1:
3439               aux->table[i].end.section   = sym->st_shndx;
3440               aux->table[i].end.offset   += rp->r_addend;
3441               break;
3442             case 2:
3443               aux->table[i].info.section  = sym->st_shndx;
3444               aux->table[i].info.offset  += rp->r_addend;
3445               break;
3446             default:
3447               break;
3448             }
3449         }
3450
3451       free (rela);
3452     }
3453
3454   aux->table_len = size / (3 * addr_size);
3455   return 1;
3456 }
3457
3458 static int
3459 process_unwind (file)
3460      FILE * file;
3461 {
3462   Elf32_Internal_Shdr *sec, *unwsec = NULL, *strsec;
3463   unsigned long i, addr_size, unwcount = 0, unwstart = 0;
3464   struct unw_aux_info aux;
3465
3466   if (!do_unwind)
3467     return 1;
3468
3469   if (elf_header.e_machine != EM_IA_64)
3470     {
3471       printf (_("\nThere are no unwind sections in this file.\n"));
3472       return 1;
3473     }
3474
3475   memset (& aux, 0, sizeof (aux));
3476
3477   addr_size = is_32bit_elf ? 4 : 8;
3478
3479   for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
3480     {
3481       if (sec->sh_type == SHT_SYMTAB)
3482         {
3483           aux.nsyms = sec->sh_size / sec->sh_entsize;
3484           aux.symtab = GET_ELF_SYMBOLS (file, sec->sh_offset, aux.nsyms);
3485
3486           strsec = section_headers + sec->sh_link;
3487           aux.strtab_size = strsec->sh_size;
3488           aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
3489                                           aux.strtab_size, _("string table"));
3490         }
3491       else if (sec->sh_type == SHT_IA_64_UNWIND)
3492         unwcount++;
3493     }
3494
3495   if (!unwcount)
3496     printf (_("\nThere are no unwind sections in this file.\n"));
3497
3498   while (unwcount-- > 0)
3499     {
3500       char *suffix;
3501       size_t len, len2;
3502
3503       for (i = unwstart, sec = section_headers + unwstart;
3504            i < elf_header.e_shnum; ++i, ++sec)
3505         if (sec->sh_type == SHT_IA_64_UNWIND)
3506           {
3507             unwsec = sec;
3508             break;
3509           }
3510
3511       unwstart = i + 1;
3512       len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
3513
3514       if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once,
3515                    len) == 0)
3516         {
3517           /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO */
3518           len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
3519           suffix = SECTION_NAME (unwsec) + len;
3520           for (i = 0, sec = section_headers; i < elf_header.e_shnum;
3521                ++i, ++sec)
3522             if (strncmp (SECTION_NAME (sec),
3523                          ELF_STRING_ia64_unwind_info_once, len2) == 0
3524                 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
3525               break;
3526         }
3527       else
3528         {
3529           /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
3530              .IA_64.unwind or BAR -> .IA_64.unwind_info */
3531           len = sizeof (ELF_STRING_ia64_unwind) - 1;
3532           len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
3533           suffix = "";
3534           if (strncmp (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind,
3535                        len) == 0)
3536             suffix = SECTION_NAME (unwsec) + len;
3537           for (i = 0, sec = section_headers; i < elf_header.e_shnum;
3538                ++i, ++sec)
3539             if (strncmp (SECTION_NAME (sec),
3540                          ELF_STRING_ia64_unwind_info, len2) == 0
3541                 && strcmp (SECTION_NAME (sec) + len2, suffix) == 0)
3542               break;
3543         }
3544
3545       if (i == elf_header.e_shnum)
3546         {
3547           printf (_("\nCould not find unwind info section for "));
3548
3549           if (string_table == NULL)
3550             printf ("%d", unwsec->sh_name);
3551           else
3552             printf ("'%s'", SECTION_NAME (unwsec));
3553         }
3554       else
3555         {
3556           aux.info_size = sec->sh_size;
3557           aux.info_addr = sec->sh_addr;
3558           aux.info = (char *) get_data (NULL, file, sec->sh_offset,
3559                                         aux.info_size, _("unwind info"));
3560
3561           printf (_("\nUnwind section "));
3562
3563           if (string_table == NULL)
3564             printf ("%d", unwsec->sh_name);
3565           else
3566             printf ("'%s'", SECTION_NAME (unwsec));
3567
3568           printf (_(" at offset 0x%lx contains %lu entries:\n"),
3569                   unwsec->sh_offset,
3570                   (unsigned long) (unwsec->sh_size / (3 * addr_size)));
3571
3572           (void) slurp_ia64_unwind_table (file, & aux, unwsec);
3573
3574           if (aux.table_len > 0)
3575             dump_ia64_unwind (& aux);
3576
3577           if (aux.table)
3578             free ((char *) aux.table);
3579           if (aux.info)
3580             free ((char *) aux.info);
3581           aux.table = NULL;
3582           aux.info = NULL;
3583         }
3584     }
3585
3586   if (aux.symtab)
3587     free (aux.symtab);
3588   if (aux.strtab)
3589     free ((char *) aux.strtab);
3590
3591   return 1;
3592 }
3593
3594 static void
3595 dynamic_segment_mips_val (entry)
3596      Elf_Internal_Dyn * entry;
3597 {
3598   switch (entry->d_tag)
3599     {
3600     case DT_MIPS_FLAGS:
3601       if (entry->d_un.d_val == 0)
3602         printf ("NONE\n");
3603       else
3604         {
3605           static const char * opts[] =
3606           {
3607             "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
3608             "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
3609             "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
3610             "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
3611             "RLD_ORDER_SAFE"
3612           };
3613           unsigned int cnt;
3614           int first = 1;
3615           for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
3616             if (entry->d_un.d_val & (1 << cnt))
3617               {
3618                 printf ("%s%s", first ? "" : " ", opts[cnt]);
3619                 first = 0;
3620               }
3621           puts ("");
3622         }
3623       break;
3624
3625     case DT_MIPS_IVERSION:
3626       if (dynamic_strings != NULL)
3627         printf ("Interface Version: %s\n",
3628                 dynamic_strings + entry->d_un.d_val);
3629       else
3630         printf ("%ld\n", (long) entry->d_un.d_ptr);
3631       break;
3632
3633     case DT_MIPS_TIME_STAMP:
3634       {
3635         char timebuf[20];
3636         struct tm * tmp;
3637
3638         time_t time = entry->d_un.d_val;
3639         tmp = gmtime (&time);
3640         sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
3641                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
3642                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
3643         printf ("Time Stamp: %s\n", timebuf);
3644       }
3645       break;
3646
3647     case DT_MIPS_RLD_VERSION:
3648     case DT_MIPS_LOCAL_GOTNO:
3649     case DT_MIPS_CONFLICTNO:
3650     case DT_MIPS_LIBLISTNO:
3651     case DT_MIPS_SYMTABNO:
3652     case DT_MIPS_UNREFEXTNO:
3653     case DT_MIPS_HIPAGENO:
3654     case DT_MIPS_DELTA_CLASS_NO:
3655     case DT_MIPS_DELTA_INSTANCE_NO:
3656     case DT_MIPS_DELTA_RELOC_NO:
3657     case DT_MIPS_DELTA_SYM_NO:
3658     case DT_MIPS_DELTA_CLASSSYM_NO:
3659     case DT_MIPS_COMPACT_SIZE:
3660       printf ("%ld\n", (long) entry->d_un.d_ptr);
3661       break;
3662
3663     default:
3664       printf ("%#lx\n", (long) entry->d_un.d_ptr);
3665     }
3666 }
3667
3668
3669 static void
3670 dynamic_segment_parisc_val (entry)
3671      Elf_Internal_Dyn * entry;
3672 {
3673   switch (entry->d_tag)
3674     {
3675     case DT_HP_DLD_FLAGS:
3676       {
3677         static struct
3678         {
3679           long int bit;
3680           const char * str;
3681         }
3682         flags[] =
3683         {
3684           { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
3685           { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
3686           { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
3687           { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
3688           { DT_HP_BIND_NOW, "HP_BIND_NOW" },
3689           { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
3690           { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
3691           { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
3692           { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
3693           { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
3694           { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
3695         };
3696         int first = 1;
3697         size_t cnt;
3698         bfd_vma val = entry->d_un.d_val;
3699
3700         for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
3701           if (val & flags[cnt].bit)
3702             {
3703               if (! first)
3704                 putchar (' ');
3705               fputs (flags[cnt].str, stdout);
3706               first = 0;
3707               val ^= flags[cnt].bit;
3708             }
3709
3710         if (val != 0 || first)
3711           {
3712             if (! first)
3713               putchar (' ');
3714             print_vma (val, HEX);
3715           }
3716       }
3717       break;
3718
3719     default:
3720       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
3721       break;
3722     }
3723 }
3724
3725 static int
3726 get_32bit_dynamic_segment (file)
3727      FILE * file;
3728 {
3729   Elf32_External_Dyn * edyn;
3730   Elf_Internal_Dyn *   entry;
3731   bfd_size_type        i;
3732
3733   edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr,
3734                                           dynamic_size, _("dynamic segment"));
3735   if (!edyn)
3736     return 0;
3737
3738   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
3739      how large this .dynamic is now.  We can do this even before the byte
3740      swapping since the DT_NULL tag is recognizable.  */
3741   dynamic_size = 0;
3742   while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
3743     ;
3744
3745   dynamic_segment = (Elf_Internal_Dyn *)
3746     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3747
3748   if (dynamic_segment == NULL)
3749     {
3750       error (_("Out of memory\n"));
3751       free (edyn);
3752       return 0;
3753     }
3754
3755   for (i = 0, entry = dynamic_segment;
3756        i < dynamic_size;
3757        i ++, entry ++)
3758     {
3759       entry->d_tag      = BYTE_GET (edyn [i].d_tag);
3760       entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
3761     }
3762
3763   free (edyn);
3764
3765   return 1;
3766 }
3767
3768 static int
3769 get_64bit_dynamic_segment (file)
3770      FILE * file;
3771 {
3772   Elf64_External_Dyn * edyn;
3773   Elf_Internal_Dyn *   entry;
3774   bfd_size_type        i;
3775
3776   edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr,
3777                                           dynamic_size, _("dynamic segment"));
3778   if (!edyn)
3779     return 0;
3780
3781   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
3782      how large this .dynamic is now.  We can do this even before the byte
3783      swapping since the DT_NULL tag is recognizable.  */
3784   dynamic_size = 0;
3785   while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
3786     ;
3787
3788   dynamic_segment = (Elf_Internal_Dyn *)
3789     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3790
3791   if (dynamic_segment == NULL)
3792     {
3793       error (_("Out of memory\n"));
3794       free (edyn);
3795       return 0;
3796     }
3797
3798   for (i = 0, entry = dynamic_segment;
3799        i < dynamic_size;
3800        i ++, entry ++)
3801     {
3802       entry->d_tag      = BYTE_GET8 (edyn [i].d_tag);
3803       entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
3804     }
3805
3806   free (edyn);
3807
3808   return 1;
3809 }
3810
3811 static const char *
3812 get_dynamic_flags (flags)
3813      bfd_vma flags;
3814 {
3815   static char buff [64];
3816   while (flags)
3817     {
3818       bfd_vma flag;
3819
3820       flag = flags & - flags;
3821       flags &= ~ flag;
3822
3823       switch (flag)
3824         {
3825         case DF_ORIGIN:   strcat (buff, "ORIGIN "); break;
3826         case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
3827         case DF_TEXTREL:  strcat (buff, "TEXTREL "); break;
3828         case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
3829         default:          strcat (buff, "unknown "); break;
3830         }
3831     }
3832   return buff;
3833 }
3834
3835 /* Parse and display the contents of the dynamic segment.  */
3836 static int
3837 process_dynamic_segment (file)
3838      FILE * file;
3839 {
3840   Elf_Internal_Dyn * entry;
3841   bfd_size_type      i;
3842
3843   if (dynamic_size == 0)
3844     {
3845       if (do_dynamic)
3846         printf (_("\nThere is no dynamic segment in this file.\n"));
3847
3848       return 1;
3849     }
3850
3851   if (is_32bit_elf)
3852     {
3853       if (! get_32bit_dynamic_segment (file))
3854         return 0;
3855     }
3856   else if (! get_64bit_dynamic_segment (file))
3857     return 0;
3858
3859   /* Find the appropriate symbol table.  */
3860   if (dynamic_symbols == NULL)
3861     {
3862       for (i = 0, entry = dynamic_segment;
3863            i < dynamic_size;
3864            ++i, ++ entry)
3865         {
3866           unsigned long        offset;
3867
3868           if (entry->d_tag != DT_SYMTAB)
3869             continue;
3870
3871           dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
3872
3873           /* Since we do not know how big the symbol table is,
3874              we default to reading in the entire file (!) and
3875              processing that.  This is overkill, I know, but it
3876              should work. */
3877           offset = entry->d_un.d_val - loadaddr;
3878
3879           if (fseek (file, 0, SEEK_END))
3880             error (_("Unable to seek to end of file!"));
3881
3882           if (is_32bit_elf)
3883             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
3884           else
3885             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
3886
3887           if (num_dynamic_syms < 1)
3888             {
3889               error (_("Unable to determine the number of symbols to load\n"));
3890               continue;
3891             }
3892
3893           dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
3894         }
3895     }
3896
3897   /* Similarly find a string table.  */
3898   if (dynamic_strings == NULL)
3899     {
3900       for (i = 0, entry = dynamic_segment;
3901            i < dynamic_size;
3902            ++i, ++ entry)
3903         {
3904           unsigned long offset;
3905           long          str_tab_len;
3906
3907           if (entry->d_tag != DT_STRTAB)
3908             continue;
3909
3910           dynamic_info[DT_STRTAB] = entry->d_un.d_val;
3911
3912           /* Since we do not know how big the string table is,
3913              we default to reading in the entire file (!) and
3914              processing that.  This is overkill, I know, but it
3915              should work. */
3916
3917           offset = entry->d_un.d_val - loadaddr;
3918           if (fseek (file, 0, SEEK_END))
3919             error (_("Unable to seek to end of file\n"));
3920           str_tab_len = ftell (file) - offset;
3921
3922           if (str_tab_len < 1)
3923             {
3924               error
3925                 (_("Unable to determine the length of the dynamic string table\n"));
3926               continue;
3927             }
3928
3929           dynamic_strings = (char *) get_data (NULL, file, offset, str_tab_len,
3930                                                _("dynamic string table"));
3931
3932           break;
3933         }
3934     }
3935
3936   /* And find the syminfo section if available.  */
3937   if (dynamic_syminfo == NULL)
3938     {
3939       unsigned int syminsz = 0;
3940
3941       for (i = 0, entry = dynamic_segment;
3942            i < dynamic_size;
3943            ++i, ++ entry)
3944         {
3945           if (entry->d_tag == DT_SYMINENT)
3946             {
3947               /* Note: these braces are necessary to avoid a syntax
3948                  error from the SunOS4 C compiler.  */
3949               assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
3950             }
3951           else if (entry->d_tag == DT_SYMINSZ)
3952             syminsz = entry->d_un.d_val;
3953           else if (entry->d_tag == DT_SYMINFO)
3954             dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
3955         }
3956
3957       if (dynamic_syminfo_offset != 0 && syminsz != 0)
3958         {
3959           Elf_External_Syminfo * extsyminfo;
3960           Elf_Internal_Syminfo * syminfo;
3961
3962           /* There is a syminfo section.  Read the data.  */
3963           extsyminfo = ((Elf_External_Syminfo *)
3964                         get_data (NULL, file, dynamic_syminfo_offset,
3965                                   syminsz, _("symbol information")));
3966           if (!extsyminfo)
3967             return 0;
3968
3969           dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
3970           if (dynamic_syminfo == NULL)
3971             {
3972               error (_("Out of memory\n"));
3973               return 0;
3974             }
3975
3976           dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
3977           for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
3978                ++i, ++syminfo)
3979             {
3980               syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
3981               syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
3982             }
3983
3984           free (extsyminfo);
3985         }
3986     }
3987
3988   if (do_dynamic && dynamic_addr)
3989     printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
3990             dynamic_addr, (long) dynamic_size);
3991   if (do_dynamic)
3992     printf (_("  Tag        Type                         Name/Value\n"));
3993
3994   for (i = 0, entry = dynamic_segment;
3995        i < dynamic_size;
3996        i++, entry ++)
3997     {
3998       if (do_dynamic)
3999         {
4000           const char * dtype;
4001
4002           putchar (' ');
4003           print_vma (entry->d_tag, FULL_HEX);
4004           dtype = get_dynamic_type (entry->d_tag);
4005           printf (" (%s)%*s", dtype,
4006                   ((is_32bit_elf ? 27 : 19)
4007                    - (int) strlen (dtype)),
4008                   " ");
4009         }
4010
4011       switch (entry->d_tag)
4012         {
4013         case DT_FLAGS:
4014           if (do_dynamic)
4015             printf ("%s", get_dynamic_flags (entry->d_un.d_val));
4016           break;
4017
4018         case DT_AUXILIARY:
4019         case DT_FILTER:
4020         case DT_CONFIG:
4021         case DT_DEPAUDIT:
4022         case DT_AUDIT:
4023           if (do_dynamic)
4024             {
4025               switch (entry->d_tag)
4026                 {
4027                 case DT_AUXILIARY:
4028                   printf (_("Auxiliary library"));
4029                   break;
4030
4031                 case DT_FILTER:
4032                   printf (_("Filter library"));
4033                   break;
4034
4035                 case DT_CONFIG:
4036                   printf (_("Configuration file"));
4037                   break;
4038
4039                 case DT_DEPAUDIT:
4040                   printf (_("Dependency audit library"));
4041                   break;
4042
4043                 case DT_AUDIT:
4044                   printf (_("Audit library"));
4045                   break;
4046                 }
4047
4048               if (dynamic_strings)
4049                 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
4050               else
4051                 {
4052                   printf (": ");
4053                   print_vma (entry->d_un.d_val, PREFIX_HEX);
4054                   putchar ('\n');
4055                 }
4056             }
4057           break;
4058
4059         case DT_FEATURE:
4060           if (do_dynamic)
4061             {
4062               printf (_("Flags:"));
4063               if (entry->d_un.d_val == 0)
4064                 printf (_(" None\n"));
4065               else
4066                 {
4067                   unsigned long int val = entry->d_un.d_val;
4068                   if (val & DTF_1_PARINIT)
4069                     {
4070                       printf (" PARINIT");
4071                       val ^= DTF_1_PARINIT;
4072                     }
4073                   if (val & DTF_1_CONFEXP)
4074                     {
4075                       printf (" CONFEXP");
4076                       val ^= DTF_1_CONFEXP;
4077                     }
4078                   if (val != 0)
4079                     printf (" %lx", val);
4080                   puts ("");
4081                 }
4082             }
4083           break;
4084
4085         case DT_POSFLAG_1:
4086           if (do_dynamic)
4087             {
4088               printf (_("Flags:"));
4089               if (entry->d_un.d_val == 0)
4090                 printf (_(" None\n"));
4091               else
4092                 {
4093                   unsigned long int val = entry->d_un.d_val;
4094                   if (val & DF_P1_LAZYLOAD)
4095                     {
4096                       printf (" LAZYLOAD");
4097                       val ^= DF_P1_LAZYLOAD;
4098                     }
4099                   if (val & DF_P1_GROUPPERM)
4100                     {
4101                       printf (" GROUPPERM");
4102                       val ^= DF_P1_GROUPPERM;
4103                     }
4104                   if (val != 0)
4105                     printf (" %lx", val);
4106                   puts ("");
4107                 }
4108             }
4109           break;
4110
4111         case DT_FLAGS_1:
4112           if (do_dynamic)
4113             {
4114               printf (_("Flags:"));
4115               if (entry->d_un.d_val == 0)
4116                 printf (_(" None\n"));
4117               else
4118                 {
4119                   unsigned long int val = entry->d_un.d_val;
4120                   if (val & DF_1_NOW)
4121                     {
4122                       printf (" NOW");
4123                       val ^= DF_1_NOW;
4124                     }
4125                   if (val & DF_1_GLOBAL)
4126                     {
4127                       printf (" GLOBAL");
4128                       val ^= DF_1_GLOBAL;
4129                     }
4130                   if (val & DF_1_GROUP)
4131                     {
4132                       printf (" GROUP");
4133                       val ^= DF_1_GROUP;
4134                     }
4135                   if (val & DF_1_NODELETE)
4136                     {
4137                       printf (" NODELETE");
4138                       val ^= DF_1_NODELETE;
4139                     }
4140                   if (val & DF_1_LOADFLTR)
4141                     {
4142                       printf (" LOADFLTR");
4143                       val ^= DF_1_LOADFLTR;
4144                     }
4145                   if (val & DF_1_INITFIRST)
4146                     {
4147                       printf (" INITFIRST");
4148                       val ^= DF_1_INITFIRST;
4149                     }
4150                   if (val & DF_1_NOOPEN)
4151                     {
4152                       printf (" NOOPEN");
4153                       val ^= DF_1_NOOPEN;
4154                     }
4155                   if (val & DF_1_ORIGIN)
4156                     {
4157                       printf (" ORIGIN");
4158                       val ^= DF_1_ORIGIN;
4159                     }
4160                   if (val & DF_1_DIRECT)
4161                     {
4162                       printf (" DIRECT");
4163                       val ^= DF_1_DIRECT;
4164                     }
4165                   if (val & DF_1_TRANS)
4166                     {
4167                       printf (" TRANS");
4168                       val ^= DF_1_TRANS;
4169                     }
4170                   if (val & DF_1_INTERPOSE)
4171                     {
4172                       printf (" INTERPOSE");
4173                       val ^= DF_1_INTERPOSE;
4174                     }
4175                   if (val & DF_1_NODEFLIB)
4176                     {
4177                       printf (" NODEFLIB");
4178                       val ^= DF_1_NODEFLIB;
4179                     }
4180                   if (val & DF_1_NODUMP)
4181                     {
4182                       printf (" NODUMP");
4183                       val ^= DF_1_NODUMP;
4184                     }
4185                   if (val & DF_1_CONLFAT)
4186                     {
4187                       printf (" CONLFAT");
4188                       val ^= DF_1_CONLFAT;
4189                     }
4190                   if (val != 0)
4191                     printf (" %lx", val);
4192                   puts ("");
4193                 }
4194             }
4195           break;
4196
4197         case DT_PLTREL:
4198           if (do_dynamic)
4199             puts (get_dynamic_type (entry->d_un.d_val));
4200           break;
4201
4202         case DT_NULL    :
4203         case DT_NEEDED  :
4204         case DT_PLTGOT  :
4205         case DT_HASH    :
4206         case DT_STRTAB  :
4207         case DT_SYMTAB  :
4208         case DT_RELA    :
4209         case DT_INIT    :
4210         case DT_FINI    :
4211         case DT_SONAME  :
4212         case DT_RPATH   :
4213         case DT_SYMBOLIC:
4214         case DT_REL     :
4215         case DT_DEBUG   :
4216         case DT_TEXTREL :
4217         case DT_JMPREL  :
4218         case DT_RUNPATH :
4219           dynamic_info[entry->d_tag] = entry->d_un.d_val;
4220
4221           if (do_dynamic)
4222             {
4223               char * name;
4224
4225               if (dynamic_strings == NULL)
4226                 name = NULL;
4227               else
4228                 name = dynamic_strings + entry->d_un.d_val;
4229
4230               if (name)
4231                 {
4232                   switch (entry->d_tag)
4233                     {
4234                     case DT_NEEDED:
4235                       printf (_("Shared library: [%s]"), name);
4236
4237                       if (strcmp (name, program_interpreter) == 0)
4238                         printf (_(" program interpreter"));
4239                       break;
4240
4241                     case DT_SONAME:
4242                       printf (_("Library soname: [%s]"), name);
4243                       break;
4244
4245                     case DT_RPATH:
4246                       printf (_("Library rpath: [%s]"), name);
4247                       break;
4248
4249                     case DT_RUNPATH:
4250                       printf (_("Library runpath: [%s]"), name);
4251                       break;
4252
4253                     default:
4254                       print_vma (entry->d_un.d_val, PREFIX_HEX);
4255                       break;
4256                     }
4257                 }
4258               else
4259                 print_vma (entry->d_un.d_val, PREFIX_HEX);
4260
4261               putchar ('\n');
4262             }
4263           break;
4264
4265         case DT_PLTRELSZ:
4266         case DT_RELASZ  :
4267         case DT_STRSZ   :
4268         case DT_RELSZ   :
4269         case DT_RELAENT :
4270         case DT_SYMENT  :
4271         case DT_RELENT  :
4272         case DT_PLTPADSZ:
4273         case DT_MOVEENT :
4274         case DT_MOVESZ  :
4275         case DT_INIT_ARRAYSZ:
4276         case DT_FINI_ARRAYSZ:
4277           if (do_dynamic)
4278             {
4279               print_vma (entry->d_un.d_val, UNSIGNED);
4280               printf (" (bytes)\n");
4281             }
4282           break;
4283
4284         case DT_VERDEFNUM:
4285         case DT_VERNEEDNUM:
4286         case DT_RELACOUNT:
4287         case DT_RELCOUNT:
4288           if (do_dynamic)
4289             {
4290               print_vma (entry->d_un.d_val, UNSIGNED);
4291               putchar ('\n');
4292             }
4293           break;
4294
4295         case DT_SYMINSZ:
4296         case DT_SYMINENT:
4297         case DT_SYMINFO:
4298         case DT_USED:
4299         case DT_INIT_ARRAY:
4300         case DT_FINI_ARRAY:
4301           if (do_dynamic)
4302             {
4303               if (dynamic_strings != NULL && entry->d_tag == DT_USED)
4304                 {
4305                   char * name;
4306
4307                   name = dynamic_strings + entry->d_un.d_val;
4308
4309                   if (* name)
4310                     {
4311                       printf (_("Not needed object: [%s]\n"), name);
4312                       break;
4313                     }
4314                 }
4315
4316               print_vma (entry->d_un.d_val, PREFIX_HEX);
4317               putchar ('\n');
4318             }
4319           break;
4320
4321         case DT_BIND_NOW:
4322           /* The value of this entry is ignored.  */
4323           break;
4324
4325         default:
4326           if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
4327             version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
4328               entry->d_un.d_val;
4329
4330           if (do_dynamic)
4331             {
4332               switch (elf_header.e_machine)
4333                 {
4334                 case EM_MIPS:
4335                 case EM_MIPS_RS3_LE:
4336                   dynamic_segment_mips_val (entry);
4337                   break;
4338                 case EM_PARISC:
4339                   dynamic_segment_parisc_val (entry);
4340                   break;
4341                 default:
4342                   print_vma (entry->d_un.d_val, PREFIX_HEX);
4343                   putchar ('\n');
4344                 }
4345             }
4346           break;
4347         }
4348     }
4349
4350   return 1;
4351 }
4352
4353 static char *
4354 get_ver_flags (flags)
4355      unsigned int flags;
4356 {
4357   static char buff [32];
4358
4359   buff[0] = 0;
4360
4361   if (flags == 0)
4362     return _("none");
4363
4364   if (flags & VER_FLG_BASE)
4365     strcat (buff, "BASE ");
4366
4367   if (flags & VER_FLG_WEAK)
4368     {
4369       if (flags & VER_FLG_BASE)
4370         strcat (buff, "| ");
4371
4372       strcat (buff, "WEAK ");
4373     }
4374
4375   if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
4376     strcat (buff, "| <unknown>");
4377
4378   return buff;
4379 }
4380
4381 /* Display the contents of the version sections.  */
4382 static int
4383 process_version_sections (file)
4384      FILE * file;
4385 {
4386   Elf32_Internal_Shdr * section;
4387   unsigned   i;
4388   int        found = 0;
4389
4390   if (! do_version)
4391     return 1;
4392
4393   for (i = 0, section = section_headers;
4394        i < elf_header.e_shnum;
4395        i++, section ++)
4396     {
4397       switch (section->sh_type)
4398         {
4399         case SHT_GNU_verdef:
4400           {
4401             Elf_External_Verdef * edefs;
4402             unsigned int          idx;
4403             unsigned int          cnt;
4404
4405             found = 1;
4406
4407             printf
4408               (_("\nVersion definition section '%s' contains %ld entries:\n"),
4409                SECTION_NAME (section), section->sh_info);
4410
4411             printf (_("  Addr: 0x"));
4412             printf_vma (section->sh_addr);
4413             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
4414                     (unsigned long) section->sh_offset, section->sh_link,
4415                     SECTION_NAME (section_headers + section->sh_link));
4416
4417             edefs = ((Elf_External_Verdef *)
4418                      get_data (NULL, file, section->sh_offset,
4419                                section->sh_size,
4420                                _("version definition section")));
4421             if (!edefs)
4422               break;
4423
4424             for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
4425               {
4426                 char *                 vstart;
4427                 Elf_External_Verdef *  edef;
4428                 Elf_Internal_Verdef    ent;
4429                 Elf_External_Verdaux * eaux;
4430                 Elf_Internal_Verdaux   aux;
4431                 int                    j;
4432                 int                    isum;
4433
4434                 vstart = ((char *) edefs) + idx;
4435
4436                 edef = (Elf_External_Verdef *) vstart;
4437
4438                 ent.vd_version = BYTE_GET (edef->vd_version);
4439                 ent.vd_flags   = BYTE_GET (edef->vd_flags);
4440                 ent.vd_ndx     = BYTE_GET (edef->vd_ndx);
4441                 ent.vd_cnt     = BYTE_GET (edef->vd_cnt);
4442                 ent.vd_hash    = BYTE_GET (edef->vd_hash);
4443                 ent.vd_aux     = BYTE_GET (edef->vd_aux);
4444                 ent.vd_next    = BYTE_GET (edef->vd_next);
4445
4446                 printf (_("  %#06x: Rev: %d  Flags: %s"),
4447                         idx, ent.vd_version, get_ver_flags (ent.vd_flags));
4448
4449                 printf (_("  Index: %d  Cnt: %d  "),
4450                         ent.vd_ndx, ent.vd_cnt);
4451
4452                 vstart += ent.vd_aux;
4453
4454                 eaux = (Elf_External_Verdaux *) vstart;
4455
4456                 aux.vda_name = BYTE_GET (eaux->vda_name);
4457                 aux.vda_next = BYTE_GET (eaux->vda_next);
4458
4459                 if (dynamic_strings)
4460                   printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
4461                 else
4462                   printf (_("Name index: %ld\n"), aux.vda_name);
4463
4464                 isum = idx + ent.vd_aux;
4465
4466                 for (j = 1; j < ent.vd_cnt; j ++)
4467                   {
4468                     isum   += aux.vda_next;
4469                     vstart += aux.vda_next;
4470
4471                     eaux = (Elf_External_Verdaux *) vstart;
4472
4473                     aux.vda_name = BYTE_GET (eaux->vda_name);
4474                     aux.vda_next = BYTE_GET (eaux->vda_next);
4475
4476                     if (dynamic_strings)
4477                       printf (_("  %#06x: Parent %d: %s\n"),
4478                               isum, j, dynamic_strings + aux.vda_name);
4479                     else
4480                       printf (_("  %#06x: Parent %d, name index: %ld\n"),
4481                               isum, j, aux.vda_name);
4482                   }
4483
4484                 idx += ent.vd_next;
4485               }
4486
4487             free (edefs);
4488           }
4489           break;
4490
4491         case SHT_GNU_verneed:
4492           {
4493             Elf_External_Verneed *  eneed;
4494             unsigned int            idx;
4495             unsigned int            cnt;
4496
4497             found = 1;
4498
4499             printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
4500                     SECTION_NAME (section), section->sh_info);
4501
4502             printf (_(" Addr: 0x"));
4503             printf_vma (section->sh_addr);
4504             printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
4505                     (unsigned long) section->sh_offset, section->sh_link,
4506                     SECTION_NAME (section_headers + section->sh_link));
4507
4508             eneed = ((Elf_External_Verneed *)
4509                      get_data (NULL, file, section->sh_offset,
4510                                section->sh_size, _("version need section")));
4511             if (!eneed)
4512               break;
4513
4514             for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
4515               {
4516                 Elf_External_Verneed * entry;
4517                 Elf_Internal_Verneed     ent;
4518                 int                      j;
4519                 int                      isum;
4520                 char *                   vstart;
4521
4522                 vstart = ((char *) eneed) + idx;
4523
4524                 entry = (Elf_External_Verneed *) vstart;
4525
4526                 ent.vn_version = BYTE_GET (entry->vn_version);
4527                 ent.vn_cnt     = BYTE_GET (entry->vn_cnt);
4528                 ent.vn_file    = BYTE_GET (entry->vn_file);
4529                 ent.vn_aux     = BYTE_GET (entry->vn_aux);
4530                 ent.vn_next    = BYTE_GET (entry->vn_next);
4531
4532                 printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
4533
4534                 if (dynamic_strings)
4535                   printf (_("  File: %s"), dynamic_strings + ent.vn_file);
4536                 else
4537                   printf (_("  File: %lx"), ent.vn_file);
4538
4539                 printf (_("  Cnt: %d\n"), ent.vn_cnt);
4540
4541                 vstart += ent.vn_aux;
4542
4543                 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
4544                   {
4545                     Elf_External_Vernaux * eaux;
4546                     Elf_Internal_Vernaux   aux;
4547
4548                     eaux = (Elf_External_Vernaux *) vstart;
4549
4550                     aux.vna_hash  = BYTE_GET (eaux->vna_hash);
4551                     aux.vna_flags = BYTE_GET (eaux->vna_flags);
4552                     aux.vna_other = BYTE_GET (eaux->vna_other);
4553                     aux.vna_name  = BYTE_GET (eaux->vna_name);
4554                     aux.vna_next  = BYTE_GET (eaux->vna_next);
4555
4556                     if (dynamic_strings)
4557                       printf (_("  %#06x: Name: %s"),
4558                               isum, dynamic_strings + aux.vna_name);
4559                     else
4560                       printf (_("  %#06x: Name index: %lx"),
4561                               isum, aux.vna_name);
4562
4563                     printf (_("  Flags: %s  Version: %d\n"),
4564                             get_ver_flags (aux.vna_flags), aux.vna_other);
4565
4566                     isum   += aux.vna_next;
4567                     vstart += aux.vna_next;
4568                   }
4569
4570                 idx += ent.vn_next;
4571               }
4572
4573             free (eneed);
4574           }
4575           break;
4576
4577         case SHT_GNU_versym:
4578           {
4579             Elf32_Internal_Shdr *       link_section;
4580             int         total;
4581             int         cnt;
4582             unsigned char *             edata;
4583             unsigned short *            data;
4584             char *              strtab;
4585             Elf_Internal_Sym *          symbols;
4586             Elf32_Internal_Shdr *       string_sec;
4587
4588             link_section = section_headers + section->sh_link;
4589             total = section->sh_size / section->sh_entsize;
4590
4591             found = 1;
4592
4593             symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
4594                                        link_section->sh_size / link_section->sh_entsize);
4595
4596             string_sec = section_headers + link_section->sh_link;
4597
4598             strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
4599                                         string_sec->sh_size,
4600                                         _("version string table"));
4601             if (!strtab)
4602               break;
4603
4604             printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
4605                     SECTION_NAME (section), total);
4606
4607             printf (_(" Addr: "));
4608             printf_vma (section->sh_addr);
4609             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
4610                     (unsigned long) section->sh_offset, section->sh_link,
4611                     SECTION_NAME (link_section));
4612
4613             edata =
4614               ((unsigned char *)
4615                get_data (NULL, file,
4616                          version_info[DT_VERSIONTAGIDX (DT_VERSYM)] - loadaddr,
4617                          total * sizeof (short), _("version symbol data")));
4618             if (!edata)
4619               {
4620                 free (strtab);
4621                 break;
4622               }
4623
4624             data = (unsigned short *) malloc (total * sizeof (short));
4625
4626             for (cnt = total; cnt --;)
4627               data [cnt] = byte_get (edata + cnt * sizeof (short),
4628                                      sizeof (short));
4629
4630             free (edata);
4631
4632             for (cnt = 0; cnt < total; cnt += 4)
4633               {
4634                 int j, nn;
4635                 int check_def, check_need;
4636                 char * name;
4637
4638                 printf ("  %03x:", cnt);
4639
4640                 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
4641                   switch (data [cnt + j])
4642                     {
4643                     case 0:
4644                       fputs (_("   0 (*local*)    "), stdout);
4645                       break;
4646
4647                     case 1:
4648                       fputs (_("   1 (*global*)   "), stdout);
4649                       break;
4650
4651                     default:
4652                       nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
4653                                    data [cnt + j] & 0x8000 ? 'h' : ' ');
4654
4655                       check_def = 1;
4656                       check_need = 1;
4657                       if (symbols [cnt + j].st_shndx >= SHN_LORESERVE
4658                           || section_headers[symbols [cnt + j].st_shndx].sh_type
4659                           != SHT_NOBITS)
4660                         {
4661                           if (symbols [cnt + j].st_shndx == SHN_UNDEF)
4662                             check_def = 0;
4663                           else
4664                             check_need = 0;
4665                         }
4666
4667                       if (check_need
4668                           && version_info [DT_VERSIONTAGIDX (DT_VERNEED)])
4669                         {
4670                           Elf_Internal_Verneed     ivn;
4671                           unsigned long            offset;
4672
4673                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4674                             - loadaddr;
4675
4676                           do
4677                             {
4678                               Elf_Internal_Vernaux   ivna;
4679                               Elf_External_Verneed   evn;
4680                               Elf_External_Vernaux   evna;
4681                               unsigned long          a_off;
4682
4683                               get_data (&evn, file, offset, sizeof (evn),
4684                                         _("version need"));
4685
4686                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
4687                               ivn.vn_next = BYTE_GET (evn.vn_next);
4688
4689                               a_off = offset + ivn.vn_aux;
4690
4691                               do
4692                                 {
4693                                   get_data (&evna, file, a_off, sizeof (evna),
4694                                             _("version need aux (2)"));
4695
4696                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
4697                                   ivna.vna_other = BYTE_GET (evna.vna_other);
4698
4699                                   a_off += ivna.vna_next;
4700                                 }
4701                               while (ivna.vna_other != data [cnt + j]
4702                                      && ivna.vna_next != 0);
4703
4704                               if (ivna.vna_other == data [cnt + j])
4705                                 {
4706                                   ivna.vna_name = BYTE_GET (evna.vna_name);
4707
4708                                   name = strtab + ivna.vna_name;
4709                                   nn += printf ("(%s%-*s",
4710                                                 name,
4711                                                 12 - (int) strlen (name),
4712                                                 ")");
4713                                   check_def = 0;
4714                                   break;
4715                                 }
4716
4717                               offset += ivn.vn_next;
4718                             }
4719                           while (ivn.vn_next);
4720                         }
4721
4722                       if (check_def && data [cnt + j] != 0x8001
4723                           && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
4724                         {
4725                           Elf_Internal_Verdef  ivd;
4726                           Elf_External_Verdef  evd;
4727                           unsigned long        offset;
4728
4729                           offset = version_info
4730                             [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
4731
4732                           do
4733                             {
4734                               get_data (&evd, file, offset, sizeof (evd),
4735                                         _("version def"));
4736
4737                               ivd.vd_next = BYTE_GET (evd.vd_next);
4738                               ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
4739
4740                               offset += ivd.vd_next;
4741                             }
4742                           while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
4743                                  && ivd.vd_next != 0);
4744
4745                           if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
4746                             {
4747                               Elf_External_Verdaux  evda;
4748                               Elf_Internal_Verdaux  ivda;
4749
4750                               ivd.vd_aux = BYTE_GET (evd.vd_aux);
4751
4752                               get_data (&evda, file,
4753                                         offset - ivd.vd_next + ivd.vd_aux,
4754                                         sizeof (evda), _("version def aux"));
4755
4756                               ivda.vda_name = BYTE_GET (evda.vda_name);
4757
4758                               name = strtab + ivda.vda_name;
4759                               nn += printf ("(%s%-*s",
4760                                             name,
4761                                             12 - (int) strlen (name),
4762                                             ")");
4763                             }
4764                         }
4765
4766                       if (nn < 18)
4767                         printf ("%*c", 18 - nn, ' ');
4768                     }
4769
4770                 putchar ('\n');
4771               }
4772
4773             free (data);
4774             free (strtab);
4775             free (symbols);
4776           }
4777           break;
4778
4779         default:
4780           break;
4781         }
4782     }
4783
4784   if (! found)
4785     printf (_("\nNo version information found in this file.\n"));
4786
4787   return 1;
4788 }
4789
4790 static const char *
4791 get_symbol_binding (binding)
4792      unsigned int binding;
4793 {
4794   static char buff [32];
4795
4796   switch (binding)
4797     {
4798     case STB_LOCAL:  return "LOCAL";
4799     case STB_GLOBAL: return "GLOBAL";
4800     case STB_WEAK:   return "WEAK";
4801     default:
4802       if (binding >= STB_LOPROC && binding <= STB_HIPROC)
4803         sprintf (buff, _("<processor specific>: %d"), binding);
4804       else if (binding >= STB_LOOS && binding <= STB_HIOS)
4805         sprintf (buff, _("<OS specific>: %d"), binding);
4806       else
4807         sprintf (buff, _("<unknown>: %d"), binding);
4808       return buff;
4809     }
4810 }
4811
4812 static const char *
4813 get_symbol_type (type)
4814      unsigned int type;
4815 {
4816   static char buff [32];
4817
4818   switch (type)
4819     {
4820     case STT_NOTYPE:   return "NOTYPE";
4821     case STT_OBJECT:   return "OBJECT";
4822     case STT_FUNC:     return "FUNC";
4823     case STT_SECTION:  return "SECTION";
4824     case STT_FILE:     return "FILE";
4825     case STT_COMMON:   return "COMMON";
4826     default:
4827       if (type >= STT_LOPROC && type <= STT_HIPROC)
4828         {
4829           if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
4830             return "THUMB_FUNC";
4831
4832           if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
4833             return "REGISTER";
4834
4835           if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
4836             return "PARISC_MILLI";
4837
4838           sprintf (buff, _("<processor specific>: %d"), type);
4839         }
4840       else if (type >= STT_LOOS && type <= STT_HIOS)
4841         {
4842           if (elf_header.e_machine == EM_PARISC)
4843             {
4844               if (type == STT_HP_OPAQUE)
4845                 return "HP_OPAQUE";
4846               if (type == STT_HP_STUB)
4847                 return "HP_STUB";
4848             }
4849
4850           sprintf (buff, _("<OS specific>: %d"), type);
4851         }
4852       else
4853         sprintf (buff, _("<unknown>: %d"), type);
4854       return buff;
4855     }
4856 }
4857
4858 static const char *
4859 get_symbol_visibility (visibility)
4860      unsigned int visibility;
4861 {
4862   switch (visibility)
4863     {
4864     case STV_DEFAULT:   return "DEFAULT";
4865     case STV_INTERNAL:  return "INTERNAL";
4866     case STV_HIDDEN:    return "HIDDEN";
4867     case STV_PROTECTED: return "PROTECTED";
4868     default: abort ();
4869     }
4870 }
4871
4872 static const char *
4873 get_symbol_index_type (type)
4874      unsigned int type;
4875 {
4876   switch (type)
4877     {
4878     case SHN_UNDEF:  return "UND";
4879     case SHN_ABS:    return "ABS";
4880     case SHN_COMMON: return "COM";
4881     default:
4882       if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4883         return "PRC";
4884       else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
4885         return "RSV";
4886       else if (type >= SHN_LOOS && type <= SHN_HIOS)
4887         return "OS ";
4888       else
4889         {
4890           static char buff [32];
4891
4892           sprintf (buff, "%3d", type);
4893           return buff;
4894         }
4895     }
4896 }
4897
4898 static int *
4899 get_dynamic_data (file, number)
4900      FILE *       file;
4901      unsigned int number;
4902 {
4903   unsigned char * e_data;
4904   int *  i_data;
4905
4906   e_data = (unsigned char *) malloc (number * 4);
4907
4908   if (e_data == NULL)
4909     {
4910       error (_("Out of memory\n"));
4911       return NULL;
4912     }
4913
4914   if (fread (e_data, 4, number, file) != number)
4915     {
4916       error (_("Unable to read in dynamic data\n"));
4917       return NULL;
4918     }
4919
4920   i_data = (int *) malloc (number * sizeof (* i_data));
4921
4922   if (i_data == NULL)
4923     {
4924       error (_("Out of memory\n"));
4925       free (e_data);
4926       return NULL;
4927     }
4928
4929   while (number--)
4930     i_data [number] = byte_get (e_data + number * 4, 4);
4931
4932   free (e_data);
4933
4934   return i_data;
4935 }
4936
4937 /* Dump the symbol table */
4938 static int
4939 process_symbol_table (file)
4940      FILE * file;
4941 {
4942   Elf32_Internal_Shdr *   section;
4943   unsigned char   nb [4];
4944   unsigned char   nc [4];
4945   int    nbuckets = 0;
4946   int    nchains = 0;
4947   int *  buckets = NULL;
4948   int *  chains = NULL;
4949
4950   if (! do_syms && !do_histogram)
4951     return 1;
4952
4953   if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
4954                                 || do_histogram))
4955     {
4956       if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
4957         {
4958           error (_("Unable to seek to start of dynamic information"));
4959           return 0;
4960         }
4961
4962       if (fread (nb, sizeof (nb), 1, file) != 1)
4963         {
4964           error (_("Failed to read in number of buckets\n"));
4965           return 0;
4966         }
4967
4968       if (fread (nc, sizeof (nc), 1, file) != 1)
4969         {
4970           error (_("Failed to read in number of chains\n"));
4971           return 0;
4972         }
4973
4974       nbuckets = byte_get (nb, 4);
4975       nchains  = byte_get (nc, 4);
4976
4977       buckets = get_dynamic_data (file, nbuckets);
4978       chains  = get_dynamic_data (file, nchains);
4979
4980       if (buckets == NULL || chains == NULL)
4981         return 0;
4982     }
4983
4984   if (do_syms
4985       && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
4986     {
4987       int    hn;
4988       int    si;
4989
4990       printf (_("\nSymbol table for image:\n"));
4991       if (is_32bit_elf)
4992         printf (_("  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name\n"));
4993       else
4994         printf (_("  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name\n"));
4995
4996       for (hn = 0; hn < nbuckets; hn++)
4997         {
4998           if (! buckets [hn])
4999             continue;
5000
5001           for (si = buckets [hn]; si < nchains && si > 0; si = chains [si])
5002             {
5003               Elf_Internal_Sym * psym;
5004
5005               psym = dynamic_symbols + si;
5006
5007               printf ("  %3d %3d: ", si, hn);
5008               print_vma (psym->st_value, LONG_HEX);
5009               putchar (' ' );
5010               print_vma (psym->st_size, DEC_5);
5011
5012               printf ("  %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
5013               printf (" %6s",  get_symbol_binding (ELF_ST_BIND (psym->st_info)));
5014               printf (" %3s",  get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5015               printf (" %3.3s", get_symbol_index_type (psym->st_shndx));
5016               printf (" %s\n", dynamic_strings + psym->st_name);
5017             }
5018         }
5019     }
5020   else if (do_syms && !do_using_dynamic)
5021     {
5022       unsigned int     i;
5023
5024       for (i = 0, section = section_headers;
5025            i < elf_header.e_shnum;
5026            i++, section++)
5027         {
5028           unsigned int          si;
5029           char *                strtab;
5030           Elf_Internal_Sym *    symtab;
5031           Elf_Internal_Sym *    psym;
5032
5033
5034           if (   section->sh_type != SHT_SYMTAB
5035               && section->sh_type != SHT_DYNSYM)
5036             continue;
5037
5038           printf (_("\nSymbol table '%s' contains %lu entries:\n"),
5039                   SECTION_NAME (section),
5040                   (unsigned long) (section->sh_size / section->sh_entsize));
5041           if (is_32bit_elf)
5042             printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
5043           else
5044             printf (_("   Num:    Value          Size Type    Bind   Vis      Ndx Name\n"));
5045
5046           symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
5047                                     section->sh_size / section->sh_entsize);
5048           if (symtab == NULL)
5049             continue;
5050
5051           if (section->sh_link == elf_header.e_shstrndx)
5052             strtab = string_table;
5053           else
5054             {
5055               Elf32_Internal_Shdr * string_sec;
5056
5057               string_sec = section_headers + section->sh_link;
5058
5059               strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
5060                                           string_sec->sh_size,
5061                                           _("string table"));
5062             }
5063
5064           for (si = 0, psym = symtab;
5065                si < section->sh_size / section->sh_entsize;
5066                si ++, psym ++)
5067             {
5068               printf ("%6d: ", si);
5069               print_vma (psym->st_value, LONG_HEX);
5070               putchar (' ');
5071               print_vma (psym->st_size, DEC_5);
5072               printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
5073               printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
5074               printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5075               printf (" %4s", get_symbol_index_type (psym->st_shndx));
5076               printf (" %s", strtab + psym->st_name);
5077
5078               if (section->sh_type == SHT_DYNSYM &&
5079                   version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
5080                 {
5081                   unsigned char   data[2];
5082                   unsigned short  vers_data;
5083                   unsigned long   offset;
5084                   int             is_nobits;
5085                   int             check_def;
5086
5087                   offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
5088                     - loadaddr;
5089
5090                   get_data (&data, file, offset + si * sizeof (vers_data),
5091                             sizeof (data), _("version data"));
5092
5093                   vers_data = byte_get (data, 2);
5094
5095                   is_nobits = psym->st_shndx < SHN_LORESERVE ?
5096                     (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
5097                     : 0;
5098
5099                   check_def = (psym->st_shndx != SHN_UNDEF);
5100
5101                   if ((vers_data & 0x8000) || vers_data > 1)
5102                     {
5103                       if (version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
5104                           && (is_nobits || ! check_def))
5105                         {
5106                           Elf_External_Verneed  evn;
5107                           Elf_Internal_Verneed  ivn;
5108                           Elf_Internal_Vernaux  ivna;
5109
5110                           /* We must test both.  */
5111                           offset = version_info
5112                             [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
5113
5114                           do
5115                             {
5116                               unsigned long  vna_off;
5117
5118                               get_data (&evn, file, offset, sizeof (evn),
5119                                         _("version need"));
5120
5121                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
5122                               ivn.vn_next = BYTE_GET (evn.vn_next);
5123
5124                               vna_off = offset + ivn.vn_aux;
5125
5126                               do
5127                                 {
5128                                   Elf_External_Vernaux  evna;
5129
5130                                   get_data (&evna, file, vna_off,
5131                                             sizeof (evna),
5132                                             _("version need aux (3)"));
5133
5134                                   ivna.vna_other = BYTE_GET (evna.vna_other);
5135                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
5136                                   ivna.vna_name  = BYTE_GET (evna.vna_name);
5137
5138                                   vna_off += ivna.vna_next;
5139                                 }
5140                               while (ivna.vna_other != vers_data
5141                                      && ivna.vna_next != 0);
5142
5143                               if (ivna.vna_other == vers_data)
5144                                 break;
5145
5146                               offset += ivn.vn_next;
5147                             }
5148                           while (ivn.vn_next != 0);
5149
5150                           if (ivna.vna_other == vers_data)
5151                             {
5152                               printf ("@%s (%d)",
5153                                       strtab + ivna.vna_name, ivna.vna_other);
5154                               check_def = 0;
5155                             }
5156                           else if (! is_nobits)
5157                             error (_("bad dynamic symbol"));
5158                           else
5159                             check_def = 1;
5160                         }
5161
5162                       if (check_def)
5163                         {
5164                           if (vers_data != 0x8001
5165                               && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
5166                             {
5167                               Elf_Internal_Verdef     ivd;
5168                               Elf_Internal_Verdaux    ivda;
5169                               Elf_External_Verdaux  evda;
5170                               unsigned long           offset;
5171
5172                               offset =
5173                                 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
5174                                 - loadaddr;
5175
5176                               do
5177                                 {
5178                                   Elf_External_Verdef   evd;
5179
5180                                   get_data (&evd, file, offset, sizeof (evd),
5181                                             _("version def"));
5182
5183                                   ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
5184                                   ivd.vd_aux  = BYTE_GET (evd.vd_aux);
5185                                   ivd.vd_next = BYTE_GET (evd.vd_next);
5186
5187                                   offset += ivd.vd_next;
5188                                 }
5189                               while (ivd.vd_ndx != (vers_data & 0x7fff)
5190                                      && ivd.vd_next != 0);
5191
5192                               offset -= ivd.vd_next;
5193                               offset += ivd.vd_aux;
5194
5195                               get_data (&evda, file, offset, sizeof (evda),
5196                                         _("version def aux"));
5197
5198                               ivda.vda_name = BYTE_GET (evda.vda_name);
5199
5200                               if (psym->st_name != ivda.vda_name)
5201                                 printf ((vers_data & 0x8000)
5202                                         ? "@%s" : "@@%s",
5203                                         strtab + ivda.vda_name);
5204                             }
5205                         }
5206                     }
5207                 }
5208
5209               putchar ('\n');
5210             }
5211
5212           free (symtab);
5213           if (strtab != string_table)
5214             free (strtab);
5215         }
5216     }
5217   else if (do_syms)
5218     printf
5219       (_("\nDynamic symbol information is not available for displaying symbols.\n"));
5220
5221   if (do_histogram && buckets != NULL)
5222     {
5223       int * lengths;
5224       int * counts;
5225       int   hn;
5226       int   si;
5227       int   maxlength = 0;
5228       int   nzero_counts = 0;
5229       int   nsyms = 0;
5230
5231       printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
5232               nbuckets);
5233       printf (_(" Length  Number     %% of total  Coverage\n"));
5234
5235       lengths = (int *) calloc (nbuckets, sizeof (int));
5236       if (lengths == NULL)
5237         {
5238           error (_("Out of memory"));
5239           return 0;
5240         }
5241       for (hn = 0; hn < nbuckets; ++hn)
5242         {
5243           if (! buckets [hn])
5244             continue;
5245
5246           for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
5247             {
5248               ++ nsyms;
5249               if (maxlength < ++lengths[hn])
5250                 ++ maxlength;
5251             }
5252         }
5253
5254       counts = (int *) calloc (maxlength + 1, sizeof (int));
5255       if (counts == NULL)
5256         {
5257           error (_("Out of memory"));
5258           return 0;
5259         }
5260
5261       for (hn = 0; hn < nbuckets; ++hn)
5262         ++ counts [lengths [hn]];
5263
5264       if (nbuckets > 0)
5265         {
5266           printf ("      0  %-10d (%5.1f%%)\n",
5267                   counts[0], (counts[0] * 100.0) / nbuckets);
5268           for (si = 1; si <= maxlength; ++si)
5269             {
5270               nzero_counts += counts[si] * si;
5271               printf ("%7d  %-10d (%5.1f%%)    %5.1f%%\n",
5272                       si, counts[si], (counts[si] * 100.0) / nbuckets,
5273                       (nzero_counts * 100.0) / nsyms);
5274             }
5275         }
5276
5277       free (counts);
5278       free (lengths);
5279     }
5280
5281   if (buckets != NULL)
5282     {
5283       free (buckets);
5284       free (chains);
5285     }
5286
5287   return 1;
5288 }
5289
5290 static int
5291 process_syminfo (file)
5292      FILE * file ATTRIBUTE_UNUSED;
5293 {
5294   unsigned int i;
5295
5296   if (dynamic_syminfo == NULL
5297       || !do_dynamic)
5298     /* No syminfo, this is ok.  */
5299     return 1;
5300
5301   /* There better should be a dynamic symbol section.  */
5302   if (dynamic_symbols == NULL || dynamic_strings == NULL)
5303     return 0;
5304
5305   if (dynamic_addr)
5306     printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
5307             dynamic_syminfo_offset, dynamic_syminfo_nent);
5308
5309   printf (_(" Num: Name                           BoundTo     Flags\n"));
5310   for (i = 0; i < dynamic_syminfo_nent; ++i)
5311     {
5312       unsigned short int flags = dynamic_syminfo[i].si_flags;
5313
5314       printf ("%4d: %-30s ", i,
5315               dynamic_strings + dynamic_symbols[i].st_name);
5316
5317       switch (dynamic_syminfo[i].si_boundto)
5318         {
5319         case SYMINFO_BT_SELF:
5320           fputs ("SELF       ", stdout);
5321           break;
5322         case SYMINFO_BT_PARENT:
5323           fputs ("PARENT     ", stdout);
5324           break;
5325         default:
5326           if (dynamic_syminfo[i].si_boundto > 0
5327               && dynamic_syminfo[i].si_boundto < dynamic_size)
5328             printf ("%-10s ",
5329                     dynamic_strings
5330                     + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
5331           else
5332             printf ("%-10d ", dynamic_syminfo[i].si_boundto);
5333           break;
5334         }
5335
5336       if (flags & SYMINFO_FLG_DIRECT)
5337         printf (" DIRECT");
5338       if (flags & SYMINFO_FLG_PASSTHRU)
5339         printf (" PASSTHRU");
5340       if (flags & SYMINFO_FLG_COPY)
5341         printf (" COPY");
5342       if (flags & SYMINFO_FLG_LAZYLOAD)
5343         printf (" LAZYLOAD");
5344
5345       puts ("");
5346     }
5347
5348   return 1;
5349 }
5350
5351 #ifdef SUPPORT_DISASSEMBLY
5352 static void
5353 disassemble_section (section, file)
5354      Elf32_Internal_Shdr * section;
5355      FILE * file;
5356 {
5357   printf (_("\nAssembly dump of section %s\n"),
5358           SECTION_NAME (section));
5359
5360   /* XXX -- to be done --- XXX */
5361
5362   return 1;
5363 }
5364 #endif
5365
5366 static int
5367 dump_section (section, file)
5368      Elf32_Internal_Shdr * section;
5369      FILE * file;
5370 {
5371   bfd_size_type   bytes;
5372   bfd_vma         addr;
5373   unsigned char * data;
5374   unsigned char * start;
5375
5376   bytes = section->sh_size;
5377
5378   if (bytes == 0)
5379     {
5380       printf (_("\nSection '%s' has no data to dump.\n"),
5381               SECTION_NAME (section));
5382       return 0;
5383     }
5384   else
5385     printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
5386
5387   addr = section->sh_addr;
5388
5389   start = (unsigned char *) get_data (NULL, file, section->sh_offset, bytes,
5390                                       _("section data"));
5391   if (!start)
5392     return 0;
5393
5394   data = start;
5395
5396   while (bytes)
5397     {
5398       int j;
5399       int k;
5400       int lbytes;
5401
5402       lbytes = (bytes > 16 ? 16 : bytes);
5403
5404       printf ("  0x%8.8lx ", (unsigned long) addr);
5405
5406       switch (elf_header.e_ident [EI_DATA])
5407         {
5408         default:
5409         case ELFDATA2LSB:
5410           for (j = 15; j >= 0; j --)
5411             {
5412               if (j < lbytes)
5413                 printf ("%2.2x", data [j]);
5414               else
5415                 printf ("  ");
5416
5417               if (!(j & 0x3))
5418                 printf (" ");
5419             }
5420           break;
5421
5422         case ELFDATA2MSB:
5423           for (j = 0; j < 16; j++)
5424             {
5425               if (j < lbytes)
5426                 printf ("%2.2x", data [j]);
5427               else
5428                 printf ("  ");
5429
5430               if ((j & 3) == 3)
5431                 printf (" ");
5432             }
5433           break;
5434         }
5435
5436       for (j = 0; j < lbytes; j++)
5437         {
5438           k = data [j];
5439           if (k >= ' ' && k < 0x80)
5440             printf ("%c", k);
5441           else
5442             printf (".");
5443         }
5444
5445       putchar ('\n');
5446
5447       data  += lbytes;
5448       addr  += lbytes;
5449       bytes -= lbytes;
5450     }
5451
5452   free (start);
5453
5454   return 1;
5455 }
5456
5457
5458 static unsigned long int
5459 read_leb128 (data, length_return, sign)
5460      unsigned char * data;
5461      int *           length_return;
5462      int             sign;
5463 {
5464   unsigned long int result = 0;
5465   unsigned int      num_read = 0;
5466   int               shift = 0;
5467   unsigned char     byte;
5468
5469   do
5470     {
5471       byte = * data ++;
5472       num_read ++;
5473
5474       result |= (byte & 0x7f) << shift;
5475
5476       shift += 7;
5477
5478     }
5479   while (byte & 0x80);
5480
5481   if (length_return != NULL)
5482     * length_return = num_read;
5483
5484   if (sign && (shift < 32) && (byte & 0x40))
5485     result |= -1 << shift;
5486
5487   return result;
5488 }
5489
5490 typedef struct State_Machine_Registers
5491 {
5492   unsigned long address;
5493   unsigned int  file;
5494   unsigned int  line;
5495   unsigned int  column;
5496   int           is_stmt;
5497   int           basic_block;
5498   int           end_sequence;
5499 /* This variable hold the number of the last entry seen
5500    in the File Table.  */
5501   unsigned int  last_file_entry;
5502 } SMR;
5503
5504 static SMR state_machine_regs;
5505
5506 static void
5507 reset_state_machine (is_stmt)
5508      int is_stmt;
5509 {
5510   state_machine_regs.address = 0;
5511   state_machine_regs.file = 1;
5512   state_machine_regs.line = 1;
5513   state_machine_regs.column = 0;
5514   state_machine_regs.is_stmt = is_stmt;
5515   state_machine_regs.basic_block = 0;
5516   state_machine_regs.end_sequence = 0;
5517   state_machine_regs.last_file_entry = 0;
5518 }
5519
5520 /* Handled an extend line op.  Returns true if this is the end
5521    of sequence.  */
5522 static int
5523 process_extended_line_op (data, is_stmt, pointer_size)
5524      unsigned char * data;
5525      int is_stmt;
5526      int pointer_size;
5527 {
5528   unsigned char   op_code;
5529   int             bytes_read;
5530   unsigned int    len;
5531   unsigned char * name;
5532   unsigned long   adr;
5533
5534   len = read_leb128 (data, & bytes_read, 0);
5535   data += bytes_read;
5536
5537   if (len == 0)
5538     {
5539       warn (_("badly formed extended line op encountered!"));
5540       return bytes_read;
5541     }
5542
5543   len += bytes_read;
5544   op_code = * data ++;
5545
5546   printf (_("  Extended opcode %d: "), op_code);
5547
5548   switch (op_code)
5549     {
5550     case DW_LNE_end_sequence:
5551       printf (_("End of Sequence\n\n"));
5552       reset_state_machine (is_stmt);
5553       break;
5554
5555     case DW_LNE_set_address:
5556       adr = byte_get (data, pointer_size);
5557       printf (_("set Address to 0x%lx\n"), adr);
5558       state_machine_regs.address = adr;
5559       break;
5560
5561     case DW_LNE_define_file:
5562       printf (_("  define new File Table entry\n"));
5563       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
5564
5565       printf (_("   %d\t"), ++ state_machine_regs.last_file_entry);
5566       name = data;
5567       data += strlen ((char *) data) + 1;
5568       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5569       data += bytes_read;
5570       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5571       data += bytes_read;
5572       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5573       printf (_("%s\n\n"), name);
5574       break;
5575
5576     default:
5577       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
5578       break;
5579     }
5580
5581   return len;
5582 }
5583
5584 /* Size of pointers in the .debug_line section.  This information is not
5585    really present in that section.  It's obtained before dumping the debug
5586    sections by doing some pre-scan of the .debug_info section.  */
5587 static int debug_line_pointer_size = 4;
5588
5589 static int
5590 display_debug_lines (section, start, file)
5591      Elf32_Internal_Shdr * section;
5592      unsigned char *       start;
5593      FILE *                file ATTRIBUTE_UNUSED;
5594 {
5595   DWARF2_External_LineInfo * external;
5596   DWARF2_Internal_LineInfo   info;
5597   unsigned char *            standard_opcodes;
5598   unsigned char *            data = start;
5599   unsigned char *            end  = start + section->sh_size;
5600   unsigned char *            end_of_sequence;
5601   int                        i;
5602
5603   printf (_("\nDump of debug contents of section %s:\n\n"),
5604           SECTION_NAME (section));
5605
5606   while (data < end)
5607     {
5608       external = (DWARF2_External_LineInfo *) data;
5609
5610       /* Check the length of the block.  */
5611       info.li_length = BYTE_GET (external->li_length);
5612       if (info.li_length + sizeof (external->li_length) > section->sh_size)
5613         {
5614           warn
5615             (_("The line info appears to be corrupt - the section is too small\n"));
5616           return 0;
5617         }
5618
5619       /* Check its version number.  */
5620       info.li_version = BYTE_GET (external->li_version);
5621       if (info.li_version != 2)
5622         {
5623           warn (_("Only DWARF version 2 line info is currently supported.\n"));
5624           return 0;
5625         }
5626
5627       info.li_prologue_length = BYTE_GET (external->li_prologue_length);
5628       info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
5629       info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
5630       info.li_line_base       = BYTE_GET (external->li_line_base);
5631       info.li_line_range      = BYTE_GET (external->li_line_range);
5632       info.li_opcode_base     = BYTE_GET (external->li_opcode_base);
5633
5634       /* Sign extend the line base field.  */
5635       info.li_line_base <<= 24;
5636       info.li_line_base >>= 24;
5637
5638       printf (_("  Length:                      %ld\n"), info.li_length);
5639       printf (_("  DWARF Version:               %d\n"), info.li_version);
5640       printf (_("  Prologue Length:             %d\n"), info.li_prologue_length);
5641       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
5642       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
5643       printf (_("  Line Base:                   %d\n"), info.li_line_base);
5644       printf (_("  Line Range:                  %d\n"), info.li_line_range);
5645       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
5646
5647       end_of_sequence = data + info.li_length + sizeof (external->li_length);
5648
5649       reset_state_machine (info.li_default_is_stmt);
5650
5651       /* Display the contents of the Opcodes table.  */
5652       standard_opcodes = data + sizeof (* external);
5653
5654       printf (_("\n Opcodes:\n"));
5655
5656       for (i = 1; i < info.li_opcode_base; i++)
5657         printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
5658
5659       /* Display the contents of the Directory table.  */
5660       data = standard_opcodes + info.li_opcode_base - 1;
5661
5662       if (* data == 0)
5663         printf (_("\n The Directory Table is empty.\n"));
5664       else
5665         {
5666           printf (_("\n The Directory Table:\n"));
5667
5668           while (* data != 0)
5669             {
5670               printf (_("  %s\n"), data);
5671
5672               data += strlen ((char *) data) + 1;
5673             }
5674         }
5675
5676       /* Skip the NUL at the end of the table.  */
5677       data ++;
5678
5679       /* Display the contents of the File Name table.  */
5680       if (* data == 0)
5681         printf (_("\n The File Name Table is empty.\n"));
5682       else
5683         {
5684           printf (_("\n The File Name Table:\n"));
5685           printf (_("  Entry\tDir\tTime\tSize\tName\n"));
5686
5687           while (* data != 0)
5688             {
5689               unsigned char * name;
5690               int bytes_read;
5691
5692               printf (_("  %d\t"), ++ state_machine_regs.last_file_entry);
5693               name = data;
5694
5695               data += strlen ((char *) data) + 1;
5696
5697               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5698               data += bytes_read;
5699               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5700               data += bytes_read;
5701               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5702               data += bytes_read;
5703               printf (_("%s\n"), name);
5704             }
5705         }
5706
5707       /* Skip the NUL at the end of the table.  */
5708       data ++;
5709
5710       /* Now display the statements.  */
5711       printf (_("\n Line Number Statements:\n"));
5712
5713
5714       while (data < end_of_sequence)
5715         {
5716           unsigned char op_code;
5717           int           adv;
5718           int           bytes_read;
5719
5720           op_code = * data ++;
5721
5722           switch (op_code)
5723             {
5724             case DW_LNS_extended_op:
5725               data += process_extended_line_op (data, info.li_default_is_stmt,
5726                                                 debug_line_pointer_size);
5727               break;
5728
5729             case DW_LNS_copy:
5730               printf (_("  Copy\n"));
5731               break;
5732
5733             case DW_LNS_advance_pc:
5734               adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
5735               data += bytes_read;
5736               state_machine_regs.address += adv;
5737               printf (_("  Advance PC by %d to %lx\n"), adv,
5738                       state_machine_regs.address);
5739               break;
5740
5741             case DW_LNS_advance_line:
5742               adv = read_leb128 (data, & bytes_read, 1);
5743               data += bytes_read;
5744               state_machine_regs.line += adv;
5745               printf (_("  Advance Line by %d to %d\n"), adv,
5746                       state_machine_regs.line);
5747               break;
5748
5749             case DW_LNS_set_file:
5750               adv = read_leb128 (data, & bytes_read, 0);
5751               data += bytes_read;
5752               printf (_("  Set File Name to entry %d in the File Name Table\n"),
5753                       adv);
5754               state_machine_regs.file = adv;
5755               break;
5756
5757             case DW_LNS_set_column:
5758               adv = read_leb128 (data, & bytes_read, 0);
5759               data += bytes_read;
5760               printf (_("  Set column to %d\n"), adv);
5761               state_machine_regs.column = adv;
5762               break;
5763
5764             case DW_LNS_negate_stmt:
5765               adv = state_machine_regs.is_stmt;
5766               adv = ! adv;
5767               printf (_("  Set is_stmt to %d\n"), adv);
5768               state_machine_regs.is_stmt = adv;
5769               break;
5770
5771             case DW_LNS_set_basic_block:
5772               printf (_("  Set basic block\n"));
5773               state_machine_regs.basic_block = 1;
5774               break;
5775
5776             case DW_LNS_const_add_pc:
5777               adv = (((255 - info.li_opcode_base) / info.li_line_range)
5778                      * info.li_min_insn_length);
5779               state_machine_regs.address += adv;
5780               printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
5781                       state_machine_regs.address);
5782               break;
5783
5784             case DW_LNS_fixed_advance_pc:
5785               adv = byte_get (data, 2);
5786               data += 2;
5787               state_machine_regs.address += adv;
5788               printf (_("  Advance PC by fixed size amount %d to 0x%lx\n"),
5789                       adv, state_machine_regs.address);
5790               break;
5791
5792             default:
5793               op_code -= info.li_opcode_base;
5794               adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
5795               state_machine_regs.address += adv;
5796               printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
5797                       op_code, adv, state_machine_regs.address);
5798               adv = (op_code % info.li_line_range) + info.li_line_base;
5799               state_machine_regs.line += adv;
5800               printf (_(" and Line by %d to %d\n"),
5801                       adv, state_machine_regs.line);
5802               break;
5803             }
5804         }
5805       printf ("\n");
5806     }
5807
5808   return 1;
5809 }
5810
5811 static int
5812 display_debug_pubnames (section, start, file)
5813      Elf32_Internal_Shdr * section;
5814      unsigned char *       start;
5815      FILE *                file ATTRIBUTE_UNUSED;
5816 {
5817   DWARF2_External_PubNames * external;
5818   DWARF2_Internal_PubNames   pubnames;
5819   unsigned char *            end;
5820
5821   end = start + section->sh_size;
5822
5823   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5824
5825   while (start < end)
5826     {
5827       unsigned char * data;
5828       unsigned long   offset;
5829
5830       external = (DWARF2_External_PubNames *) start;
5831
5832       pubnames.pn_length  = BYTE_GET (external->pn_length);
5833       pubnames.pn_version = BYTE_GET (external->pn_version);
5834       pubnames.pn_offset  = BYTE_GET (external->pn_offset);
5835       pubnames.pn_size    = BYTE_GET (external->pn_size);
5836
5837       data   = start + sizeof (* external);
5838       start += pubnames.pn_length + sizeof (external->pn_length);
5839
5840       if (pubnames.pn_version != 2)
5841         {
5842           static int warned = 0;
5843
5844           if (! warned)
5845             {
5846               warn (_("Only DWARF 2 pubnames are currently supported\n"));
5847               warned = 1;
5848             }
5849
5850           continue;
5851         }
5852
5853       printf (_("  Length:                              %ld\n"),
5854               pubnames.pn_length);
5855       printf (_("  Version:                             %d\n"),
5856               pubnames.pn_version);
5857       printf (_("  Offset into .debug_info section:     %ld\n"),
5858               pubnames.pn_offset);
5859       printf (_("  Size of area in .debug_info section: %ld\n"),
5860               pubnames.pn_size);
5861
5862       printf (_("\n    Offset\tName\n"));
5863
5864       do
5865         {
5866           offset = byte_get (data, 4);
5867
5868           if (offset != 0)
5869             {
5870               data += 4;
5871               printf ("    %ld\t\t%s\n", offset, data);
5872               data += strlen ((char *) data) + 1;
5873             }
5874         }
5875       while (offset != 0);
5876     }
5877
5878   printf ("\n");
5879   return 1;
5880 }
5881
5882 static char *
5883 get_TAG_name (tag)
5884      unsigned long tag;
5885 {
5886   switch (tag)
5887     {
5888     case DW_TAG_padding:                return "DW_TAG_padding";
5889     case DW_TAG_array_type:             return "DW_TAG_array_type";
5890     case DW_TAG_class_type:             return "DW_TAG_class_type";
5891     case DW_TAG_entry_point:            return "DW_TAG_entry_point";
5892     case DW_TAG_enumeration_type:       return "DW_TAG_enumeration_type";
5893     case DW_TAG_formal_parameter:       return "DW_TAG_formal_parameter";
5894     case DW_TAG_imported_declaration:   return "DW_TAG_imported_declaration";
5895     case DW_TAG_label:                  return "DW_TAG_label";
5896     case DW_TAG_lexical_block:          return "DW_TAG_lexical_block";
5897     case DW_TAG_member:                 return "DW_TAG_member";
5898     case DW_TAG_pointer_type:           return "DW_TAG_pointer_type";
5899     case DW_TAG_reference_type:         return "DW_TAG_reference_type";
5900     case DW_TAG_compile_unit:           return "DW_TAG_compile_unit";
5901     case DW_TAG_string_type:            return "DW_TAG_string_type";
5902     case DW_TAG_structure_type:         return "DW_TAG_structure_type";
5903     case DW_TAG_subroutine_type:        return "DW_TAG_subroutine_type";
5904     case DW_TAG_typedef:                return "DW_TAG_typedef";
5905     case DW_TAG_union_type:             return "DW_TAG_union_type";
5906     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
5907     case DW_TAG_variant:                return "DW_TAG_variant";
5908     case DW_TAG_common_block:           return "DW_TAG_common_block";
5909     case DW_TAG_common_inclusion:       return "DW_TAG_common_inclusion";
5910     case DW_TAG_inheritance:            return "DW_TAG_inheritance";
5911     case DW_TAG_inlined_subroutine:     return "DW_TAG_inlined_subroutine";
5912     case DW_TAG_module:                 return "DW_TAG_module";
5913     case DW_TAG_ptr_to_member_type:     return "DW_TAG_ptr_to_member_type";
5914     case DW_TAG_set_type:               return "DW_TAG_set_type";
5915     case DW_TAG_subrange_type:          return "DW_TAG_subrange_type";
5916     case DW_TAG_with_stmt:              return "DW_TAG_with_stmt";
5917     case DW_TAG_access_declaration:     return "DW_TAG_access_declaration";
5918     case DW_TAG_base_type:              return "DW_TAG_base_type";
5919     case DW_TAG_catch_block:            return "DW_TAG_catch_block";
5920     case DW_TAG_const_type:             return "DW_TAG_const_type";
5921     case DW_TAG_constant:               return "DW_TAG_constant";
5922     case DW_TAG_enumerator:             return "DW_TAG_enumerator";
5923     case DW_TAG_file_type:              return "DW_TAG_file_type";
5924     case DW_TAG_friend:                 return "DW_TAG_friend";
5925     case DW_TAG_namelist:               return "DW_TAG_namelist";
5926     case DW_TAG_namelist_item:          return "DW_TAG_namelist_item";
5927     case DW_TAG_packed_type:            return "DW_TAG_packed_type";
5928     case DW_TAG_subprogram:             return "DW_TAG_subprogram";
5929     case DW_TAG_template_type_param:    return "DW_TAG_template_type_param";
5930     case DW_TAG_template_value_param:   return "DW_TAG_template_value_param";
5931     case DW_TAG_thrown_type:            return "DW_TAG_thrown_type";
5932     case DW_TAG_try_block:              return "DW_TAG_try_block";
5933     case DW_TAG_variant_part:           return "DW_TAG_variant_part";
5934     case DW_TAG_variable:               return "DW_TAG_variable";
5935     case DW_TAG_volatile_type:          return "DW_TAG_volatile_type";
5936     case DW_TAG_MIPS_loop:              return "DW_TAG_MIPS_loop";
5937     case DW_TAG_format_label:           return "DW_TAG_format_label";
5938     case DW_TAG_function_template:      return "DW_TAG_function_template";
5939     case DW_TAG_class_template:         return "DW_TAG_class_template";
5940       /* DWARF 2.1 values.  */
5941     case DW_TAG_dwarf_procedure:        return "DW_TAG_dwarf_procedure";
5942     case DW_TAG_restrict_type:          return "DW_TAG_restrict_type";
5943     case DW_TAG_interface_type:         return "DW_TAG_interface_type";
5944     case DW_TAG_namespace:              return "DW_TAG_namespace";
5945     case DW_TAG_imported_module:        return "DW_TAG_imported_module";
5946     case DW_TAG_unspecified_type:       return "DW_TAG_unspecified_type";
5947     case DW_TAG_partial_unit:           return "DW_TAG_partial_unit";
5948     case DW_TAG_imported_unit:          return "DW_TAG_imported_unit";
5949     default:
5950       {
5951         static char buffer [100];
5952
5953         sprintf (buffer, _("Unknown TAG value: %lx"), tag);
5954         return buffer;
5955       }
5956     }
5957 }
5958
5959 static char *
5960 get_AT_name (attribute)
5961      unsigned long attribute;
5962 {
5963   switch (attribute)
5964     {
5965     case DW_AT_sibling:              return "DW_AT_sibling";
5966     case DW_AT_location:             return "DW_AT_location";
5967     case DW_AT_name:                 return "DW_AT_name";
5968     case DW_AT_ordering:             return "DW_AT_ordering";
5969     case DW_AT_subscr_data:          return "DW_AT_subscr_data";
5970     case DW_AT_byte_size:            return "DW_AT_byte_size";
5971     case DW_AT_bit_offset:           return "DW_AT_bit_offset";
5972     case DW_AT_bit_size:             return "DW_AT_bit_size";
5973     case DW_AT_element_list:         return "DW_AT_element_list";
5974     case DW_AT_stmt_list:            return "DW_AT_stmt_list";
5975     case DW_AT_low_pc:               return "DW_AT_low_pc";
5976     case DW_AT_high_pc:              return "DW_AT_high_pc";
5977     case DW_AT_language:             return "DW_AT_language";
5978     case DW_AT_member:               return "DW_AT_member";
5979     case DW_AT_discr:                return "DW_AT_discr";
5980     case DW_AT_discr_value:          return "DW_AT_discr_value";
5981     case DW_AT_visibility:           return "DW_AT_visibility";
5982     case DW_AT_import:               return "DW_AT_import";
5983     case DW_AT_string_length:        return "DW_AT_string_length";
5984     case DW_AT_common_reference:     return "DW_AT_common_reference";
5985     case DW_AT_comp_dir:             return "DW_AT_comp_dir";
5986     case DW_AT_const_value:          return "DW_AT_const_value";
5987     case DW_AT_containing_type:      return "DW_AT_containing_type";
5988     case DW_AT_default_value:        return "DW_AT_default_value";
5989     case DW_AT_inline:               return "DW_AT_inline";
5990     case DW_AT_is_optional:          return "DW_AT_is_optional";
5991     case DW_AT_lower_bound:          return "DW_AT_lower_bound";
5992     case DW_AT_producer:             return "DW_AT_producer";
5993     case DW_AT_prototyped:           return "DW_AT_prototyped";
5994     case DW_AT_return_addr:          return "DW_AT_return_addr";
5995     case DW_AT_start_scope:          return "DW_AT_start_scope";
5996     case DW_AT_stride_size:          return "DW_AT_stride_size";
5997     case DW_AT_upper_bound:          return "DW_AT_upper_bound";
5998     case DW_AT_abstract_origin:      return "DW_AT_abstract_origin";
5999     case DW_AT_accessibility:        return "DW_AT_accessibility";
6000     case DW_AT_address_class:        return "DW_AT_address_class";
6001     case DW_AT_artificial:           return "DW_AT_artificial";
6002     case DW_AT_base_types:           return "DW_AT_base_types";
6003     case DW_AT_calling_convention:   return "DW_AT_calling_convention";
6004     case DW_AT_count:                return "DW_AT_count";
6005     case DW_AT_data_member_location: return "DW_AT_data_member_location";
6006     case DW_AT_decl_column:          return "DW_AT_decl_column";
6007     case DW_AT_decl_file:            return "DW_AT_decl_file";
6008     case DW_AT_decl_line:            return "DW_AT_decl_line";
6009     case DW_AT_declaration:          return "DW_AT_declaration";
6010     case DW_AT_discr_list:           return "DW_AT_discr_list";
6011     case DW_AT_encoding:             return "DW_AT_encoding";
6012     case DW_AT_external:             return "DW_AT_external";
6013     case DW_AT_frame_base:           return "DW_AT_frame_base";
6014     case DW_AT_friend:               return "DW_AT_friend";
6015     case DW_AT_identifier_case:      return "DW_AT_identifier_case";
6016     case DW_AT_macro_info:           return "DW_AT_macro_info";
6017     case DW_AT_namelist_items:       return "DW_AT_namelist_items";
6018     case DW_AT_priority:             return "DW_AT_priority";
6019     case DW_AT_segment:              return "DW_AT_segment";
6020     case DW_AT_specification:        return "DW_AT_specification";
6021     case DW_AT_static_link:          return "DW_AT_static_link";
6022     case DW_AT_type:                 return "DW_AT_type";
6023     case DW_AT_use_location:         return "DW_AT_use_location";
6024     case DW_AT_variable_parameter:   return "DW_AT_variable_parameter";
6025     case DW_AT_virtuality:           return "DW_AT_virtuality";
6026     case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
6027       /* DWARF 2.1 values.  */
6028     case DW_AT_allocated:            return "DW_AT_allocated";
6029     case DW_AT_associated:           return "DW_AT_associated";
6030     case DW_AT_data_location:        return "DW_AT_data_location";
6031     case DW_AT_stride:               return "DW_AT_stride";
6032     case DW_AT_entry_pc:             return "DW_AT_entry_pc";
6033     case DW_AT_use_UTF8:             return "DW_AT_use_UTF8";
6034     case DW_AT_extension:            return "DW_AT_extension";
6035     case DW_AT_ranges:               return "DW_AT_ranges";
6036     case DW_AT_trampoline:           return "DW_AT_trampoline";
6037     case DW_AT_call_column:          return "DW_AT_call_column";
6038     case DW_AT_call_file:            return "DW_AT_call_file";
6039     case DW_AT_call_line:            return "DW_AT_call_line";
6040       /* SGI/MIPS extensions.  */
6041     case DW_AT_MIPS_fde:             return "DW_AT_MIPS_fde";
6042     case DW_AT_MIPS_loop_begin:      return "DW_AT_MIPS_loop_begin";
6043     case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
6044     case DW_AT_MIPS_epilog_begin:    return "DW_AT_MIPS_epilog_begin";
6045     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
6046     case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
6047     case DW_AT_MIPS_linkage_name:    return "DW_AT_MIPS_linkage_name";
6048     case DW_AT_MIPS_stride:          return "DW_AT_MIPS_stride";
6049     case DW_AT_MIPS_abstract_name:   return "DW_AT_MIPS_abstract_name";
6050     case DW_AT_MIPS_clone_origin:    return "DW_AT_MIPS_clone_origin";
6051     case DW_AT_MIPS_has_inlines:     return "DW_AT_MIPS_has_inlines";
6052       /* GNU extensions.  */
6053     case DW_AT_sf_names:             return "DW_AT_sf_names";
6054     case DW_AT_src_info:             return "DW_AT_src_info";
6055     case DW_AT_mac_info:             return "DW_AT_mac_info";
6056     case DW_AT_src_coords:           return "DW_AT_src_coords";
6057     case DW_AT_body_begin:           return "DW_AT_body_begin";
6058     case DW_AT_body_end:             return "DW_AT_body_end";
6059     default:
6060       {
6061         static char buffer [100];
6062
6063         sprintf (buffer, _("Unknown AT value: %lx"), attribute);
6064         return buffer;
6065       }
6066     }
6067 }
6068
6069 static char *
6070 get_FORM_name (form)
6071      unsigned long form;
6072 {
6073   switch (form)
6074     {
6075     case DW_FORM_addr:      return "DW_FORM_addr";
6076     case DW_FORM_block2:    return "DW_FORM_block2";
6077     case DW_FORM_block4:    return "DW_FORM_block4";
6078     case DW_FORM_data2:     return "DW_FORM_data2";
6079     case DW_FORM_data4:     return "DW_FORM_data4";
6080     case DW_FORM_data8:     return "DW_FORM_data8";
6081     case DW_FORM_string:    return "DW_FORM_string";
6082     case DW_FORM_block:     return "DW_FORM_block";
6083     case DW_FORM_block1:    return "DW_FORM_block1";
6084     case DW_FORM_data1:     return "DW_FORM_data1";
6085     case DW_FORM_flag:      return "DW_FORM_flag";
6086     case DW_FORM_sdata:     return "DW_FORM_sdata";
6087     case DW_FORM_strp:      return "DW_FORM_strp";
6088     case DW_FORM_udata:     return "DW_FORM_udata";
6089     case DW_FORM_ref_addr:  return "DW_FORM_ref_addr";
6090     case DW_FORM_ref1:      return "DW_FORM_ref1";
6091     case DW_FORM_ref2:      return "DW_FORM_ref2";
6092     case DW_FORM_ref4:      return "DW_FORM_ref4";
6093     case DW_FORM_ref8:      return "DW_FORM_ref8";
6094     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
6095     case DW_FORM_indirect:  return "DW_FORM_indirect";
6096     default:
6097       {
6098         static char buffer [100];
6099
6100         sprintf (buffer, _("Unknown FORM value: %lx"), form);
6101         return buffer;
6102       }
6103     }
6104 }
6105
6106 /* FIXME:  There are better and more effiecint ways to handle
6107    these structures.  For now though, I just want something that
6108    is simple to implement.  */
6109 typedef struct abbrev_attr
6110 {
6111   unsigned long        attribute;
6112   unsigned long        form;
6113   struct abbrev_attr * next;
6114 }
6115 abbrev_attr;
6116
6117 typedef struct abbrev_entry
6118 {
6119   unsigned long          entry;
6120   unsigned long          tag;
6121   int                    children;
6122   struct abbrev_attr *   first_attr;
6123   struct abbrev_attr *   last_attr;
6124   struct abbrev_entry *  next;
6125 }
6126 abbrev_entry;
6127
6128 static abbrev_entry * first_abbrev = NULL;
6129 static abbrev_entry * last_abbrev = NULL;
6130
6131 static void
6132 free_abbrevs PARAMS ((void))
6133 {
6134   abbrev_entry * abbrev;
6135
6136   for (abbrev = first_abbrev; abbrev;)
6137     {
6138       abbrev_entry * next = abbrev->next;
6139       abbrev_attr  * attr;
6140
6141       for (attr = abbrev->first_attr; attr;)
6142         {
6143           abbrev_attr * next = attr->next;
6144
6145           free (attr);
6146           attr = next;
6147         }
6148
6149       free (abbrev);
6150       abbrev = next;
6151     }
6152
6153   last_abbrev = first_abbrev = NULL;
6154 }
6155
6156 static void
6157 add_abbrev (number, tag, children)
6158      unsigned long number;
6159      unsigned long tag;
6160      int           children;
6161 {
6162   abbrev_entry * entry;
6163
6164   entry = (abbrev_entry *) malloc (sizeof (* entry));
6165
6166   if (entry == NULL)
6167     /* ugg */
6168     return;
6169
6170   entry->entry      = number;
6171   entry->tag        = tag;
6172   entry->children   = children;
6173   entry->first_attr = NULL;
6174   entry->last_attr  = NULL;
6175   entry->next       = NULL;
6176
6177   if (first_abbrev == NULL)
6178     first_abbrev = entry;
6179   else
6180     last_abbrev->next = entry;
6181
6182   last_abbrev = entry;
6183 }
6184
6185 static void
6186 add_abbrev_attr (attribute, form)
6187      unsigned long attribute;
6188      unsigned long form;
6189 {
6190   abbrev_attr * attr;
6191
6192   attr = (abbrev_attr *) malloc (sizeof (* attr));
6193
6194   if (attr == NULL)
6195     /* ugg */
6196     return;
6197
6198   attr->attribute = attribute;
6199   attr->form      = form;
6200   attr->next      = NULL;
6201
6202   if (last_abbrev->first_attr == NULL)
6203     last_abbrev->first_attr = attr;
6204   else
6205     last_abbrev->last_attr->next = attr;
6206
6207   last_abbrev->last_attr = attr;
6208 }
6209
6210 /* Processes the (partial) contents of a .debug_abbrev section.
6211    Returns NULL if the end of the section was encountered.
6212    Returns the address after the last byte read if the end of
6213    an abbreviation set was found.  */
6214
6215 static unsigned char *
6216 process_abbrev_section (start, end)
6217      unsigned char * start;
6218      unsigned char * end;
6219 {
6220   if (first_abbrev != NULL)
6221     return NULL;
6222
6223   while (start < end)
6224     {
6225       int           bytes_read;
6226       unsigned long entry;
6227       unsigned long tag;
6228       unsigned long attribute;
6229       int           children;
6230
6231       entry = read_leb128 (start, & bytes_read, 0);
6232       start += bytes_read;
6233
6234       /* A single zero is supposed to end the section according
6235          to the standard.  If there's more, then signal that to
6236          the caller.  */
6237       if (entry == 0)
6238         return start == end ? NULL : start;
6239
6240       tag = read_leb128 (start, & bytes_read, 0);
6241       start += bytes_read;
6242
6243       children = * start ++;
6244
6245       add_abbrev (entry, tag, children);
6246
6247       do
6248         {
6249           unsigned long form;
6250
6251           attribute = read_leb128 (start, & bytes_read, 0);
6252           start += bytes_read;
6253
6254           form = read_leb128 (start, & bytes_read, 0);
6255           start += bytes_read;
6256
6257           if (attribute != 0)
6258             add_abbrev_attr (attribute, form);
6259         }
6260       while (attribute != 0);
6261     }
6262
6263   return NULL;
6264 }
6265
6266
6267 static int
6268 display_debug_abbrev (section, start, file)
6269      Elf32_Internal_Shdr * section;
6270      unsigned char *       start;
6271      FILE *                file ATTRIBUTE_UNUSED;
6272 {
6273   abbrev_entry *  entry;
6274   unsigned char * end = start + section->sh_size;
6275
6276   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6277
6278   do
6279     {
6280       start = process_abbrev_section (start, end);
6281
6282       printf (_("  Number TAG\n"));
6283
6284       for (entry = first_abbrev; entry; entry = entry->next)
6285         {
6286           abbrev_attr * attr;
6287
6288           printf (_("   %ld      %s    [%s]\n"),
6289                   entry->entry,
6290                   get_TAG_name (entry->tag),
6291                   entry->children ? _("has children") : _("no children"));
6292
6293           for (attr = entry->first_attr; attr; attr = attr->next)
6294             {
6295               printf (_("    %-18s %s\n"),
6296                       get_AT_name (attr->attribute),
6297                       get_FORM_name (attr->form));
6298             }
6299         }
6300     }
6301   while (start);
6302
6303   printf ("\n");
6304
6305   return 1;
6306 }
6307
6308
6309 static unsigned char *
6310 display_block (data, length)
6311      unsigned char * data;
6312      unsigned long   length;
6313 {
6314   printf (_(" %lu byte block: "), length);
6315
6316   while (length --)
6317     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
6318
6319   return data;
6320 }
6321
6322 static void
6323 decode_location_expression (data, pointer_size, length)
6324      unsigned char * data;
6325      unsigned int    pointer_size;
6326      unsigned long   length;
6327 {
6328   unsigned        op;
6329   int             bytes_read;
6330   unsigned long   uvalue;
6331   unsigned char * end = data + length;
6332
6333   while (data < end)
6334     {
6335       op = * data ++;
6336
6337       switch (op)
6338         {
6339         case DW_OP_addr:
6340           printf ("DW_OP_addr: %lx",
6341                   (unsigned long) byte_get (data, pointer_size));
6342           data += pointer_size;
6343           break;
6344         case DW_OP_deref:
6345           printf ("DW_OP_deref");
6346           break;
6347         case DW_OP_const1u:
6348           printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6349           break;
6350         case DW_OP_const1s:
6351           printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6352           break;
6353         case DW_OP_const2u:
6354           printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6355           data += 2;
6356           break;
6357         case DW_OP_const2s:
6358           printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6359           data += 2;
6360           break;
6361         case DW_OP_const4u:
6362           printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6363           data += 4;
6364           break;
6365         case DW_OP_const4s:
6366           printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6367           data += 4;
6368           break;
6369         case DW_OP_const8u:
6370           printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6371                   (unsigned long) byte_get (data + 4, 4));
6372           data += 8;
6373           break;
6374         case DW_OP_const8s:
6375           printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6376                   (long) byte_get (data + 4, 4));
6377           data += 8;
6378           break;
6379         case DW_OP_constu:
6380           printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6381           data += bytes_read;
6382           break;
6383         case DW_OP_consts:
6384           printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6385           data += bytes_read;
6386           break;
6387         case DW_OP_dup:
6388           printf ("DW_OP_dup");
6389           break;
6390         case DW_OP_drop:
6391           printf ("DW_OP_drop");
6392           break;
6393         case DW_OP_over:
6394           printf ("DW_OP_over");
6395           break;
6396         case DW_OP_pick:
6397           printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6398           break;
6399         case DW_OP_swap:
6400           printf ("DW_OP_swap");
6401           break;
6402         case DW_OP_rot:
6403           printf ("DW_OP_rot");
6404           break;
6405         case DW_OP_xderef:
6406           printf ("DW_OP_xderef");
6407           break;
6408         case DW_OP_abs:
6409           printf ("DW_OP_abs");
6410           break;
6411         case DW_OP_and:
6412           printf ("DW_OP_and");
6413           break;
6414         case DW_OP_div:
6415           printf ("DW_OP_div");
6416           break;
6417         case DW_OP_minus:
6418           printf ("DW_OP_minus");
6419           break;
6420         case DW_OP_mod:
6421           printf ("DW_OP_mod");
6422           break;
6423         case DW_OP_mul:
6424           printf ("DW_OP_mul");
6425           break;
6426         case DW_OP_neg:
6427           printf ("DW_OP_neg");
6428           break;
6429         case DW_OP_not:
6430           printf ("DW_OP_not");
6431           break;
6432         case DW_OP_or:
6433           printf ("DW_OP_or");
6434           break;
6435         case DW_OP_plus:
6436           printf ("DW_OP_plus");
6437           break;
6438         case DW_OP_plus_uconst:
6439           printf ("DW_OP_plus_uconst: %lu",
6440                   read_leb128 (data, &bytes_read, 0));
6441           data += bytes_read;
6442           break;
6443         case DW_OP_shl:
6444           printf ("DW_OP_shl");
6445           break;
6446         case DW_OP_shr:
6447           printf ("DW_OP_shr");
6448           break;
6449         case DW_OP_shra:
6450           printf ("DW_OP_shra");
6451           break;
6452         case DW_OP_xor:
6453           printf ("DW_OP_xor");
6454           break;
6455         case DW_OP_bra:
6456           printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6457           data += 2;
6458           break;
6459         case DW_OP_eq:
6460           printf ("DW_OP_eq");
6461           break;
6462         case DW_OP_ge:
6463           printf ("DW_OP_ge");
6464           break;
6465         case DW_OP_gt:
6466           printf ("DW_OP_gt");
6467           break;
6468         case DW_OP_le:
6469           printf ("DW_OP_le");
6470           break;
6471         case DW_OP_lt:
6472           printf ("DW_OP_lt");
6473           break;
6474         case DW_OP_ne:
6475           printf ("DW_OP_ne");
6476           break;
6477         case DW_OP_skip:
6478           printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6479           data += 2;
6480           break;
6481
6482         case DW_OP_lit0:
6483         case DW_OP_lit1:
6484         case DW_OP_lit2:
6485         case DW_OP_lit3:
6486         case DW_OP_lit4:
6487         case DW_OP_lit5:
6488         case DW_OP_lit6:
6489         case DW_OP_lit7:
6490         case DW_OP_lit8:
6491         case DW_OP_lit9:
6492         case DW_OP_lit10:
6493         case DW_OP_lit11:
6494         case DW_OP_lit12:
6495         case DW_OP_lit13:
6496         case DW_OP_lit14:
6497         case DW_OP_lit15:
6498         case DW_OP_lit16:
6499         case DW_OP_lit17:
6500         case DW_OP_lit18:
6501         case DW_OP_lit19:
6502         case DW_OP_lit20:
6503         case DW_OP_lit21:
6504         case DW_OP_lit22:
6505         case DW_OP_lit23:
6506         case DW_OP_lit24:
6507         case DW_OP_lit25:
6508         case DW_OP_lit26:
6509         case DW_OP_lit27:
6510         case DW_OP_lit28:
6511         case DW_OP_lit29:
6512         case DW_OP_lit30:
6513         case DW_OP_lit31:
6514           printf ("DW_OP_lit%d", op - DW_OP_lit0);
6515           break;
6516
6517         case DW_OP_reg0:
6518         case DW_OP_reg1:
6519         case DW_OP_reg2:
6520         case DW_OP_reg3:
6521         case DW_OP_reg4:
6522         case DW_OP_reg5:
6523         case DW_OP_reg6:
6524         case DW_OP_reg7:
6525         case DW_OP_reg8:
6526         case DW_OP_reg9:
6527         case DW_OP_reg10:
6528         case DW_OP_reg11:
6529         case DW_OP_reg12:
6530         case DW_OP_reg13:
6531         case DW_OP_reg14:
6532         case DW_OP_reg15:
6533         case DW_OP_reg16:
6534         case DW_OP_reg17:
6535         case DW_OP_reg18:
6536         case DW_OP_reg19:
6537         case DW_OP_reg20:
6538         case DW_OP_reg21:
6539         case DW_OP_reg22:
6540         case DW_OP_reg23:
6541         case DW_OP_reg24:
6542         case DW_OP_reg25:
6543         case DW_OP_reg26:
6544         case DW_OP_reg27:
6545         case DW_OP_reg28:
6546         case DW_OP_reg29:
6547         case DW_OP_reg30:
6548         case DW_OP_reg31:
6549           printf ("DW_OP_reg%d", op - DW_OP_reg0);
6550           break;
6551
6552         case DW_OP_breg0:
6553         case DW_OP_breg1:
6554         case DW_OP_breg2:
6555         case DW_OP_breg3:
6556         case DW_OP_breg4:
6557         case DW_OP_breg5:
6558         case DW_OP_breg6:
6559         case DW_OP_breg7:
6560         case DW_OP_breg8:
6561         case DW_OP_breg9:
6562         case DW_OP_breg10:
6563         case DW_OP_breg11:
6564         case DW_OP_breg12:
6565         case DW_OP_breg13:
6566         case DW_OP_breg14:
6567         case DW_OP_breg15:
6568         case DW_OP_breg16:
6569         case DW_OP_breg17:
6570         case DW_OP_breg18:
6571         case DW_OP_breg19:
6572         case DW_OP_breg20:
6573         case DW_OP_breg21:
6574         case DW_OP_breg22:
6575         case DW_OP_breg23:
6576         case DW_OP_breg24:
6577         case DW_OP_breg25:
6578         case DW_OP_breg26:
6579         case DW_OP_breg27:
6580         case DW_OP_breg28:
6581         case DW_OP_breg29:
6582         case DW_OP_breg30:
6583         case DW_OP_breg31:
6584           printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6585                   read_leb128 (data, &bytes_read, 1));
6586           data += bytes_read;
6587           break;
6588
6589         case DW_OP_regx:
6590           printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6591           data += bytes_read;
6592           break;
6593         case DW_OP_fbreg:
6594           printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6595           data += bytes_read;
6596           break;
6597         case DW_OP_bregx:
6598           uvalue = read_leb128 (data, &bytes_read, 0);
6599           data += bytes_read;
6600           printf ("DW_OP_bregx: %lu %ld", uvalue,
6601                   read_leb128 (data, &bytes_read, 1));
6602           data += bytes_read;
6603           break;
6604         case DW_OP_piece:
6605           printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6606           data += bytes_read;
6607           break;
6608         case DW_OP_deref_size:
6609           printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6610           break;
6611         case DW_OP_xderef_size:
6612           printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6613           break;
6614         case DW_OP_nop:
6615           printf ("DW_OP_nop");
6616           break;
6617
6618           /* DWARF 2.1 extensions.  */
6619         case DW_OP_push_object_address:
6620           printf ("DW_OP_push_object_address");
6621           break;
6622         case DW_OP_call2:
6623           printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
6624           data += 2;
6625           break;
6626         case DW_OP_call4:
6627           printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
6628           data += 4;
6629           break;
6630         case DW_OP_calli:
6631           printf ("DW_OP_calli");
6632           break;
6633
6634         default:
6635           if (op >= DW_OP_lo_user
6636               && op <= DW_OP_hi_user)
6637             printf (_("(User defined location op)"));
6638           else
6639             printf (_("(Unknown location op)"));
6640           /* No way to tell where the next op is, so just bail.  */
6641           return;
6642         }
6643
6644       /* Separate the ops.  */
6645       printf ("; ");
6646     }
6647 }
6648
6649
6650 static unsigned char *
6651 read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
6652      unsigned long   attribute;
6653      unsigned long   form;
6654      unsigned char * data;
6655      unsigned long   cu_offset;
6656      unsigned long   pointer_size;
6657 {
6658   unsigned long   uvalue = 0;
6659   unsigned char * block_start = NULL;
6660   int             bytes_read;
6661
6662   printf ("     %-18s:", get_AT_name (attribute));
6663
6664   switch (form)
6665     {
6666     default:
6667       break;
6668
6669     case DW_FORM_ref_addr:
6670     case DW_FORM_addr:
6671       uvalue = byte_get (data, pointer_size);
6672       data += pointer_size;
6673       break;
6674
6675     case DW_FORM_ref1:
6676     case DW_FORM_flag:
6677     case DW_FORM_data1:
6678       uvalue = byte_get (data ++, 1);
6679       break;
6680
6681     case DW_FORM_ref2:
6682     case DW_FORM_data2:
6683       uvalue = byte_get (data, 2);
6684       data += 2;
6685       break;
6686
6687     case DW_FORM_ref4:
6688     case DW_FORM_data4:
6689       uvalue = byte_get (data, 4);
6690       data += 4;
6691       break;
6692
6693     case DW_FORM_sdata:
6694       uvalue = read_leb128 (data, & bytes_read, 1);
6695       data += bytes_read;
6696       break;
6697
6698     case DW_FORM_ref_udata:
6699     case DW_FORM_udata:
6700       uvalue = read_leb128 (data, & bytes_read, 0);
6701       data += bytes_read;
6702       break;
6703     }
6704
6705   switch (form)
6706     {
6707     case DW_FORM_ref_addr:
6708       printf (" <#%lx>", uvalue);
6709       break;
6710
6711     case DW_FORM_ref1:
6712     case DW_FORM_ref2:
6713     case DW_FORM_ref4:
6714     case DW_FORM_ref_udata:
6715       printf (" <%lx>", uvalue + cu_offset);
6716       break;
6717
6718     case DW_FORM_addr:
6719       printf (" %#lx", uvalue);
6720
6721     case DW_FORM_flag:
6722     case DW_FORM_data1:
6723     case DW_FORM_data2:
6724     case DW_FORM_data4:
6725     case DW_FORM_sdata:
6726     case DW_FORM_udata:
6727       printf (" %ld", uvalue);
6728       break;
6729
6730     case DW_FORM_ref8:
6731     case DW_FORM_data8:
6732       uvalue = byte_get (data, 4);
6733       printf (" %lx", uvalue);
6734       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
6735       data += 8;
6736       break;
6737
6738     case DW_FORM_string:
6739       printf (" %s", data);
6740       data += strlen ((char *) data) + 1;
6741       break;
6742
6743     case DW_FORM_block:
6744       uvalue = read_leb128 (data, & bytes_read, 0);
6745       block_start = data + bytes_read;
6746       data = display_block (block_start, uvalue);
6747       break;
6748
6749     case DW_FORM_block1:
6750       uvalue = byte_get (data, 1);
6751       block_start = data + 1;
6752       data = display_block (block_start, uvalue);
6753       break;
6754
6755     case DW_FORM_block2:
6756       uvalue = byte_get (data, 2);
6757       block_start = data + 2;
6758       data = display_block (block_start, uvalue);
6759       break;
6760
6761     case DW_FORM_block4:
6762       uvalue = byte_get (data, 4);
6763       block_start = data + 4;
6764       data = display_block (block_start, uvalue);
6765       break;
6766
6767     case DW_FORM_strp:
6768     case DW_FORM_indirect:
6769       warn (_("Unable to handle FORM: %d"), form);
6770       break;
6771
6772     default:
6773       warn (_("Unrecognised form: %d"), form);
6774       break;
6775     }
6776
6777   /* For some attributes we can display futher information.  */
6778
6779   printf ("\t");
6780
6781   switch (attribute)
6782     {
6783     case DW_AT_inline:
6784       switch (uvalue)
6785         {
6786         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
6787         case DW_INL_inlined:              printf (_("(inlined)")); break;
6788         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6789         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
6790         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
6791         }
6792       break;
6793
6794     case DW_AT_language:
6795       switch (uvalue)
6796         {
6797         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
6798         case DW_LANG_C89:            printf ("(ANSI C)"); break;
6799         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
6800         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
6801         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
6802         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
6803         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
6804         case DW_LANG_Ada83:          printf ("(Ada)"); break;
6805         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
6806         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
6807           /* DWARF 2.1 values.  */
6808         case DW_LANG_C99:            printf ("(ANSI C99)"); break;
6809         case DW_LANG_Ada95:          printf ("(ADA 95)"); break;
6810         case DW_LANG_Fortran95:       printf ("(Fortran 95)"); break;
6811           /* MIPS extension.  */
6812         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6813         default:                     printf ("(Unknown: %lx)", uvalue); break;
6814         }
6815       break;
6816
6817     case DW_AT_encoding:
6818       switch (uvalue)
6819         {
6820         case DW_ATE_void:            printf ("(void)"); break;
6821         case DW_ATE_address:         printf ("(machine address)"); break;
6822         case DW_ATE_boolean:         printf ("(boolean)"); break;
6823         case DW_ATE_complex_float:   printf ("(complex float)"); break;
6824         case DW_ATE_float:           printf ("(float)"); break;
6825         case DW_ATE_signed:          printf ("(signed)"); break;
6826         case DW_ATE_signed_char:     printf ("(signed char)"); break;
6827         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
6828         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
6829           /* DWARF 2.1 value.  */
6830         case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
6831         default:
6832           if (uvalue >= DW_ATE_lo_user
6833               && uvalue <= DW_ATE_hi_user)
6834             printf ("(user defined type)");
6835           else
6836             printf ("(unknown type)");
6837           break;
6838         }
6839       break;
6840
6841     case DW_AT_accessibility:
6842       switch (uvalue)
6843         {
6844         case DW_ACCESS_public:          printf ("(public)"); break;
6845         case DW_ACCESS_protected:       printf ("(protected)"); break;
6846         case DW_ACCESS_private:         printf ("(private)"); break;
6847         default:                        printf ("(unknown accessibility)"); break;
6848         }
6849       break;
6850
6851     case DW_AT_visibility:
6852       switch (uvalue)
6853         {
6854         case DW_VIS_local:      printf ("(local)"); break;
6855         case DW_VIS_exported:   printf ("(exported)"); break;
6856         case DW_VIS_qualified:  printf ("(qualified)"); break;
6857         default:                printf ("(unknown visibility)"); break;
6858         }
6859       break;
6860
6861     case DW_AT_virtuality:
6862       switch (uvalue)
6863         {
6864         case DW_VIRTUALITY_none:        printf ("(none)"); break;
6865         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
6866         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6867         default:                        printf ("(unknown virtuality)"); break;
6868         }
6869       break;
6870
6871     case DW_AT_identifier_case:
6872       switch (uvalue)
6873         {
6874         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
6875         case DW_ID_up_case:             printf ("(up_case)"); break;
6876         case DW_ID_down_case:           printf ("(down_case)"); break;
6877         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
6878         default:                        printf ("(unknown case)"); break;
6879         }
6880       break;
6881
6882     case DW_AT_calling_convention:
6883       switch (uvalue)
6884         {
6885         case DW_CC_normal:      printf ("(normal)"); break;
6886         case DW_CC_program:     printf ("(program)"); break;
6887         case DW_CC_nocall:      printf ("(nocall)"); break;
6888         default:
6889           if (uvalue >= DW_CC_lo_user
6890               && uvalue <= DW_CC_hi_user)
6891             printf ("(user defined)");
6892           else
6893             printf ("(unknown convention)");
6894         }
6895       break;
6896
6897     case DW_AT_ordering:
6898       switch (uvalue)
6899         {
6900         case -1: printf ("(undefined)"); break;
6901         case 0:  printf ("(row major)"); break;
6902         case 1:  printf ("(column major)"); break;
6903         }
6904       break;
6905
6906     case DW_AT_frame_base:
6907     case DW_AT_location:
6908     case DW_AT_data_member_location:
6909     case DW_AT_vtable_elem_location:
6910     case DW_AT_allocated:
6911     case DW_AT_associated:
6912     case DW_AT_data_location:
6913     case DW_AT_stride:
6914     case DW_AT_upper_bound:
6915     case DW_AT_lower_bound:
6916       if (block_start)
6917         {
6918           printf ("(");
6919           decode_location_expression (block_start, pointer_size, uvalue);
6920           printf (")");
6921         }
6922       break;
6923
6924     default:
6925       break;
6926     }
6927
6928   printf ("\n");
6929   return data;
6930 }
6931
6932 static int
6933 display_debug_info (section, start, file)
6934      Elf32_Internal_Shdr * section;
6935      unsigned char *       start;
6936      FILE *                file;
6937 {
6938   unsigned char * end = start + section->sh_size;
6939   unsigned char * section_begin = start;
6940
6941   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6942
6943   while (start < end)
6944     {
6945       DWARF2_External_CompUnit * external;
6946       DWARF2_Internal_CompUnit   compunit;
6947       unsigned char *            tags;
6948       int                        i;
6949       int                        level;
6950       unsigned long              cu_offset;
6951
6952       external = (DWARF2_External_CompUnit *) start;
6953
6954       compunit.cu_length        = BYTE_GET (external->cu_length);
6955       compunit.cu_version       = BYTE_GET (external->cu_version);
6956       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6957       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
6958
6959       tags = start + sizeof (* external);
6960       cu_offset = start - section_begin;
6961       start += compunit.cu_length + sizeof (external->cu_length);
6962
6963       printf (_("  Compilation Unit @ %lx:\n"), cu_offset);
6964       printf (_("   Length:        %ld\n"), compunit.cu_length);
6965       printf (_("   Version:       %d\n"), compunit.cu_version);
6966       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6967       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
6968
6969       if (compunit.cu_version != 2)
6970         {
6971           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6972           continue;
6973         }
6974
6975       if (first_abbrev != NULL)
6976         free_abbrevs ();
6977
6978       /* Read in the abbrevs used by this compilation unit.  */
6979
6980       {
6981         Elf32_Internal_Shdr * sec;
6982         unsigned char *       begin;
6983
6984         /* Locate the .debug_abbrev section and process it.  */
6985         for (i = 0, sec = section_headers;
6986              i < elf_header.e_shnum;
6987              i ++, sec ++)
6988           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6989             break;
6990
6991         if (i == -1 || sec->sh_size == 0)
6992           {
6993             warn (_("Unable to locate .debug_abbrev section!\n"));
6994             return 0;
6995           }
6996
6997         begin = ((unsigned char *)
6998                  get_data (NULL, file, sec->sh_offset, sec->sh_size, 
6999                            _("debug_abbrev section data")));
7000         if (!begin)
7001           return 0;
7002
7003         process_abbrev_section (begin + compunit.cu_abbrev_offset,
7004                                 begin + sec->sh_size);
7005
7006         free (begin);
7007       }
7008
7009       level = 0;
7010       while (tags < start)
7011         {
7012           int            bytes_read;
7013           unsigned long  abbrev_number;
7014           abbrev_entry * entry;
7015           abbrev_attr  * attr;
7016
7017           abbrev_number = read_leb128 (tags, & bytes_read, 0);
7018           tags += bytes_read;
7019
7020           /* A null DIE marks the end of a list of children.  */
7021           if (abbrev_number == 0)
7022             {
7023               --level;
7024               continue;
7025             }
7026
7027           /* Scan through the abbreviation list until we reach the
7028              correct entry.  */
7029           for (entry = first_abbrev;
7030                entry && entry->entry != abbrev_number;
7031                entry = entry->next)
7032             continue;
7033
7034           if (entry == NULL)
7035             {
7036               warn (_("Unable to locate entry %lu in the abbreviation table\n"),
7037                     abbrev_number);
7038               return 0;
7039             }
7040
7041           printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
7042                   level, tags - section_begin - bytes_read,
7043                   abbrev_number,
7044                   get_TAG_name (entry->tag));
7045
7046           for (attr = entry->first_attr; attr; attr = attr->next)
7047             tags = read_and_display_attr (attr->attribute,
7048                                           attr->form,
7049                                           tags, cu_offset,
7050                                           compunit.cu_pointer_size);
7051
7052           if (entry->children)
7053             ++level;
7054         }
7055     }
7056
7057   printf ("\n");
7058
7059   return 1;
7060 }
7061
7062 static int
7063 display_debug_aranges (section, start, file)
7064      Elf32_Internal_Shdr * section;
7065      unsigned char *       start;
7066      FILE *                file ATTRIBUTE_UNUSED;
7067 {
7068   unsigned char * end = start + section->sh_size;
7069
7070   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7071
7072   while (start < end)
7073     {
7074       DWARF2_External_ARange * external;
7075       DWARF2_Internal_ARange   arange;
7076       unsigned char *          ranges;
7077       unsigned long            length;
7078       unsigned long            address;
7079       int                      excess;
7080
7081       external = (DWARF2_External_ARange *) start;
7082
7083       arange.ar_length       = BYTE_GET (external->ar_length);
7084       arange.ar_version      = BYTE_GET (external->ar_version);
7085       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
7086       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
7087       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
7088
7089       if (arange.ar_version != 2)
7090         {
7091           warn (_("Only DWARF 2 aranges are currently supported.\n"));
7092           break;
7093         }
7094
7095       printf (_("  Length:                   %ld\n"), arange.ar_length);
7096       printf (_("  Version:                  %d\n"), arange.ar_version);
7097       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
7098       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
7099       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
7100
7101       printf (_("\n    Address  Length\n"));
7102
7103       ranges = start + sizeof (* external);
7104
7105       /* Must pad to an alignment boundary that is twice the pointer size.  */
7106       excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7107       if (excess)
7108         ranges += (2 * arange.ar_pointer_size) - excess;
7109
7110       for (;;)
7111         {
7112           address = byte_get (ranges, arange.ar_pointer_size);
7113
7114           ranges += arange.ar_pointer_size;
7115
7116           length  = byte_get (ranges, arange.ar_pointer_size);
7117
7118           ranges += arange.ar_pointer_size;
7119
7120           /* A pair of zeros marks the end of the list.  */
7121           if (address == 0 && length == 0)
7122             break;
7123
7124           printf ("    %8.8lx %lu\n", address, length);
7125         }
7126
7127       start += arange.ar_length + sizeof (external->ar_length);
7128     }
7129
7130   printf ("\n");
7131
7132   return 1;
7133 }
7134
7135 typedef struct Frame_Chunk
7136 {
7137   struct Frame_Chunk * next;
7138   unsigned char *      chunk_start;
7139   int                  ncols;
7140   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
7141   short int *          col_type;
7142   int *                col_offset;
7143   char *               augmentation;
7144   unsigned int         code_factor;
7145   int                  data_factor;
7146   unsigned long        pc_begin;
7147   unsigned long        pc_range;
7148   int                  cfa_reg;
7149   int                  cfa_offset;
7150   int                  ra;
7151   unsigned char        fde_encoding;
7152 }
7153 Frame_Chunk;
7154
7155 /* A marker for a col_type that means this column was never referenced
7156    in the frame info.  */
7157 #define DW_CFA_unreferenced (-1)
7158
7159 static void
7160 frame_need_space (fc, reg)
7161      Frame_Chunk * fc;
7162      int reg;
7163 {
7164   int prev = fc->ncols;
7165
7166   if (reg < fc->ncols)
7167     return;
7168
7169   fc->ncols = reg + 1;
7170   fc->col_type = (short int *) xrealloc (fc->col_type,
7171                                          fc->ncols * sizeof (short int));
7172   fc->col_offset = (int *) xrealloc (fc->col_offset,
7173                                      fc->ncols * sizeof (int));
7174
7175   while (prev < fc->ncols)
7176     {
7177       fc->col_type[prev] = DW_CFA_unreferenced;
7178       fc->col_offset[prev] = 0;
7179       prev++;
7180     }
7181 }
7182
7183 static void
7184 frame_display_row (fc, need_col_headers, max_regs)
7185      Frame_Chunk * fc;
7186      int *         need_col_headers;
7187      int *         max_regs;
7188 {
7189   int r;
7190   char tmp[100];
7191
7192   if (* max_regs < fc->ncols)
7193     * max_regs = fc->ncols;
7194
7195   if (* need_col_headers)
7196     {
7197       * need_col_headers = 0;
7198
7199       printf ("   LOC   CFA      ");
7200
7201       for (r = 0; r < * max_regs; r++)
7202         if (fc->col_type[r] != DW_CFA_unreferenced)
7203           {
7204             if (r == fc->ra)
7205               printf ("ra   ");
7206             else
7207               printf ("r%-4d", r);
7208           }
7209
7210       printf ("\n");
7211     }
7212
7213   printf ("%08lx ", fc->pc_begin);
7214   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7215   printf ("%-8s ", tmp);
7216
7217   for (r = 0; r < fc->ncols; r++)
7218     {
7219       if (fc->col_type[r] != DW_CFA_unreferenced)
7220         {
7221           switch (fc->col_type[r])
7222             {
7223             case DW_CFA_undefined:
7224               strcpy (tmp, "u");
7225               break;
7226             case DW_CFA_same_value:
7227               strcpy (tmp, "s");
7228               break;
7229             case DW_CFA_offset:
7230               sprintf (tmp, "c%+d", fc->col_offset[r]);
7231               break;
7232             case DW_CFA_register:
7233               sprintf (tmp, "r%d", fc->col_offset[r]);
7234               break;
7235             default:
7236               strcpy (tmp, "n/a");
7237               break;
7238             }
7239           printf ("%-5s", tmp);
7240         }
7241     }
7242   printf ("\n");
7243 }
7244
7245 static int
7246 size_of_encoded_value (encoding)
7247      int encoding;
7248 {
7249   switch (encoding & 0x7)
7250     {
7251     default:    /* ??? */
7252     case 0:     return is_32bit_elf ? 4 : 8;
7253     case 2:     return 2;
7254     case 3:     return 4;
7255     case 4:     return 8;
7256     }
7257 }
7258
7259 #define GET(N)  byte_get (start, N); start += N
7260 #define LEB()   read_leb128 (start, & length_return, 0); start += length_return
7261 #define SLEB()  read_leb128 (start, & length_return, 1); start += length_return
7262
7263 static int
7264 display_debug_frames (section, start, file)
7265      Elf32_Internal_Shdr * section;
7266      unsigned char *       start;
7267      FILE *                file ATTRIBUTE_UNUSED;
7268 {
7269   unsigned char * end = start + section->sh_size;
7270   unsigned char * section_start = start;
7271   Frame_Chunk *   chunks = 0;
7272   Frame_Chunk *   remembered_state = 0;
7273   Frame_Chunk *   rs;
7274   int             is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7275   int             length_return;
7276   int             max_regs = 0;
7277   int             addr_size = is_32bit_elf ? 4 : 8;
7278
7279   printf (_("The section %s contains:\n"), SECTION_NAME (section));
7280
7281   while (start < end)
7282     {
7283       unsigned char * saved_start;
7284       unsigned char * block_end;
7285       unsigned long   length;
7286       unsigned long   cie_id;
7287       Frame_Chunk *   fc;
7288       Frame_Chunk *   cie;
7289       int             need_col_headers = 1;
7290       unsigned char * augmentation_data = NULL;
7291       unsigned long   augmentation_data_len = 0;
7292       int             encoded_ptr_size = addr_size;
7293
7294       saved_start = start;
7295       length = byte_get (start, 4); start += 4;
7296
7297       if (length == 0)
7298         return 1;
7299
7300       block_end = saved_start + length + 4;
7301       cie_id = byte_get (start, 4); start += 4;
7302
7303       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7304         {
7305           int version;
7306
7307           fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7308           memset (fc, 0, sizeof (Frame_Chunk));
7309
7310           fc->next = chunks;
7311           chunks = fc;
7312           fc->chunk_start = saved_start;
7313           fc->ncols = 0;
7314           fc->col_type = (short int *) xmalloc (sizeof (short int));
7315           fc->col_offset = (int *) xmalloc (sizeof (int));
7316           frame_need_space (fc, max_regs-1);
7317
7318           version = *start++;
7319
7320           fc->augmentation = start;
7321           start = strchr (start, '\0') + 1;
7322
7323           if (fc->augmentation[0] == 'z')
7324             {
7325               fc->code_factor = LEB ();
7326               fc->data_factor = SLEB ();
7327               fc->ra = byte_get (start, 1); start += 1;
7328               augmentation_data_len = LEB ();
7329               augmentation_data = start;
7330               start += augmentation_data_len;
7331             }
7332           else if (strcmp (fc->augmentation, "eh") == 0)
7333             {
7334               start += addr_size;
7335               fc->code_factor = LEB ();
7336               fc->data_factor = SLEB ();
7337               fc->ra = byte_get (start, 1); start += 1;
7338             }
7339           else
7340             {
7341               fc->code_factor = LEB ();
7342               fc->data_factor = SLEB ();
7343               fc->ra = byte_get (start, 1); start += 1;
7344             }
7345           cie = fc;
7346
7347           if (do_debug_frames_interp)
7348             printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7349                     (unsigned long)(saved_start - section_start), length, cie_id,
7350                     fc->augmentation, fc->code_factor, fc->data_factor,
7351                     fc->ra);
7352           else
7353             {
7354               printf ("\n%08lx %08lx %08lx CIE\n",
7355                       (unsigned long)(saved_start - section_start), length, cie_id);
7356               printf ("  Version:               %d\n", version);
7357               printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
7358               printf ("  Code alignment factor: %u\n", fc->code_factor);
7359               printf ("  Data alignment factor: %d\n", fc->data_factor);
7360               printf ("  Return address column: %d\n", fc->ra);
7361
7362               if (augmentation_data_len)
7363                 {
7364                   unsigned long i;
7365                   printf ("  Augmentation data:    ");
7366                   for (i = 0; i < augmentation_data_len; ++i)
7367                     printf (" %02x", augmentation_data[i]);
7368                   putchar ('\n');
7369                 }
7370               putchar ('\n');
7371             }
7372
7373           if (augmentation_data_len)
7374             {
7375               unsigned char *p, *q;
7376               p = fc->augmentation + 1;
7377               q = augmentation_data;
7378
7379               while (1)
7380                 {
7381                   if (*p == 'L')
7382                     q++;
7383                   else if (*p == 'P')
7384                     q += 1 + size_of_encoded_value (*q);
7385                   else if (*p == 'R')
7386                     fc->fde_encoding = *q++;
7387                   else
7388                     break;
7389                   p++;
7390                 }
7391
7392               if (fc->fde_encoding)
7393                 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7394             }
7395
7396           frame_need_space (fc, fc->ra);
7397         }
7398       else
7399         {
7400           unsigned char *    look_for;
7401           static Frame_Chunk fde_fc;
7402
7403           fc = & fde_fc;
7404           memset (fc, 0, sizeof (Frame_Chunk));
7405
7406           look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
7407
7408           for (cie=chunks; cie ; cie = cie->next)
7409             if (cie->chunk_start == look_for)
7410               break;
7411
7412           if (!cie)
7413             {
7414               warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
7415                     cie_id, saved_start);
7416               start = block_end;
7417               fc->ncols = 0;
7418               fc->col_type = (short int *) xmalloc (sizeof (short int));
7419               fc->col_offset = (int *) xmalloc (sizeof (int));
7420               frame_need_space (fc, max_regs - 1);
7421               cie = fc;
7422               fc->augmentation = "";
7423               fc->fde_encoding = 0;
7424             }
7425           else
7426             {
7427               fc->ncols = cie->ncols;
7428               fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
7429               fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
7430               memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
7431               memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7432               fc->augmentation = cie->augmentation;
7433               fc->code_factor = cie->code_factor;
7434               fc->data_factor = cie->data_factor;
7435               fc->cfa_reg = cie->cfa_reg;
7436               fc->cfa_offset = cie->cfa_offset;
7437               fc->ra = cie->ra;
7438               frame_need_space (fc, max_regs-1);
7439               fc->fde_encoding = cie->fde_encoding;
7440             }
7441
7442           if (fc->fde_encoding)
7443             encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7444
7445           fc->pc_begin = byte_get (start, encoded_ptr_size);
7446           start += encoded_ptr_size;
7447           fc->pc_range = byte_get (start, encoded_ptr_size);
7448           start += encoded_ptr_size;
7449
7450           if (cie->augmentation[0] == 'z')
7451             {
7452               augmentation_data_len = LEB ();
7453               augmentation_data = start;
7454               start += augmentation_data_len;
7455             }
7456
7457           printf ("\n%08lx %08lx %08lx FDE cie=%08x pc=%08lx..%08lx\n",
7458                   (unsigned long)(saved_start - section_start), length, cie_id,
7459                   cie->chunk_start - section_start, fc->pc_begin,
7460                   fc->pc_begin + fc->pc_range);
7461           if (! do_debug_frames_interp && augmentation_data_len)
7462             {
7463               unsigned long i;
7464               printf ("  Augmentation data:    ");
7465               for (i = 0; i < augmentation_data_len; ++i)
7466                 printf (" %02x", augmentation_data[i]);
7467               putchar ('\n');
7468               putchar ('\n');
7469             }
7470         }
7471
7472       /* At this point, fc is the current chunk, cie (if any) is set, and we're
7473          about to interpret instructions for the chunk.  */
7474
7475       if (do_debug_frames_interp)
7476       {
7477         /* Start by making a pass over the chunk, allocating storage
7478            and taking note of what registers are used.  */
7479         unsigned char * tmp = start;
7480
7481         while (start < block_end)
7482           {
7483             unsigned op, opa;
7484             unsigned long reg;
7485
7486             op = * start ++;
7487             opa = op & 0x3f;
7488             if (op & 0xc0)
7489               op &= 0xc0;
7490
7491             /* Warning: if you add any more cases to this switch, be
7492                sure to add them to the corresponding switch below.  */
7493             switch (op)
7494               {
7495               case DW_CFA_advance_loc:
7496                 break;
7497               case DW_CFA_offset:
7498                 LEB ();
7499                 frame_need_space (fc, opa);
7500                 fc->col_type[opa] = DW_CFA_undefined;
7501                 break;
7502               case DW_CFA_restore:
7503                 frame_need_space (fc, opa);
7504                 fc->col_type[opa] = DW_CFA_undefined;
7505                 break;
7506               case DW_CFA_set_loc:
7507                 start += encoded_ptr_size;
7508                 break;
7509               case DW_CFA_advance_loc1:
7510                 start += 1;
7511                 break;
7512               case DW_CFA_advance_loc2:
7513                 start += 2;
7514                 break;
7515               case DW_CFA_advance_loc4:
7516                 start += 4;
7517                 break;
7518               case DW_CFA_offset_extended:
7519                 reg = LEB (); LEB ();
7520                 frame_need_space (fc, reg);
7521                 fc->col_type[reg] = DW_CFA_undefined;
7522                 break;
7523               case DW_CFA_restore_extended:
7524                 reg = LEB ();
7525                 frame_need_space (fc, reg);
7526                 fc->col_type[reg] = DW_CFA_undefined;
7527                 break;
7528               case DW_CFA_undefined:
7529                 reg = LEB ();
7530                 frame_need_space (fc, reg);
7531                 fc->col_type[reg] = DW_CFA_undefined;
7532                 break;
7533               case DW_CFA_same_value:
7534                 reg = LEB ();
7535                 frame_need_space (fc, reg);
7536                 fc->col_type[reg] = DW_CFA_undefined;
7537                 break;
7538               case DW_CFA_register:
7539                 reg = LEB (); LEB ();
7540                 frame_need_space (fc, reg);
7541                 fc->col_type[reg] = DW_CFA_undefined;
7542                 break;
7543               case DW_CFA_def_cfa:
7544                 LEB (); LEB ();
7545                 break;
7546               case DW_CFA_def_cfa_register:
7547                 LEB ();
7548                 break;
7549               case DW_CFA_def_cfa_offset:
7550                 LEB ();
7551                 break;
7552 #ifndef DW_CFA_GNU_args_size
7553 #define DW_CFA_GNU_args_size 0x2e
7554 #endif
7555               case DW_CFA_GNU_args_size:
7556                 LEB ();
7557                 break;
7558 #ifndef DW_CFA_GNU_negative_offset_extended
7559 #define DW_CFA_GNU_negative_offset_extended 0x2f
7560 #endif
7561               case DW_CFA_GNU_negative_offset_extended:
7562                 reg = LEB (); LEB ();
7563                 frame_need_space (fc, reg);
7564                 fc->col_type[reg] = DW_CFA_undefined;
7565
7566               default:
7567                 break;
7568               }
7569           }
7570         start = tmp;
7571       }
7572
7573       /* Now we know what registers are used, make a second pass over
7574          the chunk, this time actually printing out the info.  */
7575
7576       while (start < block_end)
7577         {
7578           unsigned op, opa;
7579           unsigned long ul, reg, roffs;
7580           long l, ofs;
7581           bfd_vma vma;
7582
7583           op = * start ++;
7584           opa = op & 0x3f;
7585           if (op & 0xc0)
7586             op &= 0xc0;
7587
7588             /* Warning: if you add any more cases to this switch, be
7589                sure to add them to the corresponding switch above.  */
7590           switch (op)
7591             {
7592             case DW_CFA_advance_loc:
7593               if (do_debug_frames_interp)
7594                 frame_display_row (fc, &need_col_headers, &max_regs);
7595               else
7596                 printf ("  DW_CFA_advance_loc: %d to %08lx\n",
7597                         opa * fc->code_factor,
7598                         fc->pc_begin + opa * fc->code_factor);
7599               fc->pc_begin += opa * fc->code_factor;
7600               break;
7601
7602             case DW_CFA_offset:
7603               roffs = LEB ();
7604               if (! do_debug_frames_interp)
7605                 printf ("  DW_CFA_offset: r%d at cfa%+ld\n",
7606                         opa, roffs * fc->data_factor);
7607               fc->col_type[opa] = DW_CFA_offset;
7608               fc->col_offset[opa] = roffs * fc->data_factor;
7609               break;
7610
7611             case DW_CFA_restore:
7612               if (! do_debug_frames_interp)
7613                 printf ("  DW_CFA_restore: r%d\n", opa);
7614               fc->col_type[opa] = cie->col_type[opa];
7615               fc->col_offset[opa] = cie->col_offset[opa];
7616               break;
7617
7618             case DW_CFA_set_loc:
7619               vma = byte_get (start, encoded_ptr_size);
7620               start += encoded_ptr_size;
7621               if (do_debug_frames_interp)
7622                 frame_display_row (fc, &need_col_headers, &max_regs);
7623               else
7624                 printf ("  DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
7625               fc->pc_begin = vma;
7626               break;
7627
7628             case DW_CFA_advance_loc1:
7629               ofs = byte_get (start, 1); start += 1;
7630               if (do_debug_frames_interp)
7631                 frame_display_row (fc, &need_col_headers, &max_regs);
7632               else
7633                 printf ("  DW_CFA_advance_loc1: %ld to %08lx\n",
7634                         ofs * fc->code_factor,
7635                         fc->pc_begin + ofs * fc->code_factor);
7636               fc->pc_begin += ofs * fc->code_factor;
7637               break;
7638
7639             case DW_CFA_advance_loc2:
7640               ofs = byte_get (start, 2); start += 2;
7641               if (do_debug_frames_interp)
7642                 frame_display_row (fc, &need_col_headers, &max_regs);
7643               else
7644                 printf ("  DW_CFA_advance_loc2: %ld to %08lx\n",
7645                         ofs * fc->code_factor,
7646                         fc->pc_begin + ofs * fc->code_factor);
7647               fc->pc_begin += ofs * fc->code_factor;
7648               break;
7649
7650             case DW_CFA_advance_loc4:
7651               ofs = byte_get (start, 4); start += 4;
7652               if (do_debug_frames_interp)
7653                 frame_display_row (fc, &need_col_headers, &max_regs);
7654               else
7655                 printf ("  DW_CFA_advance_loc4: %ld to %08lx\n",
7656                         ofs * fc->code_factor,
7657                         fc->pc_begin + ofs * fc->code_factor);
7658               fc->pc_begin += ofs * fc->code_factor;
7659               break;
7660
7661             case DW_CFA_offset_extended:
7662               reg = LEB ();
7663               roffs = LEB ();
7664               if (! do_debug_frames_interp)
7665                 printf ("  DW_CFA_offset_extended: r%ld at cfa%+ld\n",
7666                         reg, roffs * fc->data_factor);
7667               fc->col_type[reg] = DW_CFA_offset;
7668               fc->col_offset[reg] = roffs * fc->data_factor;
7669               break;
7670
7671             case DW_CFA_restore_extended:
7672               reg = LEB ();
7673               if (! do_debug_frames_interp)
7674                 printf ("  DW_CFA_restore_extended: r%ld\n", reg);
7675               fc->col_type[reg] = cie->col_type[reg];
7676               fc->col_offset[reg] = cie->col_offset[reg];
7677               break;
7678
7679             case DW_CFA_undefined:
7680               reg = LEB ();
7681               if (! do_debug_frames_interp)
7682                 printf ("  DW_CFA_undefined: r%ld\n", reg);
7683               fc->col_type[reg] = DW_CFA_undefined;
7684               fc->col_offset[reg] = 0;
7685               break;
7686
7687             case DW_CFA_same_value:
7688               reg = LEB ();
7689               if (! do_debug_frames_interp)
7690                 printf ("  DW_CFA_same_value: r%ld\n", reg);
7691               fc->col_type[reg] = DW_CFA_same_value;
7692               fc->col_offset[reg] = 0;
7693               break;
7694
7695             case DW_CFA_register:
7696               reg = LEB ();
7697               roffs = LEB ();
7698               if (! do_debug_frames_interp)
7699                 printf ("  DW_CFA_register: r%ld\n", reg);
7700               fc->col_type[reg] = DW_CFA_register;
7701               fc->col_offset[reg] = roffs;
7702               break;
7703
7704             case DW_CFA_remember_state:
7705               if (! do_debug_frames_interp)
7706                 printf ("  DW_CFA_remember_state\n");
7707               rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7708               rs->ncols = fc->ncols;
7709               rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
7710               rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7711               memcpy (rs->col_type, fc->col_type, rs->ncols);
7712               memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7713               rs->next = remembered_state;
7714               remembered_state = rs;
7715               break;
7716
7717             case DW_CFA_restore_state:
7718               if (! do_debug_frames_interp)
7719                 printf ("  DW_CFA_restore_state\n");
7720               rs = remembered_state;
7721               remembered_state = rs->next;
7722               frame_need_space (fc, rs->ncols-1);
7723               memcpy (fc->col_type, rs->col_type, rs->ncols);
7724               memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7725               free (rs->col_type);
7726               free (rs->col_offset);
7727               free (rs);
7728               break;
7729
7730             case DW_CFA_def_cfa:
7731               fc->cfa_reg = LEB ();
7732               fc->cfa_offset = LEB ();
7733               if (! do_debug_frames_interp)
7734                 printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
7735                         fc->cfa_reg, fc->cfa_offset);
7736               break;
7737
7738             case DW_CFA_def_cfa_register:
7739               fc->cfa_reg = LEB ();
7740               if (! do_debug_frames_interp)
7741                 printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
7742               break;
7743
7744             case DW_CFA_def_cfa_offset:
7745               fc->cfa_offset = LEB ();
7746               if (! do_debug_frames_interp)
7747                 printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
7748               break;
7749
7750             case DW_CFA_nop:
7751               if (! do_debug_frames_interp)
7752                 printf ("  DW_CFA_nop\n");
7753               break;
7754
7755 #ifndef DW_CFA_GNU_window_save
7756 #define DW_CFA_GNU_window_save 0x2d
7757 #endif
7758             case DW_CFA_GNU_window_save:
7759               if (! do_debug_frames_interp)
7760                 printf ("  DW_CFA_GNU_window_save\n");
7761               break;
7762
7763             case DW_CFA_GNU_args_size:
7764               ul = LEB ();
7765               if (! do_debug_frames_interp)
7766                 printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
7767               break;
7768
7769             case DW_CFA_GNU_negative_offset_extended:
7770               reg = LEB ();
7771               l = - LEB ();
7772               frame_need_space (fc, reg);
7773               if (! do_debug_frames_interp)
7774                 printf ("  DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
7775                         reg, l * fc->data_factor);
7776               fc->col_type[reg] = DW_CFA_offset;
7777               fc->col_offset[reg] = l * fc->data_factor;
7778               break;
7779
7780             default:
7781               fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7782               start = block_end;
7783             }
7784         }
7785
7786       if (do_debug_frames_interp)
7787         frame_display_row (fc, &need_col_headers, &max_regs);
7788
7789       start = block_end;
7790     }
7791
7792   printf ("\n");
7793
7794   return 1;
7795 }
7796
7797 #undef GET
7798 #undef LEB
7799 #undef SLEB
7800
7801 static int
7802 display_debug_not_supported (section, start, file)
7803      Elf32_Internal_Shdr * section;
7804      unsigned char *       start ATTRIBUTE_UNUSED;
7805      FILE *                file ATTRIBUTE_UNUSED;
7806 {
7807   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7808             SECTION_NAME (section));
7809
7810   return 1;
7811 }
7812
7813 /* Pre-scan the .debug_info section to record the size of address.
7814    When dumping the .debug_line, we use that size information, assuming
7815    that all compilation units have the same address size.  */
7816 static int
7817 prescan_debug_info (section, start, file)
7818      Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7819      unsigned char *       start;
7820      FILE *                file ATTRIBUTE_UNUSED;
7821 {
7822   DWARF2_External_CompUnit * external;
7823
7824   external = (DWARF2_External_CompUnit *) start;
7825
7826   debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7827   return 0;
7828 }
7829
7830   /* A structure containing the name of a debug section and a pointer
7831      to a function that can decode it.  The third field is a prescan
7832      function to be run over the section before displaying any of the
7833      sections.  */
7834 struct
7835 {
7836   char * name;
7837   int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7838   int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7839 }
7840 debug_displays[] =
7841 {
7842   { ".debug_info",        display_debug_info, prescan_debug_info },
7843   { ".debug_abbrev",      display_debug_abbrev, NULL },
7844   { ".debug_line",        display_debug_lines, NULL },
7845   { ".debug_aranges",     display_debug_aranges, NULL },
7846   { ".debug_pubnames",    display_debug_pubnames, NULL },
7847   { ".debug_frame",       display_debug_frames, NULL },
7848   { ".eh_frame",          display_debug_frames, NULL },
7849   { ".debug_macinfo",     display_debug_not_supported, NULL },
7850   { ".debug_str",         display_debug_not_supported, NULL },
7851   { ".debug_static_func", display_debug_not_supported, NULL },
7852   { ".debug_static_vars", display_debug_not_supported, NULL },
7853   { ".debug_types",       display_debug_not_supported, NULL },
7854   { ".debug_weaknames",   display_debug_not_supported, NULL }
7855 };
7856
7857 static int
7858 display_debug_section (section, file)
7859      Elf32_Internal_Shdr * section;
7860      FILE * file;
7861 {
7862   char *          name = SECTION_NAME (section);
7863   bfd_size_type   length;
7864   unsigned char * start;
7865   int             i;
7866
7867   length = section->sh_size;
7868   if (length == 0)
7869     {
7870       printf (_("\nSection '%s' has no debugging data.\n"), name);
7871       return 0;
7872     }
7873
7874   start = (unsigned char *) get_data (NULL, file, section->sh_offset, length, 
7875                                       _("debug section data"));
7876   if (!start)
7877     return 0;
7878
7879   /* See if we know how to display the contents of this section.  */
7880   if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7881     name = ".debug_info";
7882
7883   for (i = NUM_ELEM (debug_displays); i--;)
7884     if (strcmp (debug_displays[i].name, name) == 0)
7885       {
7886         debug_displays[i].display (section, start, file);
7887         break;
7888       }
7889
7890   if (i == -1)
7891     printf (_("Unrecognised debug section: %s\n"), name);
7892
7893   free (start);
7894
7895   /* If we loaded in the abbrev section at some point,
7896      we must release it here.  */
7897   if (first_abbrev != NULL)
7898     free_abbrevs ();
7899
7900   return 1;
7901 }
7902
7903 static int
7904 process_section_contents (file)
7905      FILE * file;
7906 {
7907   Elf32_Internal_Shdr * section;
7908   unsigned int  i;
7909
7910   if (! do_dump)
7911     return 1;
7912
7913   /* Pre-scan the debug sections to find some debug information not
7914      present in some of them.  For the .debug_line, we must find out the
7915      size of address (specified in .debug_info and .debug_aranges).  */
7916   for (i = 0, section = section_headers;
7917        i < elf_header.e_shnum && i < num_dump_sects;
7918        i ++, section ++)
7919     {
7920       char *    name = SECTION_NAME (section);
7921       int       j;
7922
7923       if (section->sh_size == 0)
7924         continue;
7925
7926       /* See if there is some pre-scan operation for this section.  */
7927       for (j = NUM_ELEM (debug_displays); j--;)
7928         if (strcmp (debug_displays[j].name, name) == 0)
7929           {
7930             if (debug_displays[j].prescan != NULL)
7931               {
7932                 bfd_size_type   length;
7933                 unsigned char * start;
7934
7935                 length = section->sh_size;
7936                 start = ((unsigned char *)
7937                          get_data (NULL, file, section->sh_offset, length, 
7938                                    _("debug section data")));
7939                 if (!start)
7940                   return 0;
7941
7942                 debug_displays[j].prescan (section, start, file);
7943                 free (start);
7944               }
7945
7946             break;
7947           }
7948     }
7949
7950   for (i = 0, section = section_headers;
7951        i < elf_header.e_shnum && i < num_dump_sects;
7952        i ++, section ++)
7953     {
7954 #ifdef SUPPORT_DISASSEMBLY
7955       if (dump_sects[i] & DISASS_DUMP)
7956         disassemble_section (section, file);
7957 #endif
7958       if (dump_sects[i] & HEX_DUMP)
7959         dump_section (section, file);
7960
7961       if (dump_sects[i] & DEBUG_DUMP)
7962         display_debug_section (section, file);
7963     }
7964
7965   if (i < num_dump_sects)
7966     warn (_("Some sections were not dumped because they do not exist!\n"));
7967
7968   return 1;
7969 }
7970
7971 static void
7972 process_mips_fpe_exception (mask)
7973      int mask;
7974 {
7975   if (mask)
7976     {
7977       int first = 1;
7978       if (mask & OEX_FPU_INEX)
7979         fputs ("INEX", stdout), first = 0;
7980       if (mask & OEX_FPU_UFLO)
7981         printf ("%sUFLO", first ? "" : "|"), first = 0;
7982       if (mask & OEX_FPU_OFLO)
7983         printf ("%sOFLO", first ? "" : "|"), first = 0;
7984       if (mask & OEX_FPU_DIV0)
7985         printf ("%sDIV0", first ? "" : "|"), first = 0;
7986       if (mask & OEX_FPU_INVAL)
7987         printf ("%sINVAL", first ? "" : "|");
7988     }
7989   else
7990     fputs ("0", stdout);
7991 }
7992
7993 static int
7994 process_mips_specific (file)
7995      FILE * file;
7996 {
7997   Elf_Internal_Dyn * entry;
7998   size_t liblist_offset = 0;
7999   size_t liblistno = 0;
8000   size_t conflictsno = 0;
8001   size_t options_offset = 0;
8002   size_t conflicts_offset = 0;
8003
8004   /* We have a lot of special sections.  Thanks SGI!  */
8005   if (dynamic_segment == NULL)
8006     /* No information available.  */
8007     return 0;
8008
8009   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
8010     switch (entry->d_tag)
8011       {
8012       case DT_MIPS_LIBLIST:
8013         liblist_offset = entry->d_un.d_val - loadaddr;
8014         break;
8015       case DT_MIPS_LIBLISTNO:
8016         liblistno = entry->d_un.d_val;
8017         break;
8018       case DT_MIPS_OPTIONS:
8019         options_offset = entry->d_un.d_val - loadaddr;
8020         break;
8021       case DT_MIPS_CONFLICT:
8022         conflicts_offset = entry->d_un.d_val - loadaddr;
8023         break;
8024       case DT_MIPS_CONFLICTNO:
8025         conflictsno = entry->d_un.d_val;
8026         break;
8027       default:
8028         break;
8029       }
8030
8031   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8032     {
8033       Elf32_External_Lib * elib;
8034       size_t cnt;
8035
8036       elib = ((Elf32_External_Lib *)
8037               get_data (NULL, file, liblist_offset,
8038                         liblistno * sizeof (Elf32_External_Lib),
8039                         _("liblist")));
8040       if (elib)
8041         {
8042           printf ("\nSection '.liblist' contains %lu entries:\n",
8043                   (unsigned long) liblistno);
8044           fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
8045                  stdout);
8046
8047           for (cnt = 0; cnt < liblistno; ++cnt)
8048             {
8049               Elf32_Lib liblist;
8050               time_t time;
8051               char timebuf[20];
8052               struct tm * tmp;
8053
8054               liblist.l_name = BYTE_GET (elib[cnt].l_name);
8055               time = BYTE_GET (elib[cnt].l_time_stamp);
8056               liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8057               liblist.l_version = BYTE_GET (elib[cnt].l_version);
8058               liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8059
8060               tmp = gmtime (&time);
8061               sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
8062                        tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8063                        tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8064
8065               printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
8066                       dynamic_strings + liblist.l_name, timebuf,
8067                       liblist.l_checksum, liblist.l_version);
8068
8069               if (liblist.l_flags == 0)
8070                 puts (" NONE");
8071               else
8072                 {
8073                   static const struct
8074                   {
8075                     const char * name;
8076                     int bit;
8077                   }
8078                   l_flags_vals[] =
8079                   {
8080                     { " EXACT_MATCH", LL_EXACT_MATCH },
8081                     { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8082                     { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8083                     { " EXPORTS", LL_EXPORTS },
8084                     { " DELAY_LOAD", LL_DELAY_LOAD },
8085                     { " DELTA", LL_DELTA }
8086                   };
8087                   int flags = liblist.l_flags;
8088                   size_t fcnt;
8089
8090                   for (fcnt = 0;
8091                        fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8092                        ++fcnt)
8093                     if ((flags & l_flags_vals[fcnt].bit) != 0)
8094                       {
8095                         fputs (l_flags_vals[fcnt].name, stdout);
8096                         flags ^= l_flags_vals[fcnt].bit;
8097                       }
8098                   if (flags != 0)
8099                     printf (" %#x", (unsigned int) flags);
8100
8101                   puts ("");
8102                 }
8103             }
8104
8105           free (elib);
8106         }
8107     }
8108
8109   if (options_offset != 0)
8110     {
8111       Elf_External_Options * eopt;
8112       Elf_Internal_Shdr *    sect = section_headers;
8113       Elf_Internal_Options * iopt;
8114       Elf_Internal_Options * option;
8115       size_t offset;
8116       int cnt;
8117
8118       /* Find the section header so that we get the size.  */
8119       while (sect->sh_type != SHT_MIPS_OPTIONS)
8120         ++ sect;
8121
8122       eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
8123                                                 sect->sh_size, _("options"));
8124       if (eopt)
8125         {
8126           iopt = ((Elf_Internal_Options *)
8127                   malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
8128           if (iopt == NULL)
8129             {
8130               error (_("Out of memory"));
8131               return 0;
8132             }
8133
8134           offset = cnt = 0;
8135           option = iopt;
8136
8137           while (offset < sect->sh_size)
8138             {
8139               Elf_External_Options * eoption;
8140
8141               eoption = (Elf_External_Options *) ((char *) eopt + offset);
8142
8143               option->kind = BYTE_GET (eoption->kind);
8144               option->size = BYTE_GET (eoption->size);
8145               option->section = BYTE_GET (eoption->section);
8146               option->info = BYTE_GET (eoption->info);
8147
8148               offset += option->size;
8149
8150               ++option;
8151               ++cnt;
8152             }
8153
8154           printf (_("\nSection '%s' contains %d entries:\n"),
8155                   SECTION_NAME (sect), cnt);
8156
8157           option = iopt;
8158
8159           while (cnt-- > 0)
8160             {
8161               size_t len;
8162
8163               switch (option->kind)
8164                 {
8165                 case ODK_NULL:
8166                   /* This shouldn't happen.  */
8167                   printf (" NULL       %d %lx", option->section, option->info);
8168                   break;
8169                 case ODK_REGINFO:
8170                   printf (" REGINFO    ");
8171                   if (elf_header.e_machine == EM_MIPS)
8172                     {
8173                       /* 32bit form.  */
8174                       Elf32_External_RegInfo * ereg;
8175                       Elf32_RegInfo            reginfo;
8176
8177                       ereg = (Elf32_External_RegInfo *) (option + 1);
8178                       reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8179                       reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8180                       reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8181                       reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8182                       reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8183                       reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8184
8185                       printf ("GPR %08lx  GP 0x%lx\n",
8186                               reginfo.ri_gprmask,
8187                               (unsigned long) reginfo.ri_gp_value);
8188                       printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
8189                               reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8190                               reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8191                     }
8192                   else
8193                     {
8194                       /* 64 bit form.  */
8195                       Elf64_External_RegInfo * ereg;
8196                       Elf64_Internal_RegInfo reginfo;
8197
8198                       ereg = (Elf64_External_RegInfo *) (option + 1);
8199                       reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
8200                       reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8201                       reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8202                       reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8203                       reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8204                       reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
8205
8206                       printf ("GPR %08lx  GP 0x",
8207                               reginfo.ri_gprmask);
8208                       printf_vma (reginfo.ri_gp_value);
8209                       printf ("\n");
8210
8211                       printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
8212                               reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8213                               reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8214                     }
8215                   ++option;
8216                   continue;
8217                 case ODK_EXCEPTIONS:
8218                   fputs (" EXCEPTIONS fpe_min(", stdout);
8219                   process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8220                   fputs (") fpe_max(", stdout);
8221                   process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8222                   fputs (")", stdout);
8223
8224                   if (option->info & OEX_PAGE0)
8225                     fputs (" PAGE0", stdout);
8226                   if (option->info & OEX_SMM)
8227                     fputs (" SMM", stdout);
8228                   if (option->info & OEX_FPDBUG)
8229                     fputs (" FPDBUG", stdout);
8230                   if (option->info & OEX_DISMISS)
8231                     fputs (" DISMISS", stdout);
8232                   break;
8233                 case ODK_PAD:
8234                   fputs (" PAD       ", stdout);
8235                   if (option->info & OPAD_PREFIX)
8236                     fputs (" PREFIX", stdout);
8237                   if (option->info & OPAD_POSTFIX)
8238                     fputs (" POSTFIX", stdout);
8239                   if (option->info & OPAD_SYMBOL)
8240                     fputs (" SYMBOL", stdout);
8241                   break;
8242                 case ODK_HWPATCH:
8243                   fputs (" HWPATCH   ", stdout);
8244                   if (option->info & OHW_R4KEOP)
8245                     fputs (" R4KEOP", stdout);
8246                   if (option->info & OHW_R8KPFETCH)
8247                     fputs (" R8KPFETCH", stdout);
8248                   if (option->info & OHW_R5KEOP)
8249                     fputs (" R5KEOP", stdout);
8250                   if (option->info & OHW_R5KCVTL)
8251                     fputs (" R5KCVTL", stdout);
8252                   break;
8253                 case ODK_FILL:
8254                   fputs (" FILL       ", stdout);
8255                   /* XXX Print content of info word?  */
8256                   break;
8257                 case ODK_TAGS:
8258                   fputs (" TAGS       ", stdout);
8259                   /* XXX Print content of info word?  */
8260                   break;
8261                 case ODK_HWAND:
8262                   fputs (" HWAND     ", stdout);
8263                   if (option->info & OHWA0_R4KEOP_CHECKED)
8264                     fputs (" R4KEOP_CHECKED", stdout);
8265                   if (option->info & OHWA0_R4KEOP_CLEAN)
8266                     fputs (" R4KEOP_CLEAN", stdout);
8267                   break;
8268                 case ODK_HWOR:
8269                   fputs (" HWOR      ", stdout);
8270                   if (option->info & OHWA0_R4KEOP_CHECKED)
8271                     fputs (" R4KEOP_CHECKED", stdout);
8272                   if (option->info & OHWA0_R4KEOP_CLEAN)
8273                     fputs (" R4KEOP_CLEAN", stdout);
8274                   break;
8275                 case ODK_GP_GROUP:
8276                   printf (" GP_GROUP  %#06lx  self-contained %#06lx",
8277                           option->info & OGP_GROUP,
8278                           (option->info & OGP_SELF) >> 16);
8279                   break;
8280                 case ODK_IDENT:
8281                   printf (" IDENT     %#06lx  self-contained %#06lx",
8282                           option->info & OGP_GROUP,
8283                           (option->info & OGP_SELF) >> 16);
8284                   break;
8285                 default:
8286                   /* This shouldn't happen.  */
8287                   printf (" %3d ???     %d %lx",
8288                           option->kind, option->section, option->info);
8289                   break;
8290                 }
8291
8292               len = sizeof (* eopt);
8293               while (len < option->size)
8294                 if (((char *) option)[len] >= ' '
8295                     && ((char *) option)[len] < 0x7f)
8296                   printf ("%c", ((char *) option)[len++]);
8297                 else
8298                   printf ("\\%03o", ((char *) option)[len++]);
8299
8300               fputs ("\n", stdout);
8301               ++option;
8302             }
8303
8304           free (eopt);
8305         }
8306     }
8307
8308   if (conflicts_offset != 0 && conflictsno != 0)
8309     {
8310       Elf32_Conflict * iconf;
8311       size_t cnt;
8312
8313       if (dynamic_symbols == NULL)
8314         {
8315           error (_("conflict list with without table"));
8316           return 0;
8317         }
8318
8319       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
8320       if (iconf == NULL)
8321         {
8322           error (_("Out of memory"));
8323           return 0;
8324         }
8325
8326       if (is_32bit_elf)
8327         {
8328           Elf32_External_Conflict * econf32;
8329
8330           econf32 = ((Elf32_External_Conflict *)
8331                      get_data (NULL, file, conflicts_offset,
8332                                conflictsno * sizeof (* econf32),
8333                                _("conflict")));
8334           if (!econf32)
8335             return 0;
8336
8337           for (cnt = 0; cnt < conflictsno; ++cnt)
8338             iconf[cnt] = BYTE_GET (econf32[cnt]);
8339
8340           free (econf32);
8341         }
8342       else
8343         {
8344           Elf64_External_Conflict * econf64;
8345
8346           econf64 = ((Elf64_External_Conflict *)
8347                      get_data (NULL, file, conflicts_offset,
8348                                conflictsno * sizeof (* econf64),
8349                                _("conflict")));
8350           if (!econf64)
8351             return 0;
8352
8353           for (cnt = 0; cnt < conflictsno; ++cnt)
8354             iconf[cnt] = BYTE_GET (econf64[cnt]);
8355
8356           free (econf64);
8357         }
8358
8359       printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8360       puts (_("  Num:    Index       Value  Name"));
8361
8362       for (cnt = 0; cnt < conflictsno; ++cnt)
8363         {
8364           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
8365
8366           printf ("%5lu: %8lu  ", (unsigned long) cnt, iconf[cnt]);
8367           print_vma (psym->st_value, FULL_HEX);
8368           printf ("  %s\n", dynamic_strings + psym->st_name);
8369         }
8370
8371       free (iconf);
8372     }
8373
8374   return 1;
8375 }
8376
8377 static char *
8378 get_note_type (e_type)
8379      unsigned e_type;
8380 {
8381   static char buff[64];
8382
8383   switch (e_type)
8384     {
8385     case NT_PRSTATUS:   return _("NT_PRSTATUS (prstatus structure)");
8386     case NT_FPREGSET:   return _("NT_FPREGSET (floating point registers)");
8387     case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
8388     case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
8389     case NT_PRXFPREG:   return _("NT_PRXFPREG (user_xfpregs structure)");
8390     case NT_PSTATUS:    return _("NT_PSTATUS (pstatus structure)");
8391     case NT_FPREGS:     return _("NT_FPREGS (floating point registers)");
8392     case NT_PSINFO:     return _("NT_PSINFO (psinfo structure)");
8393     case NT_LWPSTATUS:  return _("NT_LWPSTATUS (lwpstatus_t structure)");
8394     case NT_LWPSINFO:   return _("NT_LWPSINFO (lwpsinfo_t structure)");
8395     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
8396     default:
8397       sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8398       return buff;
8399     }
8400 }
8401
8402 /* Note that by the ELF standard, the name field is already null byte
8403    terminated, and namesz includes the terminating null byte.
8404    I.E. the value of namesz for the name "FSF" is 4.
8405
8406    If the value of namesz is zero, there is no name present. */
8407 static int
8408 process_note (pnote)
8409   Elf32_Internal_Note * pnote;
8410 {
8411   printf ("  %s\t\t0x%08lx\t%s\n",
8412           pnote->namesz ? pnote->namedata : "(NONE)",
8413           pnote->descsz, get_note_type (pnote->type));
8414   return 1;
8415 }
8416
8417
8418 static int
8419 process_corefile_note_segment (file, offset, length)
8420      FILE * file;
8421      bfd_vma offset;
8422      bfd_vma length;
8423 {
8424   Elf_External_Note *  pnotes;
8425   Elf_External_Note *  external;
8426   int                  res = 1;
8427
8428   if (length <= 0)
8429     return 0;
8430
8431   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
8432                                            _("notes"));
8433   if (!pnotes)
8434     return 0;
8435
8436   external = pnotes;
8437
8438   printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
8439           (unsigned long) offset, (unsigned long) length);
8440   printf (_("  Owner\t\tData size\tDescription\n"));
8441
8442   while (external < (Elf_External_Note *)((char *) pnotes + length))
8443     {
8444       Elf32_Internal_Note inote;
8445       char * temp = NULL;
8446
8447       inote.type     = BYTE_GET (external->type);
8448       inote.namesz   = BYTE_GET (external->namesz);
8449       inote.namedata = external->name;
8450       inote.descsz   = BYTE_GET (external->descsz);
8451       inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8452       inote.descpos  = offset + (inote.descdata - (char *) pnotes);
8453
8454       external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8455
8456       /* Verify that name is null terminated.  It appears that at least
8457          one version of Linux (RedHat 6.0) generates corefiles that don't
8458          comply with the ELF spec by failing to include the null byte in
8459          namesz.  */
8460       if (inote.namedata[inote.namesz] != '\0')
8461         {
8462           temp = malloc (inote.namesz + 1);
8463
8464           if (temp == NULL)
8465             {
8466               error (_("Out of memory\n"));
8467               res = 0;
8468               break;
8469             }
8470
8471           strncpy (temp, inote.namedata, inote.namesz);
8472           temp[inote.namesz] = 0;
8473
8474           /* warn (_("'%s' NOTE name not properly null terminated\n"), temp);  */
8475           inote.namedata = temp;
8476         }
8477
8478       res &= process_note (& inote);
8479
8480       if (temp != NULL)
8481         {
8482           free (temp);
8483           temp = NULL;
8484         }
8485     }
8486
8487   free (pnotes);
8488
8489   return res;
8490 }
8491
8492 static int
8493 process_corefile_note_segments (file)
8494      FILE * file;
8495 {
8496   Elf_Internal_Phdr * program_headers;
8497   Elf_Internal_Phdr * segment;
8498   unsigned int        i;
8499   int                 res = 1;
8500
8501   program_headers = (Elf_Internal_Phdr *) malloc
8502     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8503
8504   if (program_headers == NULL)
8505     {
8506       error (_("Out of memory\n"));
8507       return 0;
8508     }
8509
8510   if (is_32bit_elf)
8511     i = get_32bit_program_headers (file, program_headers);
8512   else
8513     i = get_64bit_program_headers (file, program_headers);
8514
8515   if (i == 0)
8516     {
8517       free (program_headers);
8518       return 0;
8519     }
8520
8521   for (i = 0, segment = program_headers;
8522        i < elf_header.e_phnum;
8523        i ++, segment ++)
8524     {
8525       if (segment->p_type == PT_NOTE)
8526         res &= process_corefile_note_segment (file,
8527                                               (bfd_vma) segment->p_offset,
8528                                               (bfd_vma) segment->p_filesz);
8529     }
8530
8531   free (program_headers);
8532
8533   return res;
8534 }
8535
8536 static int
8537 process_corefile_contents (file)
8538      FILE * file;
8539 {
8540   /* If we have not been asked to display the notes then do nothing.  */
8541   if (! do_notes)
8542     return 1;
8543
8544   /* If file is not a core file then exit.  */
8545   if (elf_header.e_type != ET_CORE)
8546     return 1;
8547
8548   /* No program headers means no NOTE segment.  */
8549   if (elf_header.e_phnum == 0)
8550     {
8551       printf (_("No note segments present in the core file.\n"));
8552       return 1;
8553    }
8554
8555   return process_corefile_note_segments (file);
8556 }
8557
8558 static int
8559 process_arch_specific (file)
8560      FILE * file;
8561 {
8562   if (! do_arch)
8563     return 1;
8564
8565   switch (elf_header.e_machine)
8566     {
8567     case EM_MIPS:
8568     case EM_MIPS_RS3_LE:
8569       return process_mips_specific (file);
8570       break;
8571     default:
8572       break;
8573     }
8574   return 1;
8575 }
8576
8577 static int
8578 get_file_header (file)
8579      FILE * file;
8580 {
8581   /* Read in the identity array.  */
8582   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
8583     return 0;
8584
8585   /* Determine how to read the rest of the header.  */
8586   switch (elf_header.e_ident [EI_DATA])
8587     {
8588     default: /* fall through */
8589     case ELFDATANONE: /* fall through */
8590     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8591     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8592     }
8593
8594   /* For now we only support 32 bit and 64 bit ELF files.  */
8595   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8596
8597   /* Read in the rest of the header.  */
8598   if (is_32bit_elf)
8599     {
8600       Elf32_External_Ehdr ehdr32;
8601
8602       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8603         return 0;
8604
8605       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
8606       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
8607       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
8608       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
8609       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
8610       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
8611       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
8612       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
8613       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8614       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
8615       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8616       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
8617       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
8618     }
8619   else
8620     {
8621       Elf64_External_Ehdr ehdr64;
8622
8623       /* If we have been compiled with sizeof (bfd_vma) == 4, then
8624          we will not be able to cope with the 64bit data found in
8625          64 ELF files.  Detect this now and abort before we start
8626          overwritting things.  */
8627       if (sizeof (bfd_vma) < 8)
8628         {
8629           error (_("This instance of readelf has been built without support for a\n"));
8630           error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8631           return 0;
8632         }
8633
8634       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8635         return 0;
8636
8637       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
8638       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
8639       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
8640       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
8641       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
8642       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
8643       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
8644       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
8645       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8646       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
8647       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8648       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
8649       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
8650     }
8651
8652   return 1;
8653 }
8654
8655 static void
8656 process_file (file_name)
8657      char * file_name;
8658 {
8659   FILE *       file;
8660   struct stat  statbuf;
8661   unsigned int i;
8662
8663   if (stat (file_name, & statbuf) < 0)
8664     {
8665       error (_("Cannot stat input file %s.\n"), file_name);
8666       return;
8667     }
8668
8669   file = fopen (file_name, "rb");
8670   if (file == NULL)
8671     {
8672       error (_("Input file %s not found.\n"), file_name);
8673       return;
8674     }
8675
8676   if (! get_file_header (file))
8677     {
8678       error (_("%s: Failed to read file header\n"), file_name);
8679       fclose (file);
8680       return;
8681     }
8682
8683   /* Initialise per file variables.  */
8684   for (i = NUM_ELEM (version_info); i--;)
8685     version_info[i] = 0;
8686
8687   for (i = NUM_ELEM (dynamic_info); i--;)
8688     dynamic_info[i] = 0;
8689
8690   /* Process the file.  */
8691   if (show_name)
8692     printf (_("\nFile: %s\n"), file_name);
8693
8694   if (! process_file_header ())
8695     {
8696       fclose (file);
8697       return;
8698     }
8699
8700   process_section_headers (file);
8701
8702   process_program_headers (file);
8703
8704   process_dynamic_segment (file);
8705
8706   process_relocs (file);
8707
8708   process_unwind (file);
8709
8710   process_symbol_table (file);
8711
8712   process_syminfo (file);
8713
8714   process_version_sections (file);
8715
8716   process_section_contents (file);
8717
8718   process_corefile_contents (file);
8719
8720   process_arch_specific (file);
8721
8722   fclose (file);
8723
8724   if (section_headers)
8725     {
8726       free (section_headers);
8727       section_headers = NULL;
8728     }
8729
8730   if (string_table)
8731     {
8732       free (string_table);
8733       string_table = NULL;
8734       string_table_length = 0;
8735     }
8736
8737   if (dynamic_strings)
8738     {
8739       free (dynamic_strings);
8740       dynamic_strings = NULL;
8741     }
8742
8743   if (dynamic_symbols)
8744     {
8745       free (dynamic_symbols);
8746       dynamic_symbols = NULL;
8747       num_dynamic_syms = 0;
8748     }
8749
8750   if (dynamic_syminfo)
8751     {
8752       free (dynamic_syminfo);
8753       dynamic_syminfo = NULL;
8754     }
8755 }
8756
8757 #ifdef SUPPORT_DISASSEMBLY
8758 /* Needed by the i386 disassembler.  For extra credit, someone could
8759    fix this so that we insert symbolic addresses here, esp for GOT/PLT
8760    symbols */
8761
8762 void
8763 print_address (unsigned int addr, FILE * outfile)
8764 {
8765   fprintf (outfile,"0x%8.8x", addr);
8766 }
8767
8768 /* Needed by the i386 disassembler. */
8769 void
8770 db_task_printsym (unsigned int addr)
8771 {
8772   print_address (addr, stderr);
8773 }
8774 #endif
8775
8776 int
8777 main (argc, argv)
8778      int     argc;
8779      char ** argv;
8780 {
8781 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8782   setlocale (LC_MESSAGES, "");
8783 #endif
8784   bindtextdomain (PACKAGE, LOCALEDIR);
8785   textdomain (PACKAGE);
8786
8787   parse_args (argc, argv);
8788
8789   if (optind < (argc - 1))
8790     show_name = 1;
8791
8792   while (optind < argc)
8793     process_file (argv [optind ++]);
8794
8795   if (dump_sects != NULL)
8796     free (dump_sects);
8797
8798   return 0;
8799 }