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