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