OSDN Git Service

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