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