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