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