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