OSDN Git Service

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