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