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