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