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