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