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