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