* readelf.c (GET_DATA_ALLOC): Remove.
[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@cygnus.com>
6
7    This file is part of GNU Binutils.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22    02111-1307, USA.  */
23 \f
24
25 #include <assert.h>
26 #include <sys/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     default:
5941       {
5942         static char buffer [100];
5943
5944         sprintf (buffer, _("Unknown TAG value: %lx"), tag);
5945         return buffer;
5946       }
5947     }
5948 }
5949
5950 static char *
5951 get_AT_name (attribute)
5952      unsigned long attribute;
5953 {
5954   switch (attribute)
5955     {
5956     case DW_AT_sibling: return "DW_AT_sibling";
5957     case DW_AT_location: return "DW_AT_location";
5958     case DW_AT_name: return "DW_AT_name";
5959     case DW_AT_ordering: return "DW_AT_ordering";
5960     case DW_AT_subscr_data: return "DW_AT_subscr_data";
5961     case DW_AT_byte_size: return "DW_AT_byte_size";
5962     case DW_AT_bit_offset: return "DW_AT_bit_offset";
5963     case DW_AT_bit_size: return "DW_AT_bit_size";
5964     case DW_AT_element_list: return "DW_AT_element_list";
5965     case DW_AT_stmt_list: return "DW_AT_stmt_list";
5966     case DW_AT_low_pc: return "DW_AT_low_pc";
5967     case DW_AT_high_pc: return "DW_AT_high_pc";
5968     case DW_AT_language: return "DW_AT_language";
5969     case DW_AT_member: return "DW_AT_member";
5970     case DW_AT_discr: return "DW_AT_discr";
5971     case DW_AT_discr_value: return "DW_AT_discr_value";
5972     case DW_AT_visibility: return "DW_AT_visibility";
5973     case DW_AT_import: return "DW_AT_import";
5974     case DW_AT_string_length: return "DW_AT_string_length";
5975     case DW_AT_common_reference: return "DW_AT_common_reference";
5976     case DW_AT_comp_dir: return "DW_AT_comp_dir";
5977     case DW_AT_const_value: return "DW_AT_const_value";
5978     case DW_AT_containing_type: return "DW_AT_containing_type";
5979     case DW_AT_default_value: return "DW_AT_default_value";
5980     case DW_AT_inline: return "DW_AT_inline";
5981     case DW_AT_is_optional: return "DW_AT_is_optional";
5982     case DW_AT_lower_bound: return "DW_AT_lower_bound";
5983     case DW_AT_producer: return "DW_AT_producer";
5984     case DW_AT_prototyped: return "DW_AT_prototyped";
5985     case DW_AT_return_addr: return "DW_AT_return_addr";
5986     case DW_AT_start_scope: return "DW_AT_start_scope";
5987     case DW_AT_stride_size: return "DW_AT_stride_size";
5988     case DW_AT_upper_bound: return "DW_AT_upper_bound";
5989     case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
5990     case DW_AT_accessibility: return "DW_AT_accessibility";
5991     case DW_AT_address_class: return "DW_AT_address_class";
5992     case DW_AT_artificial: return "DW_AT_artificial";
5993     case DW_AT_base_types: return "DW_AT_base_types";
5994     case DW_AT_calling_convention: return "DW_AT_calling_convention";
5995     case DW_AT_count: return "DW_AT_count";
5996     case DW_AT_data_member_location: return "DW_AT_data_member_location";
5997     case DW_AT_decl_column: return "DW_AT_decl_column";
5998     case DW_AT_decl_file: return "DW_AT_decl_file";
5999     case DW_AT_decl_line: return "DW_AT_decl_line";
6000     case DW_AT_declaration: return "DW_AT_declaration";
6001     case DW_AT_discr_list: return "DW_AT_discr_list";
6002     case DW_AT_encoding: return "DW_AT_encoding";
6003     case DW_AT_external: return "DW_AT_external";
6004     case DW_AT_frame_base: return "DW_AT_frame_base";
6005     case DW_AT_friend: return "DW_AT_friend";
6006     case DW_AT_identifier_case: return "DW_AT_identifier_case";
6007     case DW_AT_macro_info: return "DW_AT_macro_info";
6008     case DW_AT_namelist_items: return "DW_AT_namelist_items";
6009     case DW_AT_priority: return "DW_AT_priority";
6010     case DW_AT_segment: return "DW_AT_segment";
6011     case DW_AT_specification: return "DW_AT_specification";
6012     case DW_AT_static_link: return "DW_AT_static_link";
6013     case DW_AT_type: return "DW_AT_type";
6014     case DW_AT_use_location: return "DW_AT_use_location";
6015     case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
6016     case DW_AT_virtuality: return "DW_AT_virtuality";
6017     case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
6018     case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
6019     case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
6020     case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
6021     case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
6022     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
6023     case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
6024     case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
6025     case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
6026     case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
6027     case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
6028     case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
6029     case DW_AT_sf_names: return "DW_AT_sf_names";
6030     case DW_AT_src_info: return "DW_AT_src_info";
6031     case DW_AT_mac_info: return "DW_AT_mac_info";
6032     case DW_AT_src_coords: return "DW_AT_src_coords";
6033     case DW_AT_body_begin: return "DW_AT_body_begin";
6034     case DW_AT_body_end: return "DW_AT_body_end";
6035     default:
6036       {
6037         static char buffer [100];
6038
6039         sprintf (buffer, _("Unknown AT value: %lx"), attribute);
6040         return buffer;
6041       }
6042     }
6043 }
6044
6045 static char *
6046 get_FORM_name (form)
6047      unsigned long form;
6048 {
6049   switch (form)
6050     {
6051     case DW_FORM_addr: return "DW_FORM_addr";
6052     case DW_FORM_block2: return "DW_FORM_block2";
6053     case DW_FORM_block4: return "DW_FORM_block4";
6054     case DW_FORM_data2: return "DW_FORM_data2";
6055     case DW_FORM_data4: return "DW_FORM_data4";
6056     case DW_FORM_data8: return "DW_FORM_data8";
6057     case DW_FORM_string: return "DW_FORM_string";
6058     case DW_FORM_block: return "DW_FORM_block";
6059     case DW_FORM_block1: return "DW_FORM_block1";
6060     case DW_FORM_data1: return "DW_FORM_data1";
6061     case DW_FORM_flag: return "DW_FORM_flag";
6062     case DW_FORM_sdata: return "DW_FORM_sdata";
6063     case DW_FORM_strp: return "DW_FORM_strp";
6064     case DW_FORM_udata: return "DW_FORM_udata";
6065     case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
6066     case DW_FORM_ref1: return "DW_FORM_ref1";
6067     case DW_FORM_ref2: return "DW_FORM_ref2";
6068     case DW_FORM_ref4: return "DW_FORM_ref4";
6069     case DW_FORM_ref8: return "DW_FORM_ref8";
6070     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
6071     case DW_FORM_indirect: return "DW_FORM_indirect";
6072     default:
6073       {
6074         static char buffer [100];
6075
6076         sprintf (buffer, _("Unknown FORM value: %lx"), form);
6077         return buffer;
6078       }
6079     }
6080 }
6081
6082 /* FIXME:  There are better and more effiecint ways to handle
6083    these structures.  For now though, I just want something that
6084    is simple to implement.  */
6085 typedef struct abbrev_attr
6086 {
6087   unsigned long        attribute;
6088   unsigned long        form;
6089   struct abbrev_attr * next;
6090 }
6091 abbrev_attr;
6092
6093 typedef struct abbrev_entry
6094 {
6095   unsigned long          entry;
6096   unsigned long          tag;
6097   int                    children;
6098   struct abbrev_attr *   first_attr;
6099   struct abbrev_attr *   last_attr;
6100   struct abbrev_entry *  next;
6101 }
6102 abbrev_entry;
6103
6104 static abbrev_entry * first_abbrev = NULL;
6105 static abbrev_entry * last_abbrev = NULL;
6106
6107 static void
6108 free_abbrevs PARAMS ((void))
6109 {
6110   abbrev_entry * abbrev;
6111
6112   for (abbrev = first_abbrev; abbrev;)
6113     {
6114       abbrev_entry * next = abbrev->next;
6115       abbrev_attr  * attr;
6116
6117       for (attr = abbrev->first_attr; attr;)
6118         {
6119           abbrev_attr * next = attr->next;
6120
6121           free (attr);
6122           attr = next;
6123         }
6124
6125       free (abbrev);
6126       abbrev = next;
6127     }
6128
6129   last_abbrev = first_abbrev = NULL;
6130 }
6131
6132 static void
6133 add_abbrev (number, tag, children)
6134      unsigned long number;
6135      unsigned long tag;
6136      int           children;
6137 {
6138   abbrev_entry * entry;
6139
6140   entry = (abbrev_entry *) malloc (sizeof (* entry));
6141
6142   if (entry == NULL)
6143     /* ugg */
6144     return;
6145
6146   entry->entry      = number;
6147   entry->tag        = tag;
6148   entry->children   = children;
6149   entry->first_attr = NULL;
6150   entry->last_attr  = NULL;
6151   entry->next       = NULL;
6152
6153   if (first_abbrev == NULL)
6154     first_abbrev = entry;
6155   else
6156     last_abbrev->next = entry;
6157
6158   last_abbrev = entry;
6159 }
6160
6161 static void
6162 add_abbrev_attr (attribute, form)
6163      unsigned long attribute;
6164      unsigned long form;
6165 {
6166   abbrev_attr * attr;
6167
6168   attr = (abbrev_attr *) malloc (sizeof (* attr));
6169
6170   if (attr == NULL)
6171     /* ugg */
6172     return;
6173
6174   attr->attribute = attribute;
6175   attr->form      = form;
6176   attr->next      = NULL;
6177
6178   if (last_abbrev->first_attr == NULL)
6179     last_abbrev->first_attr = attr;
6180   else
6181     last_abbrev->last_attr->next = attr;
6182
6183   last_abbrev->last_attr = attr;
6184 }
6185
6186 /* Processes the (partial) contents of a .debug_abbrev section.
6187    Returns NULL if the end of the section was encountered.
6188    Returns the address after the last byte read if the end of
6189    an abbreviation set was found.  */
6190
6191 static unsigned char *
6192 process_abbrev_section (start, end)
6193      unsigned char * start;
6194      unsigned char * end;
6195 {
6196   if (first_abbrev != NULL)
6197     return NULL;
6198
6199   while (start < end)
6200     {
6201       int           bytes_read;
6202       unsigned long entry;
6203       unsigned long tag;
6204       unsigned long attribute;
6205       int           children;
6206
6207       entry = read_leb128 (start, & bytes_read, 0);
6208       start += bytes_read;
6209
6210       /* A single zero is supposed to end the section according
6211          to the standard.  If there's more, then signal that to
6212          the caller.  */
6213       if (entry == 0)
6214         return start == end ? NULL : start;
6215
6216       tag = read_leb128 (start, & bytes_read, 0);
6217       start += bytes_read;
6218
6219       children = * start ++;
6220
6221       add_abbrev (entry, tag, children);
6222
6223       do
6224         {
6225           unsigned long form;
6226
6227           attribute = read_leb128 (start, & bytes_read, 0);
6228           start += bytes_read;
6229
6230           form = read_leb128 (start, & bytes_read, 0);
6231           start += bytes_read;
6232
6233           if (attribute != 0)
6234             add_abbrev_attr (attribute, form);
6235         }
6236       while (attribute != 0);
6237     }
6238
6239   return NULL;
6240 }
6241
6242
6243 static int
6244 display_debug_abbrev (section, start, file)
6245      Elf32_Internal_Shdr * section;
6246      unsigned char *       start;
6247      FILE *                file ATTRIBUTE_UNUSED;
6248 {
6249   abbrev_entry *  entry;
6250   unsigned char * end = start + section->sh_size;
6251
6252   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6253
6254   do
6255     {
6256       start = process_abbrev_section (start, end);
6257
6258       printf (_("  Number TAG\n"));
6259
6260       for (entry = first_abbrev; entry; entry = entry->next)
6261         {
6262           abbrev_attr * attr;
6263
6264           printf (_("   %ld      %s    [%s]\n"),
6265                   entry->entry,
6266                   get_TAG_name (entry->tag),
6267                   entry->children ? _("has children") : _("no children"));
6268
6269           for (attr = entry->first_attr; attr; attr = attr->next)
6270             {
6271               printf (_("    %-18s %s\n"),
6272                       get_AT_name (attr->attribute),
6273                       get_FORM_name (attr->form));
6274             }
6275         }
6276     }
6277   while (start);
6278
6279   printf ("\n");
6280
6281   return 1;
6282 }
6283
6284
6285 static unsigned char *
6286 display_block (data, length)
6287      unsigned char * data;
6288      unsigned long   length;
6289 {
6290   printf (_(" %lu byte block: "), length);
6291
6292   while (length --)
6293     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
6294
6295   return data;
6296 }
6297
6298 static void
6299 decode_location_expression (data, pointer_size, length)
6300      unsigned char * data;
6301      unsigned int    pointer_size;
6302      unsigned long   length;
6303 {
6304   unsigned        op;
6305   int             bytes_read;
6306   unsigned long   uvalue;
6307   unsigned char * end = data + length;
6308
6309   while (data < end)
6310     {
6311       op = * data ++;
6312
6313       switch (op)
6314         {
6315         case DW_OP_addr:
6316           printf ("DW_OP_addr: %lx",
6317                   (unsigned long) byte_get (data, pointer_size));
6318           data += pointer_size;
6319           break;
6320         case DW_OP_deref:
6321           printf ("DW_OP_deref");
6322           break;
6323         case DW_OP_const1u:
6324           printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6325           break;
6326         case DW_OP_const1s:
6327           printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6328           break;
6329         case DW_OP_const2u:
6330           printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6331           data += 2;
6332           break;
6333         case DW_OP_const2s:
6334           printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6335           data += 2;
6336           break;
6337         case DW_OP_const4u:
6338           printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6339           data += 4;
6340           break;
6341         case DW_OP_const4s:
6342           printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6343           data += 4;
6344           break;
6345         case DW_OP_const8u:
6346           printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6347                   (unsigned long) byte_get (data + 4, 4));
6348           data += 8;
6349           break;
6350         case DW_OP_const8s:
6351           printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6352                   (long) byte_get (data + 4, 4));
6353           data += 8;
6354           break;
6355         case DW_OP_constu:
6356           printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6357           data += bytes_read;
6358           break;
6359         case DW_OP_consts:
6360           printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6361           data += bytes_read;
6362           break;
6363         case DW_OP_dup:
6364           printf ("DW_OP_dup");
6365           break;
6366         case DW_OP_drop:
6367           printf ("DW_OP_drop");
6368           break;
6369         case DW_OP_over:
6370           printf ("DW_OP_over");
6371           break;
6372         case DW_OP_pick:
6373           printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6374           break;
6375         case DW_OP_swap:
6376           printf ("DW_OP_swap");
6377           break;
6378         case DW_OP_rot:
6379           printf ("DW_OP_rot");
6380           break;
6381         case DW_OP_xderef:
6382           printf ("DW_OP_xderef");
6383           break;
6384         case DW_OP_abs:
6385           printf ("DW_OP_abs");
6386           break;
6387         case DW_OP_and:
6388           printf ("DW_OP_and");
6389           break;
6390         case DW_OP_div:
6391           printf ("DW_OP_div");
6392           break;
6393         case DW_OP_minus:
6394           printf ("DW_OP_minus");
6395           break;
6396         case DW_OP_mod:
6397           printf ("DW_OP_mod");
6398           break;
6399         case DW_OP_mul:
6400           printf ("DW_OP_mul");
6401           break;
6402         case DW_OP_neg:
6403           printf ("DW_OP_neg");
6404           break;
6405         case DW_OP_not:
6406           printf ("DW_OP_not");
6407           break;
6408         case DW_OP_or:
6409           printf ("DW_OP_or");
6410           break;
6411         case DW_OP_plus:
6412           printf ("DW_OP_plus");
6413           break;
6414         case DW_OP_plus_uconst:
6415           printf ("DW_OP_plus_uconst: %lu",
6416                   read_leb128 (data, &bytes_read, 0));
6417           data += bytes_read;
6418           break;
6419         case DW_OP_shl:
6420           printf ("DW_OP_shl");
6421           break;
6422         case DW_OP_shr:
6423           printf ("DW_OP_shr");
6424           break;
6425         case DW_OP_shra:
6426           printf ("DW_OP_shra");
6427           break;
6428         case DW_OP_xor:
6429           printf ("DW_OP_xor");
6430           break;
6431         case DW_OP_bra:
6432           printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6433           data += 2;
6434           break;
6435         case DW_OP_eq:
6436           printf ("DW_OP_eq");
6437           break;
6438         case DW_OP_ge:
6439           printf ("DW_OP_ge");
6440           break;
6441         case DW_OP_gt:
6442           printf ("DW_OP_gt");
6443           break;
6444         case DW_OP_le:
6445           printf ("DW_OP_le");
6446           break;
6447         case DW_OP_lt:
6448           printf ("DW_OP_lt");
6449           break;
6450         case DW_OP_ne:
6451           printf ("DW_OP_ne");
6452           break;
6453         case DW_OP_skip:
6454           printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6455           data += 2;
6456           break;
6457
6458         case DW_OP_lit0:
6459         case DW_OP_lit1:
6460         case DW_OP_lit2:
6461         case DW_OP_lit3:
6462         case DW_OP_lit4:
6463         case DW_OP_lit5:
6464         case DW_OP_lit6:
6465         case DW_OP_lit7:
6466         case DW_OP_lit8:
6467         case DW_OP_lit9:
6468         case DW_OP_lit10:
6469         case DW_OP_lit11:
6470         case DW_OP_lit12:
6471         case DW_OP_lit13:
6472         case DW_OP_lit14:
6473         case DW_OP_lit15:
6474         case DW_OP_lit16:
6475         case DW_OP_lit17:
6476         case DW_OP_lit18:
6477         case DW_OP_lit19:
6478         case DW_OP_lit20:
6479         case DW_OP_lit21:
6480         case DW_OP_lit22:
6481         case DW_OP_lit23:
6482         case DW_OP_lit24:
6483         case DW_OP_lit25:
6484         case DW_OP_lit26:
6485         case DW_OP_lit27:
6486         case DW_OP_lit28:
6487         case DW_OP_lit29:
6488         case DW_OP_lit30:
6489         case DW_OP_lit31:
6490           printf ("DW_OP_lit%d", op - DW_OP_lit0);
6491           break;
6492
6493         case DW_OP_reg0:
6494         case DW_OP_reg1:
6495         case DW_OP_reg2:
6496         case DW_OP_reg3:
6497         case DW_OP_reg4:
6498         case DW_OP_reg5:
6499         case DW_OP_reg6:
6500         case DW_OP_reg7:
6501         case DW_OP_reg8:
6502         case DW_OP_reg9:
6503         case DW_OP_reg10:
6504         case DW_OP_reg11:
6505         case DW_OP_reg12:
6506         case DW_OP_reg13:
6507         case DW_OP_reg14:
6508         case DW_OP_reg15:
6509         case DW_OP_reg16:
6510         case DW_OP_reg17:
6511         case DW_OP_reg18:
6512         case DW_OP_reg19:
6513         case DW_OP_reg20:
6514         case DW_OP_reg21:
6515         case DW_OP_reg22:
6516         case DW_OP_reg23:
6517         case DW_OP_reg24:
6518         case DW_OP_reg25:
6519         case DW_OP_reg26:
6520         case DW_OP_reg27:
6521         case DW_OP_reg28:
6522         case DW_OP_reg29:
6523         case DW_OP_reg30:
6524         case DW_OP_reg31:
6525           printf ("DW_OP_reg%d", op - DW_OP_reg0);
6526           break;
6527
6528         case DW_OP_breg0:
6529         case DW_OP_breg1:
6530         case DW_OP_breg2:
6531         case DW_OP_breg3:
6532         case DW_OP_breg4:
6533         case DW_OP_breg5:
6534         case DW_OP_breg6:
6535         case DW_OP_breg7:
6536         case DW_OP_breg8:
6537         case DW_OP_breg9:
6538         case DW_OP_breg10:
6539         case DW_OP_breg11:
6540         case DW_OP_breg12:
6541         case DW_OP_breg13:
6542         case DW_OP_breg14:
6543         case DW_OP_breg15:
6544         case DW_OP_breg16:
6545         case DW_OP_breg17:
6546         case DW_OP_breg18:
6547         case DW_OP_breg19:
6548         case DW_OP_breg20:
6549         case DW_OP_breg21:
6550         case DW_OP_breg22:
6551         case DW_OP_breg23:
6552         case DW_OP_breg24:
6553         case DW_OP_breg25:
6554         case DW_OP_breg26:
6555         case DW_OP_breg27:
6556         case DW_OP_breg28:
6557         case DW_OP_breg29:
6558         case DW_OP_breg30:
6559         case DW_OP_breg31:
6560           printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6561                   read_leb128 (data, &bytes_read, 1));
6562           data += bytes_read;
6563           break;
6564
6565         case DW_OP_regx:
6566           printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6567           data += bytes_read;
6568           break;
6569         case DW_OP_fbreg:
6570           printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6571           data += bytes_read;
6572           break;
6573         case DW_OP_bregx:
6574           uvalue = read_leb128 (data, &bytes_read, 0);
6575           data += bytes_read;
6576           printf ("DW_OP_bregx: %lu %ld", uvalue,
6577                   read_leb128 (data, &bytes_read, 1));
6578           data += bytes_read;
6579           break;
6580         case DW_OP_piece:
6581           printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6582           data += bytes_read;
6583           break;
6584         case DW_OP_deref_size:
6585           printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6586           break;
6587         case DW_OP_xderef_size:
6588           printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6589           break;
6590         case DW_OP_nop:
6591           printf ("DW_OP_nop");
6592           break;
6593
6594         default:
6595           if (op >= DW_OP_lo_user
6596               && op <= DW_OP_hi_user)
6597             printf (_("(User defined location op)"));
6598           else
6599             printf (_("(Unknown location op)"));
6600           /* No way to tell where the next op is, so just bail.  */
6601           return;
6602         }
6603     }
6604 }
6605
6606
6607 static unsigned char *
6608 read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
6609      unsigned long   attribute;
6610      unsigned long   form;
6611      unsigned char * data;
6612      unsigned long   cu_offset;
6613      unsigned long   pointer_size;
6614 {
6615   unsigned long   uvalue = 0;
6616   unsigned char * block_start = NULL;
6617   int             bytes_read;
6618
6619   printf ("     %-18s:", get_AT_name (attribute));
6620
6621   switch (form)
6622     {
6623     default:
6624       break;
6625
6626     case DW_FORM_ref_addr:
6627     case DW_FORM_addr:
6628       uvalue = byte_get (data, pointer_size);
6629       data += pointer_size;
6630       break;
6631
6632     case DW_FORM_ref1:
6633     case DW_FORM_flag:
6634     case DW_FORM_data1:
6635       uvalue = byte_get (data ++, 1);
6636       break;
6637
6638     case DW_FORM_ref2:
6639     case DW_FORM_data2:
6640       uvalue = byte_get (data, 2);
6641       data += 2;
6642       break;
6643
6644     case DW_FORM_ref4:
6645     case DW_FORM_data4:
6646       uvalue = byte_get (data, 4);
6647       data += 4;
6648       break;
6649
6650     case DW_FORM_sdata:
6651       uvalue = read_leb128 (data, & bytes_read, 1);
6652       data += bytes_read;
6653       break;
6654
6655     case DW_FORM_ref_udata:
6656     case DW_FORM_udata:
6657       uvalue = read_leb128 (data, & bytes_read, 0);
6658       data += bytes_read;
6659       break;
6660     }
6661
6662   switch (form)
6663     {
6664     case DW_FORM_ref_addr:
6665       printf (" <#%lx>", uvalue);
6666       break;
6667
6668     case DW_FORM_ref1:
6669     case DW_FORM_ref2:
6670     case DW_FORM_ref4:
6671     case DW_FORM_ref_udata:
6672       printf (" <%lx>", uvalue + cu_offset);
6673       break;
6674
6675     case DW_FORM_addr:
6676       printf (" %#lx", uvalue);
6677
6678     case DW_FORM_flag:
6679     case DW_FORM_data1:
6680     case DW_FORM_data2:
6681     case DW_FORM_data4:
6682     case DW_FORM_sdata:
6683     case DW_FORM_udata:
6684       printf (" %ld", uvalue);
6685       break;
6686
6687     case DW_FORM_ref8:
6688     case DW_FORM_data8:
6689       uvalue = byte_get (data, 4);
6690       printf (" %lx", uvalue);
6691       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
6692       data += 8;
6693       break;
6694
6695     case DW_FORM_string:
6696       printf (" %s", data);
6697       data += strlen ((char *) data) + 1;
6698       break;
6699
6700     case DW_FORM_block:
6701       uvalue = read_leb128 (data, & bytes_read, 0);
6702       block_start = data + bytes_read;
6703       data = display_block (block_start, uvalue);
6704       break;
6705
6706     case DW_FORM_block1:
6707       uvalue = byte_get (data, 1);
6708       block_start = data + 1;
6709       data = display_block (block_start, uvalue);
6710       break;
6711
6712     case DW_FORM_block2:
6713       uvalue = byte_get (data, 2);
6714       block_start = data + 2;
6715       data = display_block (block_start, uvalue);
6716       break;
6717
6718     case DW_FORM_block4:
6719       uvalue = byte_get (data, 4);
6720       block_start = data + 4;
6721       data = display_block (block_start, uvalue);
6722       break;
6723
6724     case DW_FORM_strp:
6725     case DW_FORM_indirect:
6726       warn (_("Unable to handle FORM: %d"), form);
6727       break;
6728
6729     default:
6730       warn (_("Unrecognised form: %d"), form);
6731       break;
6732     }
6733
6734   /* For some attributes we can display futher information.  */
6735
6736   printf ("\t");
6737
6738   switch (attribute)
6739     {
6740     case DW_AT_inline:
6741       switch (uvalue)
6742         {
6743         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
6744         case DW_INL_inlined:              printf (_("(inlined)")); break;
6745         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6746         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
6747         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
6748         }
6749       break;
6750
6751     case DW_AT_language:
6752       switch (uvalue)
6753         {
6754         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
6755         case DW_LANG_C89:            printf ("(ANSI C)"); break;
6756         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
6757         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
6758         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
6759         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
6760         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
6761         case DW_LANG_Ada83:          printf ("(Ada)"); break;
6762         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
6763         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
6764         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6765         default:                     printf ("(Unknown: %lx)", uvalue); break;
6766         }
6767       break;
6768
6769     case DW_AT_encoding:
6770       switch (uvalue)
6771         {
6772         case DW_ATE_void:            printf ("(void)"); break;
6773         case DW_ATE_address:         printf ("(machine address)"); break;
6774         case DW_ATE_boolean:         printf ("(boolean)"); break;
6775         case DW_ATE_complex_float:   printf ("(complex float)"); break;
6776         case DW_ATE_float:           printf ("(float)"); break;
6777         case DW_ATE_signed:          printf ("(signed)"); break;
6778         case DW_ATE_signed_char:     printf ("(signed char)"); break;
6779         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
6780         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
6781         default:
6782           if (uvalue >= DW_ATE_lo_user
6783               && uvalue <= DW_ATE_hi_user)
6784             printf ("(user defined type)");
6785           else
6786             printf ("(unknown type)");
6787           break;
6788         }
6789       break;
6790
6791     case DW_AT_accessibility:
6792       switch (uvalue)
6793         {
6794         case DW_ACCESS_public:          printf ("(public)"); break;
6795         case DW_ACCESS_protected:       printf ("(protected)"); break;
6796         case DW_ACCESS_private:         printf ("(private)"); break;
6797         default:                        printf ("(unknown accessibility)"); break;
6798         }
6799       break;
6800
6801     case DW_AT_visibility:
6802       switch (uvalue)
6803         {
6804         case DW_VIS_local:      printf ("(local)"); break;
6805         case DW_VIS_exported:   printf ("(exported)"); break;
6806         case DW_VIS_qualified:  printf ("(qualified)"); break;
6807         default:                printf ("(unknown visibility)"); break;
6808         }
6809       break;
6810
6811     case DW_AT_virtuality:
6812       switch (uvalue)
6813         {
6814         case DW_VIRTUALITY_none:        printf ("(none)"); break;
6815         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
6816         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6817         default:                        printf ("(unknown virtuality)"); break;
6818         }
6819       break;
6820
6821     case DW_AT_identifier_case:
6822       switch (uvalue)
6823         {
6824         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
6825         case DW_ID_up_case:             printf ("(up_case)"); break;
6826         case DW_ID_down_case:           printf ("(down_case)"); break;
6827         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
6828         default:                        printf ("(unknown case)"); break;
6829         }
6830       break;
6831
6832     case DW_AT_calling_convention:
6833       switch (uvalue)
6834         {
6835         case DW_CC_normal:      printf ("(normal)"); break;
6836         case DW_CC_program:     printf ("(program)"); break;
6837         case DW_CC_nocall:      printf ("(nocall)"); break;
6838         default:
6839           if (uvalue >= DW_CC_lo_user
6840               && uvalue <= DW_CC_hi_user)
6841             printf ("(user defined)");
6842           else
6843             printf ("(unknown convention)");
6844         }
6845       break;
6846
6847     case DW_AT_frame_base:
6848     case DW_AT_location:
6849     case DW_AT_data_member_location:
6850     case DW_AT_vtable_elem_location:
6851       if (block_start)
6852         {
6853           printf ("(");
6854           decode_location_expression (block_start, pointer_size, uvalue);
6855           printf (")");
6856         }
6857       break;
6858
6859     default:
6860       break;
6861     }
6862
6863   printf ("\n");
6864   return data;
6865 }
6866
6867 static int
6868 display_debug_info (section, start, file)
6869      Elf32_Internal_Shdr * section;
6870      unsigned char *       start;
6871      FILE *                file;
6872 {
6873   unsigned char * end = start + section->sh_size;
6874   unsigned char * section_begin = start;
6875
6876   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6877
6878   while (start < end)
6879     {
6880       DWARF2_External_CompUnit * external;
6881       DWARF2_Internal_CompUnit   compunit;
6882       unsigned char *            tags;
6883       int                        i;
6884       int                        level;
6885       unsigned long              cu_offset;
6886
6887       external = (DWARF2_External_CompUnit *) start;
6888
6889       compunit.cu_length        = BYTE_GET (external->cu_length);
6890       compunit.cu_version       = BYTE_GET (external->cu_version);
6891       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6892       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
6893
6894       tags = start + sizeof (* external);
6895       cu_offset = start - section_begin;
6896       start += compunit.cu_length + sizeof (external->cu_length);
6897
6898       printf (_("  Compilation Unit @ %lx:\n"), cu_offset);
6899       printf (_("   Length:        %ld\n"), compunit.cu_length);
6900       printf (_("   Version:       %d\n"), compunit.cu_version);
6901       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6902       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
6903
6904       if (compunit.cu_version != 2)
6905         {
6906           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6907           continue;
6908         }
6909
6910       if (first_abbrev != NULL)
6911         free_abbrevs ();
6912
6913       /* Read in the abbrevs used by this compilation unit.  */
6914
6915       {
6916         Elf32_Internal_Shdr * sec;
6917         unsigned char *       begin;
6918
6919         /* Locate the .debug_abbrev section and process it.  */
6920         for (i = 0, sec = section_headers;
6921              i < elf_header.e_shnum;
6922              i ++, sec ++)
6923           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6924             break;
6925
6926         if (i == -1 || sec->sh_size == 0)
6927           {
6928             warn (_("Unable to locate .debug_abbrev section!\n"));
6929             return 0;
6930           }
6931
6932         begin = ((unsigned char *)
6933                  get_data (NULL, file, sec->sh_offset, sec->sh_size, 
6934                            _("debug_abbrev section data")));
6935         if (!begin)
6936           return 0;
6937
6938         process_abbrev_section (begin + compunit.cu_abbrev_offset,
6939                                 begin + sec->sh_size);
6940
6941         free (begin);
6942       }
6943
6944       level = 0;
6945       while (tags < start)
6946         {
6947           int            bytes_read;
6948           unsigned long  abbrev_number;
6949           abbrev_entry * entry;
6950           abbrev_attr  * attr;
6951
6952           abbrev_number = read_leb128 (tags, & bytes_read, 0);
6953           tags += bytes_read;
6954
6955           /* A null DIE marks the end of a list of children.  */
6956           if (abbrev_number == 0)
6957             {
6958               --level;
6959               continue;
6960             }
6961
6962           /* Scan through the abbreviation list until we reach the
6963              correct entry.  */
6964           for (entry = first_abbrev;
6965                entry && entry->entry != abbrev_number;
6966                entry = entry->next)
6967             continue;
6968
6969           if (entry == NULL)
6970             {
6971               warn (_("Unable to locate entry %lu in the abbreviation table\n"),
6972                     abbrev_number);
6973               return 0;
6974             }
6975
6976           printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
6977                   level, tags - section_begin - bytes_read,
6978                   abbrev_number,
6979                   get_TAG_name (entry->tag));
6980
6981           for (attr = entry->first_attr; attr; attr = attr->next)
6982             tags = read_and_display_attr (attr->attribute,
6983                                           attr->form,
6984                                           tags, cu_offset,
6985                                           compunit.cu_pointer_size);
6986
6987           if (entry->children)
6988             ++level;
6989         }
6990     }
6991
6992   printf ("\n");
6993
6994   return 1;
6995 }
6996
6997 static int
6998 display_debug_aranges (section, start, file)
6999      Elf32_Internal_Shdr * section;
7000      unsigned char *       start;
7001      FILE *                file ATTRIBUTE_UNUSED;
7002 {
7003   unsigned char * end = start + section->sh_size;
7004
7005   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7006
7007   while (start < end)
7008     {
7009       DWARF2_External_ARange * external;
7010       DWARF2_Internal_ARange   arange;
7011       unsigned char *          ranges;
7012       unsigned long            length;
7013       unsigned long            address;
7014       int                      excess;
7015
7016       external = (DWARF2_External_ARange *) start;
7017
7018       arange.ar_length       = BYTE_GET (external->ar_length);
7019       arange.ar_version      = BYTE_GET (external->ar_version);
7020       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
7021       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
7022       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
7023
7024       if (arange.ar_version != 2)
7025         {
7026           warn (_("Only DWARF 2 aranges are currently supported.\n"));
7027           break;
7028         }
7029
7030       printf (_("  Length:                   %ld\n"), arange.ar_length);
7031       printf (_("  Version:                  %d\n"), arange.ar_version);
7032       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
7033       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
7034       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
7035
7036       printf (_("\n    Address  Length\n"));
7037
7038       ranges = start + sizeof (* external);
7039
7040       /* Must pad to an alignment boundary that is twice the pointer size.  */
7041       excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7042       if (excess)
7043         ranges += (2 * arange.ar_pointer_size) - excess;
7044
7045       for (;;)
7046         {
7047           address = byte_get (ranges, arange.ar_pointer_size);
7048
7049           ranges += arange.ar_pointer_size;
7050
7051           length  = byte_get (ranges, arange.ar_pointer_size);
7052
7053           ranges += arange.ar_pointer_size;
7054
7055           /* A pair of zeros marks the end of the list.  */
7056           if (address == 0 && length == 0)
7057             break;
7058
7059           printf ("    %8.8lx %lu\n", address, length);
7060         }
7061
7062       start += arange.ar_length + sizeof (external->ar_length);
7063     }
7064
7065   printf ("\n");
7066
7067   return 1;
7068 }
7069
7070 typedef struct Frame_Chunk
7071 {
7072   struct Frame_Chunk * next;
7073   unsigned char *      chunk_start;
7074   int                  ncols;
7075   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
7076   short int *          col_type;
7077   int *                col_offset;
7078   char *               augmentation;
7079   unsigned int         code_factor;
7080   int                  data_factor;
7081   unsigned long        pc_begin;
7082   unsigned long        pc_range;
7083   int                  cfa_reg;
7084   int                  cfa_offset;
7085   int                  ra;
7086   unsigned char        fde_encoding;
7087 }
7088 Frame_Chunk;
7089
7090 /* A marker for a col_type that means this column was never referenced
7091    in the frame info.  */
7092 #define DW_CFA_unreferenced (-1)
7093
7094 static void
7095 frame_need_space (fc, reg)
7096      Frame_Chunk * fc;
7097      int reg;
7098 {
7099   int prev = fc->ncols;
7100
7101   if (reg < fc->ncols)
7102     return;
7103
7104   fc->ncols = reg + 1;
7105   fc->col_type = (short int *) xrealloc (fc->col_type,
7106                                          fc->ncols * sizeof (short int));
7107   fc->col_offset = (int *) xrealloc (fc->col_offset,
7108                                      fc->ncols * sizeof (int));
7109
7110   while (prev < fc->ncols)
7111     {
7112       fc->col_type[prev] = DW_CFA_unreferenced;
7113       fc->col_offset[prev] = 0;
7114       prev++;
7115     }
7116 }
7117
7118 static void
7119 frame_display_row (fc, need_col_headers, max_regs)
7120      Frame_Chunk * fc;
7121      int *         need_col_headers;
7122      int *         max_regs;
7123 {
7124   int r;
7125   char tmp[100];
7126
7127   if (* max_regs < fc->ncols)
7128     * max_regs = fc->ncols;
7129
7130   if (* need_col_headers)
7131     {
7132       * need_col_headers = 0;
7133
7134       printf ("   LOC   CFA      ");
7135
7136       for (r = 0; r < * max_regs; r++)
7137         if (fc->col_type[r] != DW_CFA_unreferenced)
7138           {
7139             if (r == fc->ra)
7140               printf ("ra   ");
7141             else
7142               printf ("r%-4d", r);
7143           }
7144
7145       printf ("\n");
7146     }
7147
7148   printf ("%08lx ", fc->pc_begin);
7149   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7150   printf ("%-8s ", tmp);
7151
7152   for (r = 0; r < fc->ncols; r++)
7153     {
7154       if (fc->col_type[r] != DW_CFA_unreferenced)
7155         {
7156           switch (fc->col_type[r])
7157             {
7158             case DW_CFA_undefined:
7159               strcpy (tmp, "u");
7160               break;
7161             case DW_CFA_same_value:
7162               strcpy (tmp, "s");
7163               break;
7164             case DW_CFA_offset:
7165               sprintf (tmp, "c%+d", fc->col_offset[r]);
7166               break;
7167             case DW_CFA_register:
7168               sprintf (tmp, "r%d", fc->col_offset[r]);
7169               break;
7170             default:
7171               strcpy (tmp, "n/a");
7172               break;
7173             }
7174           printf ("%-5s", tmp);
7175         }
7176     }
7177   printf ("\n");
7178 }
7179
7180 static int
7181 size_of_encoded_value (encoding)
7182      int encoding;
7183 {
7184   switch (encoding & 0x7)
7185     {
7186     default:    /* ??? */
7187     case 0:     return is_32bit_elf ? 4 : 8;
7188     case 2:     return 2;
7189     case 3:     return 4;
7190     case 4:     return 8;
7191     }
7192 }
7193
7194 #define GET(N)  byte_get (start, N); start += N
7195 #define LEB()   read_leb128 (start, & length_return, 0); start += length_return
7196 #define SLEB()  read_leb128 (start, & length_return, 1); start += length_return
7197
7198 static int
7199 display_debug_frames (section, start, file)
7200      Elf32_Internal_Shdr * section;
7201      unsigned char *       start;
7202      FILE *                file ATTRIBUTE_UNUSED;
7203 {
7204   unsigned char * end = start + section->sh_size;
7205   unsigned char * section_start = start;
7206   Frame_Chunk *   chunks = 0;
7207   Frame_Chunk *   remembered_state = 0;
7208   Frame_Chunk *   rs;
7209   int             is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7210   int             length_return;
7211   int             max_regs = 0;
7212   int             addr_size = is_32bit_elf ? 4 : 8;
7213
7214   printf (_("The section %s contains:\n"), SECTION_NAME (section));
7215
7216   while (start < end)
7217     {
7218       unsigned char * saved_start;
7219       unsigned char * block_end;
7220       unsigned long   length;
7221       unsigned long   cie_id;
7222       Frame_Chunk *   fc;
7223       Frame_Chunk *   cie;
7224       int             need_col_headers = 1;
7225       unsigned char * augmentation_data = NULL;
7226       unsigned long   augmentation_data_len = 0;
7227       int             encoded_ptr_size = addr_size;
7228
7229       saved_start = start;
7230       length = byte_get (start, 4); start += 4;
7231
7232       if (length == 0)
7233         return 1;
7234
7235       block_end = saved_start + length + 4;
7236       cie_id = byte_get (start, 4); start += 4;
7237
7238       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7239         {
7240           int version;
7241
7242           fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7243           memset (fc, 0, sizeof (Frame_Chunk));
7244
7245           fc->next = chunks;
7246           chunks = fc;
7247           fc->chunk_start = saved_start;
7248           fc->ncols = 0;
7249           fc->col_type = (short int *) xmalloc (sizeof (short int));
7250           fc->col_offset = (int *) xmalloc (sizeof (int));
7251           frame_need_space (fc, max_regs-1);
7252
7253           version = *start++;
7254
7255           fc->augmentation = start;
7256           start = strchr (start, '\0') + 1;
7257
7258           if (fc->augmentation[0] == 'z')
7259             {
7260               fc->code_factor = LEB ();
7261               fc->data_factor = SLEB ();
7262               fc->ra = byte_get (start, 1); start += 1;
7263               augmentation_data_len = LEB ();
7264               augmentation_data = start;
7265               start += augmentation_data_len;
7266             }
7267           else if (strcmp (fc->augmentation, "eh") == 0)
7268             {
7269               start += addr_size;
7270               fc->code_factor = LEB ();
7271               fc->data_factor = SLEB ();
7272               fc->ra = byte_get (start, 1); start += 1;
7273             }
7274           else
7275             {
7276               fc->code_factor = LEB ();
7277               fc->data_factor = SLEB ();
7278               fc->ra = byte_get (start, 1); start += 1;
7279             }
7280           cie = fc;
7281
7282           if (do_debug_frames_interp)
7283             printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7284                     (unsigned long)(saved_start - section_start), length, cie_id,
7285                     fc->augmentation, fc->code_factor, fc->data_factor,
7286                     fc->ra);
7287           else
7288             {
7289               printf ("\n%08lx %08lx %08lx CIE\n",
7290                       (unsigned long)(saved_start - section_start), length, cie_id);
7291               printf ("  Version:               %d\n", version);
7292               printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
7293               printf ("  Code alignment factor: %u\n", fc->code_factor);
7294               printf ("  Data alignment factor: %d\n", fc->data_factor);
7295               printf ("  Return address column: %d\n", fc->ra);
7296
7297               if (augmentation_data_len)
7298                 {
7299                   unsigned long i;
7300                   printf ("  Augmentation data:    ");
7301                   for (i = 0; i < augmentation_data_len; ++i)
7302                     printf (" %02x", augmentation_data[i]);
7303                   putchar ('\n');
7304                 }
7305               putchar ('\n');
7306             }
7307
7308           if (augmentation_data_len)
7309             {
7310               unsigned char *p, *q;
7311               p = fc->augmentation + 1;
7312               q = augmentation_data;
7313
7314               while (1)
7315                 {
7316                   if (*p == 'L')
7317                     q++;
7318                   else if (*p == 'P')
7319                     q += 1 + size_of_encoded_value (*q);
7320                   else if (*p == 'R')
7321                     fc->fde_encoding = *q++;
7322                   else
7323                     break;
7324                   p++;
7325                 }
7326
7327               if (fc->fde_encoding)
7328                 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7329             }
7330
7331           frame_need_space (fc, fc->ra);
7332         }
7333       else
7334         {
7335           unsigned char *    look_for;
7336           static Frame_Chunk fde_fc;
7337
7338           fc = & fde_fc;
7339           memset (fc, 0, sizeof (Frame_Chunk));
7340
7341           look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
7342
7343           for (cie=chunks; cie ; cie = cie->next)
7344             if (cie->chunk_start == look_for)
7345               break;
7346
7347           if (!cie)
7348             {
7349               warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
7350                     cie_id, saved_start);
7351               start = block_end;
7352               fc->ncols = 0;
7353               fc->col_type = (short int *) xmalloc (sizeof (short int));
7354               fc->col_offset = (int *) xmalloc (sizeof (int));
7355               frame_need_space (fc, max_regs - 1);
7356               cie = fc;
7357               fc->augmentation = "";
7358               fc->fde_encoding = 0;
7359             }
7360           else
7361             {
7362               fc->ncols = cie->ncols;
7363               fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
7364               fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
7365               memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
7366               memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7367               fc->augmentation = cie->augmentation;
7368               fc->code_factor = cie->code_factor;
7369               fc->data_factor = cie->data_factor;
7370               fc->cfa_reg = cie->cfa_reg;
7371               fc->cfa_offset = cie->cfa_offset;
7372               fc->ra = cie->ra;
7373               frame_need_space (fc, max_regs-1);
7374               fc->fde_encoding = cie->fde_encoding;
7375             }
7376
7377           if (fc->fde_encoding)
7378             encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7379
7380           fc->pc_begin = byte_get (start, encoded_ptr_size);
7381           start += encoded_ptr_size;
7382           fc->pc_range = byte_get (start, encoded_ptr_size);
7383           start += encoded_ptr_size;
7384
7385           if (cie->augmentation[0] == 'z')
7386             {
7387               augmentation_data_len = LEB ();
7388               augmentation_data = start;
7389               start += augmentation_data_len;
7390             }
7391
7392           printf ("\n%08lx %08lx %08lx FDE cie=%08x pc=%08lx..%08lx\n",
7393                   (unsigned long)(saved_start - section_start), length, cie_id,
7394                   cie->chunk_start - section_start, fc->pc_begin,
7395                   fc->pc_begin + fc->pc_range);
7396           if (! do_debug_frames_interp && augmentation_data_len)
7397             {
7398               unsigned long i;
7399               printf ("  Augmentation data:    ");
7400               for (i = 0; i < augmentation_data_len; ++i)
7401                 printf (" %02x", augmentation_data[i]);
7402               putchar ('\n');
7403               putchar ('\n');
7404             }
7405         }
7406
7407       /* At this point, fc is the current chunk, cie (if any) is set, and we're
7408          about to interpret instructions for the chunk.  */
7409
7410       if (do_debug_frames_interp)
7411       {
7412         /* Start by making a pass over the chunk, allocating storage
7413            and taking note of what registers are used.  */
7414         unsigned char * tmp = start;
7415
7416         while (start < block_end)
7417           {
7418             unsigned op, opa;
7419             unsigned long reg;
7420
7421             op = * start ++;
7422             opa = op & 0x3f;
7423             if (op & 0xc0)
7424               op &= 0xc0;
7425
7426             /* Warning: if you add any more cases to this switch, be
7427                sure to add them to the corresponding switch below.  */
7428             switch (op)
7429               {
7430               case DW_CFA_advance_loc:
7431                 break;
7432               case DW_CFA_offset:
7433                 LEB ();
7434                 frame_need_space (fc, opa);
7435                 fc->col_type[opa] = DW_CFA_undefined;
7436                 break;
7437               case DW_CFA_restore:
7438                 frame_need_space (fc, opa);
7439                 fc->col_type[opa] = DW_CFA_undefined;
7440                 break;
7441               case DW_CFA_set_loc:
7442                 start += encoded_ptr_size;
7443                 break;
7444               case DW_CFA_advance_loc1:
7445                 start += 1;
7446                 break;
7447               case DW_CFA_advance_loc2:
7448                 start += 2;
7449                 break;
7450               case DW_CFA_advance_loc4:
7451                 start += 4;
7452                 break;
7453               case DW_CFA_offset_extended:
7454                 reg = LEB (); LEB ();
7455                 frame_need_space (fc, reg);
7456                 fc->col_type[reg] = DW_CFA_undefined;
7457                 break;
7458               case DW_CFA_restore_extended:
7459                 reg = LEB ();
7460                 frame_need_space (fc, reg);
7461                 fc->col_type[reg] = DW_CFA_undefined;
7462                 break;
7463               case DW_CFA_undefined:
7464                 reg = LEB ();
7465                 frame_need_space (fc, reg);
7466                 fc->col_type[reg] = DW_CFA_undefined;
7467                 break;
7468               case DW_CFA_same_value:
7469                 reg = LEB ();
7470                 frame_need_space (fc, reg);
7471                 fc->col_type[reg] = DW_CFA_undefined;
7472                 break;
7473               case DW_CFA_register:
7474                 reg = LEB (); LEB ();
7475                 frame_need_space (fc, reg);
7476                 fc->col_type[reg] = DW_CFA_undefined;
7477                 break;
7478               case DW_CFA_def_cfa:
7479                 LEB (); LEB ();
7480                 break;
7481               case DW_CFA_def_cfa_register:
7482                 LEB ();
7483                 break;
7484               case DW_CFA_def_cfa_offset:
7485                 LEB ();
7486                 break;
7487 #ifndef DW_CFA_GNU_args_size
7488 #define DW_CFA_GNU_args_size 0x2e
7489 #endif
7490               case DW_CFA_GNU_args_size:
7491                 LEB ();
7492                 break;
7493 #ifndef DW_CFA_GNU_negative_offset_extended
7494 #define DW_CFA_GNU_negative_offset_extended 0x2f
7495 #endif
7496               case DW_CFA_GNU_negative_offset_extended:
7497                 reg = LEB (); LEB ();
7498                 frame_need_space (fc, reg);
7499                 fc->col_type[reg] = DW_CFA_undefined;
7500
7501               default:
7502                 break;
7503               }
7504           }
7505         start = tmp;
7506       }
7507
7508       /* Now we know what registers are used, make a second pass over
7509          the chunk, this time actually printing out the info.  */
7510
7511       while (start < block_end)
7512         {
7513           unsigned op, opa;
7514           unsigned long ul, reg, roffs;
7515           long l, ofs;
7516           bfd_vma vma;
7517
7518           op = * start ++;
7519           opa = op & 0x3f;
7520           if (op & 0xc0)
7521             op &= 0xc0;
7522
7523             /* Warning: if you add any more cases to this switch, be
7524                sure to add them to the corresponding switch above.  */
7525           switch (op)
7526             {
7527             case DW_CFA_advance_loc:
7528               if (do_debug_frames_interp)
7529                 frame_display_row (fc, &need_col_headers, &max_regs);
7530               else
7531                 printf ("  DW_CFA_advance_loc: %d to %08lx\n",
7532                         opa * fc->code_factor,
7533                         fc->pc_begin + opa * fc->code_factor);
7534               fc->pc_begin += opa * fc->code_factor;
7535               break;
7536
7537             case DW_CFA_offset:
7538               roffs = LEB ();
7539               if (! do_debug_frames_interp)
7540                 printf ("  DW_CFA_offset: r%d at cfa%+ld\n",
7541                         opa, roffs * fc->data_factor);
7542               fc->col_type[opa] = DW_CFA_offset;
7543               fc->col_offset[opa] = roffs * fc->data_factor;
7544               break;
7545
7546             case DW_CFA_restore:
7547               if (! do_debug_frames_interp)
7548                 printf ("  DW_CFA_restore: r%d\n", opa);
7549               fc->col_type[opa] = cie->col_type[opa];
7550               fc->col_offset[opa] = cie->col_offset[opa];
7551               break;
7552
7553             case DW_CFA_set_loc:
7554               vma = byte_get (start, encoded_ptr_size);
7555               start += encoded_ptr_size;
7556               if (do_debug_frames_interp)
7557                 frame_display_row (fc, &need_col_headers, &max_regs);
7558               else
7559                 printf ("  DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
7560               fc->pc_begin = vma;
7561               break;
7562
7563             case DW_CFA_advance_loc1:
7564               ofs = byte_get (start, 1); start += 1;
7565               if (do_debug_frames_interp)
7566                 frame_display_row (fc, &need_col_headers, &max_regs);
7567               else
7568                 printf ("  DW_CFA_advance_loc1: %ld to %08lx\n",
7569                         ofs * fc->code_factor,
7570                         fc->pc_begin + ofs * fc->code_factor);
7571               fc->pc_begin += ofs * fc->code_factor;
7572               break;
7573
7574             case DW_CFA_advance_loc2:
7575               ofs = byte_get (start, 2); start += 2;
7576               if (do_debug_frames_interp)
7577                 frame_display_row (fc, &need_col_headers, &max_regs);
7578               else
7579                 printf ("  DW_CFA_advance_loc2: %ld to %08lx\n",
7580                         ofs * fc->code_factor,
7581                         fc->pc_begin + ofs * fc->code_factor);
7582               fc->pc_begin += ofs * fc->code_factor;
7583               break;
7584
7585             case DW_CFA_advance_loc4:
7586               ofs = byte_get (start, 4); start += 4;
7587               if (do_debug_frames_interp)
7588                 frame_display_row (fc, &need_col_headers, &max_regs);
7589               else
7590                 printf ("  DW_CFA_advance_loc4: %ld to %08lx\n",
7591                         ofs * fc->code_factor,
7592                         fc->pc_begin + ofs * fc->code_factor);
7593               fc->pc_begin += ofs * fc->code_factor;
7594               break;
7595
7596             case DW_CFA_offset_extended:
7597               reg = LEB ();
7598               roffs = LEB ();
7599               if (! do_debug_frames_interp)
7600                 printf ("  DW_CFA_offset_extended: r%ld at cfa%+ld\n",
7601                         reg, roffs * fc->data_factor);
7602               fc->col_type[reg] = DW_CFA_offset;
7603               fc->col_offset[reg] = roffs * fc->data_factor;
7604               break;
7605
7606             case DW_CFA_restore_extended:
7607               reg = LEB ();
7608               if (! do_debug_frames_interp)
7609                 printf ("  DW_CFA_restore_extended: r%ld\n", reg);
7610               fc->col_type[reg] = cie->col_type[reg];
7611               fc->col_offset[reg] = cie->col_offset[reg];
7612               break;
7613
7614             case DW_CFA_undefined:
7615               reg = LEB ();
7616               if (! do_debug_frames_interp)
7617                 printf ("  DW_CFA_undefined: r%ld\n", reg);
7618               fc->col_type[reg] = DW_CFA_undefined;
7619               fc->col_offset[reg] = 0;
7620               break;
7621
7622             case DW_CFA_same_value:
7623               reg = LEB ();
7624               if (! do_debug_frames_interp)
7625                 printf ("  DW_CFA_same_value: r%ld\n", reg);
7626               fc->col_type[reg] = DW_CFA_same_value;
7627               fc->col_offset[reg] = 0;
7628               break;
7629
7630             case DW_CFA_register:
7631               reg = LEB ();
7632               roffs = LEB ();
7633               if (! do_debug_frames_interp)
7634                 printf ("  DW_CFA_register: r%ld\n", reg);
7635               fc->col_type[reg] = DW_CFA_register;
7636               fc->col_offset[reg] = roffs;
7637               break;
7638
7639             case DW_CFA_remember_state:
7640               if (! do_debug_frames_interp)
7641                 printf ("  DW_CFA_remember_state\n");
7642               rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7643               rs->ncols = fc->ncols;
7644               rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
7645               rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7646               memcpy (rs->col_type, fc->col_type, rs->ncols);
7647               memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7648               rs->next = remembered_state;
7649               remembered_state = rs;
7650               break;
7651
7652             case DW_CFA_restore_state:
7653               if (! do_debug_frames_interp)
7654                 printf ("  DW_CFA_restore_state\n");
7655               rs = remembered_state;
7656               remembered_state = rs->next;
7657               frame_need_space (fc, rs->ncols-1);
7658               memcpy (fc->col_type, rs->col_type, rs->ncols);
7659               memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7660               free (rs->col_type);
7661               free (rs->col_offset);
7662               free (rs);
7663               break;
7664
7665             case DW_CFA_def_cfa:
7666               fc->cfa_reg = LEB ();
7667               fc->cfa_offset = LEB ();
7668               if (! do_debug_frames_interp)
7669                 printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
7670                         fc->cfa_reg, fc->cfa_offset);
7671               break;
7672
7673             case DW_CFA_def_cfa_register:
7674               fc->cfa_reg = LEB ();
7675               if (! do_debug_frames_interp)
7676                 printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
7677               break;
7678
7679             case DW_CFA_def_cfa_offset:
7680               fc->cfa_offset = LEB ();
7681               if (! do_debug_frames_interp)
7682                 printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
7683               break;
7684
7685             case DW_CFA_nop:
7686               if (! do_debug_frames_interp)
7687                 printf ("  DW_CFA_nop\n");
7688               break;
7689
7690 #ifndef DW_CFA_GNU_window_save
7691 #define DW_CFA_GNU_window_save 0x2d
7692 #endif
7693             case DW_CFA_GNU_window_save:
7694               if (! do_debug_frames_interp)
7695                 printf ("  DW_CFA_GNU_window_save\n");
7696               break;
7697
7698             case DW_CFA_GNU_args_size:
7699               ul = LEB ();
7700               if (! do_debug_frames_interp)
7701                 printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
7702               break;
7703
7704             case DW_CFA_GNU_negative_offset_extended:
7705               reg = LEB ();
7706               l = - LEB ();
7707               frame_need_space (fc, reg);
7708               if (! do_debug_frames_interp)
7709                 printf ("  DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
7710                         reg, l * fc->data_factor);
7711               fc->col_type[reg] = DW_CFA_offset;
7712               fc->col_offset[reg] = l * fc->data_factor;
7713               break;
7714
7715             default:
7716               fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7717               start = block_end;
7718             }
7719         }
7720
7721       if (do_debug_frames_interp)
7722         frame_display_row (fc, &need_col_headers, &max_regs);
7723
7724       start = block_end;
7725     }
7726
7727   printf ("\n");
7728
7729   return 1;
7730 }
7731
7732 #undef GET
7733 #undef LEB
7734 #undef SLEB
7735
7736 static int
7737 display_debug_not_supported (section, start, file)
7738      Elf32_Internal_Shdr * section;
7739      unsigned char *       start ATTRIBUTE_UNUSED;
7740      FILE *                file ATTRIBUTE_UNUSED;
7741 {
7742   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7743             SECTION_NAME (section));
7744
7745   return 1;
7746 }
7747
7748 /* Pre-scan the .debug_info section to record the size of address.
7749    When dumping the .debug_line, we use that size information, assuming
7750    that all compilation units have the same address size.  */
7751 static int
7752 prescan_debug_info (section, start, file)
7753      Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7754      unsigned char *       start;
7755      FILE *                file ATTRIBUTE_UNUSED;
7756 {
7757   DWARF2_External_CompUnit * external;
7758
7759   external = (DWARF2_External_CompUnit *) start;
7760
7761   debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7762   return 0;
7763 }
7764
7765   /* A structure containing the name of a debug section and a pointer
7766      to a function that can decode it.  The third field is a prescan
7767      function to be run over the section before displaying any of the
7768      sections.  */
7769 struct
7770 {
7771   char * name;
7772   int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7773   int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7774 }
7775 debug_displays[] =
7776 {
7777   { ".debug_info",        display_debug_info, prescan_debug_info },
7778   { ".debug_abbrev",      display_debug_abbrev, NULL },
7779   { ".debug_line",        display_debug_lines, NULL },
7780   { ".debug_aranges",     display_debug_aranges, NULL },
7781   { ".debug_pubnames",    display_debug_pubnames, NULL },
7782   { ".debug_frame",       display_debug_frames, NULL },
7783   { ".eh_frame",          display_debug_frames, NULL },
7784   { ".debug_macinfo",     display_debug_not_supported, NULL },
7785   { ".debug_str",         display_debug_not_supported, NULL },
7786   { ".debug_static_func", display_debug_not_supported, NULL },
7787   { ".debug_static_vars", display_debug_not_supported, NULL },
7788   { ".debug_types",       display_debug_not_supported, NULL },
7789   { ".debug_weaknames",   display_debug_not_supported, NULL }
7790 };
7791
7792 static int
7793 display_debug_section (section, file)
7794      Elf32_Internal_Shdr * section;
7795      FILE * file;
7796 {
7797   char *          name = SECTION_NAME (section);
7798   bfd_size_type   length;
7799   unsigned char * start;
7800   int             i;
7801
7802   length = section->sh_size;
7803   if (length == 0)
7804     {
7805       printf (_("\nSection '%s' has no debugging data.\n"), name);
7806       return 0;
7807     }
7808
7809   start = (unsigned char *) get_data (NULL, file, section->sh_offset, length, 
7810                                       _("debug section data"));
7811   if (!start)
7812     return 0;
7813
7814   /* See if we know how to display the contents of this section.  */
7815   if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7816     name = ".debug_info";
7817
7818   for (i = NUM_ELEM (debug_displays); i--;)
7819     if (strcmp (debug_displays[i].name, name) == 0)
7820       {
7821         debug_displays[i].display (section, start, file);
7822         break;
7823       }
7824
7825   if (i == -1)
7826     printf (_("Unrecognised debug section: %s\n"), name);
7827
7828   free (start);
7829
7830   /* If we loaded in the abbrev section at some point,
7831      we must release it here.  */
7832   if (first_abbrev != NULL)
7833     free_abbrevs ();
7834
7835   return 1;
7836 }
7837
7838 static int
7839 process_section_contents (file)
7840      FILE * file;
7841 {
7842   Elf32_Internal_Shdr * section;
7843   unsigned int  i;
7844
7845   if (! do_dump)
7846     return 1;
7847
7848   /* Pre-scan the debug sections to find some debug information not
7849      present in some of them.  For the .debug_line, we must find out the
7850      size of address (specified in .debug_info and .debug_aranges).  */
7851   for (i = 0, section = section_headers;
7852        i < elf_header.e_shnum && i < num_dump_sects;
7853        i ++, section ++)
7854     {
7855       char *    name = SECTION_NAME (section);
7856       int       j;
7857
7858       if (section->sh_size == 0)
7859         continue;
7860
7861       /* See if there is some pre-scan operation for this section.  */
7862       for (j = NUM_ELEM (debug_displays); j--;)
7863         if (strcmp (debug_displays[j].name, name) == 0)
7864           {
7865             if (debug_displays[j].prescan != NULL)
7866               {
7867                 bfd_size_type   length;
7868                 unsigned char * start;
7869
7870                 length = section->sh_size;
7871                 start = ((unsigned char *)
7872                          get_data (NULL, file, section->sh_offset, length, 
7873                                    _("debug section data")));
7874                 if (!start)
7875                   return 0;
7876
7877                 debug_displays[j].prescan (section, start, file);
7878                 free (start);
7879               }
7880
7881             break;
7882           }
7883     }
7884
7885   for (i = 0, section = section_headers;
7886        i < elf_header.e_shnum && i < num_dump_sects;
7887        i ++, section ++)
7888     {
7889 #ifdef SUPPORT_DISASSEMBLY
7890       if (dump_sects[i] & DISASS_DUMP)
7891         disassemble_section (section, file);
7892 #endif
7893       if (dump_sects[i] & HEX_DUMP)
7894         dump_section (section, file);
7895
7896       if (dump_sects[i] & DEBUG_DUMP)
7897         display_debug_section (section, file);
7898     }
7899
7900   if (i < num_dump_sects)
7901     warn (_("Some sections were not dumped because they do not exist!\n"));
7902
7903   return 1;
7904 }
7905
7906 static void
7907 process_mips_fpe_exception (mask)
7908      int mask;
7909 {
7910   if (mask)
7911     {
7912       int first = 1;
7913       if (mask & OEX_FPU_INEX)
7914         fputs ("INEX", stdout), first = 0;
7915       if (mask & OEX_FPU_UFLO)
7916         printf ("%sUFLO", first ? "" : "|"), first = 0;
7917       if (mask & OEX_FPU_OFLO)
7918         printf ("%sOFLO", first ? "" : "|"), first = 0;
7919       if (mask & OEX_FPU_DIV0)
7920         printf ("%sDIV0", first ? "" : "|"), first = 0;
7921       if (mask & OEX_FPU_INVAL)
7922         printf ("%sINVAL", first ? "" : "|");
7923     }
7924   else
7925     fputs ("0", stdout);
7926 }
7927
7928 static int
7929 process_mips_specific (file)
7930      FILE * file;
7931 {
7932   Elf_Internal_Dyn * entry;
7933   size_t liblist_offset = 0;
7934   size_t liblistno = 0;
7935   size_t conflictsno = 0;
7936   size_t options_offset = 0;
7937   size_t conflicts_offset = 0;
7938
7939   /* We have a lot of special sections.  Thanks SGI!  */
7940   if (dynamic_segment == NULL)
7941     /* No information available.  */
7942     return 0;
7943
7944   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7945     switch (entry->d_tag)
7946       {
7947       case DT_MIPS_LIBLIST:
7948         liblist_offset = entry->d_un.d_val - loadaddr;
7949         break;
7950       case DT_MIPS_LIBLISTNO:
7951         liblistno = entry->d_un.d_val;
7952         break;
7953       case DT_MIPS_OPTIONS:
7954         options_offset = entry->d_un.d_val - loadaddr;
7955         break;
7956       case DT_MIPS_CONFLICT:
7957         conflicts_offset = entry->d_un.d_val - loadaddr;
7958         break;
7959       case DT_MIPS_CONFLICTNO:
7960         conflictsno = entry->d_un.d_val;
7961         break;
7962       default:
7963         break;
7964       }
7965
7966   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7967     {
7968       Elf32_External_Lib * elib;
7969       size_t cnt;
7970
7971       elib = ((Elf32_External_Lib *)
7972               get_data (NULL, file, liblist_offset,
7973                         liblistno * sizeof (Elf32_External_Lib),
7974                         _("liblist")));
7975       if (elib)
7976         {
7977           printf ("\nSection '.liblist' contains %lu entries:\n",
7978                   (unsigned long) liblistno);
7979           fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
7980                  stdout);
7981
7982           for (cnt = 0; cnt < liblistno; ++cnt)
7983             {
7984               Elf32_Lib liblist;
7985               time_t time;
7986               char timebuf[20];
7987               struct tm * tmp;
7988
7989               liblist.l_name = BYTE_GET (elib[cnt].l_name);
7990               time = BYTE_GET (elib[cnt].l_time_stamp);
7991               liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7992               liblist.l_version = BYTE_GET (elib[cnt].l_version);
7993               liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7994
7995               tmp = gmtime (&time);
7996               sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7997                        tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7998                        tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7999
8000               printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
8001                       dynamic_strings + liblist.l_name, timebuf,
8002                       liblist.l_checksum, liblist.l_version);
8003
8004               if (liblist.l_flags == 0)
8005                 puts (" NONE");
8006               else
8007                 {
8008                   static const struct
8009                   {
8010                     const char * name;
8011                     int bit;
8012                   }
8013                   l_flags_vals[] =
8014                   {
8015                     { " EXACT_MATCH", LL_EXACT_MATCH },
8016                     { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8017                     { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8018                     { " EXPORTS", LL_EXPORTS },
8019                     { " DELAY_LOAD", LL_DELAY_LOAD },
8020                     { " DELTA", LL_DELTA }
8021                   };
8022                   int flags = liblist.l_flags;
8023                   size_t fcnt;
8024
8025                   for (fcnt = 0;
8026                        fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8027                        ++fcnt)
8028                     if ((flags & l_flags_vals[fcnt].bit) != 0)
8029                       {
8030                         fputs (l_flags_vals[fcnt].name, stdout);
8031                         flags ^= l_flags_vals[fcnt].bit;
8032                       }
8033                   if (flags != 0)
8034                     printf (" %#x", (unsigned int) flags);
8035
8036                   puts ("");
8037                 }
8038             }
8039
8040           free (elib);
8041         }
8042     }
8043
8044   if (options_offset != 0)
8045     {
8046       Elf_External_Options * eopt;
8047       Elf_Internal_Shdr *    sect = section_headers;
8048       Elf_Internal_Options * iopt;
8049       Elf_Internal_Options * option;
8050       size_t offset;
8051       int cnt;
8052
8053       /* Find the section header so that we get the size.  */
8054       while (sect->sh_type != SHT_MIPS_OPTIONS)
8055         ++ sect;
8056
8057       eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
8058                                                 sect->sh_size, _("options"));
8059       if (eopt)
8060         {
8061           iopt = ((Elf_Internal_Options *)
8062                   malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
8063           if (iopt == NULL)
8064             {
8065               error (_("Out of memory"));
8066               return 0;
8067             }
8068
8069           offset = cnt = 0;
8070           option = iopt;
8071
8072           while (offset < sect->sh_size)
8073             {
8074               Elf_External_Options * eoption;
8075
8076               eoption = (Elf_External_Options *) ((char *) eopt + offset);
8077
8078               option->kind = BYTE_GET (eoption->kind);
8079               option->size = BYTE_GET (eoption->size);
8080               option->section = BYTE_GET (eoption->section);
8081               option->info = BYTE_GET (eoption->info);
8082
8083               offset += option->size;
8084
8085               ++option;
8086               ++cnt;
8087             }
8088
8089           printf (_("\nSection '%s' contains %d entries:\n"),
8090                   SECTION_NAME (sect), cnt);
8091
8092           option = iopt;
8093
8094           while (cnt-- > 0)
8095             {
8096               size_t len;
8097
8098               switch (option->kind)
8099                 {
8100                 case ODK_NULL:
8101                   /* This shouldn't happen.  */
8102                   printf (" NULL       %d %lx", option->section, option->info);
8103                   break;
8104                 case ODK_REGINFO:
8105                   printf (" REGINFO    ");
8106                   if (elf_header.e_machine == EM_MIPS)
8107                     {
8108                       /* 32bit form.  */
8109                       Elf32_External_RegInfo * ereg;
8110                       Elf32_RegInfo            reginfo;
8111
8112                       ereg = (Elf32_External_RegInfo *) (option + 1);
8113                       reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8114                       reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8115                       reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8116                       reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8117                       reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8118                       reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8119
8120                       printf ("GPR %08lx  GP 0x%lx\n",
8121                               reginfo.ri_gprmask,
8122                               (unsigned long) reginfo.ri_gp_value);
8123                       printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
8124                               reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8125                               reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8126                     }
8127                   else
8128                     {
8129                       /* 64 bit form.  */
8130                       Elf64_External_RegInfo * ereg;
8131                       Elf64_Internal_RegInfo reginfo;
8132
8133                       ereg = (Elf64_External_RegInfo *) (option + 1);
8134                       reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
8135                       reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8136                       reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8137                       reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8138                       reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8139                       reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
8140
8141                       printf ("GPR %08lx  GP 0x",
8142                               reginfo.ri_gprmask);
8143                       printf_vma (reginfo.ri_gp_value);
8144                       printf ("\n");
8145
8146                       printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
8147                               reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8148                               reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8149                     }
8150                   ++option;
8151                   continue;
8152                 case ODK_EXCEPTIONS:
8153                   fputs (" EXCEPTIONS fpe_min(", stdout);
8154                   process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8155                   fputs (") fpe_max(", stdout);
8156                   process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8157                   fputs (")", stdout);
8158
8159                   if (option->info & OEX_PAGE0)
8160                     fputs (" PAGE0", stdout);
8161                   if (option->info & OEX_SMM)
8162                     fputs (" SMM", stdout);
8163                   if (option->info & OEX_FPDBUG)
8164                     fputs (" FPDBUG", stdout);
8165                   if (option->info & OEX_DISMISS)
8166                     fputs (" DISMISS", stdout);
8167                   break;
8168                 case ODK_PAD:
8169                   fputs (" PAD       ", stdout);
8170                   if (option->info & OPAD_PREFIX)
8171                     fputs (" PREFIX", stdout);
8172                   if (option->info & OPAD_POSTFIX)
8173                     fputs (" POSTFIX", stdout);
8174                   if (option->info & OPAD_SYMBOL)
8175                     fputs (" SYMBOL", stdout);
8176                   break;
8177                 case ODK_HWPATCH:
8178                   fputs (" HWPATCH   ", stdout);
8179                   if (option->info & OHW_R4KEOP)
8180                     fputs (" R4KEOP", stdout);
8181                   if (option->info & OHW_R8KPFETCH)
8182                     fputs (" R8KPFETCH", stdout);
8183                   if (option->info & OHW_R5KEOP)
8184                     fputs (" R5KEOP", stdout);
8185                   if (option->info & OHW_R5KCVTL)
8186                     fputs (" R5KCVTL", stdout);
8187                   break;
8188                 case ODK_FILL:
8189                   fputs (" FILL       ", stdout);
8190                   /* XXX Print content of info word?  */
8191                   break;
8192                 case ODK_TAGS:
8193                   fputs (" TAGS       ", stdout);
8194                   /* XXX Print content of info word?  */
8195                   break;
8196                 case ODK_HWAND:
8197                   fputs (" HWAND     ", stdout);
8198                   if (option->info & OHWA0_R4KEOP_CHECKED)
8199                     fputs (" R4KEOP_CHECKED", stdout);
8200                   if (option->info & OHWA0_R4KEOP_CLEAN)
8201                     fputs (" R4KEOP_CLEAN", stdout);
8202                   break;
8203                 case ODK_HWOR:
8204                   fputs (" HWOR      ", stdout);
8205                   if (option->info & OHWA0_R4KEOP_CHECKED)
8206                     fputs (" R4KEOP_CHECKED", stdout);
8207                   if (option->info & OHWA0_R4KEOP_CLEAN)
8208                     fputs (" R4KEOP_CLEAN", stdout);
8209                   break;
8210                 case ODK_GP_GROUP:
8211                   printf (" GP_GROUP  %#06lx  self-contained %#06lx",
8212                           option->info & OGP_GROUP,
8213                           (option->info & OGP_SELF) >> 16);
8214                   break;
8215                 case ODK_IDENT:
8216                   printf (" IDENT     %#06lx  self-contained %#06lx",
8217                           option->info & OGP_GROUP,
8218                           (option->info & OGP_SELF) >> 16);
8219                   break;
8220                 default:
8221                   /* This shouldn't happen.  */
8222                   printf (" %3d ???     %d %lx",
8223                           option->kind, option->section, option->info);
8224                   break;
8225                 }
8226
8227               len = sizeof (* eopt);
8228               while (len < option->size)
8229                 if (((char *) option)[len] >= ' '
8230                     && ((char *) option)[len] < 0x7f)
8231                   printf ("%c", ((char *) option)[len++]);
8232                 else
8233                   printf ("\\%03o", ((char *) option)[len++]);
8234
8235               fputs ("\n", stdout);
8236               ++option;
8237             }
8238
8239           free (eopt);
8240         }
8241     }
8242
8243   if (conflicts_offset != 0 && conflictsno != 0)
8244     {
8245       Elf32_Conflict * iconf;
8246       size_t cnt;
8247
8248       if (dynamic_symbols == NULL)
8249         {
8250           error (_("conflict list with without table"));
8251           return 0;
8252         }
8253
8254       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
8255       if (iconf == NULL)
8256         {
8257           error (_("Out of memory"));
8258           return 0;
8259         }
8260
8261       if (is_32bit_elf)
8262         {
8263           Elf32_External_Conflict * econf32;
8264
8265           econf32 = ((Elf32_External_Conflict *)
8266                      get_data (NULL, file, conflicts_offset,
8267                                conflictsno * sizeof (* econf32),
8268                                _("conflict")));
8269           if (!econf32)
8270             return 0;
8271
8272           for (cnt = 0; cnt < conflictsno; ++cnt)
8273             iconf[cnt] = BYTE_GET (econf32[cnt]);
8274
8275           free (econf32);
8276         }
8277       else
8278         {
8279           Elf64_External_Conflict * econf64;
8280
8281           econf64 = ((Elf64_External_Conflict *)
8282                      get_data (NULL, file, conflicts_offset,
8283                                conflictsno * sizeof (* econf64),
8284                                _("conflict")));
8285           if (!econf64)
8286             return 0;
8287
8288           for (cnt = 0; cnt < conflictsno; ++cnt)
8289             iconf[cnt] = BYTE_GET (econf64[cnt]);
8290
8291           free (econf64);
8292         }
8293
8294       printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8295       puts (_("  Num:    Index       Value  Name"));
8296
8297       for (cnt = 0; cnt < conflictsno; ++cnt)
8298         {
8299           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
8300
8301           printf ("%5lu: %8lu  ", (unsigned long) cnt, iconf[cnt]);
8302           print_vma (psym->st_value, FULL_HEX);
8303           printf ("  %s\n", dynamic_strings + psym->st_name);
8304         }
8305
8306       free (iconf);
8307     }
8308
8309   return 1;
8310 }
8311
8312 static char *
8313 get_note_type (e_type)
8314      unsigned e_type;
8315 {
8316   static char buff[64];
8317
8318   switch (e_type)
8319     {
8320     case NT_PRSTATUS:   return _("NT_PRSTATUS (prstatus structure)");
8321     case NT_FPREGSET:   return _("NT_FPREGSET (floating point registers)");
8322     case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
8323     case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
8324     case NT_PRXFPREG:   return _("NT_PRXFPREG (user_xfpregs structure)");
8325     case NT_PSTATUS:    return _("NT_PSTATUS (pstatus structure)");
8326     case NT_FPREGS:     return _("NT_FPREGS (floating point registers)");
8327     case NT_PSINFO:     return _("NT_PSINFO (psinfo structure)");
8328     case NT_LWPSTATUS:  return _("NT_LWPSTATUS (lwpstatus_t structure)");
8329     case NT_LWPSINFO:   return _("NT_LWPSINFO (lwpsinfo_t structure)");
8330     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
8331     default:
8332       sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8333       return buff;
8334     }
8335 }
8336
8337 /* Note that by the ELF standard, the name field is already null byte
8338    terminated, and namesz includes the terminating null byte.
8339    I.E. the value of namesz for the name "FSF" is 4.
8340
8341    If the value of namesz is zero, there is no name present. */
8342 static int
8343 process_note (pnote)
8344   Elf32_Internal_Note * pnote;
8345 {
8346   printf ("  %s\t\t0x%08lx\t%s\n",
8347           pnote->namesz ? pnote->namedata : "(NONE)",
8348           pnote->descsz, get_note_type (pnote->type));
8349   return 1;
8350 }
8351
8352
8353 static int
8354 process_corefile_note_segment (file, offset, length)
8355      FILE * file;
8356      bfd_vma offset;
8357      bfd_vma length;
8358 {
8359   Elf_External_Note *  pnotes;
8360   Elf_External_Note *  external;
8361   int                  res = 1;
8362
8363   if (length <= 0)
8364     return 0;
8365
8366   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
8367                                            _("notes"));
8368   if (!pnotes)
8369     return 0;
8370
8371   external = pnotes;
8372
8373   printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
8374           (unsigned long) offset, (unsigned long) length);
8375   printf (_("  Owner\t\tData size\tDescription\n"));
8376
8377   while (external < (Elf_External_Note *)((char *) pnotes + length))
8378     {
8379       Elf32_Internal_Note inote;
8380       char * temp = NULL;
8381
8382       inote.type     = BYTE_GET (external->type);
8383       inote.namesz   = BYTE_GET (external->namesz);
8384       inote.namedata = external->name;
8385       inote.descsz   = BYTE_GET (external->descsz);
8386       inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8387       inote.descpos  = offset + (inote.descdata - (char *) pnotes);
8388
8389       external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8390
8391       /* Verify that name is null terminated.  It appears that at least
8392          one version of Linux (RedHat 6.0) generates corefiles that don't
8393          comply with the ELF spec by failing to include the null byte in
8394          namesz.  */
8395       if (inote.namedata[inote.namesz] != '\0')
8396         {
8397           temp = malloc (inote.namesz + 1);
8398
8399           if (temp == NULL)
8400             {
8401               error (_("Out of memory\n"));
8402               res = 0;
8403               break;
8404             }
8405
8406           strncpy (temp, inote.namedata, inote.namesz);
8407           temp[inote.namesz] = 0;
8408
8409           /* warn (_("'%s' NOTE name not properly null terminated\n"), temp);  */
8410           inote.namedata = temp;
8411         }
8412
8413       res &= process_note (& inote);
8414
8415       if (temp != NULL)
8416         {
8417           free (temp);
8418           temp = NULL;
8419         }
8420     }
8421
8422   free (pnotes);
8423
8424   return res;
8425 }
8426
8427 static int
8428 process_corefile_note_segments (file)
8429      FILE * file;
8430 {
8431   Elf_Internal_Phdr * program_headers;
8432   Elf_Internal_Phdr * segment;
8433   unsigned int        i;
8434   int                 res = 1;
8435
8436   program_headers = (Elf_Internal_Phdr *) malloc
8437     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8438
8439   if (program_headers == NULL)
8440     {
8441       error (_("Out of memory\n"));
8442       return 0;
8443     }
8444
8445   if (is_32bit_elf)
8446     i = get_32bit_program_headers (file, program_headers);
8447   else
8448     i = get_64bit_program_headers (file, program_headers);
8449
8450   if (i == 0)
8451     {
8452       free (program_headers);
8453       return 0;
8454     }
8455
8456   for (i = 0, segment = program_headers;
8457        i < elf_header.e_phnum;
8458        i ++, segment ++)
8459     {
8460       if (segment->p_type == PT_NOTE)
8461         res &= process_corefile_note_segment (file,
8462                                               (bfd_vma) segment->p_offset,
8463                                               (bfd_vma) segment->p_filesz);
8464     }
8465
8466   free (program_headers);
8467
8468   return res;
8469 }
8470
8471 static int
8472 process_corefile_contents (file)
8473      FILE * file;
8474 {
8475   /* If we have not been asked to display the notes then do nothing.  */
8476   if (! do_notes)
8477     return 1;
8478
8479   /* If file is not a core file then exit.  */
8480   if (elf_header.e_type != ET_CORE)
8481     return 1;
8482
8483   /* No program headers means no NOTE segment.  */
8484   if (elf_header.e_phnum == 0)
8485     {
8486       printf (_("No note segments present in the core file.\n"));
8487       return 1;
8488    }
8489
8490   return process_corefile_note_segments (file);
8491 }
8492
8493 static int
8494 process_arch_specific (file)
8495      FILE * file;
8496 {
8497   if (! do_arch)
8498     return 1;
8499
8500   switch (elf_header.e_machine)
8501     {
8502     case EM_MIPS:
8503     case EM_MIPS_RS3_LE:
8504       return process_mips_specific (file);
8505       break;
8506     default:
8507       break;
8508     }
8509   return 1;
8510 }
8511
8512 static int
8513 get_file_header (file)
8514      FILE * file;
8515 {
8516   /* Read in the identity array.  */
8517   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
8518     return 0;
8519
8520   /* Determine how to read the rest of the header.  */
8521   switch (elf_header.e_ident [EI_DATA])
8522     {
8523     default: /* fall through */
8524     case ELFDATANONE: /* fall through */
8525     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8526     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8527     }
8528
8529   /* For now we only support 32 bit and 64 bit ELF files.  */
8530   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8531
8532   /* Read in the rest of the header.  */
8533   if (is_32bit_elf)
8534     {
8535       Elf32_External_Ehdr ehdr32;
8536
8537       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8538         return 0;
8539
8540       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
8541       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
8542       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
8543       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
8544       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
8545       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
8546       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
8547       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
8548       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8549       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
8550       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8551       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
8552       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
8553     }
8554   else
8555     {
8556       Elf64_External_Ehdr ehdr64;
8557
8558       /* If we have been compiled with sizeof (bfd_vma) == 4, then
8559          we will not be able to cope with the 64bit data found in
8560          64 ELF files.  Detect this now and abort before we start
8561          overwritting things.  */
8562       if (sizeof (bfd_vma) < 8)
8563         {
8564           error (_("This instance of readelf has been built without support for a\n"));
8565           error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8566           return 0;
8567         }
8568
8569       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8570         return 0;
8571
8572       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
8573       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
8574       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
8575       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
8576       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
8577       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
8578       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
8579       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
8580       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8581       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
8582       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8583       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
8584       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
8585     }
8586
8587   return 1;
8588 }
8589
8590 static void
8591 process_file (file_name)
8592      char * file_name;
8593 {
8594   FILE *       file;
8595   struct stat  statbuf;
8596   unsigned int i;
8597
8598   if (stat (file_name, & statbuf) < 0)
8599     {
8600       error (_("Cannot stat input file %s.\n"), file_name);
8601       return;
8602     }
8603
8604   file = fopen (file_name, "rb");
8605   if (file == NULL)
8606     {
8607       error (_("Input file %s not found.\n"), file_name);
8608       return;
8609     }
8610
8611   if (! get_file_header (file))
8612     {
8613       error (_("%s: Failed to read file header\n"), file_name);
8614       fclose (file);
8615       return;
8616     }
8617
8618   /* Initialise per file variables.  */
8619   for (i = NUM_ELEM (version_info); i--;)
8620     version_info[i] = 0;
8621
8622   for (i = NUM_ELEM (dynamic_info); i--;)
8623     dynamic_info[i] = 0;
8624
8625   /* Process the file.  */
8626   if (show_name)
8627     printf (_("\nFile: %s\n"), file_name);
8628
8629   if (! process_file_header ())
8630     {
8631       fclose (file);
8632       return;
8633     }
8634
8635   process_section_headers (file);
8636
8637   process_program_headers (file);
8638
8639   process_dynamic_segment (file);
8640
8641   process_relocs (file);
8642
8643   process_unwind (file);
8644
8645   process_symbol_table (file);
8646
8647   process_syminfo (file);
8648
8649   process_version_sections (file);
8650
8651   process_section_contents (file);
8652
8653   process_corefile_contents (file);
8654
8655   process_arch_specific (file);
8656
8657   fclose (file);
8658
8659   if (section_headers)
8660     {
8661       free (section_headers);
8662       section_headers = NULL;
8663     }
8664
8665   if (string_table)
8666     {
8667       free (string_table);
8668       string_table = NULL;
8669       string_table_length = 0;
8670     }
8671
8672   if (dynamic_strings)
8673     {
8674       free (dynamic_strings);
8675       dynamic_strings = NULL;
8676     }
8677
8678   if (dynamic_symbols)
8679     {
8680       free (dynamic_symbols);
8681       dynamic_symbols = NULL;
8682       num_dynamic_syms = 0;
8683     }
8684
8685   if (dynamic_syminfo)
8686     {
8687       free (dynamic_syminfo);
8688       dynamic_syminfo = NULL;
8689     }
8690 }
8691
8692 #ifdef SUPPORT_DISASSEMBLY
8693 /* Needed by the i386 disassembler.  For extra credit, someone could
8694    fix this so that we insert symbolic addresses here, esp for GOT/PLT
8695    symbols */
8696
8697 void
8698 print_address (unsigned int addr, FILE * outfile)
8699 {
8700   fprintf (outfile,"0x%8.8x", addr);
8701 }
8702
8703 /* Needed by the i386 disassembler. */
8704 void
8705 db_task_printsym (unsigned int addr)
8706 {
8707   print_address (addr, stderr);
8708 }
8709 #endif
8710
8711 int
8712 main (argc, argv)
8713      int     argc;
8714      char ** argv;
8715 {
8716 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8717   setlocale (LC_MESSAGES, "");
8718 #endif
8719   bindtextdomain (PACKAGE, LOCALEDIR);
8720   textdomain (PACKAGE);
8721
8722   parse_args (argc, argv);
8723
8724   if (optind < (argc - 1))
8725     show_name = 1;
8726
8727   while (optind < argc)
8728     process_file (argv [optind ++]);
8729
8730   if (dump_sects != NULL)
8731     free (dump_sects);
8732
8733   return 0;
8734 }