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