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