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