* readelf.c (get_elf_class): Fix ISO portability glitch.
[platform/upstream/binutils.git] / binutils / readelf.c
1 /* readelf.c -- display contents of an ELF format file
2    Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
4    Originally developed by Eric Youngdale <eric@andante.jic.com>
5    Modifications by Nick Clifton <nickc@redhat.com>
6
7    This file is part of GNU Binutils.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22    02111-1307, USA.  */
23 \f
24
25 #include <assert.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <stdio.h>
29 #include <time.h>
30
31 #if __GNUC__ >= 2
32 /* Define BFD64 here, even if our default architecture is 32 bit ELF
33    as this will allow us to read in and parse 64bit and 32bit ELF files.
34    Only do this if we belive that the compiler can support a 64 bit
35    data type.  For now we only rely on GCC being able to do this.  */
36 #define BFD64
37 #endif
38
39 #include "bfd.h"
40
41 #include "elf/common.h"
42 #include "elf/external.h"
43 #include "elf/internal.h"
44 #include "elf/dwarf2.h"
45
46 /* The following headers use the elf/reloc-macros.h file to
47    automatically generate relocation recognition functions
48    such as elf_mips_reloc_type()  */
49
50 #define RELOC_MACROS_GEN_FUNC
51
52 #include "elf/i386.h"
53 #include "elf/v850.h"
54 #include "elf/ppc.h"
55 #include "elf/mips.h"
56 #include "elf/alpha.h"
57 #include "elf/arm.h"
58 #include "elf/m68k.h"
59 #include "elf/sparc.h"
60 #include "elf/m32r.h"
61 #include "elf/d10v.h"
62 #include "elf/d30v.h"
63 #include "elf/sh.h"
64 #include "elf/mn10200.h"
65 #include "elf/mn10300.h"
66 #include "elf/hppa.h"
67 #include "elf/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, int));
237 static const char *       get_elf_class               PARAMS ((unsigned int));
238 static const char *       get_data_encoding           PARAMS ((unsigned int));
239 static const char *       get_osabi_name              PARAMS ((unsigned int));
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      int         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 int 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 int 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 int 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 static const char *debug_str;
6282 static bfd_vma debug_str_size;
6283
6284 /* FIXME:  There are better and more effiecint ways to handle
6285    these structures.  For now though, I just want something that
6286    is simple to implement.  */
6287 typedef struct abbrev_attr
6288 {
6289   unsigned long        attribute;
6290   unsigned long        form;
6291   struct abbrev_attr * next;
6292 }
6293 abbrev_attr;
6294
6295 typedef struct abbrev_entry
6296 {
6297   unsigned long          entry;
6298   unsigned long          tag;
6299   int                    children;
6300   struct abbrev_attr *   first_attr;
6301   struct abbrev_attr *   last_attr;
6302   struct abbrev_entry *  next;
6303 }
6304 abbrev_entry;
6305
6306 static abbrev_entry * first_abbrev = NULL;
6307 static abbrev_entry * last_abbrev = NULL;
6308
6309 static void
6310 free_abbrevs PARAMS ((void))
6311 {
6312   abbrev_entry * abbrev;
6313
6314   for (abbrev = first_abbrev; abbrev;)
6315     {
6316       abbrev_entry * next = abbrev->next;
6317       abbrev_attr  * attr;
6318
6319       for (attr = abbrev->first_attr; attr;)
6320         {
6321           abbrev_attr * next = attr->next;
6322
6323           free (attr);
6324           attr = next;
6325         }
6326
6327       free (abbrev);
6328       abbrev = next;
6329     }
6330
6331   last_abbrev = first_abbrev = NULL;
6332 }
6333
6334 static void
6335 add_abbrev (number, tag, children)
6336      unsigned long number;
6337      unsigned long tag;
6338      int           children;
6339 {
6340   abbrev_entry * entry;
6341
6342   entry = (abbrev_entry *) malloc (sizeof (* entry));
6343
6344   if (entry == NULL)
6345     /* ugg */
6346     return;
6347
6348   entry->entry      = number;
6349   entry->tag        = tag;
6350   entry->children   = children;
6351   entry->first_attr = NULL;
6352   entry->last_attr  = NULL;
6353   entry->next       = NULL;
6354
6355   if (first_abbrev == NULL)
6356     first_abbrev = entry;
6357   else
6358     last_abbrev->next = entry;
6359
6360   last_abbrev = entry;
6361 }
6362
6363 static void
6364 add_abbrev_attr (attribute, form)
6365      unsigned long attribute;
6366      unsigned long form;
6367 {
6368   abbrev_attr * attr;
6369
6370   attr = (abbrev_attr *) malloc (sizeof (* attr));
6371
6372   if (attr == NULL)
6373     /* ugg */
6374     return;
6375
6376   attr->attribute = attribute;
6377   attr->form      = form;
6378   attr->next      = NULL;
6379
6380   if (last_abbrev->first_attr == NULL)
6381     last_abbrev->first_attr = attr;
6382   else
6383     last_abbrev->last_attr->next = attr;
6384
6385   last_abbrev->last_attr = attr;
6386 }
6387
6388 /* Processes the (partial) contents of a .debug_abbrev section.
6389    Returns NULL if the end of the section was encountered.
6390    Returns the address after the last byte read if the end of
6391    an abbreviation set was found.  */
6392
6393 static unsigned char *
6394 process_abbrev_section (start, end)
6395      unsigned char * start;
6396      unsigned char * end;
6397 {
6398   if (first_abbrev != NULL)
6399     return NULL;
6400
6401   while (start < end)
6402     {
6403       int           bytes_read;
6404       unsigned long entry;
6405       unsigned long tag;
6406       unsigned long attribute;
6407       int           children;
6408
6409       entry = read_leb128 (start, & bytes_read, 0);
6410       start += bytes_read;
6411
6412       /* A single zero is supposed to end the section according
6413          to the standard.  If there's more, then signal that to
6414          the caller.  */
6415       if (entry == 0)
6416         return start == end ? NULL : start;
6417
6418       tag = read_leb128 (start, & bytes_read, 0);
6419       start += bytes_read;
6420
6421       children = * start ++;
6422
6423       add_abbrev (entry, tag, children);
6424
6425       do
6426         {
6427           unsigned long form;
6428
6429           attribute = read_leb128 (start, & bytes_read, 0);
6430           start += bytes_read;
6431
6432           form = read_leb128 (start, & bytes_read, 0);
6433           start += bytes_read;
6434
6435           if (attribute != 0)
6436             add_abbrev_attr (attribute, form);
6437         }
6438       while (attribute != 0);
6439     }
6440
6441   return NULL;
6442 }
6443
6444
6445 static int
6446 display_debug_macinfo (section, start, file)
6447      Elf32_Internal_Shdr * section;
6448      unsigned char *       start;
6449      FILE *                file ATTRIBUTE_UNUSED;
6450 {
6451   unsigned char * end = start + section->sh_size;
6452   unsigned char * curr = start;
6453   unsigned int bytes_read;
6454   enum dwarf_macinfo_record_type op;
6455
6456   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6457
6458   while (curr < end)
6459     {
6460       unsigned int lineno;
6461       const char * string;
6462
6463       op = * curr;
6464       curr ++;
6465
6466       switch (op)
6467         {
6468         case DW_MACINFO_start_file:
6469           {
6470             unsigned int filenum;
6471
6472             lineno = read_leb128 (curr, & bytes_read, 0);
6473             curr += bytes_read;
6474             filenum = read_leb128 (curr, & bytes_read, 0);
6475             curr += bytes_read;
6476
6477             printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), lineno, filenum);
6478           }
6479           break;
6480
6481         case DW_MACINFO_end_file:
6482           printf (_(" DW_MACINFO_end_file\n"));
6483           break;
6484
6485         case DW_MACINFO_define:
6486           lineno = read_leb128 (curr, & bytes_read, 0);
6487           curr += bytes_read;
6488           string = curr;
6489           curr += strlen (string) + 1;
6490           printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), lineno, string);
6491           break;
6492
6493         case DW_MACINFO_undef:
6494           lineno = read_leb128 (curr, & bytes_read, 0);
6495           curr += bytes_read;
6496           string = curr;
6497           curr += strlen (string) + 1;
6498           printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), lineno, string);
6499           break;
6500
6501         case DW_MACINFO_vendor_ext:
6502           {
6503             unsigned int constant;
6504
6505             constant = read_leb128 (curr, & bytes_read, 0);
6506             curr += bytes_read;
6507             string = curr;
6508             curr += strlen (string) + 1;
6509             printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), constant, string);
6510           }
6511           break;
6512         }
6513     }
6514
6515   return 1;
6516 }
6517
6518
6519 static int
6520 display_debug_abbrev (section, start, file)
6521      Elf32_Internal_Shdr * section;
6522      unsigned char *       start;
6523      FILE *                file ATTRIBUTE_UNUSED;
6524 {
6525   abbrev_entry *  entry;
6526   unsigned char * end = start + section->sh_size;
6527
6528   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6529
6530   do
6531     {
6532       start = process_abbrev_section (start, end);
6533
6534       if (first_abbrev == NULL)
6535         continue;
6536
6537       printf (_("  Number TAG\n"));
6538
6539       for (entry = first_abbrev; entry; entry = entry->next)
6540         {
6541           abbrev_attr * attr;
6542
6543           printf (_("   %ld      %s    [%s]\n"),
6544                   entry->entry,
6545                   get_TAG_name (entry->tag),
6546                   entry->children ? _("has children") : _("no children"));
6547
6548           for (attr = entry->first_attr; attr; attr = attr->next)
6549             {
6550               printf (_("    %-18s %s\n"),
6551                       get_AT_name (attr->attribute),
6552                       get_FORM_name (attr->form));
6553             }
6554         }
6555
6556       free_abbrevs ();
6557     }
6558   while (start);
6559
6560   printf ("\n");
6561
6562   return 1;
6563 }
6564
6565
6566 static unsigned char *
6567 display_block (data, length)
6568      unsigned char * data;
6569      unsigned long   length;
6570 {
6571   printf (_(" %lu byte block: "), length);
6572
6573   while (length --)
6574     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
6575
6576   return data;
6577 }
6578
6579 static void
6580 decode_location_expression (data, pointer_size, length)
6581      unsigned char * data;
6582      unsigned int    pointer_size;
6583      unsigned long   length;
6584 {
6585   unsigned        op;
6586   int             bytes_read;
6587   unsigned long   uvalue;
6588   unsigned char * end = data + length;
6589
6590   while (data < end)
6591     {
6592       op = * data ++;
6593
6594       switch (op)
6595         {
6596         case DW_OP_addr:
6597           printf ("DW_OP_addr: %lx",
6598                   (unsigned long) byte_get (data, pointer_size));
6599           data += pointer_size;
6600           break;
6601         case DW_OP_deref:
6602           printf ("DW_OP_deref");
6603           break;
6604         case DW_OP_const1u:
6605           printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6606           break;
6607         case DW_OP_const1s:
6608           printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6609           break;
6610         case DW_OP_const2u:
6611           printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6612           data += 2;
6613           break;
6614         case DW_OP_const2s:
6615           printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6616           data += 2;
6617           break;
6618         case DW_OP_const4u:
6619           printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6620           data += 4;
6621           break;
6622         case DW_OP_const4s:
6623           printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6624           data += 4;
6625           break;
6626         case DW_OP_const8u:
6627           printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6628                   (unsigned long) byte_get (data + 4, 4));
6629           data += 8;
6630           break;
6631         case DW_OP_const8s:
6632           printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6633                   (long) byte_get (data + 4, 4));
6634           data += 8;
6635           break;
6636         case DW_OP_constu:
6637           printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6638           data += bytes_read;
6639           break;
6640         case DW_OP_consts:
6641           printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6642           data += bytes_read;
6643           break;
6644         case DW_OP_dup:
6645           printf ("DW_OP_dup");
6646           break;
6647         case DW_OP_drop:
6648           printf ("DW_OP_drop");
6649           break;
6650         case DW_OP_over:
6651           printf ("DW_OP_over");
6652           break;
6653         case DW_OP_pick:
6654           printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6655           break;
6656         case DW_OP_swap:
6657           printf ("DW_OP_swap");
6658           break;
6659         case DW_OP_rot:
6660           printf ("DW_OP_rot");
6661           break;
6662         case DW_OP_xderef:
6663           printf ("DW_OP_xderef");
6664           break;
6665         case DW_OP_abs:
6666           printf ("DW_OP_abs");
6667           break;
6668         case DW_OP_and:
6669           printf ("DW_OP_and");
6670           break;
6671         case DW_OP_div:
6672           printf ("DW_OP_div");
6673           break;
6674         case DW_OP_minus:
6675           printf ("DW_OP_minus");
6676           break;
6677         case DW_OP_mod:
6678           printf ("DW_OP_mod");
6679           break;
6680         case DW_OP_mul:
6681           printf ("DW_OP_mul");
6682           break;
6683         case DW_OP_neg:
6684           printf ("DW_OP_neg");
6685           break;
6686         case DW_OP_not:
6687           printf ("DW_OP_not");
6688           break;
6689         case DW_OP_or:
6690           printf ("DW_OP_or");
6691           break;
6692         case DW_OP_plus:
6693           printf ("DW_OP_plus");
6694           break;
6695         case DW_OP_plus_uconst:
6696           printf ("DW_OP_plus_uconst: %lu",
6697                   read_leb128 (data, &bytes_read, 0));
6698           data += bytes_read;
6699           break;
6700         case DW_OP_shl:
6701           printf ("DW_OP_shl");
6702           break;
6703         case DW_OP_shr:
6704           printf ("DW_OP_shr");
6705           break;
6706         case DW_OP_shra:
6707           printf ("DW_OP_shra");
6708           break;
6709         case DW_OP_xor:
6710           printf ("DW_OP_xor");
6711           break;
6712         case DW_OP_bra:
6713           printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6714           data += 2;
6715           break;
6716         case DW_OP_eq:
6717           printf ("DW_OP_eq");
6718           break;
6719         case DW_OP_ge:
6720           printf ("DW_OP_ge");
6721           break;
6722         case DW_OP_gt:
6723           printf ("DW_OP_gt");
6724           break;
6725         case DW_OP_le:
6726           printf ("DW_OP_le");
6727           break;
6728         case DW_OP_lt:
6729           printf ("DW_OP_lt");
6730           break;
6731         case DW_OP_ne:
6732           printf ("DW_OP_ne");
6733           break;
6734         case DW_OP_skip:
6735           printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6736           data += 2;
6737           break;
6738
6739         case DW_OP_lit0:
6740         case DW_OP_lit1:
6741         case DW_OP_lit2:
6742         case DW_OP_lit3:
6743         case DW_OP_lit4:
6744         case DW_OP_lit5:
6745         case DW_OP_lit6:
6746         case DW_OP_lit7:
6747         case DW_OP_lit8:
6748         case DW_OP_lit9:
6749         case DW_OP_lit10:
6750         case DW_OP_lit11:
6751         case DW_OP_lit12:
6752         case DW_OP_lit13:
6753         case DW_OP_lit14:
6754         case DW_OP_lit15:
6755         case DW_OP_lit16:
6756         case DW_OP_lit17:
6757         case DW_OP_lit18:
6758         case DW_OP_lit19:
6759         case DW_OP_lit20:
6760         case DW_OP_lit21:
6761         case DW_OP_lit22:
6762         case DW_OP_lit23:
6763         case DW_OP_lit24:
6764         case DW_OP_lit25:
6765         case DW_OP_lit26:
6766         case DW_OP_lit27:
6767         case DW_OP_lit28:
6768         case DW_OP_lit29:
6769         case DW_OP_lit30:
6770         case DW_OP_lit31:
6771           printf ("DW_OP_lit%d", op - DW_OP_lit0);
6772           break;
6773
6774         case DW_OP_reg0:
6775         case DW_OP_reg1:
6776         case DW_OP_reg2:
6777         case DW_OP_reg3:
6778         case DW_OP_reg4:
6779         case DW_OP_reg5:
6780         case DW_OP_reg6:
6781         case DW_OP_reg7:
6782         case DW_OP_reg8:
6783         case DW_OP_reg9:
6784         case DW_OP_reg10:
6785         case DW_OP_reg11:
6786         case DW_OP_reg12:
6787         case DW_OP_reg13:
6788         case DW_OP_reg14:
6789         case DW_OP_reg15:
6790         case DW_OP_reg16:
6791         case DW_OP_reg17:
6792         case DW_OP_reg18:
6793         case DW_OP_reg19:
6794         case DW_OP_reg20:
6795         case DW_OP_reg21:
6796         case DW_OP_reg22:
6797         case DW_OP_reg23:
6798         case DW_OP_reg24:
6799         case DW_OP_reg25:
6800         case DW_OP_reg26:
6801         case DW_OP_reg27:
6802         case DW_OP_reg28:
6803         case DW_OP_reg29:
6804         case DW_OP_reg30:
6805         case DW_OP_reg31:
6806           printf ("DW_OP_reg%d", op - DW_OP_reg0);
6807           break;
6808
6809         case DW_OP_breg0:
6810         case DW_OP_breg1:
6811         case DW_OP_breg2:
6812         case DW_OP_breg3:
6813         case DW_OP_breg4:
6814         case DW_OP_breg5:
6815         case DW_OP_breg6:
6816         case DW_OP_breg7:
6817         case DW_OP_breg8:
6818         case DW_OP_breg9:
6819         case DW_OP_breg10:
6820         case DW_OP_breg11:
6821         case DW_OP_breg12:
6822         case DW_OP_breg13:
6823         case DW_OP_breg14:
6824         case DW_OP_breg15:
6825         case DW_OP_breg16:
6826         case DW_OP_breg17:
6827         case DW_OP_breg18:
6828         case DW_OP_breg19:
6829         case DW_OP_breg20:
6830         case DW_OP_breg21:
6831         case DW_OP_breg22:
6832         case DW_OP_breg23:
6833         case DW_OP_breg24:
6834         case DW_OP_breg25:
6835         case DW_OP_breg26:
6836         case DW_OP_breg27:
6837         case DW_OP_breg28:
6838         case DW_OP_breg29:
6839         case DW_OP_breg30:
6840         case DW_OP_breg31:
6841           printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6842                   read_leb128 (data, &bytes_read, 1));
6843           data += bytes_read;
6844           break;
6845
6846         case DW_OP_regx:
6847           printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6848           data += bytes_read;
6849           break;
6850         case DW_OP_fbreg:
6851           printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6852           data += bytes_read;
6853           break;
6854         case DW_OP_bregx:
6855           uvalue = read_leb128 (data, &bytes_read, 0);
6856           data += bytes_read;
6857           printf ("DW_OP_bregx: %lu %ld", uvalue,
6858                   read_leb128 (data, &bytes_read, 1));
6859           data += bytes_read;
6860           break;
6861         case DW_OP_piece:
6862           printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6863           data += bytes_read;
6864           break;
6865         case DW_OP_deref_size:
6866           printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6867           break;
6868         case DW_OP_xderef_size:
6869           printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6870           break;
6871         case DW_OP_nop:
6872           printf ("DW_OP_nop");
6873           break;
6874
6875           /* DWARF 2.1 extensions.  */
6876         case DW_OP_push_object_address:
6877           printf ("DW_OP_push_object_address");
6878           break;
6879         case DW_OP_call2:
6880           printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2));
6881           data += 2;
6882           break;
6883         case DW_OP_call4:
6884           printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4));
6885           data += 4;
6886           break;
6887         case DW_OP_calli:
6888           printf ("DW_OP_calli");
6889           break;
6890
6891         default:
6892           if (op >= DW_OP_lo_user
6893               && op <= DW_OP_hi_user)
6894             printf (_("(User defined location op)"));
6895           else
6896             printf (_("(Unknown location op)"));
6897           /* No way to tell where the next op is, so just bail.  */
6898           return;
6899         }
6900
6901       /* Separate the ops.  */
6902       printf ("; ");
6903     }
6904 }
6905
6906
6907 static unsigned char *
6908 read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
6909      unsigned long   attribute;
6910      unsigned long   form;
6911      unsigned char * data;
6912      unsigned long   cu_offset;
6913      unsigned long   pointer_size;
6914 {
6915   unsigned long   uvalue = 0;
6916   unsigned char * block_start = NULL;
6917   int             bytes_read;
6918
6919   printf ("     %-18s:", get_AT_name (attribute));
6920
6921   switch (form)
6922     {
6923     default:
6924       break;
6925
6926     case DW_FORM_ref_addr:
6927     case DW_FORM_addr:
6928       uvalue = byte_get (data, pointer_size);
6929       data += pointer_size;
6930       break;
6931
6932     case DW_FORM_strp:
6933       uvalue = byte_get (data, /* offset_size */ 4);
6934       data += /* offset_size */ 4;
6935       break;
6936
6937     case DW_FORM_ref1:
6938     case DW_FORM_flag:
6939     case DW_FORM_data1:
6940       uvalue = byte_get (data ++, 1);
6941       break;
6942
6943     case DW_FORM_ref2:
6944     case DW_FORM_data2:
6945       uvalue = byte_get (data, 2);
6946       data += 2;
6947       break;
6948
6949     case DW_FORM_ref4:
6950     case DW_FORM_data4:
6951       uvalue = byte_get (data, 4);
6952       data += 4;
6953       break;
6954
6955     case DW_FORM_sdata:
6956       uvalue = read_leb128 (data, & bytes_read, 1);
6957       data += bytes_read;
6958       break;
6959
6960     case DW_FORM_ref_udata:
6961     case DW_FORM_udata:
6962       uvalue = read_leb128 (data, & bytes_read, 0);
6963       data += bytes_read;
6964       break;
6965     }
6966
6967   switch (form)
6968     {
6969     case DW_FORM_ref_addr:
6970       printf (" <#%lx>", uvalue);
6971       break;
6972
6973     case DW_FORM_ref1:
6974     case DW_FORM_ref2:
6975     case DW_FORM_ref4:
6976     case DW_FORM_ref_udata:
6977       printf (" <%lx>", uvalue + cu_offset);
6978       break;
6979
6980     case DW_FORM_addr:
6981       printf (" %#lx", uvalue);
6982
6983     case DW_FORM_flag:
6984     case DW_FORM_data1:
6985     case DW_FORM_data2:
6986     case DW_FORM_data4:
6987     case DW_FORM_sdata:
6988     case DW_FORM_udata:
6989       printf (" %ld", uvalue);
6990       break;
6991
6992     case DW_FORM_ref8:
6993     case DW_FORM_data8:
6994       uvalue = byte_get (data, 4);
6995       printf (" %lx", uvalue);
6996       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
6997       data += 8;
6998       break;
6999
7000     case DW_FORM_string:
7001       printf (" %s", data);
7002       data += strlen ((char *) data) + 1;
7003       break;
7004
7005     case DW_FORM_block:
7006       uvalue = read_leb128 (data, & bytes_read, 0);
7007       block_start = data + bytes_read;
7008       data = display_block (block_start, uvalue);
7009       break;
7010
7011     case DW_FORM_block1:
7012       uvalue = byte_get (data, 1);
7013       block_start = data + 1;
7014       data = display_block (block_start, uvalue);
7015       break;
7016
7017     case DW_FORM_block2:
7018       uvalue = byte_get (data, 2);
7019       block_start = data + 2;
7020       data = display_block (block_start, uvalue);
7021       break;
7022
7023     case DW_FORM_block4:
7024       uvalue = byte_get (data, 4);
7025       block_start = data + 4;
7026       data = display_block (block_start, uvalue);
7027       break;
7028
7029     case DW_FORM_strp:
7030       if (debug_str == NULL)
7031         warn (_("DW_FORM_strp used but no .debug_str section"));
7032       else if (uvalue >= debug_str_size)
7033         warn (_("DW_FORM_strp %lx points outside of .debug_str section"),
7034               uvalue);
7035       else
7036         printf (" %s", debug_str + uvalue);
7037       break;
7038
7039     case DW_FORM_indirect:
7040       warn (_("Unable to handle FORM: %d"), form);
7041       break;
7042
7043     default:
7044       warn (_("Unrecognised form: %d"), form);
7045       break;
7046     }
7047
7048   /* For some attributes we can display futher information.  */
7049
7050   printf ("\t");
7051
7052   switch (attribute)
7053     {
7054     case DW_AT_inline:
7055       switch (uvalue)
7056         {
7057         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
7058         case DW_INL_inlined:              printf (_("(inlined)")); break;
7059         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
7060         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
7061         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
7062         }
7063       break;
7064
7065     case DW_AT_language:
7066       switch (uvalue)
7067         {
7068         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
7069         case DW_LANG_C89:            printf ("(ANSI C)"); break;
7070         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
7071         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
7072         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
7073         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
7074         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
7075         case DW_LANG_Ada83:          printf ("(Ada)"); break;
7076         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
7077         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
7078           /* DWARF 2.1 values.  */
7079         case DW_LANG_C99:            printf ("(ANSI C99)"); break;
7080         case DW_LANG_Ada95:          printf ("(ADA 95)"); break;
7081         case DW_LANG_Fortran95:      printf ("(Fortran 95)"); break;
7082           /* MIPS extension.  */
7083         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
7084         default:                     printf ("(Unknown: %lx)", uvalue); break;
7085         }
7086       break;
7087
7088     case DW_AT_encoding:
7089       switch (uvalue)
7090         {
7091         case DW_ATE_void:            printf ("(void)"); break;
7092         case DW_ATE_address:         printf ("(machine address)"); break;
7093         case DW_ATE_boolean:         printf ("(boolean)"); break;
7094         case DW_ATE_complex_float:   printf ("(complex float)"); break;
7095         case DW_ATE_float:           printf ("(float)"); break;
7096         case DW_ATE_signed:          printf ("(signed)"); break;
7097         case DW_ATE_signed_char:     printf ("(signed char)"); break;
7098         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
7099         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
7100           /* DWARF 2.1 value.  */
7101         case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
7102         default:
7103           if (uvalue >= DW_ATE_lo_user
7104               && uvalue <= DW_ATE_hi_user)
7105             printf ("(user defined type)");
7106           else
7107             printf ("(unknown type)");
7108           break;
7109         }
7110       break;
7111
7112     case DW_AT_accessibility:
7113       switch (uvalue)
7114         {
7115         case DW_ACCESS_public:          printf ("(public)"); break;
7116         case DW_ACCESS_protected:       printf ("(protected)"); break;
7117         case DW_ACCESS_private:         printf ("(private)"); break;
7118         default:                        printf ("(unknown accessibility)"); break;
7119         }
7120       break;
7121
7122     case DW_AT_visibility:
7123       switch (uvalue)
7124         {
7125         case DW_VIS_local:      printf ("(local)"); break;
7126         case DW_VIS_exported:   printf ("(exported)"); break;
7127         case DW_VIS_qualified:  printf ("(qualified)"); break;
7128         default:                printf ("(unknown visibility)"); break;
7129         }
7130       break;
7131
7132     case DW_AT_virtuality:
7133       switch (uvalue)
7134         {
7135         case DW_VIRTUALITY_none:        printf ("(none)"); break;
7136         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
7137         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
7138         default:                        printf ("(unknown virtuality)"); break;
7139         }
7140       break;
7141
7142     case DW_AT_identifier_case:
7143       switch (uvalue)
7144         {
7145         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
7146         case DW_ID_up_case:             printf ("(up_case)"); break;
7147         case DW_ID_down_case:           printf ("(down_case)"); break;
7148         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
7149         default:                        printf ("(unknown case)"); break;
7150         }
7151       break;
7152
7153     case DW_AT_calling_convention:
7154       switch (uvalue)
7155         {
7156         case DW_CC_normal:      printf ("(normal)"); break;
7157         case DW_CC_program:     printf ("(program)"); break;
7158         case DW_CC_nocall:      printf ("(nocall)"); break;
7159         default:
7160           if (uvalue >= DW_CC_lo_user
7161               && uvalue <= DW_CC_hi_user)
7162             printf ("(user defined)");
7163           else
7164             printf ("(unknown convention)");
7165         }
7166       break;
7167
7168     case DW_AT_ordering:
7169       switch (uvalue)
7170         {
7171         case -1: printf ("(undefined)"); break;
7172         case 0:  printf ("(row major)"); break;
7173         case 1:  printf ("(column major)"); break;
7174         }
7175       break;
7176
7177     case DW_AT_frame_base:
7178     case DW_AT_location:
7179     case DW_AT_data_member_location:
7180     case DW_AT_vtable_elem_location:
7181     case DW_AT_allocated:
7182     case DW_AT_associated:
7183     case DW_AT_data_location:
7184     case DW_AT_stride:
7185     case DW_AT_upper_bound:
7186     case DW_AT_lower_bound:
7187       if (block_start)
7188         {
7189           printf ("(");
7190           decode_location_expression (block_start, pointer_size, uvalue);
7191           printf (")");
7192         }
7193       break;
7194
7195     default:
7196       break;
7197     }
7198
7199   printf ("\n");
7200   return data;
7201 }
7202
7203 static int
7204 display_debug_info (section, start, file)
7205      Elf32_Internal_Shdr * section;
7206      unsigned char *       start;
7207      FILE *                file;
7208 {
7209   unsigned char * end = start + section->sh_size;
7210   unsigned char * section_begin = start;
7211
7212   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7213
7214   {
7215     Elf32_Internal_Shdr * sec;
7216     int i;
7217
7218     /* Locate the .debug_str section and read it.  */
7219     for (i = 0, sec = section_headers;
7220          i < elf_header.e_shnum;
7221          i ++, sec ++)
7222       if (strcmp (SECTION_NAME (sec), ".debug_str") == 0 && sec->sh_size != 0)
7223         {
7224           debug_str = (const char *)
7225                       get_data (NULL, file, sec->sh_offset, sec->sh_size,
7226                                 _("debug_str section data"));
7227           debug_str_size = sec->sh_size;
7228           break;
7229         }
7230   }
7231
7232   while (start < end)
7233     {
7234       DWARF2_External_CompUnit * external;
7235       DWARF2_Internal_CompUnit   compunit;
7236       Elf32_Internal_Shdr *      relsec;
7237       unsigned char *            tags;
7238       int                        i;
7239       int                        level;
7240       unsigned long              cu_offset;
7241
7242       external = (DWARF2_External_CompUnit *) start;
7243
7244       compunit.cu_length        = BYTE_GET (external->cu_length);
7245       compunit.cu_version       = BYTE_GET (external->cu_version);
7246       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
7247       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
7248
7249       if (compunit.cu_length == 0xffffffff)
7250         {
7251           warn (_("64-bit DWARF debug info is not supported yet.\n"));
7252           break;
7253         }
7254
7255       /* Check for RELA relocations in the abbrev_offset address, and
7256          apply them.  */
7257       for (relsec = section_headers;
7258            relsec < section_headers + elf_header.e_shnum;
7259            ++relsec)
7260         {
7261           unsigned long nrelas, nsyms;
7262           Elf_Internal_Rela *rela, *rp;
7263           Elf32_Internal_Shdr *symsec;
7264           Elf_Internal_Sym *symtab;
7265           Elf_Internal_Sym *sym;
7266
7267           if (relsec->sh_type != SHT_RELA
7268               || section_headers + relsec->sh_info != section)
7269             continue;
7270
7271           if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7272                                   & rela, & nrelas))
7273             return 0;
7274
7275           symsec = section_headers + relsec->sh_link;
7276           nsyms = symsec->sh_size / symsec->sh_entsize;
7277           symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
7278
7279           for (rp = rela; rp < rela + nrelas; ++rp)
7280             {
7281               if (rp->r_offset
7282                   != (bfd_vma) ((unsigned char *) &external->cu_abbrev_offset
7283                                 - section_begin))
7284                 continue;
7285
7286               if (is_32bit_elf)
7287                 {
7288                   sym = symtab + ELF32_R_SYM (rp->r_info);
7289
7290                   if (ELF32_ST_TYPE (sym->st_info) != STT_SECTION)
7291                     {
7292                       warn (_("Skipping unexpected symbol type %u"),
7293                             ELF32_ST_TYPE (sym->st_info));
7294                       continue;
7295                     }
7296                 }
7297               else
7298                 {
7299                   sym = symtab + ELF64_R_SYM (rp->r_info);
7300
7301                   if (ELF64_ST_TYPE (sym->st_info) != STT_SECTION)
7302                     {
7303                       warn (_("Skipping unexpected symbol type %u"),
7304                             ELF64_ST_TYPE (sym->st_info));
7305                       continue;
7306                     }
7307                 }
7308
7309               compunit.cu_abbrev_offset += rp->r_addend;
7310               break;
7311             }
7312
7313           free (rela);
7314           break;
7315         }
7316
7317       tags = start + sizeof (* external);
7318       cu_offset = start - section_begin;
7319       start += compunit.cu_length + sizeof (external->cu_length);
7320
7321       printf (_("  Compilation Unit @ %lx:\n"), cu_offset);
7322       printf (_("   Length:        %ld\n"), compunit.cu_length);
7323       printf (_("   Version:       %d\n"), compunit.cu_version);
7324       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
7325       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
7326
7327       if (compunit.cu_version != 2)
7328         {
7329           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
7330           continue;
7331         }
7332
7333       if (first_abbrev != NULL)
7334         free_abbrevs ();
7335
7336       /* Read in the abbrevs used by this compilation unit.  */
7337
7338       {
7339         Elf32_Internal_Shdr * sec;
7340         unsigned char *       begin;
7341
7342         /* Locate the .debug_abbrev section and process it.  */
7343         for (i = 0, sec = section_headers;
7344              i < elf_header.e_shnum;
7345              i ++, sec ++)
7346           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
7347             break;
7348
7349         if (i == elf_header.e_shnum || sec->sh_size == 0)
7350           {
7351             warn (_("Unable to locate .debug_abbrev section!\n"));
7352             return 0;
7353           }
7354
7355         begin = ((unsigned char *)
7356                  get_data (NULL, file, sec->sh_offset, sec->sh_size,
7357                            _("debug_abbrev section data")));
7358         if (!begin)
7359           return 0;
7360
7361         process_abbrev_section (begin + compunit.cu_abbrev_offset,
7362                                 begin + sec->sh_size);
7363
7364         free (begin);
7365       }
7366
7367       level = 0;
7368       while (tags < start)
7369         {
7370           int            bytes_read;
7371           unsigned long  abbrev_number;
7372           abbrev_entry * entry;
7373           abbrev_attr  * attr;
7374
7375           abbrev_number = read_leb128 (tags, & bytes_read, 0);
7376           tags += bytes_read;
7377
7378           /* A null DIE marks the end of a list of children.  */
7379           if (abbrev_number == 0)
7380             {
7381               --level;
7382               continue;
7383             }
7384
7385           /* Scan through the abbreviation list until we reach the
7386              correct entry.  */
7387           for (entry = first_abbrev;
7388                entry && entry->entry != abbrev_number;
7389                entry = entry->next)
7390             continue;
7391
7392           if (entry == NULL)
7393             {
7394               warn (_("Unable to locate entry %lu in the abbreviation table\n"),
7395                     abbrev_number);
7396               return 0;
7397             }
7398
7399           printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
7400                   level,
7401                   (unsigned long) (tags - section_begin - bytes_read),
7402                   abbrev_number,
7403                   get_TAG_name (entry->tag));
7404
7405           for (attr = entry->first_attr; attr; attr = attr->next)
7406             tags = read_and_display_attr (attr->attribute,
7407                                           attr->form,
7408                                           tags, cu_offset,
7409                                           compunit.cu_pointer_size);
7410
7411           if (entry->children)
7412             ++level;
7413         }
7414     }
7415
7416   if (debug_str != NULL)
7417     {
7418       free ((char *) debug_str);
7419       debug_str = NULL;
7420     }
7421
7422   printf ("\n");
7423
7424   return 1;
7425 }
7426
7427 static int
7428 display_debug_aranges (section, start, file)
7429      Elf32_Internal_Shdr * section;
7430      unsigned char *       start;
7431      FILE *                file ATTRIBUTE_UNUSED;
7432 {
7433   unsigned char * end = start + section->sh_size;
7434
7435   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
7436
7437   while (start < end)
7438     {
7439       DWARF2_External_ARange * external;
7440       DWARF2_Internal_ARange   arange;
7441       unsigned char *          ranges;
7442       unsigned long            length;
7443       unsigned long            address;
7444       int                      excess;
7445
7446       external = (DWARF2_External_ARange *) start;
7447
7448       arange.ar_length       = BYTE_GET (external->ar_length);
7449       arange.ar_version      = BYTE_GET (external->ar_version);
7450       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
7451       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
7452       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
7453
7454       if (arange.ar_length == 0xffffffff)
7455         {
7456           warn (_("64-bit DWARF aranges are not supported yet.\n"));
7457           break;
7458         }
7459
7460       if (arange.ar_version != 2)
7461         {
7462           warn (_("Only DWARF 2 aranges are currently supported.\n"));
7463           break;
7464         }
7465
7466       printf (_("  Length:                   %ld\n"), arange.ar_length);
7467       printf (_("  Version:                  %d\n"), arange.ar_version);
7468       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
7469       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
7470       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
7471
7472       printf (_("\n    Address  Length\n"));
7473
7474       ranges = start + sizeof (* external);
7475
7476       /* Must pad to an alignment boundary that is twice the pointer size.  */
7477       excess = sizeof (* external) % (2 * arange.ar_pointer_size);
7478       if (excess)
7479         ranges += (2 * arange.ar_pointer_size) - excess;
7480
7481       for (;;)
7482         {
7483           address = byte_get (ranges, arange.ar_pointer_size);
7484
7485           ranges += arange.ar_pointer_size;
7486
7487           length  = byte_get (ranges, arange.ar_pointer_size);
7488
7489           ranges += arange.ar_pointer_size;
7490
7491           /* A pair of zeros marks the end of the list.  */
7492           if (address == 0 && length == 0)
7493             break;
7494
7495           printf ("    %8.8lx %lu\n", address, length);
7496         }
7497
7498       start += arange.ar_length + sizeof (external->ar_length);
7499     }
7500
7501   printf ("\n");
7502
7503   return 1;
7504 }
7505
7506 typedef struct Frame_Chunk
7507 {
7508   struct Frame_Chunk * next;
7509   unsigned char *      chunk_start;
7510   int                  ncols;
7511   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
7512   short int *          col_type;
7513   int *                col_offset;
7514   char *               augmentation;
7515   unsigned int         code_factor;
7516   int                  data_factor;
7517   unsigned long        pc_begin;
7518   unsigned long        pc_range;
7519   int                  cfa_reg;
7520   int                  cfa_offset;
7521   int                  ra;
7522   unsigned char        fde_encoding;
7523 }
7524 Frame_Chunk;
7525
7526 /* A marker for a col_type that means this column was never referenced
7527    in the frame info.  */
7528 #define DW_CFA_unreferenced (-1)
7529
7530 static void frame_need_space PARAMS ((Frame_Chunk *, int));
7531 static void frame_display_row PARAMS ((Frame_Chunk *, int *, int *));
7532 static int size_of_encoded_value PARAMS ((int));
7533
7534 static void
7535 frame_need_space (fc, reg)
7536      Frame_Chunk * fc;
7537      int reg;
7538 {
7539   int prev = fc->ncols;
7540
7541   if (reg < fc->ncols)
7542     return;
7543
7544   fc->ncols = reg + 1;
7545   fc->col_type = (short int *) xrealloc (fc->col_type,
7546                                          fc->ncols * sizeof (short int));
7547   fc->col_offset = (int *) xrealloc (fc->col_offset,
7548                                      fc->ncols * sizeof (int));
7549
7550   while (prev < fc->ncols)
7551     {
7552       fc->col_type[prev] = DW_CFA_unreferenced;
7553       fc->col_offset[prev] = 0;
7554       prev++;
7555     }
7556 }
7557
7558 static void
7559 frame_display_row (fc, need_col_headers, max_regs)
7560      Frame_Chunk * fc;
7561      int *         need_col_headers;
7562      int *         max_regs;
7563 {
7564   int r;
7565   char tmp[100];
7566
7567   if (* max_regs < fc->ncols)
7568     * max_regs = fc->ncols;
7569
7570   if (* need_col_headers)
7571     {
7572       * need_col_headers = 0;
7573
7574       printf ("   LOC   CFA      ");
7575
7576       for (r = 0; r < * max_regs; r++)
7577         if (fc->col_type[r] != DW_CFA_unreferenced)
7578           {
7579             if (r == fc->ra)
7580               printf ("ra   ");
7581             else
7582               printf ("r%-4d", r);
7583           }
7584
7585       printf ("\n");
7586     }
7587
7588   printf ("%08lx ", fc->pc_begin);
7589   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
7590   printf ("%-8s ", tmp);
7591
7592   for (r = 0; r < fc->ncols; r++)
7593     {
7594       if (fc->col_type[r] != DW_CFA_unreferenced)
7595         {
7596           switch (fc->col_type[r])
7597             {
7598             case DW_CFA_undefined:
7599               strcpy (tmp, "u");
7600               break;
7601             case DW_CFA_same_value:
7602               strcpy (tmp, "s");
7603               break;
7604             case DW_CFA_offset:
7605               sprintf (tmp, "c%+d", fc->col_offset[r]);
7606               break;
7607             case DW_CFA_register:
7608               sprintf (tmp, "r%d", fc->col_offset[r]);
7609               break;
7610             default:
7611               strcpy (tmp, "n/a");
7612               break;
7613             }
7614           printf ("%-5s", tmp);
7615         }
7616     }
7617   printf ("\n");
7618 }
7619
7620 static int
7621 size_of_encoded_value (encoding)
7622      int encoding;
7623 {
7624   switch (encoding & 0x7)
7625     {
7626     default:    /* ??? */
7627     case 0:     return is_32bit_elf ? 4 : 8;
7628     case 2:     return 2;
7629     case 3:     return 4;
7630     case 4:     return 8;
7631     }
7632 }
7633
7634 #define GET(N)  byte_get (start, N); start += N
7635 #define LEB()   read_leb128 (start, & length_return, 0); start += length_return
7636 #define SLEB()  read_leb128 (start, & length_return, 1); start += length_return
7637
7638 static int
7639 display_debug_frames (section, start, file)
7640      Elf32_Internal_Shdr * section;
7641      unsigned char *       start;
7642      FILE *                file ATTRIBUTE_UNUSED;
7643 {
7644   unsigned char * end = start + section->sh_size;
7645   unsigned char * section_start = start;
7646   Frame_Chunk *   chunks = 0;
7647   Frame_Chunk *   remembered_state = 0;
7648   Frame_Chunk *   rs;
7649   int             is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7650   int             length_return;
7651   int             max_regs = 0;
7652   int             addr_size = is_32bit_elf ? 4 : 8;
7653
7654   printf (_("The section %s contains:\n"), SECTION_NAME (section));
7655
7656   while (start < end)
7657     {
7658       unsigned char * saved_start;
7659       unsigned char * block_end;
7660       unsigned long   length;
7661       unsigned long   cie_id;
7662       Frame_Chunk *   fc;
7663       Frame_Chunk *   cie;
7664       int             need_col_headers = 1;
7665       unsigned char * augmentation_data = NULL;
7666       unsigned long   augmentation_data_len = 0;
7667       int             encoded_ptr_size = addr_size;
7668
7669       saved_start = start;
7670       length = byte_get (start, 4); start += 4;
7671
7672       if (length == 0)
7673         return 1;
7674
7675       if (length == 0xffffffff)
7676         {
7677           warn (_("64-bit DWARF format frames are not supported yet.\n"));
7678           break;
7679         }
7680
7681       block_end = saved_start + length + 4;
7682       cie_id = byte_get (start, 4); start += 4;
7683
7684       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7685         {
7686           int version;
7687
7688           fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7689           memset (fc, 0, sizeof (Frame_Chunk));
7690
7691           fc->next = chunks;
7692           chunks = fc;
7693           fc->chunk_start = saved_start;
7694           fc->ncols = 0;
7695           fc->col_type = (short int *) xmalloc (sizeof (short int));
7696           fc->col_offset = (int *) xmalloc (sizeof (int));
7697           frame_need_space (fc, max_regs-1);
7698
7699           version = *start++;
7700
7701           fc->augmentation = start;
7702           start = strchr (start, '\0') + 1;
7703
7704           if (fc->augmentation[0] == 'z')
7705             {
7706               fc->code_factor = LEB ();
7707               fc->data_factor = SLEB ();
7708               fc->ra = byte_get (start, 1); start += 1;
7709               augmentation_data_len = LEB ();
7710               augmentation_data = start;
7711               start += augmentation_data_len;
7712             }
7713           else if (strcmp (fc->augmentation, "eh") == 0)
7714             {
7715               start += addr_size;
7716               fc->code_factor = LEB ();
7717               fc->data_factor = SLEB ();
7718               fc->ra = byte_get (start, 1); start += 1;
7719             }
7720           else
7721             {
7722               fc->code_factor = LEB ();
7723               fc->data_factor = SLEB ();
7724               fc->ra = byte_get (start, 1); start += 1;
7725             }
7726           cie = fc;
7727
7728           if (do_debug_frames_interp)
7729             printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
7730                     (unsigned long)(saved_start - section_start), length, cie_id,
7731                     fc->augmentation, fc->code_factor, fc->data_factor,
7732                     fc->ra);
7733           else
7734             {
7735               printf ("\n%08lx %08lx %08lx CIE\n",
7736                       (unsigned long)(saved_start - section_start), length, cie_id);
7737               printf ("  Version:               %d\n", version);
7738               printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
7739               printf ("  Code alignment factor: %u\n", fc->code_factor);
7740               printf ("  Data alignment factor: %d\n", fc->data_factor);
7741               printf ("  Return address column: %d\n", fc->ra);
7742
7743               if (augmentation_data_len)
7744                 {
7745                   unsigned long i;
7746                   printf ("  Augmentation data:    ");
7747                   for (i = 0; i < augmentation_data_len; ++i)
7748                     printf (" %02x", augmentation_data[i]);
7749                   putchar ('\n');
7750                 }
7751               putchar ('\n');
7752             }
7753
7754           if (augmentation_data_len)
7755             {
7756               unsigned char *p, *q;
7757               p = fc->augmentation + 1;
7758               q = augmentation_data;
7759
7760               while (1)
7761                 {
7762                   if (*p == 'L')
7763                     q++;
7764                   else if (*p == 'P')
7765                     q += 1 + size_of_encoded_value (*q);
7766                   else if (*p == 'R')
7767                     fc->fde_encoding = *q++;
7768                   else
7769                     break;
7770                   p++;
7771                 }
7772
7773               if (fc->fde_encoding)
7774                 encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7775             }
7776
7777           frame_need_space (fc, fc->ra);
7778         }
7779       else
7780         {
7781           unsigned char *    look_for;
7782           static Frame_Chunk fde_fc;
7783
7784           fc = & fde_fc;
7785           memset (fc, 0, sizeof (Frame_Chunk));
7786
7787           look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
7788
7789           for (cie = chunks; cie ; cie = cie->next)
7790             if (cie->chunk_start == look_for)
7791               break;
7792
7793           if (!cie)
7794             {
7795               warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
7796                     cie_id, saved_start);
7797               start = block_end;
7798               fc->ncols = 0;
7799               fc->col_type = (short int *) xmalloc (sizeof (short int));
7800               fc->col_offset = (int *) xmalloc (sizeof (int));
7801               frame_need_space (fc, max_regs - 1);
7802               cie = fc;
7803               fc->augmentation = "";
7804               fc->fde_encoding = 0;
7805             }
7806           else
7807             {
7808               fc->ncols = cie->ncols;
7809               fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
7810               fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
7811               memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
7812               memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7813               fc->augmentation = cie->augmentation;
7814               fc->code_factor = cie->code_factor;
7815               fc->data_factor = cie->data_factor;
7816               fc->cfa_reg = cie->cfa_reg;
7817               fc->cfa_offset = cie->cfa_offset;
7818               fc->ra = cie->ra;
7819               frame_need_space (fc, max_regs-1);
7820               fc->fde_encoding = cie->fde_encoding;
7821             }
7822
7823           if (fc->fde_encoding)
7824             encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
7825
7826           fc->pc_begin = byte_get (start, encoded_ptr_size);
7827           start += encoded_ptr_size;
7828           fc->pc_range = byte_get (start, encoded_ptr_size);
7829           start += encoded_ptr_size;
7830
7831           if (cie->augmentation[0] == 'z')
7832             {
7833               augmentation_data_len = LEB ();
7834               augmentation_data = start;
7835               start += augmentation_data_len;
7836             }
7837
7838           printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
7839                   (unsigned long)(saved_start - section_start), length, cie_id,
7840                   (unsigned long)(cie->chunk_start - section_start),
7841                   fc->pc_begin, fc->pc_begin + fc->pc_range);
7842           if (! do_debug_frames_interp && augmentation_data_len)
7843             {
7844               unsigned long i;
7845               printf ("  Augmentation data:    ");
7846               for (i = 0; i < augmentation_data_len; ++i)
7847                 printf (" %02x", augmentation_data[i]);
7848               putchar ('\n');
7849               putchar ('\n');
7850             }
7851         }
7852
7853       /* At this point, fc is the current chunk, cie (if any) is set, and we're
7854          about to interpret instructions for the chunk.  */
7855
7856       if (do_debug_frames_interp)
7857       {
7858         /* Start by making a pass over the chunk, allocating storage
7859            and taking note of what registers are used.  */
7860         unsigned char * tmp = start;
7861
7862         while (start < block_end)
7863           {
7864             unsigned op, opa;
7865             unsigned long reg;
7866
7867             op = * start ++;
7868             opa = op & 0x3f;
7869             if (op & 0xc0)
7870               op &= 0xc0;
7871
7872             /* Warning: if you add any more cases to this switch, be
7873                sure to add them to the corresponding switch below.  */
7874             switch (op)
7875               {
7876               case DW_CFA_advance_loc:
7877                 break;
7878               case DW_CFA_offset:
7879                 LEB ();
7880                 frame_need_space (fc, opa);
7881                 fc->col_type[opa] = DW_CFA_undefined;
7882                 break;
7883               case DW_CFA_restore:
7884                 frame_need_space (fc, opa);
7885                 fc->col_type[opa] = DW_CFA_undefined;
7886                 break;
7887               case DW_CFA_set_loc:
7888                 start += encoded_ptr_size;
7889                 break;
7890               case DW_CFA_advance_loc1:
7891                 start += 1;
7892                 break;
7893               case DW_CFA_advance_loc2:
7894                 start += 2;
7895                 break;
7896               case DW_CFA_advance_loc4:
7897                 start += 4;
7898                 break;
7899               case DW_CFA_offset_extended:
7900                 reg = LEB (); LEB ();
7901                 frame_need_space (fc, reg);
7902                 fc->col_type[reg] = DW_CFA_undefined;
7903                 break;
7904               case DW_CFA_restore_extended:
7905                 reg = LEB ();
7906                 frame_need_space (fc, reg);
7907                 fc->col_type[reg] = DW_CFA_undefined;
7908                 break;
7909               case DW_CFA_undefined:
7910                 reg = LEB ();
7911                 frame_need_space (fc, reg);
7912                 fc->col_type[reg] = DW_CFA_undefined;
7913                 break;
7914               case DW_CFA_same_value:
7915                 reg = LEB ();
7916                 frame_need_space (fc, reg);
7917                 fc->col_type[reg] = DW_CFA_undefined;
7918                 break;
7919               case DW_CFA_register:
7920                 reg = LEB (); LEB ();
7921                 frame_need_space (fc, reg);
7922                 fc->col_type[reg] = DW_CFA_undefined;
7923                 break;
7924               case DW_CFA_def_cfa:
7925                 LEB (); LEB ();
7926                 break;
7927               case DW_CFA_def_cfa_register:
7928                 LEB ();
7929                 break;
7930               case DW_CFA_def_cfa_offset:
7931                 LEB ();
7932                 break;
7933 #ifndef DW_CFA_GNU_args_size
7934 #define DW_CFA_GNU_args_size 0x2e
7935 #endif
7936               case DW_CFA_GNU_args_size:
7937                 LEB ();
7938                 break;
7939 #ifndef DW_CFA_GNU_negative_offset_extended
7940 #define DW_CFA_GNU_negative_offset_extended 0x2f
7941 #endif
7942               case DW_CFA_GNU_negative_offset_extended:
7943                 reg = LEB (); LEB ();
7944                 frame_need_space (fc, reg);
7945                 fc->col_type[reg] = DW_CFA_undefined;
7946
7947               default:
7948                 break;
7949               }
7950           }
7951         start = tmp;
7952       }
7953
7954       /* Now we know what registers are used, make a second pass over
7955          the chunk, this time actually printing out the info.  */
7956
7957       while (start < block_end)
7958         {
7959           unsigned op, opa;
7960           unsigned long ul, reg, roffs;
7961           long l, ofs;
7962           bfd_vma vma;
7963
7964           op = * start ++;
7965           opa = op & 0x3f;
7966           if (op & 0xc0)
7967             op &= 0xc0;
7968
7969             /* Warning: if you add any more cases to this switch, be
7970                sure to add them to the corresponding switch above.  */
7971           switch (op)
7972             {
7973             case DW_CFA_advance_loc:
7974               if (do_debug_frames_interp)
7975                 frame_display_row (fc, &need_col_headers, &max_regs);
7976               else
7977                 printf ("  DW_CFA_advance_loc: %d to %08lx\n",
7978                         opa * fc->code_factor,
7979                         fc->pc_begin + opa * fc->code_factor);
7980               fc->pc_begin += opa * fc->code_factor;
7981               break;
7982
7983             case DW_CFA_offset:
7984               roffs = LEB ();
7985               if (! do_debug_frames_interp)
7986                 printf ("  DW_CFA_offset: r%d at cfa%+ld\n",
7987                         opa, roffs * fc->data_factor);
7988               fc->col_type[opa] = DW_CFA_offset;
7989               fc->col_offset[opa] = roffs * fc->data_factor;
7990               break;
7991
7992             case DW_CFA_restore:
7993               if (! do_debug_frames_interp)
7994                 printf ("  DW_CFA_restore: r%d\n", opa);
7995               fc->col_type[opa] = cie->col_type[opa];
7996               fc->col_offset[opa] = cie->col_offset[opa];
7997               break;
7998
7999             case DW_CFA_set_loc:
8000               vma = byte_get (start, encoded_ptr_size);
8001               start += encoded_ptr_size;
8002               if (do_debug_frames_interp)
8003                 frame_display_row (fc, &need_col_headers, &max_regs);
8004               else
8005                 printf ("  DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
8006               fc->pc_begin = vma;
8007               break;
8008
8009             case DW_CFA_advance_loc1:
8010               ofs = byte_get (start, 1); start += 1;
8011               if (do_debug_frames_interp)
8012                 frame_display_row (fc, &need_col_headers, &max_regs);
8013               else
8014                 printf ("  DW_CFA_advance_loc1: %ld to %08lx\n",
8015                         ofs * fc->code_factor,
8016                         fc->pc_begin + ofs * fc->code_factor);
8017               fc->pc_begin += ofs * fc->code_factor;
8018               break;
8019
8020             case DW_CFA_advance_loc2:
8021               ofs = byte_get (start, 2); start += 2;
8022               if (do_debug_frames_interp)
8023                 frame_display_row (fc, &need_col_headers, &max_regs);
8024               else
8025                 printf ("  DW_CFA_advance_loc2: %ld to %08lx\n",
8026                         ofs * fc->code_factor,
8027                         fc->pc_begin + ofs * fc->code_factor);
8028               fc->pc_begin += ofs * fc->code_factor;
8029               break;
8030
8031             case DW_CFA_advance_loc4:
8032               ofs = byte_get (start, 4); start += 4;
8033               if (do_debug_frames_interp)
8034                 frame_display_row (fc, &need_col_headers, &max_regs);
8035               else
8036                 printf ("  DW_CFA_advance_loc4: %ld to %08lx\n",
8037                         ofs * fc->code_factor,
8038                         fc->pc_begin + ofs * fc->code_factor);
8039               fc->pc_begin += ofs * fc->code_factor;
8040               break;
8041
8042             case DW_CFA_offset_extended:
8043               reg = LEB ();
8044               roffs = LEB ();
8045               if (! do_debug_frames_interp)
8046                 printf ("  DW_CFA_offset_extended: r%ld at cfa%+ld\n",
8047                         reg, roffs * fc->data_factor);
8048               fc->col_type[reg] = DW_CFA_offset;
8049               fc->col_offset[reg] = roffs * fc->data_factor;
8050               break;
8051
8052             case DW_CFA_restore_extended:
8053               reg = LEB ();
8054               if (! do_debug_frames_interp)
8055                 printf ("  DW_CFA_restore_extended: r%ld\n", reg);
8056               fc->col_type[reg] = cie->col_type[reg];
8057               fc->col_offset[reg] = cie->col_offset[reg];
8058               break;
8059
8060             case DW_CFA_undefined:
8061               reg = LEB ();
8062               if (! do_debug_frames_interp)
8063                 printf ("  DW_CFA_undefined: r%ld\n", reg);
8064               fc->col_type[reg] = DW_CFA_undefined;
8065               fc->col_offset[reg] = 0;
8066               break;
8067
8068             case DW_CFA_same_value:
8069               reg = LEB ();
8070               if (! do_debug_frames_interp)
8071                 printf ("  DW_CFA_same_value: r%ld\n", reg);
8072               fc->col_type[reg] = DW_CFA_same_value;
8073               fc->col_offset[reg] = 0;
8074               break;
8075
8076             case DW_CFA_register:
8077               reg = LEB ();
8078               roffs = LEB ();
8079               if (! do_debug_frames_interp)
8080                 printf ("  DW_CFA_register: r%ld\n", reg);
8081               fc->col_type[reg] = DW_CFA_register;
8082               fc->col_offset[reg] = roffs;
8083               break;
8084
8085             case DW_CFA_remember_state:
8086               if (! do_debug_frames_interp)
8087                 printf ("  DW_CFA_remember_state\n");
8088               rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
8089               rs->ncols = fc->ncols;
8090               rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
8091               rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
8092               memcpy (rs->col_type, fc->col_type, rs->ncols);
8093               memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
8094               rs->next = remembered_state;
8095               remembered_state = rs;
8096               break;
8097
8098             case DW_CFA_restore_state:
8099               if (! do_debug_frames_interp)
8100                 printf ("  DW_CFA_restore_state\n");
8101               rs = remembered_state;
8102               remembered_state = rs->next;
8103               frame_need_space (fc, rs->ncols-1);
8104               memcpy (fc->col_type, rs->col_type, rs->ncols);
8105               memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
8106               free (rs->col_type);
8107               free (rs->col_offset);
8108               free (rs);
8109               break;
8110
8111             case DW_CFA_def_cfa:
8112               fc->cfa_reg = LEB ();
8113               fc->cfa_offset = LEB ();
8114               if (! do_debug_frames_interp)
8115                 printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
8116                         fc->cfa_reg, fc->cfa_offset);
8117               break;
8118
8119             case DW_CFA_def_cfa_register:
8120               fc->cfa_reg = LEB ();
8121               if (! do_debug_frames_interp)
8122                 printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
8123               break;
8124
8125             case DW_CFA_def_cfa_offset:
8126               fc->cfa_offset = LEB ();
8127               if (! do_debug_frames_interp)
8128                 printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
8129               break;
8130
8131             case DW_CFA_nop:
8132               if (! do_debug_frames_interp)
8133                 printf ("  DW_CFA_nop\n");
8134               break;
8135
8136 #ifndef DW_CFA_GNU_window_save
8137 #define DW_CFA_GNU_window_save 0x2d
8138 #endif
8139             case DW_CFA_GNU_window_save:
8140               if (! do_debug_frames_interp)
8141                 printf ("  DW_CFA_GNU_window_save\n");
8142               break;
8143
8144             case DW_CFA_GNU_args_size:
8145               ul = LEB ();
8146               if (! do_debug_frames_interp)
8147                 printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
8148               break;
8149
8150             case DW_CFA_GNU_negative_offset_extended:
8151               reg = LEB ();
8152               l = - LEB ();
8153               frame_need_space (fc, reg);
8154               if (! do_debug_frames_interp)
8155                 printf ("  DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
8156                         reg, l * fc->data_factor);
8157               fc->col_type[reg] = DW_CFA_offset;
8158               fc->col_offset[reg] = l * fc->data_factor;
8159               break;
8160
8161             default:
8162               fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
8163               start = block_end;
8164             }
8165         }
8166
8167       if (do_debug_frames_interp)
8168         frame_display_row (fc, &need_col_headers, &max_regs);
8169
8170       start = block_end;
8171     }
8172
8173   printf ("\n");
8174
8175   return 1;
8176 }
8177
8178 #undef GET
8179 #undef LEB
8180 #undef SLEB
8181
8182 static int
8183 display_debug_not_supported (section, start, file)
8184      Elf32_Internal_Shdr * section;
8185      unsigned char *       start ATTRIBUTE_UNUSED;
8186      FILE *                file ATTRIBUTE_UNUSED;
8187 {
8188   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
8189             SECTION_NAME (section));
8190
8191   return 1;
8192 }
8193
8194 /* Pre-scan the .debug_info section to record the size of address.
8195    When dumping the .debug_line, we use that size information, assuming
8196    that all compilation units have the same address size.  */
8197 static int
8198 prescan_debug_info (section, start, file)
8199      Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
8200      unsigned char *       start;
8201      FILE *                file ATTRIBUTE_UNUSED;
8202 {
8203   DWARF2_External_CompUnit * external;
8204
8205   external = (DWARF2_External_CompUnit *) start;
8206
8207   debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
8208   return 0;
8209 }
8210
8211   /* A structure containing the name of a debug section and a pointer
8212      to a function that can decode it.  The third field is a prescan
8213      function to be run over the section before displaying any of the
8214      sections.  */
8215 struct
8216 {
8217   char * name;
8218   int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
8219   int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
8220 }
8221 debug_displays[] =
8222 {
8223   { ".debug_info",        display_debug_info, prescan_debug_info },
8224   { ".debug_abbrev",      display_debug_abbrev, NULL },
8225   { ".debug_line",        display_debug_lines, NULL },
8226   { ".debug_aranges",     display_debug_aranges, NULL },
8227   { ".debug_pubnames",    display_debug_pubnames, NULL },
8228   { ".debug_frame",       display_debug_frames, NULL },
8229   { ".eh_frame",          display_debug_frames, NULL },
8230   { ".debug_macinfo",     display_debug_macinfo, NULL },
8231   { ".debug_pubtypes",    display_debug_not_supported, NULL },
8232   { ".debug_str",         display_debug_not_supported, NULL },
8233   { ".debug_static_func", display_debug_not_supported, NULL },
8234   { ".debug_static_vars", display_debug_not_supported, NULL },
8235   { ".debug_types",       display_debug_not_supported, NULL },
8236   { ".debug_weaknames",   display_debug_not_supported, NULL }
8237 };
8238
8239 static int
8240 display_debug_section (section, file)
8241      Elf32_Internal_Shdr * section;
8242      FILE * file;
8243 {
8244   char *          name = SECTION_NAME (section);
8245   bfd_size_type   length;
8246   unsigned char * start;
8247   int             i;
8248
8249   length = section->sh_size;
8250   if (length == 0)
8251     {
8252       printf (_("\nSection '%s' has no debugging data.\n"), name);
8253       return 0;
8254     }
8255
8256   start = (unsigned char *) get_data (NULL, file, section->sh_offset, length,
8257                                       _("debug section data"));
8258   if (!start)
8259     return 0;
8260
8261   /* See if we know how to display the contents of this section.  */
8262   if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
8263     name = ".debug_info";
8264
8265   for (i = NUM_ELEM (debug_displays); i--;)
8266     if (strcmp (debug_displays[i].name, name) == 0)
8267       {
8268         debug_displays[i].display (section, start, file);
8269         break;
8270       }
8271
8272   if (i == -1)
8273     printf (_("Unrecognised debug section: %s\n"), name);
8274
8275   free (start);
8276
8277   /* If we loaded in the abbrev section at some point,
8278      we must release it here.  */
8279   if (first_abbrev != NULL)
8280     free_abbrevs ();
8281
8282   return 1;
8283 }
8284
8285 static int
8286 process_section_contents (file)
8287      FILE * file;
8288 {
8289   Elf32_Internal_Shdr * section;
8290   unsigned int  i;
8291
8292   if (! do_dump)
8293     return 1;
8294
8295   /* Pre-scan the debug sections to find some debug information not
8296      present in some of them.  For the .debug_line, we must find out the
8297      size of address (specified in .debug_info and .debug_aranges).  */
8298   for (i = 0, section = section_headers;
8299        i < elf_header.e_shnum && i < num_dump_sects;
8300        i ++, section ++)
8301     {
8302       char *    name = SECTION_NAME (section);
8303       int       j;
8304
8305       if (section->sh_size == 0)
8306         continue;
8307
8308       /* See if there is some pre-scan operation for this section.  */
8309       for (j = NUM_ELEM (debug_displays); j--;)
8310         if (strcmp (debug_displays[j].name, name) == 0)
8311           {
8312             if (debug_displays[j].prescan != NULL)
8313               {
8314                 bfd_size_type   length;
8315                 unsigned char * start;
8316
8317                 length = section->sh_size;
8318                 start = ((unsigned char *)
8319                          get_data (NULL, file, section->sh_offset, length,
8320                                    _("debug section data")));
8321                 if (!start)
8322                   return 0;
8323
8324                 debug_displays[j].prescan (section, start, file);
8325                 free (start);
8326               }
8327
8328             break;
8329           }
8330     }
8331
8332   for (i = 0, section = section_headers;
8333        i < elf_header.e_shnum && i < num_dump_sects;
8334        i ++, section ++)
8335     {
8336 #ifdef SUPPORT_DISASSEMBLY
8337       if (dump_sects[i] & DISASS_DUMP)
8338         disassemble_section (section, file);
8339 #endif
8340       if (dump_sects[i] & HEX_DUMP)
8341         dump_section (section, file);
8342
8343       if (dump_sects[i] & DEBUG_DUMP)
8344         display_debug_section (section, file);
8345     }
8346
8347   if (i < num_dump_sects)
8348     warn (_("Some sections were not dumped because they do not exist!\n"));
8349
8350   return 1;
8351 }
8352
8353 static void
8354 process_mips_fpe_exception (mask)
8355      int mask;
8356 {
8357   if (mask)
8358     {
8359       int first = 1;
8360       if (mask & OEX_FPU_INEX)
8361         fputs ("INEX", stdout), first = 0;
8362       if (mask & OEX_FPU_UFLO)
8363         printf ("%sUFLO", first ? "" : "|"), first = 0;
8364       if (mask & OEX_FPU_OFLO)
8365         printf ("%sOFLO", first ? "" : "|"), first = 0;
8366       if (mask & OEX_FPU_DIV0)
8367         printf ("%sDIV0", first ? "" : "|"), first = 0;
8368       if (mask & OEX_FPU_INVAL)
8369         printf ("%sINVAL", first ? "" : "|");
8370     }
8371   else
8372     fputs ("0", stdout);
8373 }
8374
8375 static int
8376 process_mips_specific (file)
8377      FILE * file;
8378 {
8379   Elf_Internal_Dyn * entry;
8380   size_t liblist_offset = 0;
8381   size_t liblistno = 0;
8382   size_t conflictsno = 0;
8383   size_t options_offset = 0;
8384   size_t conflicts_offset = 0;
8385
8386   /* We have a lot of special sections.  Thanks SGI!  */
8387   if (dynamic_segment == NULL)
8388     /* No information available.  */
8389     return 0;
8390
8391   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
8392     switch (entry->d_tag)
8393       {
8394       case DT_MIPS_LIBLIST:
8395         liblist_offset = entry->d_un.d_val - loadaddr;
8396         break;
8397       case DT_MIPS_LIBLISTNO:
8398         liblistno = entry->d_un.d_val;
8399         break;
8400       case DT_MIPS_OPTIONS:
8401         options_offset = entry->d_un.d_val - loadaddr;
8402         break;
8403       case DT_MIPS_CONFLICT:
8404         conflicts_offset = entry->d_un.d_val - loadaddr;
8405         break;
8406       case DT_MIPS_CONFLICTNO:
8407         conflictsno = entry->d_un.d_val;
8408         break;
8409       default:
8410         break;
8411       }
8412
8413   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8414     {
8415       Elf32_External_Lib * elib;
8416       size_t cnt;
8417
8418       elib = ((Elf32_External_Lib *)
8419               get_data (NULL, file, liblist_offset,
8420                         liblistno * sizeof (Elf32_External_Lib),
8421                         _("liblist")));
8422       if (elib)
8423         {
8424           printf ("\nSection '.liblist' contains %lu entries:\n",
8425                   (unsigned long) liblistno);
8426           fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
8427                  stdout);
8428
8429           for (cnt = 0; cnt < liblistno; ++cnt)
8430             {
8431               Elf32_Lib liblist;
8432               time_t time;
8433               char timebuf[20];
8434               struct tm * tmp;
8435
8436               liblist.l_name = BYTE_GET (elib[cnt].l_name);
8437               time = BYTE_GET (elib[cnt].l_time_stamp);
8438               liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8439               liblist.l_version = BYTE_GET (elib[cnt].l_version);
8440               liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8441
8442               tmp = gmtime (&time);
8443               sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
8444                        tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8445                        tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8446
8447               printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
8448                       dynamic_strings + liblist.l_name, timebuf,
8449                       liblist.l_checksum, liblist.l_version);
8450
8451               if (liblist.l_flags == 0)
8452                 puts (" NONE");
8453               else
8454                 {
8455                   static const struct
8456                   {
8457                     const char * name;
8458                     int bit;
8459                   }
8460                   l_flags_vals[] =
8461                   {
8462                     { " EXACT_MATCH", LL_EXACT_MATCH },
8463                     { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8464                     { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8465                     { " EXPORTS", LL_EXPORTS },
8466                     { " DELAY_LOAD", LL_DELAY_LOAD },
8467                     { " DELTA", LL_DELTA }
8468                   };
8469                   int flags = liblist.l_flags;
8470                   size_t fcnt;
8471
8472                   for (fcnt = 0;
8473                        fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
8474                        ++fcnt)
8475                     if ((flags & l_flags_vals[fcnt].bit) != 0)
8476                       {
8477                         fputs (l_flags_vals[fcnt].name, stdout);
8478                         flags ^= l_flags_vals[fcnt].bit;
8479                       }
8480                   if (flags != 0)
8481                     printf (" %#x", (unsigned int) flags);
8482
8483                   puts ("");
8484                 }
8485             }
8486
8487           free (elib);
8488         }
8489     }
8490
8491   if (options_offset != 0)
8492     {
8493       Elf_External_Options * eopt;
8494       Elf_Internal_Shdr *    sect = section_headers;
8495       Elf_Internal_Options * iopt;
8496       Elf_Internal_Options * option;
8497       size_t offset;
8498       int cnt;
8499
8500       /* Find the section header so that we get the size.  */
8501       while (sect->sh_type != SHT_MIPS_OPTIONS)
8502         ++ sect;
8503
8504       eopt = (Elf_External_Options *) get_data (NULL, file, options_offset,
8505                                                 sect->sh_size, _("options"));
8506       if (eopt)
8507         {
8508           iopt = ((Elf_Internal_Options *)
8509                   malloc ((sect->sh_size / sizeof (eopt)) * sizeof (* iopt)));
8510           if (iopt == NULL)
8511             {
8512               error (_("Out of memory"));
8513               return 0;
8514             }
8515
8516           offset = cnt = 0;
8517           option = iopt;
8518
8519           while (offset < sect->sh_size)
8520             {
8521               Elf_External_Options * eoption;
8522
8523               eoption = (Elf_External_Options *) ((char *) eopt + offset);
8524
8525               option->kind = BYTE_GET (eoption->kind);
8526               option->size = BYTE_GET (eoption->size);
8527               option->section = BYTE_GET (eoption->section);
8528               option->info = BYTE_GET (eoption->info);
8529
8530               offset += option->size;
8531
8532               ++option;
8533               ++cnt;
8534             }
8535
8536           printf (_("\nSection '%s' contains %d entries:\n"),
8537                   SECTION_NAME (sect), cnt);
8538
8539           option = iopt;
8540
8541           while (cnt-- > 0)
8542             {
8543               size_t len;
8544
8545               switch (option->kind)
8546                 {
8547                 case ODK_NULL:
8548                   /* This shouldn't happen.  */
8549                   printf (" NULL       %d %lx", option->section, option->info);
8550                   break;
8551                 case ODK_REGINFO:
8552                   printf (" REGINFO    ");
8553                   if (elf_header.e_machine == EM_MIPS)
8554                     {
8555                       /* 32bit form.  */
8556                       Elf32_External_RegInfo * ereg;
8557                       Elf32_RegInfo            reginfo;
8558
8559                       ereg = (Elf32_External_RegInfo *) (option + 1);
8560                       reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8561                       reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8562                       reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8563                       reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8564                       reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8565                       reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8566
8567                       printf ("GPR %08lx  GP 0x%lx\n",
8568                               reginfo.ri_gprmask,
8569                               (unsigned long) reginfo.ri_gp_value);
8570                       printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
8571                               reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8572                               reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8573                     }
8574                   else
8575                     {
8576                       /* 64 bit form.  */
8577                       Elf64_External_RegInfo * ereg;
8578                       Elf64_Internal_RegInfo reginfo;
8579
8580                       ereg = (Elf64_External_RegInfo *) (option + 1);
8581                       reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
8582                       reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8583                       reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8584                       reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8585                       reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8586                       reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
8587
8588                       printf ("GPR %08lx  GP 0x",
8589                               reginfo.ri_gprmask);
8590                       printf_vma (reginfo.ri_gp_value);
8591                       printf ("\n");
8592
8593                       printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
8594                               reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8595                               reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8596                     }
8597                   ++option;
8598                   continue;
8599                 case ODK_EXCEPTIONS:
8600                   fputs (" EXCEPTIONS fpe_min(", stdout);
8601                   process_mips_fpe_exception (option->info & OEX_FPU_MIN);
8602                   fputs (") fpe_max(", stdout);
8603                   process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
8604                   fputs (")", stdout);
8605
8606                   if (option->info & OEX_PAGE0)
8607                     fputs (" PAGE0", stdout);
8608                   if (option->info & OEX_SMM)
8609                     fputs (" SMM", stdout);
8610                   if (option->info & OEX_FPDBUG)
8611                     fputs (" FPDBUG", stdout);
8612                   if (option->info & OEX_DISMISS)
8613                     fputs (" DISMISS", stdout);
8614                   break;
8615                 case ODK_PAD:
8616                   fputs (" PAD       ", stdout);
8617                   if (option->info & OPAD_PREFIX)
8618                     fputs (" PREFIX", stdout);
8619                   if (option->info & OPAD_POSTFIX)
8620                     fputs (" POSTFIX", stdout);
8621                   if (option->info & OPAD_SYMBOL)
8622                     fputs (" SYMBOL", stdout);
8623                   break;
8624                 case ODK_HWPATCH:
8625                   fputs (" HWPATCH   ", stdout);
8626                   if (option->info & OHW_R4KEOP)
8627                     fputs (" R4KEOP", stdout);
8628                   if (option->info & OHW_R8KPFETCH)
8629                     fputs (" R8KPFETCH", stdout);
8630                   if (option->info & OHW_R5KEOP)
8631                     fputs (" R5KEOP", stdout);
8632                   if (option->info & OHW_R5KCVTL)
8633                     fputs (" R5KCVTL", stdout);
8634                   break;
8635                 case ODK_FILL:
8636                   fputs (" FILL       ", stdout);
8637                   /* XXX Print content of info word?  */
8638                   break;
8639                 case ODK_TAGS:
8640                   fputs (" TAGS       ", stdout);
8641                   /* XXX Print content of info word?  */
8642                   break;
8643                 case ODK_HWAND:
8644                   fputs (" HWAND     ", stdout);
8645                   if (option->info & OHWA0_R4KEOP_CHECKED)
8646                     fputs (" R4KEOP_CHECKED", stdout);
8647                   if (option->info & OHWA0_R4KEOP_CLEAN)
8648                     fputs (" R4KEOP_CLEAN", stdout);
8649                   break;
8650                 case ODK_HWOR:
8651                   fputs (" HWOR      ", stdout);
8652                   if (option->info & OHWA0_R4KEOP_CHECKED)
8653                     fputs (" R4KEOP_CHECKED", stdout);
8654                   if (option->info & OHWA0_R4KEOP_CLEAN)
8655                     fputs (" R4KEOP_CLEAN", stdout);
8656                   break;
8657                 case ODK_GP_GROUP:
8658                   printf (" GP_GROUP  %#06lx  self-contained %#06lx",
8659                           option->info & OGP_GROUP,
8660                           (option->info & OGP_SELF) >> 16);
8661                   break;
8662                 case ODK_IDENT:
8663                   printf (" IDENT     %#06lx  self-contained %#06lx",
8664                           option->info & OGP_GROUP,
8665                           (option->info & OGP_SELF) >> 16);
8666                   break;
8667                 default:
8668                   /* This shouldn't happen.  */
8669                   printf (" %3d ???     %d %lx",
8670                           option->kind, option->section, option->info);
8671                   break;
8672                 }
8673
8674               len = sizeof (* eopt);
8675               while (len < option->size)
8676                 if (((char *) option)[len] >= ' '
8677                     && ((char *) option)[len] < 0x7f)
8678                   printf ("%c", ((char *) option)[len++]);
8679                 else
8680                   printf ("\\%03o", ((char *) option)[len++]);
8681
8682               fputs ("\n", stdout);
8683               ++option;
8684             }
8685
8686           free (eopt);
8687         }
8688     }
8689
8690   if (conflicts_offset != 0 && conflictsno != 0)
8691     {
8692       Elf32_Conflict * iconf;
8693       size_t cnt;
8694
8695       if (dynamic_symbols == NULL)
8696         {
8697           error (_("conflict list with without table"));
8698           return 0;
8699         }
8700
8701       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
8702       if (iconf == NULL)
8703         {
8704           error (_("Out of memory"));
8705           return 0;
8706         }
8707
8708       if (is_32bit_elf)
8709         {
8710           Elf32_External_Conflict * econf32;
8711
8712           econf32 = ((Elf32_External_Conflict *)
8713                      get_data (NULL, file, conflicts_offset,
8714                                conflictsno * sizeof (* econf32),
8715                                _("conflict")));
8716           if (!econf32)
8717             return 0;
8718
8719           for (cnt = 0; cnt < conflictsno; ++cnt)
8720             iconf[cnt] = BYTE_GET (econf32[cnt]);
8721
8722           free (econf32);
8723         }
8724       else
8725         {
8726           Elf64_External_Conflict * econf64;
8727
8728           econf64 = ((Elf64_External_Conflict *)
8729                      get_data (NULL, file, conflicts_offset,
8730                                conflictsno * sizeof (* econf64),
8731                                _("conflict")));
8732           if (!econf64)
8733             return 0;
8734
8735           for (cnt = 0; cnt < conflictsno; ++cnt)
8736             iconf[cnt] = BYTE_GET (econf64[cnt]);
8737
8738           free (econf64);
8739         }
8740
8741       printf (_("\nSection '.conflict' contains %ld entries:\n"),
8742               (long) conflictsno);
8743       puts (_("  Num:    Index       Value  Name"));
8744
8745       for (cnt = 0; cnt < conflictsno; ++cnt)
8746         {
8747           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
8748
8749           printf ("%5lu: %8lu  ", (unsigned long) cnt, iconf[cnt]);
8750           print_vma (psym->st_value, FULL_HEX);
8751           printf ("  %s\n", dynamic_strings + psym->st_name);
8752         }
8753
8754       free (iconf);
8755     }
8756
8757   return 1;
8758 }
8759
8760 static char *
8761 get_note_type (e_type)
8762      unsigned e_type;
8763 {
8764   static char buff[64];
8765
8766   switch (e_type)
8767     {
8768     case NT_PRSTATUS:   return _("NT_PRSTATUS (prstatus structure)");
8769     case NT_FPREGSET:   return _("NT_FPREGSET (floating point registers)");
8770     case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
8771     case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
8772     case NT_PRXFPREG:   return _("NT_PRXFPREG (user_xfpregs structure)");
8773     case NT_PSTATUS:    return _("NT_PSTATUS (pstatus structure)");
8774     case NT_FPREGS:     return _("NT_FPREGS (floating point registers)");
8775     case NT_PSINFO:     return _("NT_PSINFO (psinfo structure)");
8776     case NT_LWPSTATUS:  return _("NT_LWPSTATUS (lwpstatus_t structure)");
8777     case NT_LWPSINFO:   return _("NT_LWPSINFO (lwpsinfo_t structure)");
8778     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
8779     default:
8780       sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8781       return buff;
8782     }
8783 }
8784
8785 /* Note that by the ELF standard, the name field is already null byte
8786    terminated, and namesz includes the terminating null byte.
8787    I.E. the value of namesz for the name "FSF" is 4.
8788
8789    If the value of namesz is zero, there is no name present. */
8790 static int
8791 process_note (pnote)
8792   Elf32_Internal_Note * pnote;
8793 {
8794   printf ("  %s\t\t0x%08lx\t%s\n",
8795           pnote->namesz ? pnote->namedata : "(NONE)",
8796           pnote->descsz, get_note_type (pnote->type));
8797   return 1;
8798 }
8799
8800
8801 static int
8802 process_corefile_note_segment (file, offset, length)
8803      FILE * file;
8804      bfd_vma offset;
8805      bfd_vma length;
8806 {
8807   Elf_External_Note *  pnotes;
8808   Elf_External_Note *  external;
8809   int                  res = 1;
8810
8811   if (length <= 0)
8812     return 0;
8813
8814   pnotes = (Elf_External_Note *) get_data (NULL, file, offset, length,
8815                                            _("notes"));
8816   if (!pnotes)
8817     return 0;
8818
8819   external = pnotes;
8820
8821   printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
8822           (unsigned long) offset, (unsigned long) length);
8823   printf (_("  Owner\t\tData size\tDescription\n"));
8824
8825   while (external < (Elf_External_Note *)((char *) pnotes + length))
8826     {
8827       Elf32_Internal_Note inote;
8828       char * temp = NULL;
8829
8830       inote.type     = BYTE_GET (external->type);
8831       inote.namesz   = BYTE_GET (external->namesz);
8832       inote.namedata = external->name;
8833       inote.descsz   = BYTE_GET (external->descsz);
8834       inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8835       inote.descpos  = offset + (inote.descdata - (char *) pnotes);
8836
8837       external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8838
8839       /* Verify that name is null terminated.  It appears that at least
8840          one version of Linux (RedHat 6.0) generates corefiles that don't
8841          comply with the ELF spec by failing to include the null byte in
8842          namesz.  */
8843       if (inote.namedata[inote.namesz] != '\0')
8844         {
8845           temp = malloc (inote.namesz + 1);
8846
8847           if (temp == NULL)
8848             {
8849               error (_("Out of memory\n"));
8850               res = 0;
8851               break;
8852             }
8853
8854           strncpy (temp, inote.namedata, inote.namesz);
8855           temp[inote.namesz] = 0;
8856
8857           /* warn (_("'%s' NOTE name not properly null terminated\n"), temp);  */
8858           inote.namedata = temp;
8859         }
8860
8861       res &= process_note (& inote);
8862
8863       if (temp != NULL)
8864         {
8865           free (temp);
8866           temp = NULL;
8867         }
8868     }
8869
8870   free (pnotes);
8871
8872   return res;
8873 }
8874
8875 static int
8876 process_corefile_note_segments (file)
8877      FILE * file;
8878 {
8879   Elf_Internal_Phdr * program_headers;
8880   Elf_Internal_Phdr * segment;
8881   unsigned int        i;
8882   int                 res = 1;
8883
8884   program_headers = (Elf_Internal_Phdr *) malloc
8885     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8886
8887   if (program_headers == NULL)
8888     {
8889       error (_("Out of memory\n"));
8890       return 0;
8891     }
8892
8893   if (is_32bit_elf)
8894     i = get_32bit_program_headers (file, program_headers);
8895   else
8896     i = get_64bit_program_headers (file, program_headers);
8897
8898   if (i == 0)
8899     {
8900       free (program_headers);
8901       return 0;
8902     }
8903
8904   for (i = 0, segment = program_headers;
8905        i < elf_header.e_phnum;
8906        i ++, segment ++)
8907     {
8908       if (segment->p_type == PT_NOTE)
8909         res &= process_corefile_note_segment (file,
8910                                               (bfd_vma) segment->p_offset,
8911                                               (bfd_vma) segment->p_filesz);
8912     }
8913
8914   free (program_headers);
8915
8916   return res;
8917 }
8918
8919 static int
8920 process_corefile_contents (file)
8921      FILE * file;
8922 {
8923   /* If we have not been asked to display the notes then do nothing.  */
8924   if (! do_notes)
8925     return 1;
8926
8927   /* If file is not a core file then exit.  */
8928   if (elf_header.e_type != ET_CORE)
8929     return 1;
8930
8931   /* No program headers means no NOTE segment.  */
8932   if (elf_header.e_phnum == 0)
8933     {
8934       printf (_("No note segments present in the core file.\n"));
8935       return 1;
8936    }
8937
8938   return process_corefile_note_segments (file);
8939 }
8940
8941 static int
8942 process_arch_specific (file)
8943      FILE * file;
8944 {
8945   if (! do_arch)
8946     return 1;
8947
8948   switch (elf_header.e_machine)
8949     {
8950     case EM_MIPS:
8951     case EM_MIPS_RS3_LE:
8952       return process_mips_specific (file);
8953       break;
8954     default:
8955       break;
8956     }
8957   return 1;
8958 }
8959
8960 static int
8961 get_file_header (file)
8962      FILE * file;
8963 {
8964   /* Read in the identity array.  */
8965   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
8966     return 0;
8967
8968   /* Determine how to read the rest of the header.  */
8969   switch (elf_header.e_ident [EI_DATA])
8970     {
8971     default: /* fall through */
8972     case ELFDATANONE: /* fall through */
8973     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8974     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8975     }
8976
8977   /* For now we only support 32 bit and 64 bit ELF files.  */
8978   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8979
8980   /* Read in the rest of the header.  */
8981   if (is_32bit_elf)
8982     {
8983       Elf32_External_Ehdr ehdr32;
8984
8985       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8986         return 0;
8987
8988       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
8989       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
8990       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
8991       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
8992       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
8993       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
8994       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
8995       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
8996       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8997       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
8998       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8999       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
9000       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
9001     }
9002   else
9003     {
9004       Elf64_External_Ehdr ehdr64;
9005
9006       /* If we have been compiled with sizeof (bfd_vma) == 4, then
9007          we will not be able to cope with the 64bit data found in
9008          64 ELF files.  Detect this now and abort before we start
9009          overwritting things.  */
9010       if (sizeof (bfd_vma) < 8)
9011         {
9012           error (_("This instance of readelf has been built without support for a\n"));
9013           error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
9014           return 0;
9015         }
9016
9017       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
9018         return 0;
9019
9020       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
9021       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
9022       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
9023       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
9024       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
9025       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
9026       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
9027       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
9028       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
9029       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
9030       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
9031       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
9032       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
9033     }
9034
9035   return 1;
9036 }
9037
9038 static int
9039 process_file (file_name)
9040      char * file_name;
9041 {
9042   FILE *       file;
9043   struct stat  statbuf;
9044   unsigned int i;
9045
9046   if (stat (file_name, & statbuf) < 0)
9047     {
9048       error (_("Cannot stat input file %s.\n"), file_name);
9049       return 1;
9050     }
9051
9052   file = fopen (file_name, "rb");
9053   if (file == NULL)
9054     {
9055       error (_("Input file %s not found.\n"), file_name);
9056       return 1;
9057     }
9058
9059   if (! get_file_header (file))
9060     {
9061       error (_("%s: Failed to read file header\n"), file_name);
9062       fclose (file);
9063       return 1;
9064     }
9065
9066   /* Initialise per file variables.  */
9067   for (i = NUM_ELEM (version_info); i--;)
9068     version_info[i] = 0;
9069
9070   for (i = NUM_ELEM (dynamic_info); i--;)
9071     dynamic_info[i] = 0;
9072
9073   /* Process the file.  */
9074   if (show_name)
9075     printf (_("\nFile: %s\n"), file_name);
9076
9077   if (! process_file_header ())
9078     {
9079       fclose (file);
9080       return 1;
9081     }
9082
9083   process_section_headers (file);
9084
9085   process_program_headers (file);
9086
9087   process_dynamic_segment (file);
9088
9089   process_relocs (file);
9090
9091   process_unwind (file);
9092
9093   process_symbol_table (file);
9094
9095   process_syminfo (file);
9096
9097   process_version_sections (file);
9098
9099   process_section_contents (file);
9100
9101   process_corefile_contents (file);
9102
9103   process_arch_specific (file);
9104
9105   fclose (file);
9106
9107   if (section_headers)
9108     {
9109       free (section_headers);
9110       section_headers = NULL;
9111     }
9112
9113   if (string_table)
9114     {
9115       free (string_table);
9116       string_table = NULL;
9117       string_table_length = 0;
9118     }
9119
9120   if (dynamic_strings)
9121     {
9122       free (dynamic_strings);
9123       dynamic_strings = NULL;
9124     }
9125
9126   if (dynamic_symbols)
9127     {
9128       free (dynamic_symbols);
9129       dynamic_symbols = NULL;
9130       num_dynamic_syms = 0;
9131     }
9132
9133   if (dynamic_syminfo)
9134     {
9135       free (dynamic_syminfo);
9136       dynamic_syminfo = NULL;
9137     }
9138
9139   return 0;
9140 }
9141
9142 #ifdef SUPPORT_DISASSEMBLY
9143 /* Needed by the i386 disassembler.  For extra credit, someone could
9144    fix this so that we insert symbolic addresses here, esp for GOT/PLT
9145    symbols */
9146
9147 void
9148 print_address (unsigned int addr, FILE * outfile)
9149 {
9150   fprintf (outfile,"0x%8.8x", addr);
9151 }
9152
9153 /* Needed by the i386 disassembler. */
9154 void
9155 db_task_printsym (unsigned int addr)
9156 {
9157   print_address (addr, stderr);
9158 }
9159 #endif
9160
9161 int main PARAMS ((int, char **));
9162
9163 int
9164 main (argc, argv)
9165      int     argc;
9166      char ** argv;
9167 {
9168   int err;
9169
9170 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
9171   setlocale (LC_MESSAGES, "");
9172 #endif
9173 #if defined (HAVE_SETLOCALE)
9174   setlocale (LC_CTYPE, "");
9175 #endif
9176   bindtextdomain (PACKAGE, LOCALEDIR);
9177   textdomain (PACKAGE);
9178
9179   parse_args (argc, argv);
9180
9181   if (optind < (argc - 1))
9182     show_name = 1;
9183
9184   err = 0;
9185   while (optind < argc)
9186     err |= process_file (argv [optind ++]);
9187
9188   if (dump_sects != NULL)
9189     free (dump_sects);
9190
9191   return err;
9192 }