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