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