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