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