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