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