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