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