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