Add MIPS SB1 machine
[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       else if (do_debug_frames && strcmp (name, ".eh_frame") == 0)
2769         request_dump (i, DEBUG_DUMP);
2770     }
2771
2772   if (! do_sections)
2773     return 1;
2774
2775   printf (_("\nSection Header%s:\n"), elf_header.e_shnum > 1 ? "s" : "");
2776
2777   if (is_32bit_elf)
2778     printf
2779       (_("  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al\n"));
2780   else
2781     {
2782       printf (_("  [Nr] Name              Type             Address           Offset\n"));
2783       printf (_("       Size              EntSize          Flags  Link  Info  Align\n"));
2784     }
2785
2786   for (i = 0, section = section_headers;
2787        i < elf_header.e_shnum;
2788        i ++, section ++)
2789     {
2790       printf ("  [%2d] %-17.17s %-15.15s ",
2791               i,
2792               SECTION_NAME (section),
2793               get_section_type_name (section->sh_type));
2794
2795       if (is_32bit_elf)
2796         {
2797           print_vma (section->sh_addr, LONG_HEX);
2798
2799           printf ( " %6.6lx %6.6lx %2.2lx",
2800                    (unsigned long) section->sh_offset,
2801                    (unsigned long) section->sh_size,
2802                    (unsigned long) section->sh_entsize);
2803
2804           printf (" %3s ", get_elf_section_flags (section->sh_flags));
2805
2806           printf ("%2ld %3lx %2ld\n",
2807                   (unsigned long) section->sh_link,
2808                   (unsigned long) section->sh_info,
2809                   (unsigned long) section->sh_addralign);
2810         }
2811       else
2812         {
2813           putchar (' ');
2814           print_vma (section->sh_addr, LONG_HEX);
2815           printf ("  %8.8lx", section->sh_offset);
2816           printf ("\n       ");
2817           print_vma (section->sh_size, LONG_HEX);
2818           printf ("  ");
2819           print_vma (section->sh_entsize, LONG_HEX);
2820
2821           printf (" %3s ", get_elf_section_flags (section->sh_flags));
2822
2823           printf ("     %2ld   %3lx     %ld\n",
2824                   (unsigned long) section->sh_link,
2825                   (unsigned long) section->sh_info,
2826                   (unsigned long) section->sh_addralign);
2827         }
2828     }
2829
2830   printf (_("Key to Flags:\n"));
2831   printf (_("  W (write), A (alloc), X (execute), M (merge), S (strings)\n"));
2832   printf (_("  I (info), L (link order), G (group), x (unknown)\n"));
2833   printf (_("  O (extra OS processing required) o (OS specific), p (processor specific)\n"));
2834
2835   return 1;
2836 }
2837
2838 /* Process the reloc section.  */
2839 static int
2840 process_relocs (file)
2841      FILE * file;
2842 {
2843   unsigned long    rel_size;
2844   unsigned long    rel_offset;
2845
2846
2847   if (!do_reloc)
2848     return 1;
2849
2850   if (do_using_dynamic)
2851     {
2852       int is_rela = FALSE;
2853
2854       rel_size   = 0;
2855       rel_offset = 0;
2856
2857       if (dynamic_info[DT_REL])
2858         {
2859           rel_offset = dynamic_info[DT_REL];
2860           rel_size   = dynamic_info[DT_RELSZ];
2861           is_rela    = FALSE;
2862         }
2863       else if (dynamic_info [DT_RELA])
2864         {
2865           rel_offset = dynamic_info[DT_RELA];
2866           rel_size   = dynamic_info[DT_RELASZ];
2867           is_rela    = TRUE;
2868         }
2869       else if (dynamic_info[DT_JMPREL])
2870         {
2871           rel_offset = dynamic_info[DT_JMPREL];
2872           rel_size   = dynamic_info[DT_PLTRELSZ];
2873
2874           switch (dynamic_info[DT_PLTREL])
2875             {
2876             case DT_REL:
2877               is_rela = FALSE;
2878               break;
2879             case DT_RELA:
2880               is_rela = TRUE;
2881               break;
2882             default:
2883               is_rela = UNKNOWN;
2884               break;
2885             }
2886         }
2887
2888       if (rel_size)
2889         {
2890           printf
2891             (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
2892              rel_offset, rel_size);
2893
2894           dump_relocations (file, rel_offset - loadaddr, rel_size,
2895                             dynamic_symbols, num_dynamic_syms, dynamic_strings, is_rela);
2896         }
2897       else
2898         printf (_("\nThere are no dynamic relocations in this file.\n"));
2899     }
2900   else
2901     {
2902       Elf32_Internal_Shdr *     section;
2903       unsigned long             i;
2904       int                       found = 0;
2905
2906       for (i = 0, section = section_headers;
2907            i < elf_header.e_shnum;
2908            i++, section ++)
2909         {
2910           if (   section->sh_type != SHT_RELA
2911               && section->sh_type != SHT_REL)
2912             continue;
2913
2914           rel_offset = section->sh_offset;
2915           rel_size   = section->sh_size;
2916
2917           if (rel_size)
2918             {
2919               Elf32_Internal_Shdr * strsec;
2920               Elf32_Internal_Shdr * symsec;
2921               Elf_Internal_Sym *    symtab;
2922               char *                strtab;
2923               int                   is_rela;
2924               unsigned long         nsyms;
2925
2926               printf (_("\nRelocation section "));
2927
2928               if (string_table == NULL)
2929                 printf ("%d", section->sh_name);
2930               else
2931                 printf ("'%s'", SECTION_NAME (section));
2932
2933               printf (_(" at offset 0x%lx contains %lu entries:\n"),
2934                  rel_offset, (unsigned long) (rel_size / section->sh_entsize));
2935
2936               symsec = section_headers + section->sh_link;
2937
2938               nsyms = symsec->sh_size / symsec->sh_entsize;
2939               symtab = GET_ELF_SYMBOLS (file, symsec->sh_offset, nsyms);
2940
2941               if (symtab == NULL)
2942                 continue;
2943
2944               strsec = section_headers + symsec->sh_link;
2945
2946               GET_DATA_ALLOC (strsec->sh_offset, strsec->sh_size, strtab,
2947                               char *, "string table");
2948
2949               is_rela = section->sh_type == SHT_RELA;
2950
2951               dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela);
2952
2953               free (strtab);
2954               free (symtab);
2955
2956               found = 1;
2957             }
2958         }
2959
2960       if (! found)
2961         printf (_("\nThere are no relocations in this file.\n"));
2962     }
2963
2964   return 1;
2965 }
2966
2967
2968 static void
2969 dynamic_segment_mips_val (entry)
2970      Elf_Internal_Dyn * entry;
2971 {
2972   switch (entry->d_tag)
2973     {
2974     case DT_MIPS_FLAGS:
2975       if (entry->d_un.d_val == 0)
2976         printf ("NONE\n");
2977       else
2978         {
2979           static const char * opts[] =
2980           {
2981             "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
2982             "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
2983             "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
2984             "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
2985             "RLD_ORDER_SAFE"
2986           };
2987           unsigned int cnt;
2988           int first = 1;
2989           for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
2990             if (entry->d_un.d_val & (1 << cnt))
2991               {
2992                 printf ("%s%s", first ? "" : " ", opts[cnt]);
2993                 first = 0;
2994               }
2995           puts ("");
2996         }
2997       break;
2998
2999     case DT_MIPS_IVERSION:
3000       if (dynamic_strings != NULL)
3001         printf ("Interface Version: %s\n",
3002                 dynamic_strings + entry->d_un.d_val);
3003       else
3004         printf ("%ld\n", (long) entry->d_un.d_ptr);
3005       break;
3006
3007     case DT_MIPS_TIME_STAMP:
3008       {
3009         char timebuf[20];
3010         struct tm * tmp;
3011
3012         time_t time = entry->d_un.d_val;
3013         tmp = gmtime (&time);
3014         sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
3015                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
3016                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
3017         printf ("Time Stamp: %s\n", timebuf);
3018       }
3019       break;
3020
3021     case DT_MIPS_RLD_VERSION:
3022     case DT_MIPS_LOCAL_GOTNO:
3023     case DT_MIPS_CONFLICTNO:
3024     case DT_MIPS_LIBLISTNO:
3025     case DT_MIPS_SYMTABNO:
3026     case DT_MIPS_UNREFEXTNO:
3027     case DT_MIPS_HIPAGENO:
3028     case DT_MIPS_DELTA_CLASS_NO:
3029     case DT_MIPS_DELTA_INSTANCE_NO:
3030     case DT_MIPS_DELTA_RELOC_NO:
3031     case DT_MIPS_DELTA_SYM_NO:
3032     case DT_MIPS_DELTA_CLASSSYM_NO:
3033     case DT_MIPS_COMPACT_SIZE:
3034       printf ("%ld\n", (long) entry->d_un.d_ptr);
3035       break;
3036
3037     default:
3038       printf ("%#lx\n", (long) entry->d_un.d_ptr);
3039     }
3040 }
3041
3042
3043 static void
3044 dynamic_segment_parisc_val (entry)
3045      Elf_Internal_Dyn * entry;
3046 {
3047   switch (entry->d_tag)
3048     {
3049     case DT_HP_DLD_FLAGS:
3050       {
3051         static struct
3052         {
3053           long int bit;
3054           const char * str;
3055         }
3056         flags[] =
3057         {
3058           { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
3059           { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
3060           { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
3061           { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
3062           { DT_HP_BIND_NOW, "HP_BIND_NOW" },
3063           { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
3064           { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
3065           { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
3066           { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
3067           { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
3068           { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
3069         };
3070         int first = 1;
3071         size_t cnt;
3072         bfd_vma val = entry->d_un.d_val;
3073
3074         for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
3075           if (val & flags[cnt].bit)
3076             {
3077               if (! first)
3078                 putchar (' ');
3079               fputs (flags[cnt].str, stdout);
3080               first = 0;
3081               val ^= flags[cnt].bit;
3082             }
3083
3084         if (val != 0 || first)
3085           {
3086             if (! first)
3087               putchar (' ');
3088             print_vma (val, HEX);
3089           }
3090       }
3091       break;
3092
3093     default:
3094       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
3095       break;
3096     }
3097 }
3098
3099 static int
3100 get_32bit_dynamic_segment (file)
3101      FILE * file;
3102 {
3103   Elf32_External_Dyn * edyn;
3104   Elf_Internal_Dyn *   entry;
3105   bfd_size_type        i;
3106
3107   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3108                   edyn, Elf32_External_Dyn *, "dynamic segment");
3109
3110   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
3111      how large this .dynamic is now.  We can do this even before the byte
3112      swapping since the DT_NULL tag is recognizable.  */
3113   dynamic_size = 0;
3114   while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
3115     ;
3116
3117   dynamic_segment = (Elf_Internal_Dyn *)
3118     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3119
3120   if (dynamic_segment == NULL)
3121     {
3122       error (_("Out of memory\n"));
3123       free (edyn);
3124       return 0;
3125     }
3126
3127   for (i = 0, entry = dynamic_segment;
3128        i < dynamic_size;
3129        i ++, entry ++)
3130     {
3131       entry->d_tag      = BYTE_GET (edyn [i].d_tag);
3132       entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
3133     }
3134
3135   free (edyn);
3136
3137   return 1;
3138 }
3139
3140 static int
3141 get_64bit_dynamic_segment (file)
3142      FILE * file;
3143 {
3144   Elf64_External_Dyn * edyn;
3145   Elf_Internal_Dyn *   entry;
3146   bfd_size_type        i;
3147
3148   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3149                   edyn, Elf64_External_Dyn *, "dynamic segment");
3150
3151   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
3152      how large this .dynamic is now.  We can do this even before the byte
3153      swapping since the DT_NULL tag is recognizable.  */
3154   dynamic_size = 0;
3155   while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
3156     ;
3157
3158   dynamic_segment = (Elf_Internal_Dyn *)
3159     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3160
3161   if (dynamic_segment == NULL)
3162     {
3163       error (_("Out of memory\n"));
3164       free (edyn);
3165       return 0;
3166     }
3167
3168   for (i = 0, entry = dynamic_segment;
3169        i < dynamic_size;
3170        i ++, entry ++)
3171     {
3172       entry->d_tag      = BYTE_GET8 (edyn [i].d_tag);
3173       entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
3174     }
3175
3176   free (edyn);
3177
3178   return 1;
3179 }
3180
3181 static const char *
3182 get_dynamic_flags (flags)
3183      bfd_vma flags;
3184 {
3185   static char buff [64];
3186   while (flags)
3187     {
3188       bfd_vma flag;
3189
3190       flag = flags & - flags;
3191       flags &= ~ flag;
3192
3193       switch (flag)
3194         {
3195         case DF_ORIGIN:   strcat (buff, "ORIGIN "); break;
3196         case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
3197         case DF_TEXTREL:  strcat (buff, "TEXTREL "); break;
3198         case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
3199         default:          strcat (buff, "unknown "); break;
3200         }
3201     }
3202   return buff;
3203 }
3204
3205 /* Parse and display the contents of the dynamic segment.  */
3206 static int
3207 process_dynamic_segment (file)
3208      FILE * file;
3209 {
3210   Elf_Internal_Dyn * entry;
3211   bfd_size_type      i;
3212
3213   if (dynamic_size == 0)
3214     {
3215       if (do_dynamic)
3216         printf (_("\nThere is no dynamic segment in this file.\n"));
3217
3218       return 1;
3219     }
3220
3221   if (is_32bit_elf)
3222     {
3223       if (! get_32bit_dynamic_segment (file))
3224         return 0;
3225     }
3226   else if (! get_64bit_dynamic_segment (file))
3227     return 0;
3228
3229   /* Find the appropriate symbol table.  */
3230   if (dynamic_symbols == NULL)
3231     {
3232       for (i = 0, entry = dynamic_segment;
3233            i < dynamic_size;
3234            ++i, ++ entry)
3235         {
3236           unsigned long        offset;
3237
3238           if (entry->d_tag != DT_SYMTAB)
3239             continue;
3240
3241           dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
3242
3243           /* Since we do not know how big the symbol table is,
3244              we default to reading in the entire file (!) and
3245              processing that.  This is overkill, I know, but it
3246              should work. */
3247           offset = entry->d_un.d_val - loadaddr;
3248
3249           if (fseek (file, 0, SEEK_END))
3250             error (_("Unable to seek to end of file!"));
3251
3252           if (is_32bit_elf)
3253             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
3254           else
3255             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
3256
3257           if (num_dynamic_syms < 1)
3258             {
3259               error (_("Unable to determine the number of symbols to load\n"));
3260               continue;
3261             }
3262
3263           dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
3264         }
3265     }
3266
3267   /* Similarly find a string table.  */
3268   if (dynamic_strings == NULL)
3269     {
3270       for (i = 0, entry = dynamic_segment;
3271            i < dynamic_size;
3272            ++i, ++ entry)
3273         {
3274           unsigned long offset;
3275           long          str_tab_len;
3276
3277           if (entry->d_tag != DT_STRTAB)
3278             continue;
3279
3280           dynamic_info[DT_STRTAB] = entry->d_un.d_val;
3281
3282           /* Since we do not know how big the string table is,
3283              we default to reading in the entire file (!) and
3284              processing that.  This is overkill, I know, but it
3285              should work. */
3286
3287           offset = entry->d_un.d_val - loadaddr;
3288           if (fseek (file, 0, SEEK_END))
3289             error (_("Unable to seek to end of file\n"));
3290           str_tab_len = ftell (file) - offset;
3291
3292           if (str_tab_len < 1)
3293             {
3294               error
3295                 (_("Unable to determine the length of the dynamic string table\n"));
3296               continue;
3297             }
3298
3299           GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
3300                           "dynamic string table");
3301
3302           break;
3303         }
3304     }
3305
3306   /* And find the syminfo section if available.  */
3307   if (dynamic_syminfo == NULL)
3308     {
3309       unsigned int syminsz = 0;
3310
3311       for (i = 0, entry = dynamic_segment;
3312            i < dynamic_size;
3313            ++i, ++ entry)
3314         {
3315           if (entry->d_tag == DT_SYMINENT)
3316             {
3317               /* Note: these braces are necessary to avoid a syntax
3318                  error from the SunOS4 C compiler.  */
3319               assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
3320             }
3321           else if (entry->d_tag == DT_SYMINSZ)
3322             syminsz = entry->d_un.d_val;
3323           else if (entry->d_tag == DT_SYMINFO)
3324             dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
3325         }
3326
3327       if (dynamic_syminfo_offset != 0 && syminsz != 0)
3328         {
3329           Elf_External_Syminfo * extsyminfo;
3330           Elf_Internal_Syminfo * syminfo;
3331
3332           /* There is a syminfo section.  Read the data.  */
3333           GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
3334                           Elf_External_Syminfo *, "symbol information");
3335
3336           dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
3337           if (dynamic_syminfo == NULL)
3338             {
3339               error (_("Out of memory\n"));
3340               return 0;
3341             }
3342
3343           dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
3344           for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
3345                ++i, ++syminfo)
3346             {
3347               syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
3348               syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
3349             }
3350
3351           free (extsyminfo);
3352         }
3353     }
3354
3355   if (do_dynamic && dynamic_addr)
3356     printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
3357             dynamic_addr, (long) dynamic_size);
3358   if (do_dynamic)
3359     printf (_("  Tag        Type                         Name/Value\n"));
3360
3361   for (i = 0, entry = dynamic_segment;
3362        i < dynamic_size;
3363        i++, entry ++)
3364     {
3365       if (do_dynamic)
3366         {
3367           const char * dtype;
3368
3369           putchar (' ');
3370           print_vma (entry->d_tag, FULL_HEX);
3371           dtype = get_dynamic_type (entry->d_tag);
3372           printf (" (%s)%*s", dtype,
3373                   ((is_32bit_elf ? 27 : 19)
3374                    - (int) strlen (dtype)),
3375                   " ");
3376         }
3377
3378       switch (entry->d_tag)
3379         {
3380         case DT_FLAGS:
3381           if (do_dynamic)
3382             printf ("%s", get_dynamic_flags (entry->d_un.d_val));
3383           break;
3384
3385         case DT_AUXILIARY:
3386         case DT_FILTER:
3387         case DT_CONFIG:
3388         case DT_DEPAUDIT:
3389         case DT_AUDIT:
3390           if (do_dynamic)
3391             {
3392               switch (entry->d_tag)
3393                 {
3394                 case DT_AUXILIARY:
3395                   printf (_("Auxiliary library"));
3396                   break;
3397
3398                 case DT_FILTER:
3399                   printf (_("Filter library"));
3400                   break;
3401
3402                 case DT_CONFIG:
3403                   printf (_("Configuration file"));
3404                   break;
3405
3406                 case DT_DEPAUDIT:
3407                   printf (_("Dependency audit library"));
3408                   break;
3409
3410                 case DT_AUDIT:
3411                   printf (_("Audit library"));
3412                   break;
3413                 }
3414
3415               if (dynamic_strings)
3416                 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
3417               else
3418                 {
3419                   printf (": ");
3420                   print_vma (entry->d_un.d_val, PREFIX_HEX);
3421                   putchar ('\n');
3422                 }
3423             }
3424           break;
3425
3426         case DT_FEATURE:
3427           if (do_dynamic)
3428             {
3429               printf (_("Flags:"));
3430               if (entry->d_un.d_val == 0)
3431                 printf (_(" None\n"));
3432               else
3433                 {
3434                   unsigned long int val = entry->d_un.d_val;
3435                   if (val & DTF_1_PARINIT)
3436                     {
3437                       printf (" PARINIT");
3438                       val ^= DTF_1_PARINIT;
3439                     }
3440                   if (val & DTF_1_CONFEXP)
3441                     {
3442                       printf (" CONFEXP");
3443                       val ^= DTF_1_CONFEXP;
3444                     }
3445                   if (val != 0)
3446                     printf (" %lx", val);
3447                   puts ("");
3448                 }
3449             }
3450           break;
3451
3452         case DT_POSFLAG_1:
3453           if (do_dynamic)
3454             {
3455               printf (_("Flags:"));
3456               if (entry->d_un.d_val == 0)
3457                 printf (_(" None\n"));
3458               else
3459                 {
3460                   unsigned long int val = entry->d_un.d_val;
3461                   if (val & DF_P1_LAZYLOAD)
3462                     {
3463                       printf (" LAZYLOAD");
3464                       val ^= DF_P1_LAZYLOAD;
3465                     }
3466                   if (val & DF_P1_GROUPPERM)
3467                     {
3468                       printf (" GROUPPERM");
3469                       val ^= DF_P1_GROUPPERM;
3470                     }
3471                   if (val != 0)
3472                     printf (" %lx", val);
3473                   puts ("");
3474                 }
3475             }
3476           break;
3477
3478         case DT_FLAGS_1:
3479           if (do_dynamic)
3480             {
3481               printf (_("Flags:"));
3482               if (entry->d_un.d_val == 0)
3483                 printf (_(" None\n"));
3484               else
3485                 {
3486                   unsigned long int val = entry->d_un.d_val;
3487                   if (val & DF_1_NOW)
3488                     {
3489                       printf (" NOW");
3490                       val ^= DF_1_NOW;
3491                     }
3492                   if (val & DF_1_GLOBAL)
3493                     {
3494                       printf (" GLOBAL");
3495                       val ^= DF_1_GLOBAL;
3496                     }
3497                   if (val & DF_1_GROUP)
3498                     {
3499                       printf (" GROUP");
3500                       val ^= DF_1_GROUP;
3501                     }
3502                   if (val & DF_1_NODELETE)
3503                     {
3504                       printf (" NODELETE");
3505                       val ^= DF_1_NODELETE;
3506                     }
3507                   if (val & DF_1_LOADFLTR)
3508                     {
3509                       printf (" LOADFLTR");
3510                       val ^= DF_1_LOADFLTR;
3511                     }
3512                   if (val & DF_1_INITFIRST)
3513                     {
3514                       printf (" INITFIRST");
3515                       val ^= DF_1_INITFIRST;
3516                     }
3517                   if (val & DF_1_NOOPEN)
3518                     {
3519                       printf (" NOOPEN");
3520                       val ^= DF_1_NOOPEN;
3521                     }
3522                   if (val & DF_1_ORIGIN)
3523                     {
3524                       printf (" ORIGIN");
3525                       val ^= DF_1_ORIGIN;
3526                     }
3527                   if (val & DF_1_DIRECT)
3528                     {
3529                       printf (" DIRECT");
3530                       val ^= DF_1_DIRECT;
3531                     }
3532                   if (val & DF_1_TRANS)
3533                     {
3534                       printf (" TRANS");
3535                       val ^= DF_1_TRANS;
3536                     }
3537                   if (val & DF_1_INTERPOSE)
3538                     {
3539                       printf (" INTERPOSE");
3540                       val ^= DF_1_INTERPOSE;
3541                     }
3542                   if (val & DF_1_NODEFLIB)
3543                     {
3544                       printf (" NODEFLIB");
3545                       val ^= DF_1_NODEFLIB;
3546                     }
3547                   if (val & DF_1_NODUMP)
3548                     {
3549                       printf (" NODUMP");
3550                       val ^= DF_1_NODUMP;
3551                     }
3552                   if (val & DF_1_CONLFAT)
3553                     {
3554                       printf (" CONLFAT");
3555                       val ^= DF_1_CONLFAT;
3556                     }
3557                   if (val != 0)
3558                     printf (" %lx", val);
3559                   puts ("");
3560                 }
3561             }
3562           break;
3563
3564         case DT_PLTREL:
3565           if (do_dynamic)
3566             puts (get_dynamic_type (entry->d_un.d_val));
3567           break;
3568
3569         case DT_NULL    :
3570         case DT_NEEDED  :
3571         case DT_PLTGOT  :
3572         case DT_HASH    :
3573         case DT_STRTAB  :
3574         case DT_SYMTAB  :
3575         case DT_RELA    :
3576         case DT_INIT    :
3577         case DT_FINI    :
3578         case DT_SONAME  :
3579         case DT_RPATH   :
3580         case DT_SYMBOLIC:
3581         case DT_REL     :
3582         case DT_DEBUG   :
3583         case DT_TEXTREL :
3584         case DT_JMPREL  :
3585         case DT_RUNPATH :
3586           dynamic_info[entry->d_tag] = entry->d_un.d_val;
3587
3588           if (do_dynamic)
3589             {
3590               char * name;
3591
3592               if (dynamic_strings == NULL)
3593                 name = NULL;
3594               else
3595                 name = dynamic_strings + entry->d_un.d_val;
3596
3597               if (name)
3598                 {
3599                   switch (entry->d_tag)
3600                     {
3601                     case DT_NEEDED:
3602                       printf (_("Shared library: [%s]"), name);
3603
3604                       if (strcmp (name, program_interpreter) == 0)
3605                         printf (_(" program interpreter"));
3606                       break;
3607
3608                     case DT_SONAME:
3609                       printf (_("Library soname: [%s]"), name);
3610                       break;
3611
3612                     case DT_RPATH:
3613                       printf (_("Library rpath: [%s]"), name);
3614                       break;
3615
3616                     case DT_RUNPATH:
3617                       printf (_("Library runpath: [%s]"), name);
3618                       break;
3619
3620                     default:
3621                       print_vma (entry->d_un.d_val, PREFIX_HEX);
3622                       break;
3623                     }
3624                 }
3625               else
3626                 print_vma (entry->d_un.d_val, PREFIX_HEX);
3627
3628               putchar ('\n');
3629             }
3630           break;
3631
3632         case DT_PLTRELSZ:
3633         case DT_RELASZ  :
3634         case DT_STRSZ   :
3635         case DT_RELSZ   :
3636         case DT_RELAENT :
3637         case DT_SYMENT  :
3638         case DT_RELENT  :
3639         case DT_PLTPADSZ:
3640         case DT_MOVEENT :
3641         case DT_MOVESZ  :
3642         case DT_INIT_ARRAYSZ:
3643         case DT_FINI_ARRAYSZ:
3644           if (do_dynamic)
3645             {
3646               print_vma (entry->d_un.d_val, UNSIGNED);
3647               printf (" (bytes)\n");
3648             }
3649           break;
3650
3651         case DT_VERDEFNUM:
3652         case DT_VERNEEDNUM:
3653         case DT_RELACOUNT:
3654         case DT_RELCOUNT:
3655           if (do_dynamic)
3656             {
3657               print_vma (entry->d_un.d_val, UNSIGNED);
3658               putchar ('\n');
3659             }
3660           break;
3661
3662         case DT_SYMINSZ:
3663         case DT_SYMINENT:
3664         case DT_SYMINFO:
3665         case DT_USED:
3666         case DT_INIT_ARRAY:
3667         case DT_FINI_ARRAY:
3668           if (do_dynamic)
3669             {
3670               if (dynamic_strings != NULL && entry->d_tag == DT_USED)
3671                 {
3672                   char * name;
3673
3674                   name = dynamic_strings + entry->d_un.d_val;
3675
3676                   if (* name)
3677                     {
3678                       printf (_("Not needed object: [%s]\n"), name);
3679                       break;
3680                     }
3681                 }
3682
3683               print_vma (entry->d_un.d_val, PREFIX_HEX);
3684               putchar ('\n');
3685             }
3686           break;
3687
3688         case DT_BIND_NOW:
3689           /* The value of this entry is ignored.  */
3690           break;
3691
3692         default:
3693           if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
3694             version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
3695               entry->d_un.d_val;
3696
3697           if (do_dynamic)
3698             {
3699               switch (elf_header.e_machine)
3700                 {
3701                 case EM_MIPS:
3702                 case EM_MIPS_RS4_BE:
3703                   dynamic_segment_mips_val (entry);
3704                   break;
3705                 case EM_PARISC:
3706                   dynamic_segment_parisc_val (entry);
3707                   break;
3708                 default:
3709                   print_vma (entry->d_un.d_val, PREFIX_HEX);
3710                   putchar ('\n');
3711                 }
3712             }
3713           break;
3714         }
3715     }
3716
3717   return 1;
3718 }
3719
3720 static char *
3721 get_ver_flags (flags)
3722      unsigned int flags;
3723 {
3724   static char buff [32];
3725
3726   buff[0] = 0;
3727
3728   if (flags == 0)
3729     return _("none");
3730
3731   if (flags & VER_FLG_BASE)
3732     strcat (buff, "BASE ");
3733
3734   if (flags & VER_FLG_WEAK)
3735     {
3736       if (flags & VER_FLG_BASE)
3737         strcat (buff, "| ");
3738
3739       strcat (buff, "WEAK ");
3740     }
3741
3742   if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
3743     strcat (buff, "| <unknown>");
3744
3745   return buff;
3746 }
3747
3748 /* Display the contents of the version sections.  */
3749 static int
3750 process_version_sections (file)
3751      FILE * file;
3752 {
3753   Elf32_Internal_Shdr * section;
3754   unsigned   i;
3755   int        found = 0;
3756
3757   if (! do_version)
3758     return 1;
3759
3760   for (i = 0, section = section_headers;
3761        i < elf_header.e_shnum;
3762        i++, section ++)
3763     {
3764       switch (section->sh_type)
3765         {
3766         case SHT_GNU_verdef:
3767           {
3768             Elf_External_Verdef * edefs;
3769             unsigned int          idx;
3770             unsigned int          cnt;
3771
3772             found = 1;
3773
3774             printf
3775               (_("\nVersion definition section '%s' contains %ld entries:\n"),
3776                SECTION_NAME (section), section->sh_info);
3777
3778             printf (_("  Addr: 0x"));
3779             printf_vma (section->sh_addr);
3780             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
3781                     (unsigned long) section->sh_offset, section->sh_link,
3782                     SECTION_NAME (section_headers + section->sh_link));
3783
3784             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3785                             edefs, Elf_External_Verdef *,
3786                             "version definition section");
3787
3788             for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
3789               {
3790                 char *                 vstart;
3791                 Elf_External_Verdef *  edef;
3792                 Elf_Internal_Verdef    ent;
3793                 Elf_External_Verdaux * eaux;
3794                 Elf_Internal_Verdaux   aux;
3795                 int                    j;
3796                 int                    isum;
3797
3798                 vstart = ((char *) edefs) + idx;
3799
3800                 edef = (Elf_External_Verdef *) vstart;
3801
3802                 ent.vd_version = BYTE_GET (edef->vd_version);
3803                 ent.vd_flags   = BYTE_GET (edef->vd_flags);
3804                 ent.vd_ndx     = BYTE_GET (edef->vd_ndx);
3805                 ent.vd_cnt     = BYTE_GET (edef->vd_cnt);
3806                 ent.vd_hash    = BYTE_GET (edef->vd_hash);
3807                 ent.vd_aux     = BYTE_GET (edef->vd_aux);
3808                 ent.vd_next    = BYTE_GET (edef->vd_next);
3809
3810                 printf (_("  %#06x: Rev: %d  Flags: %s"),
3811                         idx, ent.vd_version, get_ver_flags (ent.vd_flags));
3812
3813                 printf (_("  Index: %d  Cnt: %d  "),
3814                         ent.vd_ndx, ent.vd_cnt);
3815
3816                 vstart += ent.vd_aux;
3817
3818                 eaux = (Elf_External_Verdaux *) vstart;
3819
3820                 aux.vda_name = BYTE_GET (eaux->vda_name);
3821                 aux.vda_next = BYTE_GET (eaux->vda_next);
3822
3823                 if (dynamic_strings)
3824                   printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
3825                 else
3826                   printf (_("Name index: %ld\n"), aux.vda_name);
3827
3828                 isum = idx + ent.vd_aux;
3829
3830                 for (j = 1; j < ent.vd_cnt; j ++)
3831                   {
3832                     isum   += aux.vda_next;
3833                     vstart += aux.vda_next;
3834
3835                     eaux = (Elf_External_Verdaux *) vstart;
3836
3837                     aux.vda_name = BYTE_GET (eaux->vda_name);
3838                     aux.vda_next = BYTE_GET (eaux->vda_next);
3839
3840                     if (dynamic_strings)
3841                       printf (_("  %#06x: Parent %d: %s\n"),
3842                               isum, j, dynamic_strings + aux.vda_name);
3843                     else
3844                       printf (_("  %#06x: Parent %d, name index: %ld\n"),
3845                               isum, j, aux.vda_name);
3846                   }
3847
3848                 idx += ent.vd_next;
3849               }
3850
3851             free (edefs);
3852           }
3853           break;
3854
3855         case SHT_GNU_verneed:
3856           {
3857             Elf_External_Verneed *  eneed;
3858             unsigned int            idx;
3859             unsigned int            cnt;
3860
3861             found = 1;
3862
3863             printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
3864                     SECTION_NAME (section), section->sh_info);
3865
3866             printf (_(" Addr: 0x"));
3867             printf_vma (section->sh_addr);
3868             printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
3869                     (unsigned long) section->sh_offset, section->sh_link,
3870                     SECTION_NAME (section_headers + section->sh_link));
3871
3872             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
3873                             eneed, Elf_External_Verneed *,
3874                             "version need section");
3875
3876             for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
3877               {
3878                 Elf_External_Verneed * entry;
3879                 Elf_Internal_Verneed     ent;
3880                 int                      j;
3881                 int                      isum;
3882                 char *                   vstart;
3883
3884                 vstart = ((char *) eneed) + idx;
3885
3886                 entry = (Elf_External_Verneed *) vstart;
3887
3888                 ent.vn_version = BYTE_GET (entry->vn_version);
3889                 ent.vn_cnt     = BYTE_GET (entry->vn_cnt);
3890                 ent.vn_file    = BYTE_GET (entry->vn_file);
3891                 ent.vn_aux     = BYTE_GET (entry->vn_aux);
3892                 ent.vn_next    = BYTE_GET (entry->vn_next);
3893
3894                 printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
3895
3896                 if (dynamic_strings)
3897                   printf (_("  File: %s"), dynamic_strings + ent.vn_file);
3898                 else
3899                   printf (_("  File: %lx"), ent.vn_file);
3900
3901                 printf (_("  Cnt: %d\n"), ent.vn_cnt);
3902
3903                 vstart += ent.vn_aux;
3904
3905                 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
3906                   {
3907                     Elf_External_Vernaux * eaux;
3908                     Elf_Internal_Vernaux   aux;
3909
3910                     eaux = (Elf_External_Vernaux *) vstart;
3911
3912                     aux.vna_hash  = BYTE_GET (eaux->vna_hash);
3913                     aux.vna_flags = BYTE_GET (eaux->vna_flags);
3914                     aux.vna_other = BYTE_GET (eaux->vna_other);
3915                     aux.vna_name  = BYTE_GET (eaux->vna_name);
3916                     aux.vna_next  = BYTE_GET (eaux->vna_next);
3917
3918                     if (dynamic_strings)
3919                       printf (_("  %#06x: Name: %s"),
3920                               isum, dynamic_strings + aux.vna_name);
3921                     else
3922                       printf (_("  %#06x: Name index: %lx"),
3923                               isum, aux.vna_name);
3924
3925                     printf (_("  Flags: %s  Version: %d\n"),
3926                             get_ver_flags (aux.vna_flags), aux.vna_other);
3927
3928                     isum   += aux.vna_next;
3929                     vstart += aux.vna_next;
3930                   }
3931
3932                 idx += ent.vn_next;
3933               }
3934
3935             free (eneed);
3936           }
3937           break;
3938
3939         case SHT_GNU_versym:
3940           {
3941             Elf32_Internal_Shdr *       link_section;
3942             int                         total;
3943             int                         cnt;
3944             unsigned char *             edata;
3945             unsigned short *            data;
3946             char *                      strtab;
3947             Elf_Internal_Sym *          symbols;
3948             Elf32_Internal_Shdr *       string_sec;
3949
3950             link_section = section_headers + section->sh_link;
3951             total = section->sh_size / section->sh_entsize;
3952
3953             found = 1;
3954
3955             symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
3956                                        link_section->sh_size / link_section->sh_entsize);
3957
3958             string_sec = section_headers + link_section->sh_link;
3959
3960             GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
3961                             strtab, char *, "version string table");
3962
3963             printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
3964                     SECTION_NAME (section), total);
3965
3966             printf (_(" Addr: "));
3967             printf_vma (section->sh_addr);
3968             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
3969                     (unsigned long) section->sh_offset, section->sh_link,
3970                     SECTION_NAME (link_section));
3971
3972             GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
3973                             - loadaddr,
3974                             total * sizeof (short), edata,
3975                             unsigned char *, "version symbol data");
3976
3977             data = (unsigned short *) malloc (total * sizeof (short));
3978
3979             for (cnt = total; cnt --;)
3980               data [cnt] = byte_get (edata + cnt * sizeof (short),
3981                                      sizeof (short));
3982
3983             free (edata);
3984
3985             for (cnt = 0; cnt < total; cnt += 4)
3986               {
3987                 int j, nn;
3988                 char * name;
3989
3990                 printf ("  %03x:", cnt);
3991
3992                 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
3993                   switch (data [cnt + j])
3994                     {
3995                     case 0:
3996                       fputs (_("   0 (*local*)    "), stdout);
3997                       break;
3998
3999                     case 1:
4000                       fputs (_("   1 (*global*)   "), stdout);
4001                       break;
4002
4003                     default:
4004                       nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
4005                                    data [cnt + j] & 0x8000 ? 'h' : ' ');
4006
4007                       if (symbols [cnt + j].st_shndx < SHN_LORESERVE
4008                           && section_headers[symbols [cnt + j].st_shndx].sh_type
4009                           == SHT_NOBITS)
4010                         {
4011                           /* We must test both.  */
4012                           Elf_Internal_Verneed     ivn;
4013                           unsigned long            offset;
4014
4015                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4016                             - loadaddr;
4017
4018                           do
4019                             {
4020                               Elf_External_Verneed   evn;
4021                               Elf_External_Vernaux   evna;
4022                               Elf_Internal_Vernaux   ivna;
4023                               unsigned long          vna_off;
4024
4025                               GET_DATA (offset, evn, "version need");
4026
4027                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
4028                               ivn.vn_next = BYTE_GET (evn.vn_next);
4029
4030                               vna_off = offset + ivn.vn_aux;
4031
4032                               do
4033                                 {
4034                                   GET_DATA (vna_off, evna,
4035                                             "version need aux (1)");
4036
4037                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
4038                                   ivna.vna_other = BYTE_GET (evna.vna_other);
4039
4040                                   vna_off += ivna.vna_next;
4041                                 }
4042                               while (ivna.vna_other != data [cnt + j]
4043                                      && ivna.vna_next != 0);
4044
4045                               if (ivna.vna_other == data [cnt + j])
4046                                 {
4047                                   ivna.vna_name = BYTE_GET (evna.vna_name);
4048
4049                                   name = strtab + ivna.vna_name;
4050                                   nn += printf ("(%s%-*s",
4051                                                 name,
4052                                                 12 - (int) strlen (name),
4053                                                 ")");
4054                                   break;
4055                                 }
4056                               else if (ivn.vn_next == 0)
4057                                 {
4058                                   if (data [cnt + j] != 0x8001)
4059                                     {
4060                                       Elf_Internal_Verdef  ivd;
4061                                       Elf_External_Verdef  evd;
4062
4063                                       offset = version_info
4064                                         [DT_VERSIONTAGIDX (DT_VERDEF)]
4065                                         - loadaddr;
4066
4067                                       do
4068                                         {
4069                                           GET_DATA (offset, evd,
4070                                                     "version definition");
4071
4072                                           ivd.vd_next = BYTE_GET (evd.vd_next);
4073                                           ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
4074
4075                                           offset += ivd.vd_next;
4076                                         }
4077                                       while (ivd.vd_ndx
4078                                              != (data [cnt + j] & 0x7fff)
4079                                              && ivd.vd_next != 0);
4080
4081                                       if (ivd.vd_ndx
4082                                           == (data [cnt + j] & 0x7fff))
4083                                         {
4084                                           Elf_External_Verdaux  evda;
4085                                           Elf_Internal_Verdaux  ivda;
4086
4087                                           ivd.vd_aux = BYTE_GET (evd.vd_aux);
4088
4089                                           GET_DATA (offset + ivd.vd_aux, evda,
4090                                                     "version definition aux");
4091
4092                                           ivda.vda_name =
4093                                             BYTE_GET (evda.vda_name);
4094
4095                                           name = strtab + ivda.vda_name;
4096                                           nn +=
4097                                             printf ("(%s%-*s",
4098                                                     name,
4099                                                     12 - (int) strlen (name),
4100                                                     ")");
4101                                         }
4102                                     }
4103
4104                                   break;
4105                                 }
4106                               else
4107                                 offset += ivn.vn_next;
4108                             }
4109                           while (ivn.vn_next);
4110                         }
4111                       else if (symbols [cnt + j].st_shndx == SHN_UNDEF)
4112                         {
4113                           Elf_Internal_Verneed     ivn;
4114                           unsigned long            offset;
4115
4116                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4117                             - loadaddr;
4118
4119                           do
4120                             {
4121                               Elf_Internal_Vernaux   ivna;
4122                               Elf_External_Verneed   evn;
4123                               Elf_External_Vernaux   evna;
4124                               unsigned long          a_off;
4125
4126                               GET_DATA (offset, evn, "version need");
4127
4128                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
4129                               ivn.vn_next = BYTE_GET (evn.vn_next);
4130
4131                               a_off = offset + ivn.vn_aux;
4132
4133                               do
4134                                 {
4135                                   GET_DATA (a_off, evna,
4136                                             "version need aux (2)");
4137
4138                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
4139                                   ivna.vna_other = BYTE_GET (evna.vna_other);
4140
4141                                   a_off += ivna.vna_next;
4142                                 }
4143                               while (ivna.vna_other != data [cnt + j]
4144                                      && ivna.vna_next != 0);
4145
4146                               if (ivna.vna_other == data [cnt + j])
4147                                 {
4148                                   ivna.vna_name = BYTE_GET (evna.vna_name);
4149
4150                                   name = strtab + ivna.vna_name;
4151                                   nn += printf ("(%s%-*s",
4152                                                 name,
4153                                                 12 - (int) strlen (name),
4154                                                 ")");
4155                                   break;
4156                                 }
4157
4158                               offset += ivn.vn_next;
4159                             }
4160                           while (ivn.vn_next);
4161                         }
4162                       else if (data [cnt + j] != 0x8001)
4163                         {
4164                           Elf_Internal_Verdef  ivd;
4165                           Elf_External_Verdef  evd;
4166                           unsigned long        offset;
4167
4168                           offset = version_info
4169                             [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
4170
4171                           do
4172                             {
4173                               GET_DATA (offset, evd, "version def");
4174
4175                               ivd.vd_next = BYTE_GET (evd.vd_next);
4176                               ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
4177
4178                               offset += ivd.vd_next;
4179                             }
4180                           while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
4181                                  && ivd.vd_next != 0);
4182
4183                           if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
4184                             {
4185                               Elf_External_Verdaux  evda;
4186                               Elf_Internal_Verdaux  ivda;
4187
4188                               ivd.vd_aux = BYTE_GET (evd.vd_aux);
4189
4190                               GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
4191                                         evda, "version def aux");
4192
4193                               ivda.vda_name = BYTE_GET (evda.vda_name);
4194
4195                               name = strtab + ivda.vda_name;
4196                               nn += printf ("(%s%-*s",
4197                                             name,
4198                                             12 - (int) strlen (name),
4199                                             ")");
4200                             }
4201                         }
4202
4203                       if (nn < 18)
4204                         printf ("%*c", 18 - nn, ' ');
4205                     }
4206
4207                 putchar ('\n');
4208               }
4209
4210             free (data);
4211             free (strtab);
4212             free (symbols);
4213           }
4214           break;
4215
4216         default:
4217           break;
4218         }
4219     }
4220
4221   if (! found)
4222     printf (_("\nNo version information found in this file.\n"));
4223
4224   return 1;
4225 }
4226
4227 static const char *
4228 get_symbol_binding (binding)
4229      unsigned int binding;
4230 {
4231   static char buff [32];
4232
4233   switch (binding)
4234     {
4235     case STB_LOCAL:  return "LOCAL";
4236     case STB_GLOBAL: return "GLOBAL";
4237     case STB_WEAK:   return "WEAK";
4238     default:
4239       if (binding >= STB_LOPROC && binding <= STB_HIPROC)
4240         sprintf (buff, _("<processor specific>: %d"), binding);
4241       else if (binding >= STB_LOOS && binding <= STB_HIOS)
4242         sprintf (buff, _("<OS specific>: %d"), binding);
4243       else
4244         sprintf (buff, _("<unknown>: %d"), binding);
4245       return buff;
4246     }
4247 }
4248
4249 static const char *
4250 get_symbol_type (type)
4251      unsigned int type;
4252 {
4253   static char buff [32];
4254
4255   switch (type)
4256     {
4257     case STT_NOTYPE:   return "NOTYPE";
4258     case STT_OBJECT:   return "OBJECT";
4259     case STT_FUNC:     return "FUNC";
4260     case STT_SECTION:  return "SECTION";
4261     case STT_FILE:     return "FILE";
4262     case STT_COMMON:   return "COMMON";
4263     default:
4264       if (type >= STT_LOPROC && type <= STT_HIPROC)
4265         {
4266           if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
4267             return "THUMB_FUNC";
4268
4269           if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
4270             return "REGISTER";
4271
4272           if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
4273             return "PARISC_MILLI";
4274
4275           sprintf (buff, _("<processor specific>: %d"), type);
4276         }
4277       else if (type >= STT_LOOS && type <= STT_HIOS)
4278         {
4279           if (elf_header.e_machine == EM_PARISC)
4280             {
4281               if (type == STT_HP_OPAQUE)
4282                 return "HP_OPAQUE";
4283               if (type == STT_HP_STUB)
4284                 return "HP_STUB";
4285             }
4286
4287           sprintf (buff, _("<OS specific>: %d"), type);
4288         }
4289       else
4290         sprintf (buff, _("<unknown>: %d"), type);
4291       return buff;
4292     }
4293 }
4294
4295 static const char *
4296 get_symbol_visibility (visibility)
4297      unsigned int visibility;
4298 {
4299   switch (visibility)
4300     {
4301     case STV_DEFAULT:   return "DEFAULT";
4302     case STV_INTERNAL:  return "INTERNAL";
4303     case STV_HIDDEN:    return "HIDDEN";
4304     case STV_PROTECTED: return "PROTECTED";
4305     default: abort ();
4306     }
4307 }
4308
4309 static const char *
4310 get_symbol_index_type (type)
4311      unsigned int type;
4312 {
4313   switch (type)
4314     {
4315     case SHN_UNDEF:  return "UND";
4316     case SHN_ABS:    return "ABS";
4317     case SHN_COMMON: return "COM";
4318     default:
4319       if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4320         return "PRC";
4321       else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
4322         return "RSV";
4323       else if (type >= SHN_LOOS && type <= SHN_HIOS)
4324         return "OS ";
4325       else
4326         {
4327           static char buff [32];
4328
4329           sprintf (buff, "%3d", type);
4330           return buff;
4331         }
4332     }
4333 }
4334
4335 static int *
4336 get_dynamic_data (file, number)
4337      FILE *       file;
4338      unsigned int number;
4339 {
4340   unsigned char * e_data;
4341   int *  i_data;
4342
4343   e_data = (unsigned char *) malloc (number * 4);
4344
4345   if (e_data == NULL)
4346     {
4347       error (_("Out of memory\n"));
4348       return NULL;
4349     }
4350
4351   if (fread (e_data, 4, number, file) != number)
4352     {
4353       error (_("Unable to read in dynamic data\n"));
4354       return NULL;
4355     }
4356
4357   i_data = (int *) malloc (number * sizeof (* i_data));
4358
4359   if (i_data == NULL)
4360     {
4361       error (_("Out of memory\n"));
4362       free (e_data);
4363       return NULL;
4364     }
4365
4366   while (number--)
4367     i_data [number] = byte_get (e_data + number * 4, 4);
4368
4369   free (e_data);
4370
4371   return i_data;
4372 }
4373
4374 /* Dump the symbol table */
4375 static int
4376 process_symbol_table (file)
4377      FILE * file;
4378 {
4379   Elf32_Internal_Shdr *   section;
4380   unsigned char   nb [4];
4381   unsigned char   nc [4];
4382   int    nbuckets = 0;
4383   int    nchains = 0;
4384   int *  buckets = NULL;
4385   int *  chains = NULL;
4386
4387   if (! do_syms && !do_histogram)
4388     return 1;
4389
4390   if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
4391                                 || do_histogram))
4392     {
4393       if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
4394         {
4395           error (_("Unable to seek to start of dynamic information"));
4396           return 0;
4397         }
4398
4399       if (fread (nb, sizeof (nb), 1, file) != 1)
4400         {
4401           error (_("Failed to read in number of buckets\n"));
4402           return 0;
4403         }
4404
4405       if (fread (nc, sizeof (nc), 1, file) != 1)
4406         {
4407           error (_("Failed to read in number of chains\n"));
4408           return 0;
4409         }
4410
4411       nbuckets = byte_get (nb, 4);
4412       nchains  = byte_get (nc, 4);
4413
4414       buckets = get_dynamic_data (file, nbuckets);
4415       chains  = get_dynamic_data (file, nchains);
4416
4417       if (buckets == NULL || chains == NULL)
4418         return 0;
4419     }
4420
4421   if (do_syms
4422       && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
4423     {
4424       int    hn;
4425       int    si;
4426
4427       printf (_("\nSymbol table for image:\n"));
4428       if (is_32bit_elf)
4429         printf (_("  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name\n"));
4430       else
4431         printf (_("  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name\n"));
4432
4433       for (hn = 0; hn < nbuckets; hn++)
4434         {
4435           if (! buckets [hn])
4436             continue;
4437
4438           for (si = buckets [hn]; si < nchains && si > 0; si = chains [si])
4439             {
4440               Elf_Internal_Sym * psym;
4441
4442               psym = dynamic_symbols + si;
4443
4444               printf ("  %3d %3d: ", si, hn);
4445               print_vma (psym->st_value, LONG_HEX);
4446               putchar (' ' );
4447               print_vma (psym->st_size, DEC_5);
4448
4449               printf ("  %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4450               printf (" %6s",  get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4451               printf (" %3s",  get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
4452               printf (" %3.3s", get_symbol_index_type (psym->st_shndx));
4453               printf (" %s\n", dynamic_strings + psym->st_name);
4454             }
4455         }
4456     }
4457   else if (do_syms && !do_using_dynamic)
4458     {
4459       unsigned int     i;
4460
4461       for (i = 0, section = section_headers;
4462            i < elf_header.e_shnum;
4463            i++, section++)
4464         {
4465           unsigned int          si;
4466           char *                strtab;
4467           Elf_Internal_Sym *    symtab;
4468           Elf_Internal_Sym *    psym;
4469
4470
4471           if (   section->sh_type != SHT_SYMTAB
4472               && section->sh_type != SHT_DYNSYM)
4473             continue;
4474
4475           printf (_("\nSymbol table '%s' contains %lu entries:\n"),
4476                   SECTION_NAME (section),
4477                   (unsigned long) (section->sh_size / section->sh_entsize));
4478           if (is_32bit_elf)
4479             printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
4480           else
4481             printf (_("   Num:    Value          Size Type    Bind   Vis      Ndx Name\n"));
4482
4483           symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
4484                                     section->sh_size / section->sh_entsize);
4485           if (symtab == NULL)
4486             continue;
4487
4488           if (section->sh_link == elf_header.e_shstrndx)
4489             strtab = string_table;
4490           else
4491             {
4492               Elf32_Internal_Shdr * string_sec;
4493
4494               string_sec = section_headers + section->sh_link;
4495
4496               GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4497                               strtab, char *, "string table");
4498             }
4499
4500           for (si = 0, psym = symtab;
4501                si < section->sh_size / section->sh_entsize;
4502                si ++, psym ++)
4503             {
4504               printf ("%6d: ", si);
4505               print_vma (psym->st_value, LONG_HEX);
4506               putchar (' ');
4507               print_vma (psym->st_size, DEC_5);
4508               printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4509               printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4510               printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
4511               printf (" %4s", get_symbol_index_type (psym->st_shndx));
4512               printf (" %s", strtab + psym->st_name);
4513
4514               if (section->sh_type == SHT_DYNSYM &&
4515                   version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
4516                 {
4517                   unsigned char   data[2];
4518                   unsigned short  vers_data;
4519                   unsigned long   offset;
4520                   int             is_nobits;
4521                   int             check_def;
4522
4523                   offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4524                     - loadaddr;
4525
4526                   GET_DATA (offset + si * sizeof (vers_data), data,
4527                             "version data");
4528
4529                   vers_data = byte_get (data, 2);
4530
4531                   is_nobits = psym->st_shndx < SHN_LORESERVE ?
4532                     (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
4533                     : 0;
4534
4535                   check_def = (psym->st_shndx != SHN_UNDEF);
4536
4537                   if ((vers_data & 0x8000) || vers_data > 1)
4538                     {
4539                       if (is_nobits || ! check_def)
4540                         {
4541                           Elf_External_Verneed  evn;
4542                           Elf_Internal_Verneed  ivn;
4543                           Elf_Internal_Vernaux  ivna;
4544
4545                           /* We must test both.  */
4546                           offset = version_info
4547                             [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
4548
4549                           do
4550                             {
4551                               unsigned long  vna_off;
4552
4553                               GET_DATA (offset, evn, "version need");
4554
4555                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
4556                               ivn.vn_next = BYTE_GET (evn.vn_next);
4557
4558                               vna_off = offset + ivn.vn_aux;
4559
4560                               do
4561                                 {
4562                                   Elf_External_Vernaux  evna;
4563
4564                                   GET_DATA (vna_off, evna,
4565                                             "version need aux (3)");
4566
4567                                   ivna.vna_other = BYTE_GET (evna.vna_other);
4568                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
4569                                   ivna.vna_name  = BYTE_GET (evna.vna_name);
4570
4571                                   vna_off += ivna.vna_next;
4572                                 }
4573                               while (ivna.vna_other != vers_data
4574                                      && ivna.vna_next != 0);
4575
4576                               if (ivna.vna_other == vers_data)
4577                                 break;
4578
4579                               offset += ivn.vn_next;
4580                             }
4581                           while (ivn.vn_next != 0);
4582
4583                           if (ivna.vna_other == vers_data)
4584                             {
4585                               printf ("@%s (%d)",
4586                                       strtab + ivna.vna_name, ivna.vna_other);
4587                               check_def = 0;
4588                             }
4589                           else if (! is_nobits)
4590                             error (_("bad dynamic symbol"));
4591                           else
4592                             check_def = 1;
4593                         }
4594
4595                       if (check_def)
4596                         {
4597                           if (vers_data != 0x8001)
4598                             {
4599                               Elf_Internal_Verdef     ivd;
4600                               Elf_Internal_Verdaux    ivda;
4601                               Elf_External_Verdaux  evda;
4602                               unsigned long           offset;
4603
4604                               offset =
4605                                 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
4606                                 - loadaddr;
4607
4608                               do
4609                                 {
4610                                   Elf_External_Verdef   evd;
4611
4612                                   GET_DATA (offset, evd, "version def");
4613
4614                                   ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
4615                                   ivd.vd_aux  = BYTE_GET (evd.vd_aux);
4616                                   ivd.vd_next = BYTE_GET (evd.vd_next);
4617
4618                                   offset += ivd.vd_next;
4619                                 }
4620                               while (ivd.vd_ndx != (vers_data & 0x7fff)
4621                                      && ivd.vd_next != 0);
4622
4623                               offset -= ivd.vd_next;
4624                               offset += ivd.vd_aux;
4625
4626                               GET_DATA (offset, evda, "version def aux");
4627
4628                               ivda.vda_name = BYTE_GET (evda.vda_name);
4629
4630                               if (psym->st_name != ivda.vda_name)
4631                                 printf ((vers_data & 0x8000)
4632                                         ? "@%s" : "@@%s",
4633                                         strtab + ivda.vda_name);
4634                             }
4635                         }
4636                     }
4637                 }
4638
4639               putchar ('\n');
4640             }
4641
4642           free (symtab);
4643           if (strtab != string_table)
4644             free (strtab);
4645         }
4646     }
4647   else if (do_syms)
4648     printf
4649       (_("\nDynamic symbol information is not available for displaying symbols.\n"));
4650
4651   if (do_histogram && buckets != NULL)
4652     {
4653       int *lengths;
4654       int *counts;
4655       int hn;
4656       int si;
4657       int maxlength = 0;
4658       int nzero_counts = 0;
4659       int nsyms = 0;
4660
4661       printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
4662               nbuckets);
4663       printf (_(" Length  Number     %% of total  Coverage\n"));
4664
4665       lengths = (int *) calloc (nbuckets, sizeof (int));
4666       if (lengths == NULL)
4667         {
4668           error (_("Out of memory"));
4669           return 0;
4670         }
4671       for (hn = 0; hn < nbuckets; ++hn)
4672         {
4673           if (! buckets [hn])
4674             continue;
4675
4676           for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
4677             {
4678               ++ nsyms;
4679               if (maxlength < ++lengths[hn])
4680                 ++ maxlength;
4681             }
4682         }
4683
4684       counts = (int *) calloc (maxlength + 1, sizeof (int));
4685       if (counts == NULL)
4686         {
4687           error (_("Out of memory"));
4688           return 0;
4689         }
4690
4691       for (hn = 0; hn < nbuckets; ++hn)
4692         ++ counts [lengths [hn]];
4693
4694       if (nbuckets > 0)
4695         {
4696           printf ("      0  %-10d (%5.1f%%)\n",
4697                   counts[0], (counts[0] * 100.0) / nbuckets);
4698           for (si = 1; si <= maxlength; ++si)
4699             {
4700               nzero_counts += counts[si] * si;
4701               printf ("%7d  %-10d (%5.1f%%)    %5.1f%%\n",
4702                       si, counts[si], (counts[si] * 100.0) / nbuckets,
4703                       (nzero_counts * 100.0) / nsyms);
4704             }
4705         }
4706
4707       free (counts);
4708       free (lengths);
4709     }
4710
4711   if (buckets != NULL)
4712     {
4713       free (buckets);
4714       free (chains);
4715     }
4716
4717   return 1;
4718 }
4719
4720 static int
4721 process_syminfo (file)
4722      FILE * file ATTRIBUTE_UNUSED;
4723 {
4724   unsigned int i;
4725
4726   if (dynamic_syminfo == NULL
4727       || !do_dynamic)
4728     /* No syminfo, this is ok.  */
4729     return 1;
4730
4731   /* There better should be a dynamic symbol section.  */
4732   if (dynamic_symbols == NULL || dynamic_strings == NULL)
4733     return 0;
4734
4735   if (dynamic_addr)
4736     printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
4737             dynamic_syminfo_offset, dynamic_syminfo_nent);
4738
4739   printf (_(" Num: Name                           BoundTo     Flags\n"));
4740   for (i = 0; i < dynamic_syminfo_nent; ++i)
4741     {
4742       unsigned short int flags = dynamic_syminfo[i].si_flags;
4743
4744       printf ("%4d: %-30s ", i,
4745               dynamic_strings + dynamic_symbols[i].st_name);
4746
4747       switch (dynamic_syminfo[i].si_boundto)
4748         {
4749         case SYMINFO_BT_SELF:
4750           fputs ("SELF       ", stdout);
4751           break;
4752         case SYMINFO_BT_PARENT:
4753           fputs ("PARENT     ", stdout);
4754           break;
4755         default:
4756           if (dynamic_syminfo[i].si_boundto > 0
4757               && dynamic_syminfo[i].si_boundto < dynamic_size)
4758             printf ("%-10s ",
4759                     dynamic_strings
4760                     + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
4761           else
4762             printf ("%-10d ", dynamic_syminfo[i].si_boundto);
4763           break;
4764         }
4765
4766       if (flags & SYMINFO_FLG_DIRECT)
4767         printf (" DIRECT");
4768       if (flags & SYMINFO_FLG_PASSTHRU)
4769         printf (" PASSTHRU");
4770       if (flags & SYMINFO_FLG_COPY)
4771         printf (" COPY");
4772       if (flags & SYMINFO_FLG_LAZYLOAD)
4773         printf (" LAZYLOAD");
4774
4775       puts ("");
4776     }
4777
4778   return 1;
4779 }
4780
4781 #ifdef SUPPORT_DISASSEMBLY
4782 static void
4783 disassemble_section (section, file)
4784      Elf32_Internal_Shdr * section;
4785      FILE * file;
4786 {
4787   printf (_("\nAssembly dump of section %s\n"),
4788           SECTION_NAME (section));
4789
4790   /* XXX -- to be done --- XXX */
4791
4792   return 1;
4793 }
4794 #endif
4795
4796 static int
4797 dump_section (section, file)
4798      Elf32_Internal_Shdr * section;
4799      FILE * file;
4800 {
4801   bfd_size_type   bytes;
4802   bfd_vma         addr;
4803   unsigned char * data;
4804   unsigned char * start;
4805
4806   bytes = section->sh_size;
4807
4808   if (bytes == 0)
4809     {
4810       printf (_("\nSection '%s' has no data to dump.\n"),
4811               SECTION_NAME (section));
4812       return 0;
4813     }
4814   else
4815     printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
4816
4817   addr = section->sh_addr;
4818
4819   GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
4820                   "section data");
4821
4822   data = start;
4823
4824   while (bytes)
4825     {
4826       int j;
4827       int k;
4828       int lbytes;
4829
4830       lbytes = (bytes > 16 ? 16 : bytes);
4831
4832       printf ("  0x%8.8lx ", (unsigned long) addr);
4833
4834       switch (elf_header.e_ident [EI_DATA])
4835         {
4836         default:
4837         case ELFDATA2LSB:
4838           for (j = 15; j >= 0; j --)
4839             {
4840               if (j < lbytes)
4841                 printf ("%2.2x", data [j]);
4842               else
4843                 printf ("  ");
4844
4845               if (!(j & 0x3))
4846                 printf (" ");
4847             }
4848           break;
4849
4850         case ELFDATA2MSB:
4851           for (j = 0; j < 16; j++)
4852             {
4853               if (j < lbytes)
4854                 printf ("%2.2x", data [j]);
4855               else
4856                 printf ("  ");
4857
4858               if ((j & 3) == 3)
4859                 printf (" ");
4860             }
4861           break;
4862         }
4863
4864       for (j = 0; j < lbytes; j++)
4865         {
4866           k = data [j];
4867           if (k >= ' ' && k < 0x80)
4868             printf ("%c", k);
4869           else
4870             printf (".");
4871         }
4872
4873       putchar ('\n');
4874
4875       data  += lbytes;
4876       addr  += lbytes;
4877       bytes -= lbytes;
4878     }
4879
4880   free (start);
4881
4882   return 1;
4883 }
4884
4885
4886 static unsigned long int
4887 read_leb128 (data, length_return, sign)
4888      unsigned char * data;
4889      int *           length_return;
4890      int             sign;
4891 {
4892   unsigned long int result = 0;
4893   unsigned int      num_read = 0;
4894   int               shift = 0;
4895   unsigned char     byte;
4896
4897   do
4898     {
4899       byte = * data ++;
4900       num_read ++;
4901
4902       result |= (byte & 0x7f) << shift;
4903
4904       shift += 7;
4905
4906     }
4907   while (byte & 0x80);
4908
4909   if (length_return != NULL)
4910     * length_return = num_read;
4911
4912   if (sign && (shift < 32) && (byte & 0x40))
4913     result |= -1 << shift;
4914
4915   return result;
4916 }
4917
4918 typedef struct State_Machine_Registers
4919 {
4920   unsigned long address;
4921   unsigned int  file;
4922   unsigned int  line;
4923   unsigned int  column;
4924   int           is_stmt;
4925   int           basic_block;
4926   int           end_sequence;
4927 /* This variable hold the number of the last entry seen
4928    in the File Table.  */
4929   unsigned int  last_file_entry;
4930 } SMR;
4931
4932 static SMR state_machine_regs;
4933
4934 static void
4935 reset_state_machine (is_stmt)
4936      int is_stmt;
4937 {
4938   state_machine_regs.address = 0;
4939   state_machine_regs.file = 1;
4940   state_machine_regs.line = 1;
4941   state_machine_regs.column = 0;
4942   state_machine_regs.is_stmt = is_stmt;
4943   state_machine_regs.basic_block = 0;
4944   state_machine_regs.end_sequence = 0;
4945   state_machine_regs.last_file_entry = 0;
4946 }
4947
4948 /* Handled an extend line op.  Returns true if this is the end
4949    of sequence.  */
4950 static int
4951 process_extended_line_op (data, is_stmt, pointer_size)
4952      unsigned char * data;
4953      int is_stmt;
4954      int pointer_size;
4955 {
4956   unsigned char   op_code;
4957   int             bytes_read;
4958   unsigned int    len;
4959   unsigned char * name;
4960   unsigned long   adr;
4961
4962   len = read_leb128 (data, & bytes_read, 0);
4963   data += bytes_read;
4964
4965   if (len == 0)
4966     {
4967       warn (_("badly formed extended line op encountered!"));
4968       return bytes_read;
4969     }
4970
4971   len += bytes_read;
4972   op_code = * data ++;
4973
4974   printf (_("  Extended opcode %d: "), op_code);
4975
4976   switch (op_code)
4977     {
4978     case DW_LNE_end_sequence:
4979       printf (_("End of Sequence\n\n"));
4980       reset_state_machine (is_stmt);
4981       break;
4982
4983     case DW_LNE_set_address:
4984       adr = byte_get (data, pointer_size);
4985       printf (_("set Address to 0x%lx\n"), adr);
4986       state_machine_regs.address = adr;
4987       break;
4988
4989     case DW_LNE_define_file:
4990       printf (_("  define new File Table entry\n"));
4991       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
4992
4993       printf (_("   %d\t"), ++ state_machine_regs.last_file_entry);
4994       name = data;
4995       data += strlen ((char *) data) + 1;
4996       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4997       data += bytes_read;
4998       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
4999       data += bytes_read;
5000       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5001       printf (_("%s\n\n"), name);
5002       break;
5003
5004     default:
5005       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
5006       break;
5007     }
5008
5009   return len;
5010 }
5011
5012 /* Size of pointers in the .debug_line section.  This information is not
5013    really present in that section.  It's obtained before dumping the debug
5014    sections by doing some pre-scan of the .debug_info section.  */
5015 static int debug_line_pointer_size = 4;
5016
5017 static int
5018 display_debug_lines (section, start, file)
5019      Elf32_Internal_Shdr * section;
5020      unsigned char *       start;
5021      FILE *                file ATTRIBUTE_UNUSED;
5022 {
5023   DWARF2_External_LineInfo * external;
5024   DWARF2_Internal_LineInfo   info;
5025   unsigned char *            standard_opcodes;
5026   unsigned char *            data = start;
5027   unsigned char *            end  = start + section->sh_size;
5028   unsigned char *            end_of_sequence;
5029   int                        i;
5030
5031   printf (_("\nDump of debug contents of section %s:\n\n"),
5032           SECTION_NAME (section));
5033
5034   while (data < end)
5035     {
5036       external = (DWARF2_External_LineInfo *) data;
5037
5038       /* Check the length of the block.  */
5039       info.li_length = BYTE_GET (external->li_length);
5040       if (info.li_length + sizeof (external->li_length) > section->sh_size)
5041         {
5042           warn
5043             (_("The line info appears to be corrupt - the section is too small\n"));
5044           return 0;
5045         }
5046
5047       /* Check its version number.  */
5048       info.li_version = BYTE_GET (external->li_version);
5049       if (info.li_version != 2)
5050         {
5051           warn (_("Only DWARF version 2 line info is currently supported.\n"));
5052           return 0;
5053         }
5054
5055       info.li_prologue_length = BYTE_GET (external->li_prologue_length);
5056       info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
5057       info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
5058       info.li_line_base       = BYTE_GET (external->li_line_base);
5059       info.li_line_range      = BYTE_GET (external->li_line_range);
5060       info.li_opcode_base     = BYTE_GET (external->li_opcode_base);
5061
5062       /* Sign extend the line base field.  */
5063       info.li_line_base <<= 24;
5064       info.li_line_base >>= 24;
5065
5066       printf (_("  Length:                      %ld\n"), info.li_length);
5067       printf (_("  DWARF Version:               %d\n"), info.li_version);
5068       printf (_("  Prolgue Length:              %d\n"), info.li_prologue_length);
5069       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
5070       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
5071       printf (_("  Line Base:                   %d\n"), info.li_line_base);
5072       printf (_("  Line Range:                  %d\n"), info.li_line_range);
5073       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
5074
5075       end_of_sequence = data + info.li_length + sizeof (external->li_length);
5076
5077       reset_state_machine (info.li_default_is_stmt);
5078
5079       /* Display the contents of the Opcodes table.  */
5080       standard_opcodes = data + sizeof (* external);
5081
5082       printf (_("\n Opcodes:\n"));
5083
5084       for (i = 1; i < info.li_opcode_base; i++)
5085         printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
5086
5087       /* Display the contents of the Directory table.  */
5088       data = standard_opcodes + info.li_opcode_base - 1;
5089
5090       if (* data == 0)
5091         printf (_("\n The Directory Table is empty.\n"));
5092       else
5093         {
5094           printf (_("\n The Directory Table:\n"));
5095
5096           while (* data != 0)
5097             {
5098               printf (_("  %s\n"), data);
5099
5100               data += strlen ((char *) data) + 1;
5101             }
5102         }
5103
5104       /* Skip the NUL at the end of the table.  */
5105       data ++;
5106
5107       /* Display the contents of the File Name table.  */
5108       if (* data == 0)
5109         printf (_("\n The File Name Table is empty.\n"));
5110       else
5111         {
5112           printf (_("\n The File Name Table:\n"));
5113           printf (_("  Entry\tDir\tTime\tSize\tName\n"));
5114
5115           while (* data != 0)
5116             {
5117               unsigned char * name;
5118               int bytes_read;
5119
5120               printf (_("  %d\t"), ++ state_machine_regs.last_file_entry);
5121               name = data;
5122
5123               data += strlen ((char *) data) + 1;
5124
5125               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5126               data += bytes_read;
5127               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5128               data += bytes_read;
5129               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5130               data += bytes_read;
5131               printf (_("%s\n"), name);
5132             }
5133         }
5134
5135       /* Skip the NUL at the end of the table.  */
5136       data ++;
5137
5138       /* Now display the statements.  */
5139       printf (_("\n Line Number Statements:\n"));
5140
5141
5142       while (data < end_of_sequence)
5143         {
5144           unsigned char op_code;
5145           int           adv;
5146           int           bytes_read;
5147
5148           op_code = * data ++;
5149
5150           switch (op_code)
5151             {
5152             case DW_LNS_extended_op:
5153               data += process_extended_line_op (data, info.li_default_is_stmt,
5154                                                 debug_line_pointer_size);
5155               break;
5156
5157             case DW_LNS_copy:
5158               printf (_("  Copy\n"));
5159               break;
5160
5161             case DW_LNS_advance_pc:
5162               adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
5163               data += bytes_read;
5164               state_machine_regs.address += adv;
5165               printf (_("  Advance PC by %d to %lx\n"), adv,
5166                       state_machine_regs.address);
5167               break;
5168
5169             case DW_LNS_advance_line:
5170               adv = read_leb128 (data, & bytes_read, 1);
5171               data += bytes_read;
5172               state_machine_regs.line += adv;
5173               printf (_("  Advance Line by %d to %d\n"), adv,
5174                       state_machine_regs.line);
5175               break;
5176
5177             case DW_LNS_set_file:
5178               adv = read_leb128 (data, & bytes_read, 0);
5179               data += bytes_read;
5180               printf (_("  Set File Name to entry %d in the File Name Table\n"),
5181                       adv);
5182               state_machine_regs.file = adv;
5183               break;
5184
5185             case DW_LNS_set_column:
5186               adv = read_leb128 (data, & bytes_read, 0);
5187               data += bytes_read;
5188               printf (_("  Set column to %d\n"), adv);
5189               state_machine_regs.column = adv;
5190               break;
5191
5192             case DW_LNS_negate_stmt:
5193               adv = state_machine_regs.is_stmt;
5194               adv = ! adv;
5195               printf (_("  Set is_stmt to %d\n"), adv);
5196               state_machine_regs.is_stmt = adv;
5197               break;
5198
5199             case DW_LNS_set_basic_block:
5200               printf (_("  Set basic block\n"));
5201               state_machine_regs.basic_block = 1;
5202               break;
5203
5204             case DW_LNS_const_add_pc:
5205               adv = (((255 - info.li_opcode_base) / info.li_line_range)
5206                      * info.li_min_insn_length);
5207               state_machine_regs.address += adv;
5208               printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
5209                       state_machine_regs.address);
5210               break;
5211
5212             case DW_LNS_fixed_advance_pc:
5213               adv = byte_get (data, 2);
5214               data += 2;
5215               state_machine_regs.address += adv;
5216               printf (_("  Advance PC by fixed size amount %d to 0x%lx\n"),
5217                       adv, state_machine_regs.address);
5218               break;
5219
5220             default:
5221               op_code -= info.li_opcode_base;
5222               adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
5223               state_machine_regs.address += adv;
5224               printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
5225                       op_code, adv, state_machine_regs.address);
5226               adv = (op_code % info.li_line_range) + info.li_line_base;
5227               state_machine_regs.line += adv;
5228               printf (_(" and Line by %d to %d\n"),
5229                       adv, state_machine_regs.line);
5230               break;
5231             }
5232         }
5233       printf ("\n");
5234     }
5235
5236   return 1;
5237 }
5238
5239 static int
5240 display_debug_pubnames (section, start, file)
5241      Elf32_Internal_Shdr * section;
5242      unsigned char *       start;
5243      FILE *                file ATTRIBUTE_UNUSED;
5244 {
5245   DWARF2_External_PubNames * external;
5246   DWARF2_Internal_PubNames   pubnames;
5247   unsigned char *            end;
5248
5249   end = start + section->sh_size;
5250
5251   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5252
5253   while (start < end)
5254     {
5255       unsigned char * data;
5256       unsigned long   offset;
5257
5258       external = (DWARF2_External_PubNames *) start;
5259
5260       pubnames.pn_length  = BYTE_GET (external->pn_length);
5261       pubnames.pn_version = BYTE_GET (external->pn_version);
5262       pubnames.pn_offset  = BYTE_GET (external->pn_offset);
5263       pubnames.pn_size    = BYTE_GET (external->pn_size);
5264
5265       data   = start + sizeof (* external);
5266       start += pubnames.pn_length + sizeof (external->pn_length);
5267
5268       if (pubnames.pn_version != 2)
5269         {
5270           static int warned = 0;
5271
5272           if (! warned)
5273             {
5274               warn (_("Only DWARF 2 pubnames are currently supported\n"));
5275               warned = 1;
5276             }
5277
5278           continue;
5279         }
5280
5281       printf (_("  Length:                              %ld\n"),
5282               pubnames.pn_length);
5283       printf (_("  Version:                             %d\n"),
5284               pubnames.pn_version);
5285       printf (_("  Offset into .debug_info section:     %ld\n"),
5286               pubnames.pn_offset);
5287       printf (_("  Size of area in .debug_info section: %ld\n"),
5288               pubnames.pn_size);
5289
5290       printf (_("\n    Offset\tName\n"));
5291
5292       do
5293         {
5294           offset = byte_get (data, 4);
5295
5296           if (offset != 0)
5297             {
5298               data += 4;
5299               printf ("    %ld\t\t%s\n", offset, data);
5300               data += strlen ((char *) data) + 1;
5301             }
5302         }
5303       while (offset != 0);
5304     }
5305
5306   printf ("\n");
5307   return 1;
5308 }
5309
5310 static char *
5311 get_TAG_name (tag)
5312      unsigned long tag;
5313 {
5314   switch (tag)
5315     {
5316     case DW_TAG_padding: return "DW_TAG_padding";
5317     case DW_TAG_array_type: return "DW_TAG_array_type";
5318     case DW_TAG_class_type: return "DW_TAG_class_type";
5319     case DW_TAG_entry_point: return "DW_TAG_entry_point";
5320     case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
5321     case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
5322     case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
5323     case DW_TAG_label: return "DW_TAG_label";
5324     case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
5325     case DW_TAG_member: return "DW_TAG_member";
5326     case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
5327     case DW_TAG_reference_type: return "DW_TAG_reference_type";
5328     case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
5329     case DW_TAG_string_type: return "DW_TAG_string_type";
5330     case DW_TAG_structure_type: return "DW_TAG_structure_type";
5331     case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
5332     case DW_TAG_typedef: return "DW_TAG_typedef";
5333     case DW_TAG_union_type: return "DW_TAG_union_type";
5334     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
5335     case DW_TAG_variant: return "DW_TAG_variant";
5336     case DW_TAG_common_block: return "DW_TAG_common_block";
5337     case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
5338     case DW_TAG_inheritance: return "DW_TAG_inheritance";
5339     case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
5340     case DW_TAG_module: return "DW_TAG_module";
5341     case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
5342     case DW_TAG_set_type: return "DW_TAG_set_type";
5343     case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
5344     case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
5345     case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
5346     case DW_TAG_base_type: return "DW_TAG_base_type";
5347     case DW_TAG_catch_block: return "DW_TAG_catch_block";
5348     case DW_TAG_const_type: return "DW_TAG_const_type";
5349     case DW_TAG_constant: return "DW_TAG_constant";
5350     case DW_TAG_enumerator: return "DW_TAG_enumerator";
5351     case DW_TAG_file_type: return "DW_TAG_file_type";
5352     case DW_TAG_friend: return "DW_TAG_friend";
5353     case DW_TAG_namelist: return "DW_TAG_namelist";
5354     case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
5355     case DW_TAG_packed_type: return "DW_TAG_packed_type";
5356     case DW_TAG_subprogram: return "DW_TAG_subprogram";
5357     case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
5358     case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
5359     case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
5360     case DW_TAG_try_block: return "DW_TAG_try_block";
5361     case DW_TAG_variant_part: return "DW_TAG_variant_part";
5362     case DW_TAG_variable: return "DW_TAG_variable";
5363     case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
5364     case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
5365     case DW_TAG_format_label: return "DW_TAG_format_label";
5366     case DW_TAG_function_template: return "DW_TAG_function_template";
5367     case DW_TAG_class_template: return "DW_TAG_class_template";
5368     default:
5369       {
5370         static char buffer [100];
5371
5372         sprintf (buffer, _("Unknown TAG value: %lx"), tag);
5373         return buffer;
5374       }
5375     }
5376 }
5377
5378 static char *
5379 get_AT_name (attribute)
5380      unsigned long attribute;
5381 {
5382   switch (attribute)
5383     {
5384     case DW_AT_sibling: return "DW_AT_sibling";
5385     case DW_AT_location: return "DW_AT_location";
5386     case DW_AT_name: return "DW_AT_name";
5387     case DW_AT_ordering: return "DW_AT_ordering";
5388     case DW_AT_subscr_data: return "DW_AT_subscr_data";
5389     case DW_AT_byte_size: return "DW_AT_byte_size";
5390     case DW_AT_bit_offset: return "DW_AT_bit_offset";
5391     case DW_AT_bit_size: return "DW_AT_bit_size";
5392     case DW_AT_element_list: return "DW_AT_element_list";
5393     case DW_AT_stmt_list: return "DW_AT_stmt_list";
5394     case DW_AT_low_pc: return "DW_AT_low_pc";
5395     case DW_AT_high_pc: return "DW_AT_high_pc";
5396     case DW_AT_language: return "DW_AT_language";
5397     case DW_AT_member: return "DW_AT_member";
5398     case DW_AT_discr: return "DW_AT_discr";
5399     case DW_AT_discr_value: return "DW_AT_discr_value";
5400     case DW_AT_visibility: return "DW_AT_visibility";
5401     case DW_AT_import: return "DW_AT_import";
5402     case DW_AT_string_length: return "DW_AT_string_length";
5403     case DW_AT_common_reference: return "DW_AT_common_reference";
5404     case DW_AT_comp_dir: return "DW_AT_comp_dir";
5405     case DW_AT_const_value: return "DW_AT_const_value";
5406     case DW_AT_containing_type: return "DW_AT_containing_type";
5407     case DW_AT_default_value: return "DW_AT_default_value";
5408     case DW_AT_inline: return "DW_AT_inline";
5409     case DW_AT_is_optional: return "DW_AT_is_optional";
5410     case DW_AT_lower_bound: return "DW_AT_lower_bound";
5411     case DW_AT_producer: return "DW_AT_producer";
5412     case DW_AT_prototyped: return "DW_AT_prototyped";
5413     case DW_AT_return_addr: return "DW_AT_return_addr";
5414     case DW_AT_start_scope: return "DW_AT_start_scope";
5415     case DW_AT_stride_size: return "DW_AT_stride_size";
5416     case DW_AT_upper_bound: return "DW_AT_upper_bound";
5417     case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
5418     case DW_AT_accessibility: return "DW_AT_accessibility";
5419     case DW_AT_address_class: return "DW_AT_address_class";
5420     case DW_AT_artificial: return "DW_AT_artificial";
5421     case DW_AT_base_types: return "DW_AT_base_types";
5422     case DW_AT_calling_convention: return "DW_AT_calling_convention";
5423     case DW_AT_count: return "DW_AT_count";
5424     case DW_AT_data_member_location: return "DW_AT_data_member_location";
5425     case DW_AT_decl_column: return "DW_AT_decl_column";
5426     case DW_AT_decl_file: return "DW_AT_decl_file";
5427     case DW_AT_decl_line: return "DW_AT_decl_line";
5428     case DW_AT_declaration: return "DW_AT_declaration";
5429     case DW_AT_discr_list: return "DW_AT_discr_list";
5430     case DW_AT_encoding: return "DW_AT_encoding";
5431     case DW_AT_external: return "DW_AT_external";
5432     case DW_AT_frame_base: return "DW_AT_frame_base";
5433     case DW_AT_friend: return "DW_AT_friend";
5434     case DW_AT_identifier_case: return "DW_AT_identifier_case";
5435     case DW_AT_macro_info: return "DW_AT_macro_info";
5436     case DW_AT_namelist_items: return "DW_AT_namelist_items";
5437     case DW_AT_priority: return "DW_AT_priority";
5438     case DW_AT_segment: return "DW_AT_segment";
5439     case DW_AT_specification: return "DW_AT_specification";
5440     case DW_AT_static_link: return "DW_AT_static_link";
5441     case DW_AT_type: return "DW_AT_type";
5442     case DW_AT_use_location: return "DW_AT_use_location";
5443     case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
5444     case DW_AT_virtuality: return "DW_AT_virtuality";
5445     case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
5446     case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
5447     case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
5448     case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
5449     case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
5450     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
5451     case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
5452     case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
5453     case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
5454     case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
5455     case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
5456     case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
5457     case DW_AT_sf_names: return "DW_AT_sf_names";
5458     case DW_AT_src_info: return "DW_AT_src_info";
5459     case DW_AT_mac_info: return "DW_AT_mac_info";
5460     case DW_AT_src_coords: return "DW_AT_src_coords";
5461     case DW_AT_body_begin: return "DW_AT_body_begin";
5462     case DW_AT_body_end: return "DW_AT_body_end";
5463     default:
5464       {
5465         static char buffer [100];
5466
5467         sprintf (buffer, _("Unknown AT value: %lx"), attribute);
5468         return buffer;
5469       }
5470     }
5471 }
5472
5473 static char *
5474 get_FORM_name (form)
5475      unsigned long form;
5476 {
5477   switch (form)
5478     {
5479     case DW_FORM_addr: return "DW_FORM_addr";
5480     case DW_FORM_block2: return "DW_FORM_block2";
5481     case DW_FORM_block4: return "DW_FORM_block4";
5482     case DW_FORM_data2: return "DW_FORM_data2";
5483     case DW_FORM_data4: return "DW_FORM_data4";
5484     case DW_FORM_data8: return "DW_FORM_data8";
5485     case DW_FORM_string: return "DW_FORM_string";
5486     case DW_FORM_block: return "DW_FORM_block";
5487     case DW_FORM_block1: return "DW_FORM_block1";
5488     case DW_FORM_data1: return "DW_FORM_data1";
5489     case DW_FORM_flag: return "DW_FORM_flag";
5490     case DW_FORM_sdata: return "DW_FORM_sdata";
5491     case DW_FORM_strp: return "DW_FORM_strp";
5492     case DW_FORM_udata: return "DW_FORM_udata";
5493     case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
5494     case DW_FORM_ref1: return "DW_FORM_ref1";
5495     case DW_FORM_ref2: return "DW_FORM_ref2";
5496     case DW_FORM_ref4: return "DW_FORM_ref4";
5497     case DW_FORM_ref8: return "DW_FORM_ref8";
5498     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
5499     case DW_FORM_indirect: return "DW_FORM_indirect";
5500     default:
5501       {
5502         static char buffer [100];
5503
5504         sprintf (buffer, _("Unknown FORM value: %lx"), form);
5505         return buffer;
5506       }
5507     }
5508 }
5509
5510 /* FIXME:  There are better and more effiecint ways to handle
5511    these structures.  For now though, I just want something that
5512    is simple to implement.  */
5513 typedef struct abbrev_attr
5514 {
5515   unsigned long        attribute;
5516   unsigned long        form;
5517   struct abbrev_attr * next;
5518 }
5519 abbrev_attr;
5520
5521 typedef struct abbrev_entry
5522 {
5523   unsigned long          entry;
5524   unsigned long          tag;
5525   int                    children;
5526   struct abbrev_attr *   first_attr;
5527   struct abbrev_attr *   last_attr;
5528   struct abbrev_entry *  next;
5529 }
5530 abbrev_entry;
5531
5532 static abbrev_entry * first_abbrev = NULL;
5533 static abbrev_entry * last_abbrev = NULL;
5534
5535 static void
5536 free_abbrevs PARAMS ((void))
5537 {
5538   abbrev_entry * abbrev;
5539
5540   for (abbrev = first_abbrev; abbrev;)
5541     {
5542       abbrev_entry * next = abbrev->next;
5543       abbrev_attr  * attr;
5544
5545       for (attr = abbrev->first_attr; attr;)
5546         {
5547           abbrev_attr * next = attr->next;
5548
5549           free (attr);
5550           attr = next;
5551         }
5552
5553       free (abbrev);
5554       abbrev = next;
5555     }
5556
5557   last_abbrev = first_abbrev = NULL;
5558 }
5559
5560 static void
5561 add_abbrev (number, tag, children)
5562      unsigned long number;
5563      unsigned long tag;
5564      int           children;
5565 {
5566   abbrev_entry * entry;
5567
5568   entry = (abbrev_entry *) malloc (sizeof (* entry));
5569
5570   if (entry == NULL)
5571     /* ugg */
5572     return;
5573
5574   entry->entry      = number;
5575   entry->tag        = tag;
5576   entry->children   = children;
5577   entry->first_attr = NULL;
5578   entry->last_attr  = NULL;
5579   entry->next       = NULL;
5580
5581   if (first_abbrev == NULL)
5582     first_abbrev = entry;
5583   else
5584     last_abbrev->next = entry;
5585
5586   last_abbrev = entry;
5587 }
5588
5589 static void
5590 add_abbrev_attr (attribute, form)
5591      unsigned long attribute;
5592      unsigned long form;
5593 {
5594   abbrev_attr * attr;
5595
5596   attr = (abbrev_attr *) malloc (sizeof (* attr));
5597
5598   if (attr == NULL)
5599     /* ugg */
5600     return;
5601
5602   attr->attribute = attribute;
5603   attr->form      = form;
5604   attr->next      = NULL;
5605
5606   if (last_abbrev->first_attr == NULL)
5607     last_abbrev->first_attr = attr;
5608   else
5609     last_abbrev->last_attr->next = attr;
5610
5611   last_abbrev->last_attr = attr;
5612 }
5613
5614 /* Processes the (partial) contents of a .debug_abbrev section.
5615    Returns NULL if the end of the section was encountered.
5616    Returns the address after the last byte read if the end of
5617    an abbreviation set was found.  */
5618
5619 static unsigned char *
5620 process_abbrev_section (start, end)
5621      unsigned char * start;
5622      unsigned char * end;
5623 {
5624   if (first_abbrev != NULL)
5625     return NULL;
5626
5627   while (start < end)
5628     {
5629       int           bytes_read;
5630       unsigned long entry;
5631       unsigned long tag;
5632       unsigned long attribute;
5633       int           children;
5634
5635       entry = read_leb128 (start, & bytes_read, 0);
5636       start += bytes_read;
5637
5638       /* A single zero is supposed to end the section according
5639          to the standard.  If there's more, then signal that to
5640          the caller.  */
5641       if (entry == 0)
5642         return start == end ? NULL : start;
5643
5644       tag = read_leb128 (start, & bytes_read, 0);
5645       start += bytes_read;
5646
5647       children = * start ++;
5648
5649       add_abbrev (entry, tag, children);
5650
5651       do
5652         {
5653           unsigned long form;
5654
5655           attribute = read_leb128 (start, & bytes_read, 0);
5656           start += bytes_read;
5657
5658           form = read_leb128 (start, & bytes_read, 0);
5659           start += bytes_read;
5660
5661           if (attribute != 0)
5662             add_abbrev_attr (attribute, form);
5663         }
5664       while (attribute != 0);
5665     }
5666
5667   return NULL;
5668 }
5669
5670
5671 static int
5672 display_debug_abbrev (section, start, file)
5673      Elf32_Internal_Shdr * section;
5674      unsigned char *       start;
5675      FILE *                file ATTRIBUTE_UNUSED;
5676 {
5677   abbrev_entry * entry;
5678   unsigned char * end = start + section->sh_size;
5679
5680   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5681
5682   do
5683     {
5684       start = process_abbrev_section (start, end);
5685
5686       printf (_("  Number TAG\n"));
5687
5688       for (entry = first_abbrev; entry; entry = entry->next)
5689         {
5690           abbrev_attr * attr;
5691
5692           printf (_("   %ld      %s    [%s]\n"),
5693                   entry->entry,
5694                   get_TAG_name (entry->tag),
5695                   entry->children ? _("has children") : _("no children"));
5696
5697           for (attr = entry->first_attr; attr; attr = attr->next)
5698             {
5699               printf (_("    %-18s %s\n"),
5700                       get_AT_name (attr->attribute),
5701                       get_FORM_name (attr->form));
5702             }
5703         }
5704     }
5705   while (start);
5706
5707   printf ("\n");
5708
5709   return 1;
5710 }
5711
5712
5713 static unsigned char *
5714 display_block (data, length)
5715      unsigned char * data;
5716      unsigned long   length;
5717 {
5718   printf (_(" %lu byte block: "), length);
5719
5720   while (length --)
5721     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
5722
5723   return data;
5724 }
5725
5726 static void
5727 decode_location_expression (data, pointer_size, length)
5728      unsigned char * data;
5729      unsigned int    pointer_size;
5730      unsigned long length;
5731 {
5732   unsigned op;
5733   int           bytes_read;
5734   unsigned long uvalue;
5735   unsigned char *end = data + length;
5736
5737   while (data < end)
5738     {
5739       op = * data ++;
5740
5741       switch (op)
5742         {
5743         case DW_OP_addr:
5744           printf ("DW_OP_addr: %lx",
5745                   (unsigned long) byte_get (data, pointer_size));
5746           data += pointer_size;
5747           break;
5748         case DW_OP_deref:
5749           printf ("DW_OP_deref");
5750           break;
5751         case DW_OP_const1u:
5752           printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
5753           break;
5754         case DW_OP_const1s:
5755           printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
5756           break;
5757         case DW_OP_const2u:
5758           printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
5759           data += 2;
5760           break;
5761         case DW_OP_const2s:
5762           printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
5763           data += 2;
5764           break;
5765         case DW_OP_const4u:
5766           printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
5767           data += 4;
5768           break;
5769         case DW_OP_const4s:
5770           printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
5771           data += 4;
5772           break;
5773         case DW_OP_const8u:
5774           printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
5775                   (unsigned long) byte_get (data + 4, 4));
5776           data += 8;
5777           break;
5778         case DW_OP_const8s:
5779           printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
5780                   (long) byte_get (data + 4, 4));
5781           data += 8;
5782           break;
5783         case DW_OP_constu:
5784           printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
5785           data += bytes_read;
5786           break;
5787         case DW_OP_consts:
5788           printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
5789           data += bytes_read;
5790           break;
5791         case DW_OP_dup:
5792           printf ("DW_OP_dup");
5793           break;
5794         case DW_OP_drop:
5795           printf ("DW_OP_drop");
5796           break;
5797         case DW_OP_over:
5798           printf ("DW_OP_over");
5799           break;
5800         case DW_OP_pick:
5801           printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
5802           break;
5803         case DW_OP_swap:
5804           printf ("DW_OP_swap");
5805           break;
5806         case DW_OP_rot:
5807           printf ("DW_OP_rot");
5808           break;
5809         case DW_OP_xderef:
5810           printf ("DW_OP_xderef");
5811           break;
5812         case DW_OP_abs:
5813           printf ("DW_OP_abs");
5814           break;
5815         case DW_OP_and:
5816           printf ("DW_OP_and");
5817           break;
5818         case DW_OP_div:
5819           printf ("DW_OP_div");
5820           break;
5821         case DW_OP_minus:
5822           printf ("DW_OP_minus");
5823           break;
5824         case DW_OP_mod:
5825           printf ("DW_OP_mod");
5826           break;
5827         case DW_OP_mul:
5828           printf ("DW_OP_mul");
5829           break;
5830         case DW_OP_neg:
5831           printf ("DW_OP_neg");
5832           break;
5833         case DW_OP_not:
5834           printf ("DW_OP_not");
5835           break;
5836         case DW_OP_or:
5837           printf ("DW_OP_or");
5838           break;
5839         case DW_OP_plus:
5840           printf ("DW_OP_plus");
5841           break;
5842         case DW_OP_plus_uconst:
5843           printf ("DW_OP_plus_uconst: %lu",
5844                   read_leb128 (data, &bytes_read, 0));
5845           data += bytes_read;
5846           break;
5847         case DW_OP_shl:
5848           printf ("DW_OP_shl");
5849           break;
5850         case DW_OP_shr:
5851           printf ("DW_OP_shr");
5852           break;
5853         case DW_OP_shra:
5854           printf ("DW_OP_shra");
5855           break;
5856         case DW_OP_xor:
5857           printf ("DW_OP_xor");
5858           break;
5859         case DW_OP_bra:
5860           printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
5861           data += 2;
5862           break;
5863         case DW_OP_eq:
5864           printf ("DW_OP_eq");
5865           break;
5866         case DW_OP_ge:
5867           printf ("DW_OP_ge");
5868           break;
5869         case DW_OP_gt:
5870           printf ("DW_OP_gt");
5871           break;
5872         case DW_OP_le:
5873           printf ("DW_OP_le");
5874           break;
5875         case DW_OP_lt:
5876           printf ("DW_OP_lt");
5877           break;
5878         case DW_OP_ne:
5879           printf ("DW_OP_ne");
5880           break;
5881         case DW_OP_skip:
5882           printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
5883           data += 2;
5884           break;
5885
5886         case DW_OP_lit0:
5887         case DW_OP_lit1:
5888         case DW_OP_lit2:
5889         case DW_OP_lit3:
5890         case DW_OP_lit4:
5891         case DW_OP_lit5:
5892         case DW_OP_lit6:
5893         case DW_OP_lit7:
5894         case DW_OP_lit8:
5895         case DW_OP_lit9:
5896         case DW_OP_lit10:
5897         case DW_OP_lit11:
5898         case DW_OP_lit12:
5899         case DW_OP_lit13:
5900         case DW_OP_lit14:
5901         case DW_OP_lit15:
5902         case DW_OP_lit16:
5903         case DW_OP_lit17:
5904         case DW_OP_lit18:
5905         case DW_OP_lit19:
5906         case DW_OP_lit20:
5907         case DW_OP_lit21:
5908         case DW_OP_lit22:
5909         case DW_OP_lit23:
5910         case DW_OP_lit24:
5911         case DW_OP_lit25:
5912         case DW_OP_lit26:
5913         case DW_OP_lit27:
5914         case DW_OP_lit28:
5915         case DW_OP_lit29:
5916         case DW_OP_lit30:
5917         case DW_OP_lit31:
5918           printf ("DW_OP_lit%d", op - DW_OP_lit0);
5919           break;
5920
5921         case DW_OP_reg0:
5922         case DW_OP_reg1:
5923         case DW_OP_reg2:
5924         case DW_OP_reg3:
5925         case DW_OP_reg4:
5926         case DW_OP_reg5:
5927         case DW_OP_reg6:
5928         case DW_OP_reg7:
5929         case DW_OP_reg8:
5930         case DW_OP_reg9:
5931         case DW_OP_reg10:
5932         case DW_OP_reg11:
5933         case DW_OP_reg12:
5934         case DW_OP_reg13:
5935         case DW_OP_reg14:
5936         case DW_OP_reg15:
5937         case DW_OP_reg16:
5938         case DW_OP_reg17:
5939         case DW_OP_reg18:
5940         case DW_OP_reg19:
5941         case DW_OP_reg20:
5942         case DW_OP_reg21:
5943         case DW_OP_reg22:
5944         case DW_OP_reg23:
5945         case DW_OP_reg24:
5946         case DW_OP_reg25:
5947         case DW_OP_reg26:
5948         case DW_OP_reg27:
5949         case DW_OP_reg28:
5950         case DW_OP_reg29:
5951         case DW_OP_reg30:
5952         case DW_OP_reg31:
5953           printf ("DW_OP_reg%d", op - DW_OP_reg0);
5954           break;
5955
5956         case DW_OP_breg0:
5957         case DW_OP_breg1:
5958         case DW_OP_breg2:
5959         case DW_OP_breg3:
5960         case DW_OP_breg4:
5961         case DW_OP_breg5:
5962         case DW_OP_breg6:
5963         case DW_OP_breg7:
5964         case DW_OP_breg8:
5965         case DW_OP_breg9:
5966         case DW_OP_breg10:
5967         case DW_OP_breg11:
5968         case DW_OP_breg12:
5969         case DW_OP_breg13:
5970         case DW_OP_breg14:
5971         case DW_OP_breg15:
5972         case DW_OP_breg16:
5973         case DW_OP_breg17:
5974         case DW_OP_breg18:
5975         case DW_OP_breg19:
5976         case DW_OP_breg20:
5977         case DW_OP_breg21:
5978         case DW_OP_breg22:
5979         case DW_OP_breg23:
5980         case DW_OP_breg24:
5981         case DW_OP_breg25:
5982         case DW_OP_breg26:
5983         case DW_OP_breg27:
5984         case DW_OP_breg28:
5985         case DW_OP_breg29:
5986         case DW_OP_breg30:
5987         case DW_OP_breg31:
5988           printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
5989                   read_leb128 (data, &bytes_read, 1));
5990           data += bytes_read;
5991           break;
5992
5993         case DW_OP_regx:
5994           printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
5995           data += bytes_read;
5996           break;
5997         case DW_OP_fbreg:
5998           printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
5999           data += bytes_read;
6000           break;
6001         case DW_OP_bregx:
6002           uvalue = read_leb128 (data, &bytes_read, 0);
6003           data += bytes_read;
6004           printf ("DW_OP_bregx: %lu %ld", uvalue,
6005                   read_leb128 (data, &bytes_read, 1));
6006           data += bytes_read;
6007           break;
6008         case DW_OP_piece:
6009           printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6010           data += bytes_read;
6011           break;
6012         case DW_OP_deref_size:
6013           printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6014           break;
6015         case DW_OP_xderef_size:
6016           printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6017           break;
6018         case DW_OP_nop:
6019           printf ("DW_OP_nop");
6020           break;
6021
6022         default:
6023           if (op >= DW_OP_lo_user
6024               && op <= DW_OP_hi_user)
6025             printf (_("(User defined location op)"));
6026           else
6027             printf (_("(Unknown location op)"));
6028           /* No way to tell where the next op is, so just bail.  */
6029           return;
6030         }
6031     }
6032 }
6033
6034
6035 static unsigned char *
6036 read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
6037      unsigned long   attribute;
6038      unsigned long   form;
6039      unsigned char * data;
6040      unsigned long   cu_offset;
6041      unsigned long   pointer_size;
6042 {
6043   unsigned long   uvalue = 0;
6044   unsigned char * block_start = NULL;
6045   int             bytes_read;
6046
6047   printf ("     %-18s:", get_AT_name (attribute));
6048
6049   switch (form)
6050     {
6051     default:
6052       break;
6053
6054     case DW_FORM_ref_addr:
6055     case DW_FORM_addr:
6056       uvalue = byte_get (data, pointer_size);
6057       data += pointer_size;
6058       break;
6059
6060     case DW_FORM_ref1:
6061     case DW_FORM_flag:
6062     case DW_FORM_data1:
6063       uvalue = byte_get (data ++, 1);
6064       break;
6065
6066     case DW_FORM_ref2:
6067     case DW_FORM_data2:
6068       uvalue = byte_get (data, 2);
6069       data += 2;
6070       break;
6071
6072     case DW_FORM_ref4:
6073     case DW_FORM_data4:
6074       uvalue = byte_get (data, 4);
6075       data += 4;
6076       break;
6077
6078     case DW_FORM_sdata:
6079       uvalue = read_leb128 (data, & bytes_read, 1);
6080       data += bytes_read;
6081       break;
6082
6083     case DW_FORM_ref_udata:
6084     case DW_FORM_udata:
6085       uvalue = read_leb128 (data, & bytes_read, 0);
6086       data += bytes_read;
6087       break;
6088     }
6089
6090   switch (form)
6091     {
6092     case DW_FORM_ref_addr:
6093       printf (" <#%lx>", uvalue);
6094       break;
6095
6096     case DW_FORM_ref1:
6097     case DW_FORM_ref2:
6098     case DW_FORM_ref4:
6099     case DW_FORM_ref_udata:
6100       printf (" <%lx>", uvalue + cu_offset);
6101       break;
6102
6103     case DW_FORM_addr:
6104       printf (" %#lx", uvalue);
6105
6106     case DW_FORM_flag:
6107     case DW_FORM_data1:
6108     case DW_FORM_data2:
6109     case DW_FORM_data4:
6110     case DW_FORM_sdata:
6111     case DW_FORM_udata:
6112       printf (" %ld", uvalue);
6113       break;
6114
6115     case DW_FORM_ref8:
6116     case DW_FORM_data8:
6117       uvalue = byte_get (data, 4);
6118       printf (" %lx", uvalue);
6119       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
6120       data += 8;
6121       break;
6122
6123     case DW_FORM_string:
6124       printf (" %s", data);
6125       data += strlen ((char *) data) + 1;
6126       break;
6127
6128     case DW_FORM_block:
6129       uvalue = read_leb128 (data, & bytes_read, 0);
6130       block_start = data + bytes_read;
6131       data = display_block (block_start, uvalue);
6132       break;
6133
6134     case DW_FORM_block1:
6135       uvalue = byte_get (data, 1);
6136       block_start = data + 1;
6137       data = display_block (block_start, uvalue);
6138       break;
6139
6140     case DW_FORM_block2:
6141       uvalue = byte_get (data, 2);
6142       block_start = data + 2;
6143       data = display_block (block_start, uvalue);
6144       break;
6145
6146     case DW_FORM_block4:
6147       uvalue = byte_get (data, 4);
6148       block_start = data + 4;
6149       data = display_block (block_start, uvalue);
6150       break;
6151
6152     case DW_FORM_strp:
6153     case DW_FORM_indirect:
6154       warn (_("Unable to handle FORM: %d"), form);
6155       break;
6156
6157     default:
6158       warn (_("Unrecognised form: %d"), form);
6159       break;
6160     }
6161
6162   /* For some attributes we can display futher information.  */
6163
6164   printf ("\t");
6165
6166   switch (attribute)
6167     {
6168     case DW_AT_inline:
6169       switch (uvalue)
6170         {
6171         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
6172         case DW_INL_inlined:              printf (_("(inlined)")); break;
6173         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6174         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
6175         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
6176         }
6177       break;
6178
6179     case DW_AT_language:
6180       switch (uvalue)
6181         {
6182         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
6183         case DW_LANG_C89:            printf ("(ANSI C)"); break;
6184         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
6185         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
6186         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
6187         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
6188         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
6189         case DW_LANG_Ada83:          printf ("(Ada)"); break;
6190         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
6191         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
6192         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6193         default:                     printf ("(Unknown: %lx)", uvalue); break;
6194         }
6195       break;
6196
6197     case DW_AT_encoding:
6198       switch (uvalue)
6199         {
6200         case DW_ATE_void:            printf ("(void)"); break;
6201         case DW_ATE_address:         printf ("(machine address)"); break;
6202         case DW_ATE_boolean:         printf ("(boolean)"); break;
6203         case DW_ATE_complex_float:   printf ("(complex float)"); break;
6204         case DW_ATE_float:           printf ("(float)"); break;
6205         case DW_ATE_signed:          printf ("(signed)"); break;
6206         case DW_ATE_signed_char:     printf ("(signed char)"); break;
6207         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
6208         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
6209         default:
6210           if (uvalue >= DW_ATE_lo_user
6211               && uvalue <= DW_ATE_hi_user)
6212             printf ("(user defined type)");
6213           else
6214             printf ("(unknown type)");
6215           break;
6216         }
6217       break;
6218
6219     case DW_AT_accessibility:
6220       switch (uvalue)
6221         {
6222         case DW_ACCESS_public:          printf ("(public)"); break;
6223         case DW_ACCESS_protected:       printf ("(protected)"); break;
6224         case DW_ACCESS_private:         printf ("(private)"); break;
6225         default:                        printf ("(unknown accessibility)"); break;
6226         }
6227       break;
6228
6229     case DW_AT_visibility:
6230       switch (uvalue)
6231         {
6232         case DW_VIS_local:      printf ("(local)"); break;
6233         case DW_VIS_exported:   printf ("(exported)"); break;
6234         case DW_VIS_qualified:  printf ("(qualified)"); break;
6235         default:                printf ("(unknown visibility)"); break;
6236         }
6237       break;
6238
6239     case DW_AT_virtuality:
6240       switch (uvalue)
6241         {
6242         case DW_VIRTUALITY_none:        printf ("(none)"); break;
6243         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
6244         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6245         default:                        printf ("(unknown virtuality)"); break;
6246         }
6247       break;
6248
6249     case DW_AT_identifier_case:
6250       switch (uvalue)
6251         {
6252         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
6253         case DW_ID_up_case:             printf ("(up_case)"); break;
6254         case DW_ID_down_case:           printf ("(down_case)"); break;
6255         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
6256         default:                        printf ("(unknown case)"); break;
6257         }
6258       break;
6259
6260     case DW_AT_calling_convention:
6261       switch (uvalue)
6262         {
6263         case DW_CC_normal:      printf ("(normal)"); break;
6264         case DW_CC_program:     printf ("(program)"); break;
6265         case DW_CC_nocall:      printf ("(nocall)"); break;
6266         default:
6267           if (uvalue >= DW_CC_lo_user
6268               && uvalue <= DW_CC_hi_user)
6269             printf ("(user defined)");
6270           else
6271             printf ("(unknown convention)");
6272         }
6273       break;
6274
6275     case DW_AT_frame_base:
6276     case DW_AT_location:
6277     case DW_AT_data_member_location:
6278     case DW_AT_vtable_elem_location:
6279       if (block_start)
6280         {
6281           printf ("(");
6282           decode_location_expression (block_start, pointer_size, uvalue);
6283           printf (")");
6284         }
6285       break;
6286
6287     default:
6288       break;
6289     }
6290
6291   printf ("\n");
6292   return data;
6293 }
6294
6295 static int
6296 display_debug_info (section, start, file)
6297      Elf32_Internal_Shdr * section;
6298      unsigned char *       start;
6299      FILE *                file;
6300 {
6301   unsigned char * end = start + section->sh_size;
6302   unsigned char * section_begin = start;
6303
6304   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6305
6306   while (start < end)
6307     {
6308       DWARF2_External_CompUnit * external;
6309       DWARF2_Internal_CompUnit   compunit;
6310       unsigned char *            tags;
6311       int                        i;
6312       int                        level;
6313       unsigned long              cu_offset;
6314
6315       external = (DWARF2_External_CompUnit *) start;
6316
6317       compunit.cu_length        = BYTE_GET (external->cu_length);
6318       compunit.cu_version       = BYTE_GET (external->cu_version);
6319       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6320       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
6321
6322       tags = start + sizeof (* external);
6323       cu_offset = start - section_begin;
6324       start += compunit.cu_length + sizeof (external->cu_length);
6325
6326       if (compunit.cu_version != 2)
6327         {
6328           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6329           continue;
6330         }
6331
6332       printf (_("  Compilation Unit:\n"));
6333       printf (_("   Length:        %ld\n"), compunit.cu_length);
6334       printf (_("   Version:       %d\n"), compunit.cu_version);
6335       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6336       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
6337
6338       if (first_abbrev != NULL)
6339         free_abbrevs ();
6340
6341       /* Read in the abbrevs used by this compilation unit.  */
6342
6343       {
6344         Elf32_Internal_Shdr * sec;
6345         unsigned char *       begin;
6346
6347         /* Locate the .debug_abbrev section and process it.  */
6348         for (i = 0, sec = section_headers;
6349              i < elf_header.e_shnum;
6350              i ++, sec ++)
6351           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6352             break;
6353
6354         if (i == -1 || sec->sh_size == 0)
6355           {
6356             warn (_("Unable to locate .debug_abbrev section!\n"));
6357             return 0;
6358           }
6359
6360         GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
6361                         "debug_abbrev section data");
6362
6363         process_abbrev_section (begin + compunit.cu_abbrev_offset,
6364                                 begin + sec->sh_size);
6365
6366         free (begin);
6367       }
6368
6369       level = 0;
6370       while (tags < start)
6371         {
6372           int            bytes_read;
6373           unsigned long  abbrev_number;
6374           abbrev_entry * entry;
6375           abbrev_attr  * attr;
6376
6377           abbrev_number = read_leb128 (tags, & bytes_read, 0);
6378           tags += bytes_read;
6379
6380           /* A null DIE marks the end of a list of children.  */
6381           if (abbrev_number == 0)
6382             {
6383               --level;
6384               continue;
6385             }
6386
6387           /* Scan through the abbreviation list until we reach the
6388              correct entry.  */
6389           for (entry = first_abbrev;
6390                entry && entry->entry != abbrev_number;
6391                entry = entry->next)
6392             continue;
6393
6394           if (entry == NULL)
6395             {
6396               warn (_("Unable to locate entry %lu in the abbreviation table\n"),
6397                     abbrev_number);
6398               return 0;
6399             }
6400
6401           printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
6402                   level, tags - section_begin - bytes_read,
6403                   abbrev_number,
6404                   get_TAG_name (entry->tag));
6405
6406           for (attr = entry->first_attr; attr; attr = attr->next)
6407             tags = read_and_display_attr (attr->attribute,
6408                                           attr->form,
6409                                           tags, cu_offset,
6410                                           compunit.cu_pointer_size);
6411
6412           if (entry->children)
6413             ++level;
6414         }
6415     }
6416
6417   printf ("\n");
6418
6419   return 1;
6420 }
6421
6422 static int
6423 display_debug_aranges (section, start, file)
6424      Elf32_Internal_Shdr * section;
6425      unsigned char *       start;
6426      FILE *                file ATTRIBUTE_UNUSED;
6427 {
6428   unsigned char * end = start + section->sh_size;
6429
6430   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6431
6432   while (start < end)
6433     {
6434       DWARF2_External_ARange * external;
6435       DWARF2_Internal_ARange   arange;
6436       unsigned char *          ranges;
6437       unsigned long            length;
6438       unsigned long            address;
6439       int                      excess;
6440
6441       external = (DWARF2_External_ARange *) start;
6442
6443       arange.ar_length       = BYTE_GET (external->ar_length);
6444       arange.ar_version      = BYTE_GET (external->ar_version);
6445       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
6446       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
6447       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
6448
6449       if (arange.ar_version != 2)
6450         {
6451           warn (_("Only DWARF 2 aranges are currently supported.\n"));
6452           break;
6453         }
6454
6455       printf (_("  Length:                   %ld\n"), arange.ar_length);
6456       printf (_("  Version:                  %d\n"), arange.ar_version);
6457       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
6458       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
6459       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
6460
6461       printf (_("\n    Address  Length\n"));
6462
6463       ranges = start + sizeof (* external);
6464
6465       /* Must pad to an alignment boundary that is twice the pointer size.  */
6466       excess = sizeof (*external) % (2 * arange.ar_pointer_size);
6467       if (excess)
6468         ranges += (2 * arange.ar_pointer_size) - excess;
6469
6470       for (;;)
6471         {
6472           address = byte_get (ranges, arange.ar_pointer_size);
6473
6474           ranges += arange.ar_pointer_size;
6475
6476           length  = byte_get (ranges, arange.ar_pointer_size);
6477
6478           ranges += arange.ar_pointer_size;
6479
6480           /* A pair of zeros marks the end of the list.  */
6481           if (address == 0 && length == 0)
6482             break;
6483
6484           printf ("    %8.8lx %lu\n", address, length);
6485         }
6486
6487       start += arange.ar_length + sizeof (external->ar_length);
6488     }
6489
6490   printf ("\n");
6491
6492   return 1;
6493 }
6494
6495 typedef struct Frame_Chunk
6496 {
6497   struct Frame_Chunk *next;
6498   unsigned char *chunk_start;
6499   int ncols;
6500   /* DW_CFA_{undefined,same_value,offset,register}  */
6501   unsigned char *col_type;
6502   int *col_offset;
6503   char *augmentation;
6504   unsigned int code_factor;
6505   unsigned int data_factor;
6506   unsigned long pc_begin;
6507   unsigned long pc_range;
6508   int cfa_reg;
6509   int cfa_offset;
6510   int ra;
6511 }
6512 Frame_Chunk;
6513
6514 static void
6515 frame_need_space (fc, reg)
6516      Frame_Chunk *fc;
6517      int reg;
6518 {
6519   int prev = fc->ncols;
6520
6521   if (reg < fc->ncols)
6522     return;
6523   fc->ncols = reg + 1;
6524   fc->col_type = (unsigned char *) xrealloc (fc->col_type,
6525                                              fc->ncols * sizeof (unsigned char));
6526   fc->col_offset = (int *) xrealloc (fc->col_offset,
6527                                      fc->ncols * sizeof (int));
6528
6529   while (prev < fc->ncols)
6530     {
6531       fc->col_type[prev] = DW_CFA_undefined;
6532       fc->col_offset[prev] = 0;
6533       prev++;
6534     }
6535 }
6536
6537 static void
6538 frame_display_row (fc, need_col_headers, max_regs)
6539      Frame_Chunk *fc;
6540      int *need_col_headers;
6541      int *max_regs;
6542 {
6543   int r;
6544   char tmp[100];
6545
6546   if (*max_regs < fc->ncols)
6547     *max_regs = fc->ncols;
6548   if (*need_col_headers)
6549     {
6550       *need_col_headers = 0;
6551       printf ("   LOC   CFA      ");
6552       for (r=0; r<*max_regs; r++)
6553         if (r == fc->ra)
6554           printf ("ra   ");
6555         else
6556           printf ("r%-4d", r);
6557       printf ("\n");
6558     }
6559   printf ("%08x ", (unsigned int) fc->pc_begin);
6560   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
6561   printf ("%-8s ", tmp);
6562   for (r=0; r<fc->ncols; r++)
6563     {
6564       switch (fc->col_type[r])
6565         {
6566         case DW_CFA_undefined:
6567           strcpy (tmp, "u");
6568           break;
6569         case DW_CFA_same_value:
6570           strcpy (tmp, "s");
6571           break;
6572         case DW_CFA_offset:
6573           sprintf (tmp, "c%+d", fc->col_offset[r]);
6574           break;
6575         case DW_CFA_register:
6576           sprintf (tmp, "r%d", fc->col_offset[r]);
6577           break;
6578         default:
6579           strcpy (tmp, "n/a");
6580           break;
6581         }
6582       printf ("%-5s", tmp);
6583     }
6584   printf ("\n");
6585 }
6586
6587 #define GET(N)  byte_get (start, N); start += N
6588 #define LEB()   read_leb128 (start, &length_return, 0); start += length_return
6589 #define SLEB()  read_leb128 (start, &length_return, 1); start += length_return
6590
6591 static int
6592 display_debug_frames (section, start, file)
6593      Elf32_Internal_Shdr * section;
6594      unsigned char *       start;
6595      FILE *                file ATTRIBUTE_UNUSED;
6596 {
6597   unsigned char * end = start + section->sh_size;
6598   unsigned char *section_start = start;
6599   Frame_Chunk *chunks = 0;
6600   Frame_Chunk *remembered_state = 0, *rs;
6601   int is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
6602   int length_return;
6603   int max_regs = 0;
6604
6605   printf (_("The section %s contains:\n"), SECTION_NAME (section));
6606
6607   while (start < end)
6608     {
6609       unsigned char *saved_start, *block_end;
6610       unsigned long length, cie_id;
6611       Frame_Chunk *fc, *cie;
6612       int need_col_headers = 1;
6613
6614       saved_start = start;
6615       length = byte_get (start, 4); start += 4;
6616
6617       if (length == 0)
6618         return 1;
6619
6620       block_end = saved_start + length + 4;
6621       cie_id = byte_get (start, 4); start += 4;
6622
6623       printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
6624
6625       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
6626         {
6627           fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
6628           memset (fc, 0, sizeof (Frame_Chunk));
6629
6630           fc->next = chunks;
6631           chunks = fc;
6632           fc->chunk_start = saved_start;
6633           fc->ncols = 0;
6634           fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char));
6635           fc->col_offset = (int *) xmalloc (sizeof (int));
6636           frame_need_space (fc, max_regs-1);
6637
6638           start ++; /* version */
6639           fc->augmentation = start;
6640           while (*start) start++; start++; /* skip past NUL */
6641           if (fc->augmentation[0] == 'z')
6642             {
6643               int xtra;
6644               fc->code_factor = LEB ();
6645               fc->data_factor = SLEB ();
6646               fc->ra = byte_get (start, 1); start += 1;
6647               xtra = LEB ();
6648               printf ("skipping %d extra bytes\n", xtra);
6649               start += xtra;
6650             }
6651           else if (strcmp (fc->augmentation, "eh") == 0)
6652             {
6653               start += 4;
6654               fc->code_factor = LEB ();
6655               fc->data_factor = SLEB ();
6656               fc->ra = byte_get (start, 1); start += 1;
6657             }
6658           else
6659             {
6660               fc->code_factor = LEB ();
6661               fc->data_factor = SLEB ();
6662               fc->ra = byte_get (start, 1); start += 1;
6663             }
6664           cie = fc;
6665           printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
6666                   fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
6667
6668           frame_need_space (fc, fc->ra);
6669         }
6670       else
6671         {
6672           unsigned char *look_for;
6673           static Frame_Chunk fde_fc;
6674           fc = &fde_fc;
6675           memset (fc, 0, sizeof (Frame_Chunk));
6676
6677           look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
6678
6679           fc->pc_begin = byte_get (start, 4); start += 4;
6680           fc->pc_range = byte_get (start, 4); start += 4;
6681
6682           for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
6683           if (!cie)
6684             {
6685               warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start);
6686               start = block_end;
6687               fc->ncols = 0;
6688               fc->col_type = (unsigned char *) xmalloc (sizeof (unsigned char));
6689               fc->col_offset = (int *) xmalloc (sizeof (int));
6690               frame_need_space (fc, max_regs-1);
6691               cie = fc;
6692               fc->augmentation = "";
6693             }
6694           else
6695             {
6696               fc->ncols = cie->ncols;
6697               fc->col_type = (unsigned char *) xmalloc (fc->ncols * sizeof (unsigned char));
6698               fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
6699               memcpy (fc->col_type, cie->col_type, fc->ncols);
6700               memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
6701               fc->augmentation = cie->augmentation;
6702               fc->code_factor = cie->code_factor;
6703               fc->data_factor = cie->data_factor;
6704               fc->cfa_reg = cie->cfa_reg;
6705               fc->cfa_offset = cie->cfa_offset;
6706               fc->ra = cie->ra;
6707               frame_need_space (fc, max_regs-1);
6708             }
6709
6710           if (cie->augmentation[0] == 'z')
6711             {
6712               unsigned long l = LEB ();
6713               start += l;
6714             }
6715
6716           printf ("FDE cie=%08x pc=%08lx..%08lx\n",
6717                   cie->chunk_start-section_start, fc->pc_begin,
6718                   fc->pc_begin + fc->pc_range);
6719         }
6720
6721       /* At this point, fc is the current chunk, cie (if any) is set, and we're
6722          about to interpret instructions for the chunk.  */
6723
6724       /* This exists for readelf maintainers.  */
6725 #define FDEBUG 0
6726
6727       while (start < block_end)
6728         {
6729           unsigned op, opa;
6730           unsigned long ul, reg, roffs;
6731           long l, ofs;
6732           bfd_vma vma;
6733
6734           op = * start ++;
6735           opa = op & 0x3f;
6736           if (op & 0xc0)
6737             op &= 0xc0;
6738
6739           switch (op)
6740             {
6741             case DW_CFA_advance_loc:
6742               frame_display_row (fc, &need_col_headers, &max_regs);
6743 #if FDEBUG
6744               printf ("  DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
6745                       fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
6746 #endif
6747               fc->pc_begin += opa * fc->code_factor;
6748               break;
6749
6750             case DW_CFA_offset:
6751               frame_need_space (fc, opa);
6752               roffs = LEB ();
6753 #if FDEBUG
6754               printf ("  DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
6755 #endif
6756               fc->col_type[opa] = DW_CFA_offset;
6757               fc->col_offset[opa] = roffs * fc->data_factor;
6758               break;
6759
6760             case DW_CFA_restore:
6761               frame_need_space (fc, opa);
6762 #if FDEBUG
6763               printf ("  DW_CFA_restore: r%d\n", opa);
6764 #endif
6765               fc->col_type[opa] = cie->col_type[opa];
6766               fc->col_offset[opa] = cie->col_offset[opa];
6767               break;
6768
6769             case DW_CFA_set_loc:
6770               frame_display_row (fc, &need_col_headers, &max_regs);
6771               vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
6772 #if FDEBUG
6773               printf ("  DW_CFA_set_loc: %08x\n", vma);
6774 #endif
6775               fc->pc_begin = vma;
6776               break;
6777
6778             case DW_CFA_advance_loc1:
6779               frame_display_row (fc, &need_col_headers, &max_regs);
6780               ofs = byte_get (start, 1); start += 1;
6781 #if FDEBUG
6782               printf ("  DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
6783                       fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
6784 #endif
6785               fc->pc_begin += ofs * fc->code_factor;
6786               break;
6787
6788             case DW_CFA_advance_loc2:
6789               frame_display_row (fc, &need_col_headers, &max_regs);
6790               ofs = byte_get (start, 2); start += 2;
6791 #if FDEBUG
6792               printf ("  DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
6793                       fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
6794 #endif
6795               fc->pc_begin += ofs * fc->code_factor;
6796               break;
6797
6798             case DW_CFA_advance_loc4:
6799               frame_display_row (fc, &need_col_headers, &max_regs);
6800               ofs = byte_get (start, 4); start += 4;
6801 #if FDEBUG
6802               printf ("  DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
6803                       fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
6804 #endif
6805               fc->pc_begin += ofs * fc->code_factor;
6806               break;
6807
6808             case DW_CFA_offset_extended:
6809               reg = LEB ();
6810               roffs = LEB ();
6811               frame_need_space (fc, reg);
6812 #if FDEBUG
6813               printf ("  DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
6814 #endif
6815               fc->col_type[reg] = DW_CFA_offset;
6816               fc->col_offset[reg] = roffs * fc->data_factor;
6817               break;
6818
6819             case DW_CFA_restore_extended:
6820               reg = LEB ();
6821               frame_need_space (fc, reg);
6822 #if FDEBUG
6823               printf ("  DW_CFA_restore_extended: r%d\n", reg);
6824 #endif
6825               fc->col_type[reg] = cie->col_type[reg];
6826               fc->col_offset[reg] = cie->col_offset[reg];
6827               break;
6828
6829             case DW_CFA_undefined:
6830               reg = LEB ();
6831               frame_need_space (fc, reg);
6832 #if FDEBUG
6833               printf ("  DW_CFA_undefined: r%d\n", reg);
6834 #endif
6835               fc->col_type[reg] = DW_CFA_undefined;
6836               fc->col_offset[reg] = 0;
6837               break;
6838
6839             case DW_CFA_same_value:
6840               reg = LEB ();
6841               frame_need_space (fc, reg);
6842 #if FDEBUG
6843               printf ("  DW_CFA_same_value: r%d\n", reg);
6844 #endif
6845               fc->col_type[reg] = DW_CFA_same_value;
6846               fc->col_offset[reg] = 0;
6847               break;
6848
6849             case DW_CFA_register:
6850               reg = LEB ();
6851               roffs = LEB ();
6852               frame_need_space (fc, reg);
6853 #if FDEBUG
6854               printf ("  DW_CFA_ame_value: r%d\n", reg);
6855 #endif
6856               fc->col_type[reg] = DW_CFA_register;
6857               fc->col_offset[reg] = roffs;
6858               break;
6859
6860             case DW_CFA_remember_state:
6861 #if FDEBUG
6862               printf ("  DW_CFA_remember_state\n");
6863 #endif
6864               rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
6865               rs->ncols = fc->ncols;
6866               rs->col_type = (unsigned char *) xmalloc (rs->ncols);
6867               rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
6868               memcpy (rs->col_type, fc->col_type, rs->ncols);
6869               memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
6870               rs->next = remembered_state;
6871               remembered_state = rs;
6872               break;
6873
6874             case DW_CFA_restore_state:
6875 #if FDEBUG
6876               printf ("  DW_CFA_restore_state\n");
6877 #endif
6878               rs = remembered_state;
6879               remembered_state = rs->next;
6880               frame_need_space (fc, rs->ncols-1);
6881               memcpy (fc->col_type, rs->col_type, rs->ncols);
6882               memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
6883               free (rs->col_type);
6884               free (rs->col_offset);
6885               free (rs);
6886               break;
6887
6888             case DW_CFA_def_cfa:
6889               fc->cfa_reg = LEB ();
6890               fc->cfa_offset = LEB ();
6891 #if FDEBUG
6892               printf ("  DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
6893 #endif
6894               break;
6895
6896             case DW_CFA_def_cfa_register:
6897               fc->cfa_reg = LEB ();
6898 #if FDEBUG
6899               printf ("  DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
6900 #endif
6901               break;
6902
6903             case DW_CFA_def_cfa_offset:
6904               fc->cfa_offset = LEB ();
6905 #if FDEBUG
6906               printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
6907 #endif
6908               break;
6909
6910             case DW_CFA_nop:
6911 #if FDEBUG
6912               printf ("  DW_CFA_nop\n");
6913 #endif
6914               break;
6915
6916 #ifndef DW_CFA_GNU_window_save
6917 #define DW_CFA_GNU_window_save 0x2d
6918 #endif
6919             case DW_CFA_GNU_window_save:
6920 #if FDEBUG
6921               printf ("  DW_CFA_GNU_window_save\n");
6922 #endif
6923               break;
6924
6925 #ifndef DW_CFA_GNU_args_size
6926 #define DW_CFA_GNU_args_size 0x2e
6927 #endif
6928             case DW_CFA_GNU_args_size:
6929               ul = LEB ();
6930 #if FDEBUG
6931               printf ("  DW_CFA_GNU_args_size: %d\n", ul);
6932 #endif
6933               break;
6934
6935 #ifndef DW_CFA_GNU_negative_offset_extended
6936 #define DW_CFA_GNU_negative_offset_extended 0x2f
6937 #endif
6938             case DW_CFA_GNU_negative_offset_extended:
6939               reg = LEB ();
6940               l = - LEB ();
6941               frame_need_space (fc, reg);
6942 #if FDEBUG
6943               printf ("  DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
6944 #endif
6945               fc->col_type[reg] = DW_CFA_offset;
6946               fc->col_offset[reg] = l * fc->data_factor;
6947               break;
6948
6949             default:
6950               fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
6951               start = block_end;
6952             }
6953         }
6954
6955       frame_display_row (fc, &need_col_headers, &max_regs);
6956
6957       start = block_end;
6958     }
6959
6960   printf ("\n");
6961
6962   return 1;
6963 }
6964
6965 #undef GET
6966 #undef LEB
6967 #undef SLEB
6968
6969 static int
6970 display_debug_not_supported (section, start, file)
6971      Elf32_Internal_Shdr * section;
6972      unsigned char *       start ATTRIBUTE_UNUSED;
6973      FILE *                file ATTRIBUTE_UNUSED;
6974 {
6975   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
6976             SECTION_NAME (section));
6977
6978   return 1;
6979 }
6980
6981 /* Pre-scan the .debug_info section to record the size of address.
6982    When dumping the .debug_line, we use that size information, assuming
6983    that all compilation units have the same address size.  */
6984 static int
6985 prescan_debug_info (section, start, file)
6986      Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
6987      unsigned char *       start;
6988      FILE *                file ATTRIBUTE_UNUSED;
6989 {
6990   DWARF2_External_CompUnit * external;
6991
6992   external = (DWARF2_External_CompUnit *) start;
6993
6994   debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
6995   return 0;
6996 }
6997
6998   /* A structure containing the name of a debug section and a pointer
6999      to a function that can decode it.  The third field is a prescan
7000      function to be run over the section before displaying any of the
7001      sections.  */
7002 struct
7003 {
7004   char * name;
7005   int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7006   int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7007 }
7008 debug_displays[] =
7009 {
7010   { ".debug_info",        display_debug_info, prescan_debug_info },
7011   { ".debug_abbrev",      display_debug_abbrev, NULL },
7012   { ".debug_line",        display_debug_lines, NULL },
7013   { ".debug_aranges",     display_debug_aranges, NULL },
7014   { ".debug_pubnames",    display_debug_pubnames, NULL },
7015   { ".debug_frame",       display_debug_frames, NULL },
7016   { ".eh_frame",          display_debug_frames, NULL },
7017   { ".debug_macinfo",     display_debug_not_supported, NULL },
7018   { ".debug_frame",       display_debug_not_supported, NULL },
7019   { ".debug_str",         display_debug_not_supported, NULL },
7020   { ".debug_static_func", display_debug_not_supported, NULL },
7021   { ".debug_static_vars", display_debug_not_supported, NULL },
7022   { ".debug_types",       display_debug_not_supported, NULL },
7023   { ".debug_weaknames",   display_debug_not_supported, NULL }
7024 };
7025
7026 static int
7027 display_debug_section (section, file)
7028      Elf32_Internal_Shdr * section;
7029      FILE * file;
7030 {
7031   char *          name = SECTION_NAME (section);
7032   bfd_size_type   length;
7033   unsigned char * start;
7034   int             i;
7035
7036   length = section->sh_size;
7037   if (length == 0)
7038     {
7039       printf (_("\nSection '%s' has no debugging data.\n"), name);
7040       return 0;
7041     }
7042
7043   GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7044                   "debug section data");
7045
7046   /* See if we know how to display the contents of this section.  */
7047   for (i = NUM_ELEM (debug_displays); i--;)
7048     if (strcmp (debug_displays[i].name, name) == 0)
7049       {
7050         debug_displays[i].display (section, start, file);
7051         break;
7052       }
7053
7054   if (i == -1)
7055     printf (_("Unrecognised debug section: %s\n"), name);
7056
7057   free (start);
7058
7059   /* If we loaded in the abbrev section at some point,
7060      we must release it here.  */
7061   if (first_abbrev != NULL)
7062     free_abbrevs ();
7063
7064   return 1;
7065 }
7066
7067 static int
7068 process_section_contents (file)
7069      FILE * file;
7070 {
7071   Elf32_Internal_Shdr * section;
7072   unsigned int          i;
7073
7074   if (! do_dump)
7075     return 1;
7076
7077   /* Pre-scan the debug sections to find some debug information not
7078      present in some of them.  For the .debug_line, we must find out the
7079      size of address (specified in .debug_info and .debug_aranges).  */
7080   for (i = 0, section = section_headers;
7081        i < elf_header.e_shnum && i < num_dump_sects;
7082        i ++, section ++)
7083     {
7084       char *    name = SECTION_NAME (section);
7085       int       j;
7086
7087       if (section->sh_size == 0)
7088         continue;
7089
7090       /* See if there is some pre-scan operation for this section.  */
7091       for (j = NUM_ELEM (debug_displays); j--;)
7092         if (strcmp (debug_displays[j].name, name) == 0)
7093           {
7094             if (debug_displays[j].prescan != NULL)
7095               {
7096                 bfd_size_type   length;
7097                 unsigned char * start;
7098
7099                 length = section->sh_size;
7100                 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7101                                 "debug section data");
7102
7103                 debug_displays[j].prescan (section, start, file);
7104                 free (start);
7105               }
7106
7107             break;
7108           }
7109     }
7110
7111   for (i = 0, section = section_headers;
7112        i < elf_header.e_shnum && i < num_dump_sects;
7113        i ++, section ++)
7114     {
7115 #ifdef SUPPORT_DISASSEMBLY
7116       if (dump_sects[i] & DISASS_DUMP)
7117         disassemble_section (section, file);
7118 #endif
7119       if (dump_sects[i] & HEX_DUMP)
7120         dump_section (section, file);
7121
7122       if (dump_sects[i] & DEBUG_DUMP)
7123         display_debug_section (section, file);
7124     }
7125
7126   if (i < num_dump_sects)
7127     warn (_("Some sections were not dumped because they do not exist!\n"));
7128
7129   return 1;
7130 }
7131
7132 static void
7133 process_mips_fpe_exception (mask)
7134      int mask;
7135 {
7136   if (mask)
7137     {
7138       int first = 1;
7139       if (mask & OEX_FPU_INEX)
7140         fputs ("INEX", stdout), first = 0;
7141       if (mask & OEX_FPU_UFLO)
7142         printf ("%sUFLO", first ? "" : "|"), first = 0;
7143       if (mask & OEX_FPU_OFLO)
7144         printf ("%sOFLO", first ? "" : "|"), first = 0;
7145       if (mask & OEX_FPU_DIV0)
7146         printf ("%sDIV0", first ? "" : "|"), first = 0;
7147       if (mask & OEX_FPU_INVAL)
7148         printf ("%sINVAL", first ? "" : "|");
7149     }
7150   else
7151     fputs ("0", stdout);
7152 }
7153
7154 static int
7155 process_mips_specific (file)
7156      FILE * file;
7157 {
7158   Elf_Internal_Dyn * entry;
7159   size_t liblist_offset = 0;
7160   size_t liblistno = 0;
7161   size_t conflictsno = 0;
7162   size_t options_offset = 0;
7163   size_t conflicts_offset = 0;
7164
7165   /* We have a lot of special sections.  Thanks SGI!  */
7166   if (dynamic_segment == NULL)
7167     /* No information available.  */
7168     return 0;
7169
7170   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7171     switch (entry->d_tag)
7172       {
7173       case DT_MIPS_LIBLIST:
7174         liblist_offset = entry->d_un.d_val - loadaddr;
7175         break;
7176       case DT_MIPS_LIBLISTNO:
7177         liblistno = entry->d_un.d_val;
7178         break;
7179       case DT_MIPS_OPTIONS:
7180         options_offset = entry->d_un.d_val - loadaddr;
7181         break;
7182       case DT_MIPS_CONFLICT:
7183         conflicts_offset = entry->d_un.d_val - loadaddr;
7184         break;
7185       case DT_MIPS_CONFLICTNO:
7186         conflictsno = entry->d_un.d_val;
7187         break;
7188       default:
7189         break;
7190       }
7191
7192   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7193     {
7194       Elf32_External_Lib * elib;
7195       size_t cnt;
7196
7197       GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
7198                       elib, Elf32_External_Lib *, "liblist");
7199
7200       printf ("\nSection '.liblist' contains %lu entries:\n",
7201               (unsigned long) liblistno);
7202       fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
7203              stdout);
7204
7205       for (cnt = 0; cnt < liblistno; ++cnt)
7206         {
7207           Elf32_Lib liblist;
7208           time_t time;
7209           char timebuf[20];
7210           struct tm * tmp;
7211
7212           liblist.l_name = BYTE_GET (elib[cnt].l_name);
7213           time = BYTE_GET (elib[cnt].l_time_stamp);
7214           liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7215           liblist.l_version = BYTE_GET (elib[cnt].l_version);
7216           liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7217
7218           tmp = gmtime (&time);
7219           sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7220                    tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7221                    tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7222
7223           printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
7224                   dynamic_strings + liblist.l_name, timebuf,
7225                   liblist.l_checksum, liblist.l_version);
7226
7227           if (liblist.l_flags == 0)
7228             puts (" NONE");
7229           else
7230             {
7231               static const struct
7232               {
7233                 const char * name;
7234                 int bit;
7235               }
7236               l_flags_vals[] =
7237               {
7238                 { " EXACT_MATCH", LL_EXACT_MATCH },
7239                 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
7240                 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
7241                 { " EXPORTS", LL_EXPORTS },
7242                 { " DELAY_LOAD", LL_DELAY_LOAD },
7243                 { " DELTA", LL_DELTA }
7244               };
7245               int flags = liblist.l_flags;
7246               size_t fcnt;
7247
7248               for (fcnt = 0;
7249                    fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
7250                    ++fcnt)
7251                 if ((flags & l_flags_vals[fcnt].bit) != 0)
7252                   {
7253                     fputs (l_flags_vals[fcnt].name, stdout);
7254                     flags ^= l_flags_vals[fcnt].bit;
7255                   }
7256               if (flags != 0)
7257                 printf (" %#x", (unsigned int) flags);
7258
7259               puts ("");
7260             }
7261         }
7262
7263       free (elib);
7264     }
7265
7266   if (options_offset != 0)
7267     {
7268       Elf_External_Options * eopt;
7269       Elf_Internal_Shdr *    sect = section_headers;
7270       Elf_Internal_Options * iopt;
7271       Elf_Internal_Options * option;
7272       size_t offset;
7273       int cnt;
7274
7275       /* Find the section header so that we get the size.  */
7276       while (sect->sh_type != SHT_MIPS_OPTIONS)
7277         ++ sect;
7278
7279       GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
7280                       Elf_External_Options *, "options");
7281
7282       iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
7283                                               * sizeof (*iopt));
7284       if (iopt == NULL)
7285         {
7286           error (_("Out of memory"));
7287           return 0;
7288         }
7289
7290       offset = cnt = 0;
7291       option = iopt;
7292
7293       while (offset < sect->sh_size)
7294         {
7295           Elf_External_Options * eoption;
7296
7297           eoption = (Elf_External_Options *) ((char *) eopt + offset);
7298
7299           option->kind = BYTE_GET (eoption->kind);
7300           option->size = BYTE_GET (eoption->size);
7301           option->section = BYTE_GET (eoption->section);
7302           option->info = BYTE_GET (eoption->info);
7303
7304           offset += option->size;
7305
7306           ++option;
7307           ++cnt;
7308         }
7309
7310       printf (_("\nSection '%s' contains %d entries:\n"),
7311               string_table + sect->sh_name, cnt);
7312
7313       option = iopt;
7314
7315       while (cnt-- > 0)
7316         {
7317           size_t len;
7318
7319           switch (option->kind)
7320             {
7321             case ODK_NULL:
7322               /* This shouldn't happen.  */
7323               printf (" NULL       %d %lx", option->section, option->info);
7324               break;
7325             case ODK_REGINFO:
7326               printf (" REGINFO    ");
7327               if (elf_header.e_machine == EM_MIPS)
7328                 {
7329                   /* 32bit form.  */
7330                   Elf32_External_RegInfo *ereg;
7331                   Elf32_RegInfo reginfo;
7332
7333                   ereg = (Elf32_External_RegInfo *) (option + 1);
7334                   reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
7335                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7336                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7337                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7338                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7339                   reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
7340
7341                   printf ("GPR %08lx  GP 0x%lx\n",
7342                           reginfo.ri_gprmask,
7343                           (unsigned long) reginfo.ri_gp_value);
7344                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
7345                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7346                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7347                 }
7348               else
7349                 {
7350                   /* 64 bit form.  */
7351                   Elf64_External_RegInfo * ereg;
7352                   Elf64_Internal_RegInfo reginfo;
7353
7354                   ereg = (Elf64_External_RegInfo *) (option + 1);
7355                   reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
7356                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7357                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7358                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7359                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7360                   reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
7361
7362                   printf ("GPR %08lx  GP 0x",
7363                           reginfo.ri_gprmask);
7364                   printf_vma (reginfo.ri_gp_value);
7365                   printf ("\n");
7366
7367                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
7368                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7369                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7370                 }
7371               ++option;
7372               continue;
7373             case ODK_EXCEPTIONS:
7374               fputs (" EXCEPTIONS fpe_min(", stdout);
7375               process_mips_fpe_exception (option->info & OEX_FPU_MIN);
7376               fputs (") fpe_max(", stdout);
7377               process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
7378               fputs (")", stdout);
7379
7380               if (option->info & OEX_PAGE0)
7381                 fputs (" PAGE0", stdout);
7382               if (option->info & OEX_SMM)
7383                 fputs (" SMM", stdout);
7384               if (option->info & OEX_FPDBUG)
7385                 fputs (" FPDBUG", stdout);
7386               if (option->info & OEX_DISMISS)
7387                 fputs (" DISMISS", stdout);
7388               break;
7389             case ODK_PAD:
7390               fputs (" PAD       ", stdout);
7391               if (option->info & OPAD_PREFIX)
7392                 fputs (" PREFIX", stdout);
7393               if (option->info & OPAD_POSTFIX)
7394                 fputs (" POSTFIX", stdout);
7395               if (option->info & OPAD_SYMBOL)
7396                 fputs (" SYMBOL", stdout);
7397               break;
7398             case ODK_HWPATCH:
7399               fputs (" HWPATCH   ", stdout);
7400               if (option->info & OHW_R4KEOP)
7401                 fputs (" R4KEOP", stdout);
7402               if (option->info & OHW_R8KPFETCH)
7403                 fputs (" R8KPFETCH", stdout);
7404               if (option->info & OHW_R5KEOP)
7405                 fputs (" R5KEOP", stdout);
7406               if (option->info & OHW_R5KCVTL)
7407                 fputs (" R5KCVTL", stdout);
7408               break;
7409             case ODK_FILL:
7410               fputs (" FILL       ", stdout);
7411               /* XXX Print content of info word?  */
7412               break;
7413             case ODK_TAGS:
7414               fputs (" TAGS       ", stdout);
7415               /* XXX Print content of info word?  */
7416               break;
7417             case ODK_HWAND:
7418               fputs (" HWAND     ", stdout);
7419               if (option->info & OHWA0_R4KEOP_CHECKED)
7420                 fputs (" R4KEOP_CHECKED", stdout);
7421               if (option->info & OHWA0_R4KEOP_CLEAN)
7422                 fputs (" R4KEOP_CLEAN", stdout);
7423               break;
7424             case ODK_HWOR:
7425               fputs (" HWOR      ", stdout);
7426               if (option->info & OHWA0_R4KEOP_CHECKED)
7427                 fputs (" R4KEOP_CHECKED", stdout);
7428               if (option->info & OHWA0_R4KEOP_CLEAN)
7429                 fputs (" R4KEOP_CLEAN", stdout);
7430               break;
7431             case ODK_GP_GROUP:
7432               printf (" GP_GROUP  %#06lx  self-contained %#06lx",
7433                       option->info & OGP_GROUP,
7434                       (option->info & OGP_SELF) >> 16);
7435               break;
7436             case ODK_IDENT:
7437               printf (" IDENT     %#06lx  self-contained %#06lx",
7438                       option->info & OGP_GROUP,
7439                       (option->info & OGP_SELF) >> 16);
7440               break;
7441             default:
7442               /* This shouldn't happen.  */
7443               printf (" %3d ???     %d %lx",
7444                       option->kind, option->section, option->info);
7445               break;
7446             }
7447
7448           len = sizeof (*eopt);
7449           while (len < option->size)
7450             if (((char *) option)[len] >= ' '
7451                 && ((char *) option)[len] < 0x7f)
7452               printf ("%c", ((char *) option)[len++]);
7453             else
7454               printf ("\\%03o", ((char *) option)[len++]);
7455
7456           fputs ("\n", stdout);
7457           ++option;
7458         }
7459
7460       free (eopt);
7461     }
7462
7463   if (conflicts_offset != 0 && conflictsno != 0)
7464     {
7465       Elf32_External_Conflict * econf32;
7466       Elf64_External_Conflict * econf64;
7467       Elf32_Conflict * iconf;
7468       size_t cnt;
7469
7470       if (dynamic_symbols == NULL)
7471         {
7472           error (_("conflict list with without table"));
7473           return 0;
7474         }
7475
7476       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (*iconf));
7477       if (iconf == NULL)
7478         {
7479           error (_("Out of memory"));
7480           return 0;
7481         }
7482
7483       if (is_32bit_elf)
7484         {
7485           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf32),
7486                           econf32, Elf32_External_Conflict *, "conflict");
7487
7488           for (cnt = 0; cnt < conflictsno; ++cnt)
7489             iconf[cnt] = BYTE_GET (econf32[cnt]);
7490         }
7491       else
7492         {
7493           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (*econf64),
7494                           econf64, Elf64_External_Conflict *, "conflict");
7495
7496           for (cnt = 0; cnt < conflictsno; ++cnt)
7497             iconf[cnt] = BYTE_GET (econf64[cnt]);
7498         }
7499
7500       printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
7501       puts (_("  Num:    Index       Value  Name"));
7502
7503       for (cnt = 0; cnt < conflictsno; ++cnt)
7504         {
7505           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
7506
7507           printf ("%5lu: %8lu  ", (unsigned long) cnt, iconf[cnt]);
7508           print_vma (psym->st_value, FULL_HEX);
7509           printf ("  %s\n", dynamic_strings + psym->st_name);
7510         }
7511
7512       free (iconf);
7513     }
7514
7515   return 1;
7516 }
7517
7518 static char *
7519 get_note_type (e_type)
7520      unsigned e_type;
7521 {
7522   static char buff[64];
7523
7524   switch (e_type)
7525     {
7526     case NT_PRSTATUS:   return _("NT_PRSTATUS (prstatus structure)");
7527     case NT_FPREGSET:   return _("NT_FPREGSET (floating point registers)");
7528     case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
7529     case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
7530     case NT_PRXFPREG:   return _("NT_PRXFPREG (user_xfpregs structure)");
7531     case NT_PSTATUS:    return _("NT_PSTATUS (pstatus structure)");
7532     case NT_FPREGS:     return _("NT_FPREGS (floating point registers)");
7533     case NT_PSINFO:     return _("NT_PSINFO (psinfo structure)");
7534     case NT_LWPSTATUS:  return _("NT_LWPSTATUS (lwpstatus_t structure)");
7535     case NT_LWPSINFO:   return _("NT_LWPSINFO (lwpsinfo_t structure)");
7536     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
7537     default:
7538       sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
7539       return buff;
7540     }
7541 }
7542
7543 /* Note that by the ELF standard, the name field is already null byte
7544    terminated, and namesz includes the terminating null byte.
7545    I.E. the value of namesz for the name "FSF" is 4.
7546
7547    If the value of namesz is zero, there is no name present. */
7548 static int
7549 process_note (pnote)
7550   Elf32_Internal_Note * pnote;
7551 {
7552   printf ("  %s\t\t0x%08lx\t%s\n",
7553           pnote->namesz ? pnote->namedata : "(NONE)",
7554           pnote->descsz, get_note_type (pnote->type));
7555   return 1;
7556 }
7557
7558
7559 static int
7560 process_corefile_note_segment (file, offset, length)
7561      FILE * file;
7562      bfd_vma offset;
7563      bfd_vma length;
7564 {
7565   Elf_External_Note *  pnotes;
7566   Elf_External_Note *  external;
7567   int                  res = 1;
7568
7569   if (length <= 0)
7570     return 0;
7571
7572   GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
7573
7574   external = pnotes;
7575
7576   printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
7577           (unsigned long) offset, (unsigned long) length);
7578   printf (_("  Owner\t\tData size\tDescription\n"));
7579
7580   while (external < (Elf_External_Note *)((char *) pnotes + length))
7581     {
7582       Elf32_Internal_Note inote;
7583       char * temp = NULL;
7584
7585       inote.type     = BYTE_GET (external->type);
7586       inote.namesz   = BYTE_GET (external->namesz);
7587       inote.namedata = external->name;
7588       inote.descsz   = BYTE_GET (external->descsz);
7589       inote.descdata = inote.namedata + align_power (inote.namesz, 2);
7590       inote.descpos  = offset + (inote.descdata - (char *) pnotes);
7591
7592       external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
7593
7594       /* Verify that name is null terminated.  It appears that at least
7595          one version of Linux (RedHat 6.0) generates corefiles that don't
7596          comply with the ELF spec by failing to include the null byte in
7597          namesz.  */
7598       if (inote.namedata[inote.namesz] != '\0')
7599         {
7600           temp = malloc (inote.namesz + 1);
7601
7602           if (temp == NULL)
7603             {
7604               error (_("Out of memory\n"));
7605               res = 0;
7606               break;
7607             }
7608
7609           strncpy (temp, inote.namedata, inote.namesz);
7610           temp[inote.namesz] = 0;
7611
7612           /* warn (_("'%s' NOTE name not properly null terminated\n"), temp);  */
7613           inote.namedata = temp;
7614         }
7615
7616       res &= process_note (& inote);
7617
7618       if (temp != NULL)
7619         {
7620           free (temp);
7621           temp = NULL;
7622         }
7623     }
7624
7625   free (pnotes);
7626
7627   return res;
7628 }
7629
7630 static int
7631 process_corefile_note_segments (file)
7632      FILE * file;
7633 {
7634   Elf_Internal_Phdr * program_headers;
7635   Elf_Internal_Phdr * segment;
7636   unsigned int        i;
7637   int                 res = 1;
7638
7639   program_headers = (Elf_Internal_Phdr *) malloc
7640     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
7641
7642   if (program_headers == NULL)
7643     {
7644       error (_("Out of memory\n"));
7645       return 0;
7646     }
7647
7648   if (is_32bit_elf)
7649     i = get_32bit_program_headers (file, program_headers);
7650   else
7651     i = get_64bit_program_headers (file, program_headers);
7652
7653   if (i == 0)
7654     {
7655       free (program_headers);
7656       return 0;
7657     }
7658
7659   for (i = 0, segment = program_headers;
7660        i < elf_header.e_phnum;
7661        i ++, segment ++)
7662     {
7663       if (segment->p_type == PT_NOTE)
7664         res &= process_corefile_note_segment (file,
7665                                               (bfd_vma) segment->p_offset,
7666                                               (bfd_vma) segment->p_filesz);
7667     }
7668
7669   free (program_headers);
7670
7671   return res;
7672 }
7673
7674 static int
7675 process_corefile_contents (file)
7676      FILE * file;
7677 {
7678   /* If we have not been asked to display the notes then do nothing.  */
7679   if (! do_notes)
7680     return 1;
7681
7682   /* If file is not a core file then exit.  */
7683   if (elf_header.e_type != ET_CORE)
7684     return 1;
7685
7686   /* No program headers means no NOTE segment.  */
7687   if (elf_header.e_phnum == 0)
7688     {
7689       printf (_("No note segments present in the core file.\n"));
7690       return 1;
7691    }
7692
7693   return process_corefile_note_segments (file);
7694 }
7695
7696 static int
7697 process_arch_specific (file)
7698      FILE * file;
7699 {
7700   if (! do_arch)
7701     return 1;
7702
7703   switch (elf_header.e_machine)
7704     {
7705     case EM_MIPS:
7706     case EM_MIPS_RS4_BE:
7707       return process_mips_specific (file);
7708       break;
7709     default:
7710       break;
7711     }
7712   return 1;
7713 }
7714
7715 static int
7716 get_file_header (file)
7717      FILE * file;
7718 {
7719   /* Read in the identity array.  */
7720   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
7721     return 0;
7722
7723   /* Determine how to read the rest of the header.  */
7724   switch (elf_header.e_ident [EI_DATA])
7725     {
7726     default: /* fall through */
7727     case ELFDATANONE: /* fall through */
7728     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
7729     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
7730     }
7731
7732   /* For now we only support 32 bit and 64 bit ELF files.  */
7733   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
7734
7735   /* Read in the rest of the header.  */
7736   if (is_32bit_elf)
7737     {
7738       Elf32_External_Ehdr ehdr32;
7739
7740       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
7741         return 0;
7742
7743       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
7744       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
7745       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
7746       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
7747       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
7748       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
7749       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
7750       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
7751       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
7752       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
7753       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
7754       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
7755       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
7756     }
7757   else
7758     {
7759       Elf64_External_Ehdr ehdr64;
7760
7761       /* If we have been compiled with sizeof (bfd_vma) == 4, then
7762          we will not be able to cope with the 64bit data found in
7763          64 ELF files.  Detect this now and abort before we start
7764          overwritting things.  */
7765       if (sizeof (bfd_vma) < 8)
7766         {
7767           error (_("This instance of readelf has been built without support for a\n"));
7768           error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
7769           return 0;
7770         }
7771
7772       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
7773         return 0;
7774
7775       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
7776       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
7777       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
7778       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
7779       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
7780       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
7781       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
7782       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
7783       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
7784       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
7785       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
7786       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
7787       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
7788     }
7789
7790   return 1;
7791 }
7792
7793 static void
7794 process_file (file_name)
7795      char * file_name;
7796 {
7797   FILE *       file;
7798   struct stat  statbuf;
7799   unsigned int i;
7800
7801   if (stat (file_name, & statbuf) < 0)
7802     {
7803       error (_("Cannot stat input file %s.\n"), file_name);
7804       return;
7805     }
7806
7807   file = fopen (file_name, "rb");
7808   if (file == NULL)
7809     {
7810       error (_("Input file %s not found.\n"), file_name);
7811       return;
7812     }
7813
7814   if (! get_file_header (file))
7815     {
7816       error (_("%s: Failed to read file header\n"), file_name);
7817       fclose (file);
7818       return;
7819     }
7820
7821   /* Initialise per file variables.  */
7822   for (i = NUM_ELEM (version_info); i--;)
7823     version_info[i] = 0;
7824
7825   for (i = NUM_ELEM (dynamic_info); i--;)
7826     dynamic_info[i] = 0;
7827
7828   /* Process the file.  */
7829   if (show_name)
7830     printf (_("\nFile: %s\n"), file_name);
7831
7832   if (! process_file_header ())
7833     {
7834       fclose (file);
7835       return;
7836     }
7837
7838   process_section_headers (file);
7839
7840   process_program_headers (file);
7841
7842   process_dynamic_segment (file);
7843
7844   process_relocs (file);
7845
7846   process_symbol_table (file);
7847
7848   process_syminfo (file);
7849
7850   process_version_sections (file);
7851
7852   process_section_contents (file);
7853
7854   process_corefile_contents (file);
7855
7856   process_arch_specific (file);
7857
7858   fclose (file);
7859
7860   if (section_headers)
7861     {
7862       free (section_headers);
7863       section_headers = NULL;
7864     }
7865
7866   if (string_table)
7867     {
7868       free (string_table);
7869       string_table = NULL;
7870     }
7871
7872   if (dynamic_strings)
7873     {
7874       free (dynamic_strings);
7875       dynamic_strings = NULL;
7876     }
7877
7878   if (dynamic_symbols)
7879     {
7880       free (dynamic_symbols);
7881       dynamic_symbols = NULL;
7882       num_dynamic_syms = 0;
7883     }
7884
7885   if (dynamic_syminfo)
7886     {
7887       free (dynamic_syminfo);
7888       dynamic_syminfo = NULL;
7889     }
7890 }
7891
7892 #ifdef SUPPORT_DISASSEMBLY
7893 /* Needed by the i386 disassembler.  For extra credit, someone could
7894    fix this so that we insert symbolic addresses here, esp for GOT/PLT
7895    symbols */
7896
7897 void
7898 print_address (unsigned int addr, FILE * outfile)
7899 {
7900   fprintf (outfile,"0x%8.8x", addr);
7901 }
7902
7903 /* Needed by the i386 disassembler. */
7904 void
7905 db_task_printsym (unsigned int addr)
7906 {
7907   print_address (addr, stderr);
7908 }
7909 #endif
7910
7911 int
7912 main (argc, argv)
7913      int     argc;
7914      char ** argv;
7915 {
7916 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
7917   setlocale (LC_MESSAGES, "");
7918 #endif
7919   bindtextdomain (PACKAGE, LOCALEDIR);
7920   textdomain (PACKAGE);
7921
7922   parse_args (argc, argv);
7923
7924   if (optind < (argc - 1))
7925     show_name = 1;
7926
7927   while (optind < argc)
7928     process_file (argv [optind ++]);
7929
7930   if (dump_sects != NULL)
7931     free (dump_sects);
7932
7933   return 0;
7934 }