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