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