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