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