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