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