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