Add s390 support
[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 *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
3438 static void
3439 dynamic_segment_mips_val (entry)
3440      Elf_Internal_Dyn * entry;
3441 {
3442   switch (entry->d_tag)
3443     {
3444     case DT_MIPS_FLAGS:
3445       if (entry->d_un.d_val == 0)
3446         printf ("NONE\n");
3447       else
3448         {
3449           static const char * opts[] =
3450           {
3451             "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
3452             "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
3453             "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
3454             "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
3455             "RLD_ORDER_SAFE"
3456           };
3457           unsigned int cnt;
3458           int first = 1;
3459           for (cnt = 0; cnt < NUM_ELEM (opts); ++ cnt)
3460             if (entry->d_un.d_val & (1 << cnt))
3461               {
3462                 printf ("%s%s", first ? "" : " ", opts[cnt]);
3463                 first = 0;
3464               }
3465           puts ("");
3466         }
3467       break;
3468
3469     case DT_MIPS_IVERSION:
3470       if (dynamic_strings != NULL)
3471         printf ("Interface Version: %s\n",
3472                 dynamic_strings + entry->d_un.d_val);
3473       else
3474         printf ("%ld\n", (long) entry->d_un.d_ptr);
3475       break;
3476
3477     case DT_MIPS_TIME_STAMP:
3478       {
3479         char timebuf[20];
3480         struct tm * tmp;
3481
3482         time_t time = entry->d_un.d_val;
3483         tmp = gmtime (&time);
3484         sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
3485                  tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
3486                  tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
3487         printf ("Time Stamp: %s\n", timebuf);
3488       }
3489       break;
3490
3491     case DT_MIPS_RLD_VERSION:
3492     case DT_MIPS_LOCAL_GOTNO:
3493     case DT_MIPS_CONFLICTNO:
3494     case DT_MIPS_LIBLISTNO:
3495     case DT_MIPS_SYMTABNO:
3496     case DT_MIPS_UNREFEXTNO:
3497     case DT_MIPS_HIPAGENO:
3498     case DT_MIPS_DELTA_CLASS_NO:
3499     case DT_MIPS_DELTA_INSTANCE_NO:
3500     case DT_MIPS_DELTA_RELOC_NO:
3501     case DT_MIPS_DELTA_SYM_NO:
3502     case DT_MIPS_DELTA_CLASSSYM_NO:
3503     case DT_MIPS_COMPACT_SIZE:
3504       printf ("%ld\n", (long) entry->d_un.d_ptr);
3505       break;
3506
3507     default:
3508       printf ("%#lx\n", (long) entry->d_un.d_ptr);
3509     }
3510 }
3511
3512
3513 static void
3514 dynamic_segment_parisc_val (entry)
3515      Elf_Internal_Dyn * entry;
3516 {
3517   switch (entry->d_tag)
3518     {
3519     case DT_HP_DLD_FLAGS:
3520       {
3521         static struct
3522         {
3523           long int bit;
3524           const char * str;
3525         }
3526         flags[] =
3527         {
3528           { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
3529           { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
3530           { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
3531           { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
3532           { DT_HP_BIND_NOW, "HP_BIND_NOW" },
3533           { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
3534           { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
3535           { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
3536           { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
3537           { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
3538           { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" }
3539         };
3540         int first = 1;
3541         size_t cnt;
3542         bfd_vma val = entry->d_un.d_val;
3543
3544         for (cnt = 0; cnt < sizeof (flags) / sizeof (flags[0]); ++cnt)
3545           if (val & flags[cnt].bit)
3546             {
3547               if (! first)
3548                 putchar (' ');
3549               fputs (flags[cnt].str, stdout);
3550               first = 0;
3551               val ^= flags[cnt].bit;
3552             }
3553
3554         if (val != 0 || first)
3555           {
3556             if (! first)
3557               putchar (' ');
3558             print_vma (val, HEX);
3559           }
3560       }
3561       break;
3562
3563     default:
3564       print_vma (entry->d_un.d_ptr, PREFIX_HEX);
3565       break;
3566     }
3567 }
3568
3569 static int
3570 get_32bit_dynamic_segment (file)
3571      FILE * file;
3572 {
3573   Elf32_External_Dyn * edyn;
3574   Elf_Internal_Dyn *   entry;
3575   bfd_size_type        i;
3576
3577   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3578                   edyn, Elf32_External_Dyn *, "dynamic segment");
3579
3580   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
3581      how large this .dynamic is now.  We can do this even before the byte
3582      swapping since the DT_NULL tag is recognizable.  */
3583   dynamic_size = 0;
3584   while (*(Elf32_Word *) edyn [dynamic_size++].d_tag != DT_NULL)
3585     ;
3586
3587   dynamic_segment = (Elf_Internal_Dyn *)
3588     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3589
3590   if (dynamic_segment == NULL)
3591     {
3592       error (_("Out of memory\n"));
3593       free (edyn);
3594       return 0;
3595     }
3596
3597   for (i = 0, entry = dynamic_segment;
3598        i < dynamic_size;
3599        i ++, entry ++)
3600     {
3601       entry->d_tag      = BYTE_GET (edyn [i].d_tag);
3602       entry->d_un.d_val = BYTE_GET (edyn [i].d_un.d_val);
3603     }
3604
3605   free (edyn);
3606
3607   return 1;
3608 }
3609
3610 static int
3611 get_64bit_dynamic_segment (file)
3612      FILE * file;
3613 {
3614   Elf64_External_Dyn * edyn;
3615   Elf_Internal_Dyn *   entry;
3616   bfd_size_type        i;
3617
3618   GET_DATA_ALLOC (dynamic_addr, dynamic_size,
3619                   edyn, Elf64_External_Dyn *, "dynamic segment");
3620
3621   /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
3622      how large this .dynamic is now.  We can do this even before the byte
3623      swapping since the DT_NULL tag is recognizable.  */
3624   dynamic_size = 0;
3625   while (*(bfd_vma *) edyn [dynamic_size ++].d_tag != DT_NULL)
3626     ;
3627
3628   dynamic_segment = (Elf_Internal_Dyn *)
3629     malloc (dynamic_size * sizeof (Elf_Internal_Dyn));
3630
3631   if (dynamic_segment == NULL)
3632     {
3633       error (_("Out of memory\n"));
3634       free (edyn);
3635       return 0;
3636     }
3637
3638   for (i = 0, entry = dynamic_segment;
3639        i < dynamic_size;
3640        i ++, entry ++)
3641     {
3642       entry->d_tag      = BYTE_GET8 (edyn [i].d_tag);
3643       entry->d_un.d_val = BYTE_GET8 (edyn [i].d_un.d_val);
3644     }
3645
3646   free (edyn);
3647
3648   return 1;
3649 }
3650
3651 static const char *
3652 get_dynamic_flags (flags)
3653      bfd_vma flags;
3654 {
3655   static char buff [64];
3656   while (flags)
3657     {
3658       bfd_vma flag;
3659
3660       flag = flags & - flags;
3661       flags &= ~ flag;
3662
3663       switch (flag)
3664         {
3665         case DF_ORIGIN:   strcat (buff, "ORIGIN "); break;
3666         case DF_SYMBOLIC: strcat (buff, "SYMBOLIC "); break;
3667         case DF_TEXTREL:  strcat (buff, "TEXTREL "); break;
3668         case DF_BIND_NOW: strcat (buff, "BIND_NOW "); break;
3669         default:          strcat (buff, "unknown "); break;
3670         }
3671     }
3672   return buff;
3673 }
3674
3675 /* Parse and display the contents of the dynamic segment.  */
3676 static int
3677 process_dynamic_segment (file)
3678      FILE * file;
3679 {
3680   Elf_Internal_Dyn * entry;
3681   bfd_size_type      i;
3682
3683   if (dynamic_size == 0)
3684     {
3685       if (do_dynamic)
3686         printf (_("\nThere is no dynamic segment in this file.\n"));
3687
3688       return 1;
3689     }
3690
3691   if (is_32bit_elf)
3692     {
3693       if (! get_32bit_dynamic_segment (file))
3694         return 0;
3695     }
3696   else if (! get_64bit_dynamic_segment (file))
3697     return 0;
3698
3699   /* Find the appropriate symbol table.  */
3700   if (dynamic_symbols == NULL)
3701     {
3702       for (i = 0, entry = dynamic_segment;
3703            i < dynamic_size;
3704            ++i, ++ entry)
3705         {
3706           unsigned long        offset;
3707
3708           if (entry->d_tag != DT_SYMTAB)
3709             continue;
3710
3711           dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
3712
3713           /* Since we do not know how big the symbol table is,
3714              we default to reading in the entire file (!) and
3715              processing that.  This is overkill, I know, but it
3716              should work. */
3717           offset = entry->d_un.d_val - loadaddr;
3718
3719           if (fseek (file, 0, SEEK_END))
3720             error (_("Unable to seek to end of file!"));
3721
3722           if (is_32bit_elf)
3723             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf32_External_Sym);
3724           else
3725             num_dynamic_syms = (ftell (file) - offset) / sizeof (Elf64_External_Sym);
3726
3727           if (num_dynamic_syms < 1)
3728             {
3729               error (_("Unable to determine the number of symbols to load\n"));
3730               continue;
3731             }
3732
3733           dynamic_symbols = GET_ELF_SYMBOLS (file, offset, num_dynamic_syms);
3734         }
3735     }
3736
3737   /* Similarly find a string table.  */
3738   if (dynamic_strings == NULL)
3739     {
3740       for (i = 0, entry = dynamic_segment;
3741            i < dynamic_size;
3742            ++i, ++ entry)
3743         {
3744           unsigned long offset;
3745           long          str_tab_len;
3746
3747           if (entry->d_tag != DT_STRTAB)
3748             continue;
3749
3750           dynamic_info[DT_STRTAB] = entry->d_un.d_val;
3751
3752           /* Since we do not know how big the string table is,
3753              we default to reading in the entire file (!) and
3754              processing that.  This is overkill, I know, but it
3755              should work. */
3756
3757           offset = entry->d_un.d_val - loadaddr;
3758           if (fseek (file, 0, SEEK_END))
3759             error (_("Unable to seek to end of file\n"));
3760           str_tab_len = ftell (file) - offset;
3761
3762           if (str_tab_len < 1)
3763             {
3764               error
3765                 (_("Unable to determine the length of the dynamic string table\n"));
3766               continue;
3767             }
3768
3769           GET_DATA_ALLOC (offset, str_tab_len, dynamic_strings, char *,
3770                           "dynamic string table");
3771
3772           break;
3773         }
3774     }
3775
3776   /* And find the syminfo section if available.  */
3777   if (dynamic_syminfo == NULL)
3778     {
3779       unsigned int syminsz = 0;
3780
3781       for (i = 0, entry = dynamic_segment;
3782            i < dynamic_size;
3783            ++i, ++ entry)
3784         {
3785           if (entry->d_tag == DT_SYMINENT)
3786             {
3787               /* Note: these braces are necessary to avoid a syntax
3788                  error from the SunOS4 C compiler.  */
3789               assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
3790             }
3791           else if (entry->d_tag == DT_SYMINSZ)
3792             syminsz = entry->d_un.d_val;
3793           else if (entry->d_tag == DT_SYMINFO)
3794             dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
3795         }
3796
3797       if (dynamic_syminfo_offset != 0 && syminsz != 0)
3798         {
3799           Elf_External_Syminfo * extsyminfo;
3800           Elf_Internal_Syminfo * syminfo;
3801
3802           /* There is a syminfo section.  Read the data.  */
3803           GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
3804                           Elf_External_Syminfo *, "symbol information");
3805
3806           dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
3807           if (dynamic_syminfo == NULL)
3808             {
3809               error (_("Out of memory\n"));
3810               return 0;
3811             }
3812
3813           dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
3814           for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
3815                ++i, ++syminfo)
3816             {
3817               syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
3818               syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
3819             }
3820
3821           free (extsyminfo);
3822         }
3823     }
3824
3825   if (do_dynamic && dynamic_addr)
3826     printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
3827             dynamic_addr, (long) dynamic_size);
3828   if (do_dynamic)
3829     printf (_("  Tag        Type                         Name/Value\n"));
3830
3831   for (i = 0, entry = dynamic_segment;
3832        i < dynamic_size;
3833        i++, entry ++)
3834     {
3835       if (do_dynamic)
3836         {
3837           const char * dtype;
3838
3839           putchar (' ');
3840           print_vma (entry->d_tag, FULL_HEX);
3841           dtype = get_dynamic_type (entry->d_tag);
3842           printf (" (%s)%*s", dtype,
3843                   ((is_32bit_elf ? 27 : 19)
3844                    - (int) strlen (dtype)),
3845                   " ");
3846         }
3847
3848       switch (entry->d_tag)
3849         {
3850         case DT_FLAGS:
3851           if (do_dynamic)
3852             printf ("%s", get_dynamic_flags (entry->d_un.d_val));
3853           break;
3854
3855         case DT_AUXILIARY:
3856         case DT_FILTER:
3857         case DT_CONFIG:
3858         case DT_DEPAUDIT:
3859         case DT_AUDIT:
3860           if (do_dynamic)
3861             {
3862               switch (entry->d_tag)
3863                 {
3864                 case DT_AUXILIARY:
3865                   printf (_("Auxiliary library"));
3866                   break;
3867
3868                 case DT_FILTER:
3869                   printf (_("Filter library"));
3870                   break;
3871
3872                 case DT_CONFIG:
3873                   printf (_("Configuration file"));
3874                   break;
3875
3876                 case DT_DEPAUDIT:
3877                   printf (_("Dependency audit library"));
3878                   break;
3879
3880                 case DT_AUDIT:
3881                   printf (_("Audit library"));
3882                   break;
3883                 }
3884
3885               if (dynamic_strings)
3886                 printf (": [%s]\n", dynamic_strings + entry->d_un.d_val);
3887               else
3888                 {
3889                   printf (": ");
3890                   print_vma (entry->d_un.d_val, PREFIX_HEX);
3891                   putchar ('\n');
3892                 }
3893             }
3894           break;
3895
3896         case DT_FEATURE:
3897           if (do_dynamic)
3898             {
3899               printf (_("Flags:"));
3900               if (entry->d_un.d_val == 0)
3901                 printf (_(" None\n"));
3902               else
3903                 {
3904                   unsigned long int val = entry->d_un.d_val;
3905                   if (val & DTF_1_PARINIT)
3906                     {
3907                       printf (" PARINIT");
3908                       val ^= DTF_1_PARINIT;
3909                     }
3910                   if (val & DTF_1_CONFEXP)
3911                     {
3912                       printf (" CONFEXP");
3913                       val ^= DTF_1_CONFEXP;
3914                     }
3915                   if (val != 0)
3916                     printf (" %lx", val);
3917                   puts ("");
3918                 }
3919             }
3920           break;
3921
3922         case DT_POSFLAG_1:
3923           if (do_dynamic)
3924             {
3925               printf (_("Flags:"));
3926               if (entry->d_un.d_val == 0)
3927                 printf (_(" None\n"));
3928               else
3929                 {
3930                   unsigned long int val = entry->d_un.d_val;
3931                   if (val & DF_P1_LAZYLOAD)
3932                     {
3933                       printf (" LAZYLOAD");
3934                       val ^= DF_P1_LAZYLOAD;
3935                     }
3936                   if (val & DF_P1_GROUPPERM)
3937                     {
3938                       printf (" GROUPPERM");
3939                       val ^= DF_P1_GROUPPERM;
3940                     }
3941                   if (val != 0)
3942                     printf (" %lx", val);
3943                   puts ("");
3944                 }
3945             }
3946           break;
3947
3948         case DT_FLAGS_1:
3949           if (do_dynamic)
3950             {
3951               printf (_("Flags:"));
3952               if (entry->d_un.d_val == 0)
3953                 printf (_(" None\n"));
3954               else
3955                 {
3956                   unsigned long int val = entry->d_un.d_val;
3957                   if (val & DF_1_NOW)
3958                     {
3959                       printf (" NOW");
3960                       val ^= DF_1_NOW;
3961                     }
3962                   if (val & DF_1_GLOBAL)
3963                     {
3964                       printf (" GLOBAL");
3965                       val ^= DF_1_GLOBAL;
3966                     }
3967                   if (val & DF_1_GROUP)
3968                     {
3969                       printf (" GROUP");
3970                       val ^= DF_1_GROUP;
3971                     }
3972                   if (val & DF_1_NODELETE)
3973                     {
3974                       printf (" NODELETE");
3975                       val ^= DF_1_NODELETE;
3976                     }
3977                   if (val & DF_1_LOADFLTR)
3978                     {
3979                       printf (" LOADFLTR");
3980                       val ^= DF_1_LOADFLTR;
3981                     }
3982                   if (val & DF_1_INITFIRST)
3983                     {
3984                       printf (" INITFIRST");
3985                       val ^= DF_1_INITFIRST;
3986                     }
3987                   if (val & DF_1_NOOPEN)
3988                     {
3989                       printf (" NOOPEN");
3990                       val ^= DF_1_NOOPEN;
3991                     }
3992                   if (val & DF_1_ORIGIN)
3993                     {
3994                       printf (" ORIGIN");
3995                       val ^= DF_1_ORIGIN;
3996                     }
3997                   if (val & DF_1_DIRECT)
3998                     {
3999                       printf (" DIRECT");
4000                       val ^= DF_1_DIRECT;
4001                     }
4002                   if (val & DF_1_TRANS)
4003                     {
4004                       printf (" TRANS");
4005                       val ^= DF_1_TRANS;
4006                     }
4007                   if (val & DF_1_INTERPOSE)
4008                     {
4009                       printf (" INTERPOSE");
4010                       val ^= DF_1_INTERPOSE;
4011                     }
4012                   if (val & DF_1_NODEFLIB)
4013                     {
4014                       printf (" NODEFLIB");
4015                       val ^= DF_1_NODEFLIB;
4016                     }
4017                   if (val & DF_1_NODUMP)
4018                     {
4019                       printf (" NODUMP");
4020                       val ^= DF_1_NODUMP;
4021                     }
4022                   if (val & DF_1_CONLFAT)
4023                     {
4024                       printf (" CONLFAT");
4025                       val ^= DF_1_CONLFAT;
4026                     }
4027                   if (val != 0)
4028                     printf (" %lx", val);
4029                   puts ("");
4030                 }
4031             }
4032           break;
4033
4034         case DT_PLTREL:
4035           if (do_dynamic)
4036             puts (get_dynamic_type (entry->d_un.d_val));
4037           break;
4038
4039         case DT_NULL    :
4040         case DT_NEEDED  :
4041         case DT_PLTGOT  :
4042         case DT_HASH    :
4043         case DT_STRTAB  :
4044         case DT_SYMTAB  :
4045         case DT_RELA    :
4046         case DT_INIT    :
4047         case DT_FINI    :
4048         case DT_SONAME  :
4049         case DT_RPATH   :
4050         case DT_SYMBOLIC:
4051         case DT_REL     :
4052         case DT_DEBUG   :
4053         case DT_TEXTREL :
4054         case DT_JMPREL  :
4055         case DT_RUNPATH :
4056           dynamic_info[entry->d_tag] = entry->d_un.d_val;
4057
4058           if (do_dynamic)
4059             {
4060               char * name;
4061
4062               if (dynamic_strings == NULL)
4063                 name = NULL;
4064               else
4065                 name = dynamic_strings + entry->d_un.d_val;
4066
4067               if (name)
4068                 {
4069                   switch (entry->d_tag)
4070                     {
4071                     case DT_NEEDED:
4072                       printf (_("Shared library: [%s]"), name);
4073
4074                       if (strcmp (name, program_interpreter) == 0)
4075                         printf (_(" program interpreter"));
4076                       break;
4077
4078                     case DT_SONAME:
4079                       printf (_("Library soname: [%s]"), name);
4080                       break;
4081
4082                     case DT_RPATH:
4083                       printf (_("Library rpath: [%s]"), name);
4084                       break;
4085
4086                     case DT_RUNPATH:
4087                       printf (_("Library runpath: [%s]"), name);
4088                       break;
4089
4090                     default:
4091                       print_vma (entry->d_un.d_val, PREFIX_HEX);
4092                       break;
4093                     }
4094                 }
4095               else
4096                 print_vma (entry->d_un.d_val, PREFIX_HEX);
4097
4098               putchar ('\n');
4099             }
4100           break;
4101
4102         case DT_PLTRELSZ:
4103         case DT_RELASZ  :
4104         case DT_STRSZ   :
4105         case DT_RELSZ   :
4106         case DT_RELAENT :
4107         case DT_SYMENT  :
4108         case DT_RELENT  :
4109         case DT_PLTPADSZ:
4110         case DT_MOVEENT :
4111         case DT_MOVESZ  :
4112         case DT_INIT_ARRAYSZ:
4113         case DT_FINI_ARRAYSZ:
4114           if (do_dynamic)
4115             {
4116               print_vma (entry->d_un.d_val, UNSIGNED);
4117               printf (" (bytes)\n");
4118             }
4119           break;
4120
4121         case DT_VERDEFNUM:
4122         case DT_VERNEEDNUM:
4123         case DT_RELACOUNT:
4124         case DT_RELCOUNT:
4125           if (do_dynamic)
4126             {
4127               print_vma (entry->d_un.d_val, UNSIGNED);
4128               putchar ('\n');
4129             }
4130           break;
4131
4132         case DT_SYMINSZ:
4133         case DT_SYMINENT:
4134         case DT_SYMINFO:
4135         case DT_USED:
4136         case DT_INIT_ARRAY:
4137         case DT_FINI_ARRAY:
4138           if (do_dynamic)
4139             {
4140               if (dynamic_strings != NULL && entry->d_tag == DT_USED)
4141                 {
4142                   char * name;
4143
4144                   name = dynamic_strings + entry->d_un.d_val;
4145
4146                   if (* name)
4147                     {
4148                       printf (_("Not needed object: [%s]\n"), name);
4149                       break;
4150                     }
4151                 }
4152
4153               print_vma (entry->d_un.d_val, PREFIX_HEX);
4154               putchar ('\n');
4155             }
4156           break;
4157
4158         case DT_BIND_NOW:
4159           /* The value of this entry is ignored.  */
4160           break;
4161
4162         default:
4163           if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
4164             version_info [DT_VERSIONTAGIDX (entry->d_tag)] =
4165               entry->d_un.d_val;
4166
4167           if (do_dynamic)
4168             {
4169               switch (elf_header.e_machine)
4170                 {
4171                 case EM_MIPS:
4172                 case EM_MIPS_RS4_BE:
4173                   dynamic_segment_mips_val (entry);
4174                   break;
4175                 case EM_PARISC:
4176                   dynamic_segment_parisc_val (entry);
4177                   break;
4178                 default:
4179                   print_vma (entry->d_un.d_val, PREFIX_HEX);
4180                   putchar ('\n');
4181                 }
4182             }
4183           break;
4184         }
4185     }
4186
4187   return 1;
4188 }
4189
4190 static char *
4191 get_ver_flags (flags)
4192      unsigned int flags;
4193 {
4194   static char buff [32];
4195
4196   buff[0] = 0;
4197
4198   if (flags == 0)
4199     return _("none");
4200
4201   if (flags & VER_FLG_BASE)
4202     strcat (buff, "BASE ");
4203
4204   if (flags & VER_FLG_WEAK)
4205     {
4206       if (flags & VER_FLG_BASE)
4207         strcat (buff, "| ");
4208
4209       strcat (buff, "WEAK ");
4210     }
4211
4212   if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
4213     strcat (buff, "| <unknown>");
4214
4215   return buff;
4216 }
4217
4218 /* Display the contents of the version sections.  */
4219 static int
4220 process_version_sections (file)
4221      FILE * file;
4222 {
4223   Elf32_Internal_Shdr * section;
4224   unsigned   i;
4225   int        found = 0;
4226
4227   if (! do_version)
4228     return 1;
4229
4230   for (i = 0, section = section_headers;
4231        i < elf_header.e_shnum;
4232        i++, section ++)
4233     {
4234       switch (section->sh_type)
4235         {
4236         case SHT_GNU_verdef:
4237           {
4238             Elf_External_Verdef * edefs;
4239             unsigned int          idx;
4240             unsigned int          cnt;
4241
4242             found = 1;
4243
4244             printf
4245               (_("\nVersion definition section '%s' contains %ld entries:\n"),
4246                SECTION_NAME (section), section->sh_info);
4247
4248             printf (_("  Addr: 0x"));
4249             printf_vma (section->sh_addr);
4250             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
4251                     (unsigned long) section->sh_offset, section->sh_link,
4252                     SECTION_NAME (section_headers + section->sh_link));
4253
4254             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
4255                             edefs, Elf_External_Verdef *,
4256                             "version definition section");
4257
4258             for (idx = cnt = 0; cnt < section->sh_info; ++ cnt)
4259               {
4260                 char *                 vstart;
4261                 Elf_External_Verdef *  edef;
4262                 Elf_Internal_Verdef    ent;
4263                 Elf_External_Verdaux * eaux;
4264                 Elf_Internal_Verdaux   aux;
4265                 int                    j;
4266                 int                    isum;
4267
4268                 vstart = ((char *) edefs) + idx;
4269
4270                 edef = (Elf_External_Verdef *) vstart;
4271
4272                 ent.vd_version = BYTE_GET (edef->vd_version);
4273                 ent.vd_flags   = BYTE_GET (edef->vd_flags);
4274                 ent.vd_ndx     = BYTE_GET (edef->vd_ndx);
4275                 ent.vd_cnt     = BYTE_GET (edef->vd_cnt);
4276                 ent.vd_hash    = BYTE_GET (edef->vd_hash);
4277                 ent.vd_aux     = BYTE_GET (edef->vd_aux);
4278                 ent.vd_next    = BYTE_GET (edef->vd_next);
4279
4280                 printf (_("  %#06x: Rev: %d  Flags: %s"),
4281                         idx, ent.vd_version, get_ver_flags (ent.vd_flags));
4282
4283                 printf (_("  Index: %d  Cnt: %d  "),
4284                         ent.vd_ndx, ent.vd_cnt);
4285
4286                 vstart += ent.vd_aux;
4287
4288                 eaux = (Elf_External_Verdaux *) vstart;
4289
4290                 aux.vda_name = BYTE_GET (eaux->vda_name);
4291                 aux.vda_next = BYTE_GET (eaux->vda_next);
4292
4293                 if (dynamic_strings)
4294                   printf (_("Name: %s\n"), dynamic_strings + aux.vda_name);
4295                 else
4296                   printf (_("Name index: %ld\n"), aux.vda_name);
4297
4298                 isum = idx + ent.vd_aux;
4299
4300                 for (j = 1; j < ent.vd_cnt; j ++)
4301                   {
4302                     isum   += aux.vda_next;
4303                     vstart += aux.vda_next;
4304
4305                     eaux = (Elf_External_Verdaux *) vstart;
4306
4307                     aux.vda_name = BYTE_GET (eaux->vda_name);
4308                     aux.vda_next = BYTE_GET (eaux->vda_next);
4309
4310                     if (dynamic_strings)
4311                       printf (_("  %#06x: Parent %d: %s\n"),
4312                               isum, j, dynamic_strings + aux.vda_name);
4313                     else
4314                       printf (_("  %#06x: Parent %d, name index: %ld\n"),
4315                               isum, j, aux.vda_name);
4316                   }
4317
4318                 idx += ent.vd_next;
4319               }
4320
4321             free (edefs);
4322           }
4323           break;
4324
4325         case SHT_GNU_verneed:
4326           {
4327             Elf_External_Verneed *  eneed;
4328             unsigned int            idx;
4329             unsigned int            cnt;
4330
4331             found = 1;
4332
4333             printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
4334                     SECTION_NAME (section), section->sh_info);
4335
4336             printf (_(" Addr: 0x"));
4337             printf_vma (section->sh_addr);
4338             printf (_("  Offset: %#08lx  Link to section: %ld (%s)\n"),
4339                     (unsigned long) section->sh_offset, section->sh_link,
4340                     SECTION_NAME (section_headers + section->sh_link));
4341
4342             GET_DATA_ALLOC (section->sh_offset, section->sh_size,
4343                             eneed, Elf_External_Verneed *,
4344                             "version need section");
4345
4346             for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
4347               {
4348                 Elf_External_Verneed * entry;
4349                 Elf_Internal_Verneed     ent;
4350                 int                      j;
4351                 int                      isum;
4352                 char *                   vstart;
4353
4354                 vstart = ((char *) eneed) + idx;
4355
4356                 entry = (Elf_External_Verneed *) vstart;
4357
4358                 ent.vn_version = BYTE_GET (entry->vn_version);
4359                 ent.vn_cnt     = BYTE_GET (entry->vn_cnt);
4360                 ent.vn_file    = BYTE_GET (entry->vn_file);
4361                 ent.vn_aux     = BYTE_GET (entry->vn_aux);
4362                 ent.vn_next    = BYTE_GET (entry->vn_next);
4363
4364                 printf (_("  %#06x: Version: %d"), idx, ent.vn_version);
4365
4366                 if (dynamic_strings)
4367                   printf (_("  File: %s"), dynamic_strings + ent.vn_file);
4368                 else
4369                   printf (_("  File: %lx"), ent.vn_file);
4370
4371                 printf (_("  Cnt: %d\n"), ent.vn_cnt);
4372
4373                 vstart += ent.vn_aux;
4374
4375                 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
4376                   {
4377                     Elf_External_Vernaux * eaux;
4378                     Elf_Internal_Vernaux   aux;
4379
4380                     eaux = (Elf_External_Vernaux *) vstart;
4381
4382                     aux.vna_hash  = BYTE_GET (eaux->vna_hash);
4383                     aux.vna_flags = BYTE_GET (eaux->vna_flags);
4384                     aux.vna_other = BYTE_GET (eaux->vna_other);
4385                     aux.vna_name  = BYTE_GET (eaux->vna_name);
4386                     aux.vna_next  = BYTE_GET (eaux->vna_next);
4387
4388                     if (dynamic_strings)
4389                       printf (_("  %#06x: Name: %s"),
4390                               isum, dynamic_strings + aux.vna_name);
4391                     else
4392                       printf (_("  %#06x: Name index: %lx"),
4393                               isum, aux.vna_name);
4394
4395                     printf (_("  Flags: %s  Version: %d\n"),
4396                             get_ver_flags (aux.vna_flags), aux.vna_other);
4397
4398                     isum   += aux.vna_next;
4399                     vstart += aux.vna_next;
4400                   }
4401
4402                 idx += ent.vn_next;
4403               }
4404
4405             free (eneed);
4406           }
4407           break;
4408
4409         case SHT_GNU_versym:
4410           {
4411             Elf32_Internal_Shdr *       link_section;
4412             int                         total;
4413             int                         cnt;
4414             unsigned char *             edata;
4415             unsigned short *            data;
4416             char *                      strtab;
4417             Elf_Internal_Sym *          symbols;
4418             Elf32_Internal_Shdr *       string_sec;
4419
4420             link_section = section_headers + section->sh_link;
4421             total = section->sh_size / section->sh_entsize;
4422
4423             found = 1;
4424
4425             symbols = GET_ELF_SYMBOLS (file, link_section->sh_offset,
4426                                        link_section->sh_size / link_section->sh_entsize);
4427
4428             string_sec = section_headers + link_section->sh_link;
4429
4430             GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4431                             strtab, char *, "version string table");
4432
4433             printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
4434                     SECTION_NAME (section), total);
4435
4436             printf (_(" Addr: "));
4437             printf_vma (section->sh_addr);
4438             printf (_("  Offset: %#08lx  Link: %lx (%s)\n"),
4439                     (unsigned long) section->sh_offset, section->sh_link,
4440                     SECTION_NAME (link_section));
4441
4442             GET_DATA_ALLOC (version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4443                             - loadaddr,
4444                             total * sizeof (short), edata,
4445                             unsigned char *, "version symbol data");
4446
4447             data = (unsigned short *) malloc (total * sizeof (short));
4448
4449             for (cnt = total; cnt --;)
4450               data [cnt] = byte_get (edata + cnt * sizeof (short),
4451                                      sizeof (short));
4452
4453             free (edata);
4454
4455             for (cnt = 0; cnt < total; cnt += 4)
4456               {
4457                 int j, nn;
4458                 int check_def, check_need;
4459                 char * name;
4460
4461                 printf ("  %03x:", cnt);
4462
4463                 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
4464                   switch (data [cnt + j])
4465                     {
4466                     case 0:
4467                       fputs (_("   0 (*local*)    "), stdout);
4468                       break;
4469
4470                     case 1:
4471                       fputs (_("   1 (*global*)   "), stdout);
4472                       break;
4473
4474                     default:
4475                       nn = printf ("%4x%c", data [cnt + j] & 0x7fff,
4476                                    data [cnt + j] & 0x8000 ? 'h' : ' ');
4477
4478                       check_def = 1;
4479                       check_need = 1;
4480                       if (symbols [cnt + j].st_shndx >= SHN_LORESERVE
4481                           || section_headers[symbols [cnt + j].st_shndx].sh_type
4482                           != SHT_NOBITS)
4483                         {
4484                           if (symbols [cnt + j].st_shndx == SHN_UNDEF)
4485                             check_def = 0;
4486                           else
4487                             check_need = 0;
4488                         }
4489
4490                       if (check_need
4491                           && version_info [DT_VERSIONTAGIDX (DT_VERNEED)])
4492                         {
4493                           Elf_Internal_Verneed     ivn;
4494                           unsigned long            offset;
4495
4496                           offset = version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4497                             - loadaddr;
4498
4499                           do
4500                             {
4501                               Elf_Internal_Vernaux   ivna;
4502                               Elf_External_Verneed   evn;
4503                               Elf_External_Vernaux   evna;
4504                               unsigned long          a_off;
4505
4506                               GET_DATA (offset, evn, "version need");
4507
4508                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
4509                               ivn.vn_next = BYTE_GET (evn.vn_next);
4510
4511                               a_off = offset + ivn.vn_aux;
4512
4513                               do
4514                                 {
4515                                   GET_DATA (a_off, evna,
4516                                             "version need aux (2)");
4517
4518                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
4519                                   ivna.vna_other = BYTE_GET (evna.vna_other);
4520
4521                                   a_off += ivna.vna_next;
4522                                 }
4523                               while (ivna.vna_other != data [cnt + j]
4524                                      && ivna.vna_next != 0);
4525
4526                               if (ivna.vna_other == data [cnt + j])
4527                                 {
4528                                   ivna.vna_name = BYTE_GET (evna.vna_name);
4529
4530                                   name = strtab + ivna.vna_name;
4531                                   nn += printf ("(%s%-*s",
4532                                                 name,
4533                                                 12 - (int) strlen (name),
4534                                                 ")");
4535                                   check_def = 0;
4536                                   break;
4537                                 }
4538
4539                               offset += ivn.vn_next;
4540                             }
4541                           while (ivn.vn_next);
4542                         }
4543
4544                       if (check_def && data [cnt + j] != 0x8001
4545                           && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
4546                         {
4547                           Elf_Internal_Verdef  ivd;
4548                           Elf_External_Verdef  evd;
4549                           unsigned long        offset;
4550
4551                           offset = version_info
4552                             [DT_VERSIONTAGIDX (DT_VERDEF)] - loadaddr;
4553
4554                           do
4555                             {
4556                               GET_DATA (offset, evd, "version def");
4557
4558                               ivd.vd_next = BYTE_GET (evd.vd_next);
4559                               ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
4560
4561                               offset += ivd.vd_next;
4562                             }
4563                           while (ivd.vd_ndx != (data [cnt + j] & 0x7fff)
4564                                  && ivd.vd_next != 0);
4565
4566                           if (ivd.vd_ndx == (data [cnt + j] & 0x7fff))
4567                             {
4568                               Elf_External_Verdaux  evda;
4569                               Elf_Internal_Verdaux  ivda;
4570
4571                               ivd.vd_aux = BYTE_GET (evd.vd_aux);
4572
4573                               GET_DATA (offset - ivd.vd_next + ivd.vd_aux,
4574                                         evda, "version def aux");
4575
4576                               ivda.vda_name = BYTE_GET (evda.vda_name);
4577
4578                               name = strtab + ivda.vda_name;
4579                               nn += printf ("(%s%-*s",
4580                                             name,
4581                                             12 - (int) strlen (name),
4582                                             ")");
4583                             }
4584                         }
4585
4586                       if (nn < 18)
4587                         printf ("%*c", 18 - nn, ' ');
4588                     }
4589
4590                 putchar ('\n');
4591               }
4592
4593             free (data);
4594             free (strtab);
4595             free (symbols);
4596           }
4597           break;
4598
4599         default:
4600           break;
4601         }
4602     }
4603
4604   if (! found)
4605     printf (_("\nNo version information found in this file.\n"));
4606
4607   return 1;
4608 }
4609
4610 static const char *
4611 get_symbol_binding (binding)
4612      unsigned int binding;
4613 {
4614   static char buff [32];
4615
4616   switch (binding)
4617     {
4618     case STB_LOCAL:  return "LOCAL";
4619     case STB_GLOBAL: return "GLOBAL";
4620     case STB_WEAK:   return "WEAK";
4621     default:
4622       if (binding >= STB_LOPROC && binding <= STB_HIPROC)
4623         sprintf (buff, _("<processor specific>: %d"), binding);
4624       else if (binding >= STB_LOOS && binding <= STB_HIOS)
4625         sprintf (buff, _("<OS specific>: %d"), binding);
4626       else
4627         sprintf (buff, _("<unknown>: %d"), binding);
4628       return buff;
4629     }
4630 }
4631
4632 static const char *
4633 get_symbol_type (type)
4634      unsigned int type;
4635 {
4636   static char buff [32];
4637
4638   switch (type)
4639     {
4640     case STT_NOTYPE:   return "NOTYPE";
4641     case STT_OBJECT:   return "OBJECT";
4642     case STT_FUNC:     return "FUNC";
4643     case STT_SECTION:  return "SECTION";
4644     case STT_FILE:     return "FILE";
4645     case STT_COMMON:   return "COMMON";
4646     default:
4647       if (type >= STT_LOPROC && type <= STT_HIPROC)
4648         {
4649           if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
4650             return "THUMB_FUNC";
4651
4652           if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
4653             return "REGISTER";
4654
4655           if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
4656             return "PARISC_MILLI";
4657
4658           sprintf (buff, _("<processor specific>: %d"), type);
4659         }
4660       else if (type >= STT_LOOS && type <= STT_HIOS)
4661         {
4662           if (elf_header.e_machine == EM_PARISC)
4663             {
4664               if (type == STT_HP_OPAQUE)
4665                 return "HP_OPAQUE";
4666               if (type == STT_HP_STUB)
4667                 return "HP_STUB";
4668             }
4669
4670           sprintf (buff, _("<OS specific>: %d"), type);
4671         }
4672       else
4673         sprintf (buff, _("<unknown>: %d"), type);
4674       return buff;
4675     }
4676 }
4677
4678 static const char *
4679 get_symbol_visibility (visibility)
4680      unsigned int visibility;
4681 {
4682   switch (visibility)
4683     {
4684     case STV_DEFAULT:   return "DEFAULT";
4685     case STV_INTERNAL:  return "INTERNAL";
4686     case STV_HIDDEN:    return "HIDDEN";
4687     case STV_PROTECTED: return "PROTECTED";
4688     default: abort ();
4689     }
4690 }
4691
4692 static const char *
4693 get_symbol_index_type (type)
4694      unsigned int type;
4695 {
4696   switch (type)
4697     {
4698     case SHN_UNDEF:  return "UND";
4699     case SHN_ABS:    return "ABS";
4700     case SHN_COMMON: return "COM";
4701     default:
4702       if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4703         return "PRC";
4704       else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
4705         return "RSV";
4706       else if (type >= SHN_LOOS && type <= SHN_HIOS)
4707         return "OS ";
4708       else
4709         {
4710           static char buff [32];
4711
4712           sprintf (buff, "%3d", type);
4713           return buff;
4714         }
4715     }
4716 }
4717
4718 static int *
4719 get_dynamic_data (file, number)
4720      FILE *       file;
4721      unsigned int number;
4722 {
4723   unsigned char * e_data;
4724   int *  i_data;
4725
4726   e_data = (unsigned char *) malloc (number * 4);
4727
4728   if (e_data == NULL)
4729     {
4730       error (_("Out of memory\n"));
4731       return NULL;
4732     }
4733
4734   if (fread (e_data, 4, number, file) != number)
4735     {
4736       error (_("Unable to read in dynamic data\n"));
4737       return NULL;
4738     }
4739
4740   i_data = (int *) malloc (number * sizeof (* i_data));
4741
4742   if (i_data == NULL)
4743     {
4744       error (_("Out of memory\n"));
4745       free (e_data);
4746       return NULL;
4747     }
4748
4749   while (number--)
4750     i_data [number] = byte_get (e_data + number * 4, 4);
4751
4752   free (e_data);
4753
4754   return i_data;
4755 }
4756
4757 /* Dump the symbol table */
4758 static int
4759 process_symbol_table (file)
4760      FILE * file;
4761 {
4762   Elf32_Internal_Shdr *   section;
4763   unsigned char   nb [4];
4764   unsigned char   nc [4];
4765   int    nbuckets = 0;
4766   int    nchains = 0;
4767   int *  buckets = NULL;
4768   int *  chains = NULL;
4769
4770   if (! do_syms && !do_histogram)
4771     return 1;
4772
4773   if (dynamic_info[DT_HASH] && ((do_using_dynamic && dynamic_strings != NULL)
4774                                 || do_histogram))
4775     {
4776       if (fseek (file, dynamic_info[DT_HASH] - loadaddr, SEEK_SET))
4777         {
4778           error (_("Unable to seek to start of dynamic information"));
4779           return 0;
4780         }
4781
4782       if (fread (nb, sizeof (nb), 1, file) != 1)
4783         {
4784           error (_("Failed to read in number of buckets\n"));
4785           return 0;
4786         }
4787
4788       if (fread (nc, sizeof (nc), 1, file) != 1)
4789         {
4790           error (_("Failed to read in number of chains\n"));
4791           return 0;
4792         }
4793
4794       nbuckets = byte_get (nb, 4);
4795       nchains  = byte_get (nc, 4);
4796
4797       buckets = get_dynamic_data (file, nbuckets);
4798       chains  = get_dynamic_data (file, nchains);
4799
4800       if (buckets == NULL || chains == NULL)
4801         return 0;
4802     }
4803
4804   if (do_syms
4805       && dynamic_info[DT_HASH] && do_using_dynamic && dynamic_strings != NULL)
4806     {
4807       int    hn;
4808       int    si;
4809
4810       printf (_("\nSymbol table for image:\n"));
4811       if (is_32bit_elf)
4812         printf (_("  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name\n"));
4813       else
4814         printf (_("  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name\n"));
4815
4816       for (hn = 0; hn < nbuckets; hn++)
4817         {
4818           if (! buckets [hn])
4819             continue;
4820
4821           for (si = buckets [hn]; si < nchains && si > 0; si = chains [si])
4822             {
4823               Elf_Internal_Sym * psym;
4824
4825               psym = dynamic_symbols + si;
4826
4827               printf ("  %3d %3d: ", si, hn);
4828               print_vma (psym->st_value, LONG_HEX);
4829               putchar (' ' );
4830               print_vma (psym->st_size, DEC_5);
4831
4832               printf ("  %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4833               printf (" %6s",  get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4834               printf (" %3s",  get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
4835               printf (" %3.3s", get_symbol_index_type (psym->st_shndx));
4836               printf (" %s\n", dynamic_strings + psym->st_name);
4837             }
4838         }
4839     }
4840   else if (do_syms && !do_using_dynamic)
4841     {
4842       unsigned int     i;
4843
4844       for (i = 0, section = section_headers;
4845            i < elf_header.e_shnum;
4846            i++, section++)
4847         {
4848           unsigned int          si;
4849           char *                strtab;
4850           Elf_Internal_Sym *    symtab;
4851           Elf_Internal_Sym *    psym;
4852
4853
4854           if (   section->sh_type != SHT_SYMTAB
4855               && section->sh_type != SHT_DYNSYM)
4856             continue;
4857
4858           printf (_("\nSymbol table '%s' contains %lu entries:\n"),
4859                   SECTION_NAME (section),
4860                   (unsigned long) (section->sh_size / section->sh_entsize));
4861           if (is_32bit_elf)
4862             printf (_("   Num:    Value  Size Type    Bind   Vis      Ndx Name\n"));
4863           else
4864             printf (_("   Num:    Value          Size Type    Bind   Vis      Ndx Name\n"));
4865
4866           symtab = GET_ELF_SYMBOLS (file, section->sh_offset,
4867                                     section->sh_size / section->sh_entsize);
4868           if (symtab == NULL)
4869             continue;
4870
4871           if (section->sh_link == elf_header.e_shstrndx)
4872             strtab = string_table;
4873           else
4874             {
4875               Elf32_Internal_Shdr * string_sec;
4876
4877               string_sec = section_headers + section->sh_link;
4878
4879               GET_DATA_ALLOC (string_sec->sh_offset, string_sec->sh_size,
4880                               strtab, char *, "string table");
4881             }
4882
4883           for (si = 0, psym = symtab;
4884                si < section->sh_size / section->sh_entsize;
4885                si ++, psym ++)
4886             {
4887               printf ("%6d: ", si);
4888               print_vma (psym->st_value, LONG_HEX);
4889               putchar (' ');
4890               print_vma (psym->st_size, DEC_5);
4891               printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
4892               printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
4893               printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
4894               printf (" %4s", get_symbol_index_type (psym->st_shndx));
4895               printf (" %s", strtab + psym->st_name);
4896
4897               if (section->sh_type == SHT_DYNSYM &&
4898                   version_info [DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
4899                 {
4900                   unsigned char   data[2];
4901                   unsigned short  vers_data;
4902                   unsigned long   offset;
4903                   int             is_nobits;
4904                   int             check_def;
4905
4906                   offset = version_info [DT_VERSIONTAGIDX (DT_VERSYM)]
4907                     - loadaddr;
4908
4909                   GET_DATA (offset + si * sizeof (vers_data), data,
4910                             "version data");
4911
4912                   vers_data = byte_get (data, 2);
4913
4914                   is_nobits = psym->st_shndx < SHN_LORESERVE ?
4915                     (section_headers [psym->st_shndx].sh_type == SHT_NOBITS)
4916                     : 0;
4917
4918                   check_def = (psym->st_shndx != SHN_UNDEF);
4919
4920                   if ((vers_data & 0x8000) || vers_data > 1)
4921                     {
4922                       if (version_info [DT_VERSIONTAGIDX (DT_VERNEED)]
4923                           && (is_nobits || ! check_def))
4924                         {
4925                           Elf_External_Verneed  evn;
4926                           Elf_Internal_Verneed  ivn;
4927                           Elf_Internal_Vernaux  ivna;
4928
4929                           /* We must test both.  */
4930                           offset = version_info
4931                             [DT_VERSIONTAGIDX (DT_VERNEED)] - loadaddr;
4932
4933                           do
4934                             {
4935                               unsigned long  vna_off;
4936
4937                               GET_DATA (offset, evn, "version need");
4938
4939                               ivn.vn_aux  = BYTE_GET (evn.vn_aux);
4940                               ivn.vn_next = BYTE_GET (evn.vn_next);
4941
4942                               vna_off = offset + ivn.vn_aux;
4943
4944                               do
4945                                 {
4946                                   Elf_External_Vernaux  evna;
4947
4948                                   GET_DATA (vna_off, evna,
4949                                             "version need aux (3)");
4950
4951                                   ivna.vna_other = BYTE_GET (evna.vna_other);
4952                                   ivna.vna_next  = BYTE_GET (evna.vna_next);
4953                                   ivna.vna_name  = BYTE_GET (evna.vna_name);
4954
4955                                   vna_off += ivna.vna_next;
4956                                 }
4957                               while (ivna.vna_other != vers_data
4958                                      && ivna.vna_next != 0);
4959
4960                               if (ivna.vna_other == vers_data)
4961                                 break;
4962
4963                               offset += ivn.vn_next;
4964                             }
4965                           while (ivn.vn_next != 0);
4966
4967                           if (ivna.vna_other == vers_data)
4968                             {
4969                               printf ("@%s (%d)",
4970                                       strtab + ivna.vna_name, ivna.vna_other);
4971                               check_def = 0;
4972                             }
4973                           else if (! is_nobits)
4974                             error (_("bad dynamic symbol"));
4975                           else
4976                             check_def = 1;
4977                         }
4978
4979                       if (check_def)
4980                         {
4981                           if (vers_data != 0x8001
4982                               && version_info [DT_VERSIONTAGIDX (DT_VERDEF)])
4983                             {
4984                               Elf_Internal_Verdef     ivd;
4985                               Elf_Internal_Verdaux    ivda;
4986                               Elf_External_Verdaux  evda;
4987                               unsigned long           offset;
4988
4989                               offset =
4990                                 version_info [DT_VERSIONTAGIDX (DT_VERDEF)]
4991                                 - loadaddr;
4992
4993                               do
4994                                 {
4995                                   Elf_External_Verdef   evd;
4996
4997                                   GET_DATA (offset, evd, "version def");
4998
4999                                   ivd.vd_ndx  = BYTE_GET (evd.vd_ndx);
5000                                   ivd.vd_aux  = BYTE_GET (evd.vd_aux);
5001                                   ivd.vd_next = BYTE_GET (evd.vd_next);
5002
5003                                   offset += ivd.vd_next;
5004                                 }
5005                               while (ivd.vd_ndx != (vers_data & 0x7fff)
5006                                      && ivd.vd_next != 0);
5007
5008                               offset -= ivd.vd_next;
5009                               offset += ivd.vd_aux;
5010
5011                               GET_DATA (offset, evda, "version def aux");
5012
5013                               ivda.vda_name = BYTE_GET (evda.vda_name);
5014
5015                               if (psym->st_name != ivda.vda_name)
5016                                 printf ((vers_data & 0x8000)
5017                                         ? "@%s" : "@@%s",
5018                                         strtab + ivda.vda_name);
5019                             }
5020                         }
5021                     }
5022                 }
5023
5024               putchar ('\n');
5025             }
5026
5027           free (symtab);
5028           if (strtab != string_table)
5029             free (strtab);
5030         }
5031     }
5032   else if (do_syms)
5033     printf
5034       (_("\nDynamic symbol information is not available for displaying symbols.\n"));
5035
5036   if (do_histogram && buckets != NULL)
5037     {
5038       int * lengths;
5039       int * counts;
5040       int   hn;
5041       int   si;
5042       int   maxlength = 0;
5043       int   nzero_counts = 0;
5044       int   nsyms = 0;
5045
5046       printf (_("\nHistogram for bucket list length (total of %d buckets):\n"),
5047               nbuckets);
5048       printf (_(" Length  Number     %% of total  Coverage\n"));
5049
5050       lengths = (int *) calloc (nbuckets, sizeof (int));
5051       if (lengths == NULL)
5052         {
5053           error (_("Out of memory"));
5054           return 0;
5055         }
5056       for (hn = 0; hn < nbuckets; ++hn)
5057         {
5058           if (! buckets [hn])
5059             continue;
5060
5061           for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
5062             {
5063               ++ nsyms;
5064               if (maxlength < ++lengths[hn])
5065                 ++ maxlength;
5066             }
5067         }
5068
5069       counts = (int *) calloc (maxlength + 1, sizeof (int));
5070       if (counts == NULL)
5071         {
5072           error (_("Out of memory"));
5073           return 0;
5074         }
5075
5076       for (hn = 0; hn < nbuckets; ++hn)
5077         ++ counts [lengths [hn]];
5078
5079       if (nbuckets > 0)
5080         {
5081           printf ("      0  %-10d (%5.1f%%)\n",
5082                   counts[0], (counts[0] * 100.0) / nbuckets);
5083           for (si = 1; si <= maxlength; ++si)
5084             {
5085               nzero_counts += counts[si] * si;
5086               printf ("%7d  %-10d (%5.1f%%)    %5.1f%%\n",
5087                       si, counts[si], (counts[si] * 100.0) / nbuckets,
5088                       (nzero_counts * 100.0) / nsyms);
5089             }
5090         }
5091
5092       free (counts);
5093       free (lengths);
5094     }
5095
5096   if (buckets != NULL)
5097     {
5098       free (buckets);
5099       free (chains);
5100     }
5101
5102   return 1;
5103 }
5104
5105 static int
5106 process_syminfo (file)
5107      FILE * file ATTRIBUTE_UNUSED;
5108 {
5109   unsigned int i;
5110
5111   if (dynamic_syminfo == NULL
5112       || !do_dynamic)
5113     /* No syminfo, this is ok.  */
5114     return 1;
5115
5116   /* There better should be a dynamic symbol section.  */
5117   if (dynamic_symbols == NULL || dynamic_strings == NULL)
5118     return 0;
5119
5120   if (dynamic_addr)
5121     printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
5122             dynamic_syminfo_offset, dynamic_syminfo_nent);
5123
5124   printf (_(" Num: Name                           BoundTo     Flags\n"));
5125   for (i = 0; i < dynamic_syminfo_nent; ++i)
5126     {
5127       unsigned short int flags = dynamic_syminfo[i].si_flags;
5128
5129       printf ("%4d: %-30s ", i,
5130               dynamic_strings + dynamic_symbols[i].st_name);
5131
5132       switch (dynamic_syminfo[i].si_boundto)
5133         {
5134         case SYMINFO_BT_SELF:
5135           fputs ("SELF       ", stdout);
5136           break;
5137         case SYMINFO_BT_PARENT:
5138           fputs ("PARENT     ", stdout);
5139           break;
5140         default:
5141           if (dynamic_syminfo[i].si_boundto > 0
5142               && dynamic_syminfo[i].si_boundto < dynamic_size)
5143             printf ("%-10s ",
5144                     dynamic_strings
5145                     + dynamic_segment[dynamic_syminfo[i].si_boundto].d_un.d_val);
5146           else
5147             printf ("%-10d ", dynamic_syminfo[i].si_boundto);
5148           break;
5149         }
5150
5151       if (flags & SYMINFO_FLG_DIRECT)
5152         printf (" DIRECT");
5153       if (flags & SYMINFO_FLG_PASSTHRU)
5154         printf (" PASSTHRU");
5155       if (flags & SYMINFO_FLG_COPY)
5156         printf (" COPY");
5157       if (flags & SYMINFO_FLG_LAZYLOAD)
5158         printf (" LAZYLOAD");
5159
5160       puts ("");
5161     }
5162
5163   return 1;
5164 }
5165
5166 #ifdef SUPPORT_DISASSEMBLY
5167 static void
5168 disassemble_section (section, file)
5169      Elf32_Internal_Shdr * section;
5170      FILE * file;
5171 {
5172   printf (_("\nAssembly dump of section %s\n"),
5173           SECTION_NAME (section));
5174
5175   /* XXX -- to be done --- XXX */
5176
5177   return 1;
5178 }
5179 #endif
5180
5181 static int
5182 dump_section (section, file)
5183      Elf32_Internal_Shdr * section;
5184      FILE * file;
5185 {
5186   bfd_size_type   bytes;
5187   bfd_vma         addr;
5188   unsigned char * data;
5189   unsigned char * start;
5190
5191   bytes = section->sh_size;
5192
5193   if (bytes == 0)
5194     {
5195       printf (_("\nSection '%s' has no data to dump.\n"),
5196               SECTION_NAME (section));
5197       return 0;
5198     }
5199   else
5200     printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
5201
5202   addr = section->sh_addr;
5203
5204   GET_DATA_ALLOC (section->sh_offset, bytes, start, unsigned char *,
5205                   "section data");
5206
5207   data = start;
5208
5209   while (bytes)
5210     {
5211       int j;
5212       int k;
5213       int lbytes;
5214
5215       lbytes = (bytes > 16 ? 16 : bytes);
5216
5217       printf ("  0x%8.8lx ", (unsigned long) addr);
5218
5219       switch (elf_header.e_ident [EI_DATA])
5220         {
5221         default:
5222         case ELFDATA2LSB:
5223           for (j = 15; j >= 0; j --)
5224             {
5225               if (j < lbytes)
5226                 printf ("%2.2x", data [j]);
5227               else
5228                 printf ("  ");
5229
5230               if (!(j & 0x3))
5231                 printf (" ");
5232             }
5233           break;
5234
5235         case ELFDATA2MSB:
5236           for (j = 0; j < 16; j++)
5237             {
5238               if (j < lbytes)
5239                 printf ("%2.2x", data [j]);
5240               else
5241                 printf ("  ");
5242
5243               if ((j & 3) == 3)
5244                 printf (" ");
5245             }
5246           break;
5247         }
5248
5249       for (j = 0; j < lbytes; j++)
5250         {
5251           k = data [j];
5252           if (k >= ' ' && k < 0x80)
5253             printf ("%c", k);
5254           else
5255             printf (".");
5256         }
5257
5258       putchar ('\n');
5259
5260       data  += lbytes;
5261       addr  += lbytes;
5262       bytes -= lbytes;
5263     }
5264
5265   free (start);
5266
5267   return 1;
5268 }
5269
5270
5271 static unsigned long int
5272 read_leb128 (data, length_return, sign)
5273      unsigned char * data;
5274      int *           length_return;
5275      int             sign;
5276 {
5277   unsigned long int result = 0;
5278   unsigned int      num_read = 0;
5279   int               shift = 0;
5280   unsigned char     byte;
5281
5282   do
5283     {
5284       byte = * data ++;
5285       num_read ++;
5286
5287       result |= (byte & 0x7f) << shift;
5288
5289       shift += 7;
5290
5291     }
5292   while (byte & 0x80);
5293
5294   if (length_return != NULL)
5295     * length_return = num_read;
5296
5297   if (sign && (shift < 32) && (byte & 0x40))
5298     result |= -1 << shift;
5299
5300   return result;
5301 }
5302
5303 typedef struct State_Machine_Registers
5304 {
5305   unsigned long address;
5306   unsigned int  file;
5307   unsigned int  line;
5308   unsigned int  column;
5309   int           is_stmt;
5310   int           basic_block;
5311   int           end_sequence;
5312 /* This variable hold the number of the last entry seen
5313    in the File Table.  */
5314   unsigned int  last_file_entry;
5315 } SMR;
5316
5317 static SMR state_machine_regs;
5318
5319 static void
5320 reset_state_machine (is_stmt)
5321      int is_stmt;
5322 {
5323   state_machine_regs.address = 0;
5324   state_machine_regs.file = 1;
5325   state_machine_regs.line = 1;
5326   state_machine_regs.column = 0;
5327   state_machine_regs.is_stmt = is_stmt;
5328   state_machine_regs.basic_block = 0;
5329   state_machine_regs.end_sequence = 0;
5330   state_machine_regs.last_file_entry = 0;
5331 }
5332
5333 /* Handled an extend line op.  Returns true if this is the end
5334    of sequence.  */
5335 static int
5336 process_extended_line_op (data, is_stmt, pointer_size)
5337      unsigned char * data;
5338      int is_stmt;
5339      int pointer_size;
5340 {
5341   unsigned char   op_code;
5342   int             bytes_read;
5343   unsigned int    len;
5344   unsigned char * name;
5345   unsigned long   adr;
5346
5347   len = read_leb128 (data, & bytes_read, 0);
5348   data += bytes_read;
5349
5350   if (len == 0)
5351     {
5352       warn (_("badly formed extended line op encountered!"));
5353       return bytes_read;
5354     }
5355
5356   len += bytes_read;
5357   op_code = * data ++;
5358
5359   printf (_("  Extended opcode %d: "), op_code);
5360
5361   switch (op_code)
5362     {
5363     case DW_LNE_end_sequence:
5364       printf (_("End of Sequence\n\n"));
5365       reset_state_machine (is_stmt);
5366       break;
5367
5368     case DW_LNE_set_address:
5369       adr = byte_get (data, pointer_size);
5370       printf (_("set Address to 0x%lx\n"), adr);
5371       state_machine_regs.address = adr;
5372       break;
5373
5374     case DW_LNE_define_file:
5375       printf (_("  define new File Table entry\n"));
5376       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
5377
5378       printf (_("   %d\t"), ++ state_machine_regs.last_file_entry);
5379       name = data;
5380       data += strlen ((char *) data) + 1;
5381       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5382       data += bytes_read;
5383       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5384       data += bytes_read;
5385       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5386       printf (_("%s\n\n"), name);
5387       break;
5388
5389     default:
5390       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
5391       break;
5392     }
5393
5394   return len;
5395 }
5396
5397 /* Size of pointers in the .debug_line section.  This information is not
5398    really present in that section.  It's obtained before dumping the debug
5399    sections by doing some pre-scan of the .debug_info section.  */
5400 static int debug_line_pointer_size = 4;
5401
5402 static int
5403 display_debug_lines (section, start, file)
5404      Elf32_Internal_Shdr * section;
5405      unsigned char *       start;
5406      FILE *                file ATTRIBUTE_UNUSED;
5407 {
5408   DWARF2_External_LineInfo * external;
5409   DWARF2_Internal_LineInfo   info;
5410   unsigned char *            standard_opcodes;
5411   unsigned char *            data = start;
5412   unsigned char *            end  = start + section->sh_size;
5413   unsigned char *            end_of_sequence;
5414   int                        i;
5415
5416   printf (_("\nDump of debug contents of section %s:\n\n"),
5417           SECTION_NAME (section));
5418
5419   while (data < end)
5420     {
5421       external = (DWARF2_External_LineInfo *) data;
5422
5423       /* Check the length of the block.  */
5424       info.li_length = BYTE_GET (external->li_length);
5425       if (info.li_length + sizeof (external->li_length) > section->sh_size)
5426         {
5427           warn
5428             (_("The line info appears to be corrupt - the section is too small\n"));
5429           return 0;
5430         }
5431
5432       /* Check its version number.  */
5433       info.li_version = BYTE_GET (external->li_version);
5434       if (info.li_version != 2)
5435         {
5436           warn (_("Only DWARF version 2 line info is currently supported.\n"));
5437           return 0;
5438         }
5439
5440       info.li_prologue_length = BYTE_GET (external->li_prologue_length);
5441       info.li_min_insn_length = BYTE_GET (external->li_min_insn_length);
5442       info.li_default_is_stmt = BYTE_GET (external->li_default_is_stmt);
5443       info.li_line_base       = BYTE_GET (external->li_line_base);
5444       info.li_line_range      = BYTE_GET (external->li_line_range);
5445       info.li_opcode_base     = BYTE_GET (external->li_opcode_base);
5446
5447       /* Sign extend the line base field.  */
5448       info.li_line_base <<= 24;
5449       info.li_line_base >>= 24;
5450
5451       printf (_("  Length:                      %ld\n"), info.li_length);
5452       printf (_("  DWARF Version:               %d\n"), info.li_version);
5453       printf (_("  Prolgue Length:              %d\n"), info.li_prologue_length);
5454       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
5455       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
5456       printf (_("  Line Base:                   %d\n"), info.li_line_base);
5457       printf (_("  Line Range:                  %d\n"), info.li_line_range);
5458       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
5459
5460       end_of_sequence = data + info.li_length + sizeof (external->li_length);
5461
5462       reset_state_machine (info.li_default_is_stmt);
5463
5464       /* Display the contents of the Opcodes table.  */
5465       standard_opcodes = data + sizeof (* external);
5466
5467       printf (_("\n Opcodes:\n"));
5468
5469       for (i = 1; i < info.li_opcode_base; i++)
5470         printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
5471
5472       /* Display the contents of the Directory table.  */
5473       data = standard_opcodes + info.li_opcode_base - 1;
5474
5475       if (* data == 0)
5476         printf (_("\n The Directory Table is empty.\n"));
5477       else
5478         {
5479           printf (_("\n The Directory Table:\n"));
5480
5481           while (* data != 0)
5482             {
5483               printf (_("  %s\n"), data);
5484
5485               data += strlen ((char *) data) + 1;
5486             }
5487         }
5488
5489       /* Skip the NUL at the end of the table.  */
5490       data ++;
5491
5492       /* Display the contents of the File Name table.  */
5493       if (* data == 0)
5494         printf (_("\n The File Name Table is empty.\n"));
5495       else
5496         {
5497           printf (_("\n The File Name Table:\n"));
5498           printf (_("  Entry\tDir\tTime\tSize\tName\n"));
5499
5500           while (* data != 0)
5501             {
5502               unsigned char * name;
5503               int bytes_read;
5504
5505               printf (_("  %d\t"), ++ state_machine_regs.last_file_entry);
5506               name = data;
5507
5508               data += strlen ((char *) data) + 1;
5509
5510               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5511               data += bytes_read;
5512               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5513               data += bytes_read;
5514               printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
5515               data += bytes_read;
5516               printf (_("%s\n"), name);
5517             }
5518         }
5519
5520       /* Skip the NUL at the end of the table.  */
5521       data ++;
5522
5523       /* Now display the statements.  */
5524       printf (_("\n Line Number Statements:\n"));
5525
5526
5527       while (data < end_of_sequence)
5528         {
5529           unsigned char op_code;
5530           int           adv;
5531           int           bytes_read;
5532
5533           op_code = * data ++;
5534
5535           switch (op_code)
5536             {
5537             case DW_LNS_extended_op:
5538               data += process_extended_line_op (data, info.li_default_is_stmt,
5539                                                 debug_line_pointer_size);
5540               break;
5541
5542             case DW_LNS_copy:
5543               printf (_("  Copy\n"));
5544               break;
5545
5546             case DW_LNS_advance_pc:
5547               adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
5548               data += bytes_read;
5549               state_machine_regs.address += adv;
5550               printf (_("  Advance PC by %d to %lx\n"), adv,
5551                       state_machine_regs.address);
5552               break;
5553
5554             case DW_LNS_advance_line:
5555               adv = read_leb128 (data, & bytes_read, 1);
5556               data += bytes_read;
5557               state_machine_regs.line += adv;
5558               printf (_("  Advance Line by %d to %d\n"), adv,
5559                       state_machine_regs.line);
5560               break;
5561
5562             case DW_LNS_set_file:
5563               adv = read_leb128 (data, & bytes_read, 0);
5564               data += bytes_read;
5565               printf (_("  Set File Name to entry %d in the File Name Table\n"),
5566                       adv);
5567               state_machine_regs.file = adv;
5568               break;
5569
5570             case DW_LNS_set_column:
5571               adv = read_leb128 (data, & bytes_read, 0);
5572               data += bytes_read;
5573               printf (_("  Set column to %d\n"), adv);
5574               state_machine_regs.column = adv;
5575               break;
5576
5577             case DW_LNS_negate_stmt:
5578               adv = state_machine_regs.is_stmt;
5579               adv = ! adv;
5580               printf (_("  Set is_stmt to %d\n"), adv);
5581               state_machine_regs.is_stmt = adv;
5582               break;
5583
5584             case DW_LNS_set_basic_block:
5585               printf (_("  Set basic block\n"));
5586               state_machine_regs.basic_block = 1;
5587               break;
5588
5589             case DW_LNS_const_add_pc:
5590               adv = (((255 - info.li_opcode_base) / info.li_line_range)
5591                      * info.li_min_insn_length);
5592               state_machine_regs.address += adv;
5593               printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
5594                       state_machine_regs.address);
5595               break;
5596
5597             case DW_LNS_fixed_advance_pc:
5598               adv = byte_get (data, 2);
5599               data += 2;
5600               state_machine_regs.address += adv;
5601               printf (_("  Advance PC by fixed size amount %d to 0x%lx\n"),
5602                       adv, state_machine_regs.address);
5603               break;
5604
5605             default:
5606               op_code -= info.li_opcode_base;
5607               adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
5608               state_machine_regs.address += adv;
5609               printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
5610                       op_code, adv, state_machine_regs.address);
5611               adv = (op_code % info.li_line_range) + info.li_line_base;
5612               state_machine_regs.line += adv;
5613               printf (_(" and Line by %d to %d\n"),
5614                       adv, state_machine_regs.line);
5615               break;
5616             }
5617         }
5618       printf ("\n");
5619     }
5620
5621   return 1;
5622 }
5623
5624 static int
5625 display_debug_pubnames (section, start, file)
5626      Elf32_Internal_Shdr * section;
5627      unsigned char *       start;
5628      FILE *                file ATTRIBUTE_UNUSED;
5629 {
5630   DWARF2_External_PubNames * external;
5631   DWARF2_Internal_PubNames   pubnames;
5632   unsigned char *            end;
5633
5634   end = start + section->sh_size;
5635
5636   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
5637
5638   while (start < end)
5639     {
5640       unsigned char * data;
5641       unsigned long   offset;
5642
5643       external = (DWARF2_External_PubNames *) start;
5644
5645       pubnames.pn_length  = BYTE_GET (external->pn_length);
5646       pubnames.pn_version = BYTE_GET (external->pn_version);
5647       pubnames.pn_offset  = BYTE_GET (external->pn_offset);
5648       pubnames.pn_size    = BYTE_GET (external->pn_size);
5649
5650       data   = start + sizeof (* external);
5651       start += pubnames.pn_length + sizeof (external->pn_length);
5652
5653       if (pubnames.pn_version != 2)
5654         {
5655           static int warned = 0;
5656
5657           if (! warned)
5658             {
5659               warn (_("Only DWARF 2 pubnames are currently supported\n"));
5660               warned = 1;
5661             }
5662
5663           continue;
5664         }
5665
5666       printf (_("  Length:                              %ld\n"),
5667               pubnames.pn_length);
5668       printf (_("  Version:                             %d\n"),
5669               pubnames.pn_version);
5670       printf (_("  Offset into .debug_info section:     %ld\n"),
5671               pubnames.pn_offset);
5672       printf (_("  Size of area in .debug_info section: %ld\n"),
5673               pubnames.pn_size);
5674
5675       printf (_("\n    Offset\tName\n"));
5676
5677       do
5678         {
5679           offset = byte_get (data, 4);
5680
5681           if (offset != 0)
5682             {
5683               data += 4;
5684               printf ("    %ld\t\t%s\n", offset, data);
5685               data += strlen ((char *) data) + 1;
5686             }
5687         }
5688       while (offset != 0);
5689     }
5690
5691   printf ("\n");
5692   return 1;
5693 }
5694
5695 static char *
5696 get_TAG_name (tag)
5697      unsigned long tag;
5698 {
5699   switch (tag)
5700     {
5701     case DW_TAG_padding: return "DW_TAG_padding";
5702     case DW_TAG_array_type: return "DW_TAG_array_type";
5703     case DW_TAG_class_type: return "DW_TAG_class_type";
5704     case DW_TAG_entry_point: return "DW_TAG_entry_point";
5705     case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
5706     case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
5707     case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
5708     case DW_TAG_label: return "DW_TAG_label";
5709     case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
5710     case DW_TAG_member: return "DW_TAG_member";
5711     case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
5712     case DW_TAG_reference_type: return "DW_TAG_reference_type";
5713     case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
5714     case DW_TAG_string_type: return "DW_TAG_string_type";
5715     case DW_TAG_structure_type: return "DW_TAG_structure_type";
5716     case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
5717     case DW_TAG_typedef: return "DW_TAG_typedef";
5718     case DW_TAG_union_type: return "DW_TAG_union_type";
5719     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
5720     case DW_TAG_variant: return "DW_TAG_variant";
5721     case DW_TAG_common_block: return "DW_TAG_common_block";
5722     case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
5723     case DW_TAG_inheritance: return "DW_TAG_inheritance";
5724     case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
5725     case DW_TAG_module: return "DW_TAG_module";
5726     case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
5727     case DW_TAG_set_type: return "DW_TAG_set_type";
5728     case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
5729     case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
5730     case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
5731     case DW_TAG_base_type: return "DW_TAG_base_type";
5732     case DW_TAG_catch_block: return "DW_TAG_catch_block";
5733     case DW_TAG_const_type: return "DW_TAG_const_type";
5734     case DW_TAG_constant: return "DW_TAG_constant";
5735     case DW_TAG_enumerator: return "DW_TAG_enumerator";
5736     case DW_TAG_file_type: return "DW_TAG_file_type";
5737     case DW_TAG_friend: return "DW_TAG_friend";
5738     case DW_TAG_namelist: return "DW_TAG_namelist";
5739     case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
5740     case DW_TAG_packed_type: return "DW_TAG_packed_type";
5741     case DW_TAG_subprogram: return "DW_TAG_subprogram";
5742     case DW_TAG_template_type_param: return "DW_TAG_template_type_param";
5743     case DW_TAG_template_value_param: return "DW_TAG_template_value_param";
5744     case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
5745     case DW_TAG_try_block: return "DW_TAG_try_block";
5746     case DW_TAG_variant_part: return "DW_TAG_variant_part";
5747     case DW_TAG_variable: return "DW_TAG_variable";
5748     case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
5749     case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
5750     case DW_TAG_format_label: return "DW_TAG_format_label";
5751     case DW_TAG_function_template: return "DW_TAG_function_template";
5752     case DW_TAG_class_template: return "DW_TAG_class_template";
5753     default:
5754       {
5755         static char buffer [100];
5756
5757         sprintf (buffer, _("Unknown TAG value: %lx"), tag);
5758         return buffer;
5759       }
5760     }
5761 }
5762
5763 static char *
5764 get_AT_name (attribute)
5765      unsigned long attribute;
5766 {
5767   switch (attribute)
5768     {
5769     case DW_AT_sibling: return "DW_AT_sibling";
5770     case DW_AT_location: return "DW_AT_location";
5771     case DW_AT_name: return "DW_AT_name";
5772     case DW_AT_ordering: return "DW_AT_ordering";
5773     case DW_AT_subscr_data: return "DW_AT_subscr_data";
5774     case DW_AT_byte_size: return "DW_AT_byte_size";
5775     case DW_AT_bit_offset: return "DW_AT_bit_offset";
5776     case DW_AT_bit_size: return "DW_AT_bit_size";
5777     case DW_AT_element_list: return "DW_AT_element_list";
5778     case DW_AT_stmt_list: return "DW_AT_stmt_list";
5779     case DW_AT_low_pc: return "DW_AT_low_pc";
5780     case DW_AT_high_pc: return "DW_AT_high_pc";
5781     case DW_AT_language: return "DW_AT_language";
5782     case DW_AT_member: return "DW_AT_member";
5783     case DW_AT_discr: return "DW_AT_discr";
5784     case DW_AT_discr_value: return "DW_AT_discr_value";
5785     case DW_AT_visibility: return "DW_AT_visibility";
5786     case DW_AT_import: return "DW_AT_import";
5787     case DW_AT_string_length: return "DW_AT_string_length";
5788     case DW_AT_common_reference: return "DW_AT_common_reference";
5789     case DW_AT_comp_dir: return "DW_AT_comp_dir";
5790     case DW_AT_const_value: return "DW_AT_const_value";
5791     case DW_AT_containing_type: return "DW_AT_containing_type";
5792     case DW_AT_default_value: return "DW_AT_default_value";
5793     case DW_AT_inline: return "DW_AT_inline";
5794     case DW_AT_is_optional: return "DW_AT_is_optional";
5795     case DW_AT_lower_bound: return "DW_AT_lower_bound";
5796     case DW_AT_producer: return "DW_AT_producer";
5797     case DW_AT_prototyped: return "DW_AT_prototyped";
5798     case DW_AT_return_addr: return "DW_AT_return_addr";
5799     case DW_AT_start_scope: return "DW_AT_start_scope";
5800     case DW_AT_stride_size: return "DW_AT_stride_size";
5801     case DW_AT_upper_bound: return "DW_AT_upper_bound";
5802     case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
5803     case DW_AT_accessibility: return "DW_AT_accessibility";
5804     case DW_AT_address_class: return "DW_AT_address_class";
5805     case DW_AT_artificial: return "DW_AT_artificial";
5806     case DW_AT_base_types: return "DW_AT_base_types";
5807     case DW_AT_calling_convention: return "DW_AT_calling_convention";
5808     case DW_AT_count: return "DW_AT_count";
5809     case DW_AT_data_member_location: return "DW_AT_data_member_location";
5810     case DW_AT_decl_column: return "DW_AT_decl_column";
5811     case DW_AT_decl_file: return "DW_AT_decl_file";
5812     case DW_AT_decl_line: return "DW_AT_decl_line";
5813     case DW_AT_declaration: return "DW_AT_declaration";
5814     case DW_AT_discr_list: return "DW_AT_discr_list";
5815     case DW_AT_encoding: return "DW_AT_encoding";
5816     case DW_AT_external: return "DW_AT_external";
5817     case DW_AT_frame_base: return "DW_AT_frame_base";
5818     case DW_AT_friend: return "DW_AT_friend";
5819     case DW_AT_identifier_case: return "DW_AT_identifier_case";
5820     case DW_AT_macro_info: return "DW_AT_macro_info";
5821     case DW_AT_namelist_items: return "DW_AT_namelist_items";
5822     case DW_AT_priority: return "DW_AT_priority";
5823     case DW_AT_segment: return "DW_AT_segment";
5824     case DW_AT_specification: return "DW_AT_specification";
5825     case DW_AT_static_link: return "DW_AT_static_link";
5826     case DW_AT_type: return "DW_AT_type";
5827     case DW_AT_use_location: return "DW_AT_use_location";
5828     case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
5829     case DW_AT_virtuality: return "DW_AT_virtuality";
5830     case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
5831     case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde";
5832     case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
5833     case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
5834     case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
5835     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
5836     case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
5837     case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
5838     case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
5839     case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
5840     case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
5841     case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
5842     case DW_AT_sf_names: return "DW_AT_sf_names";
5843     case DW_AT_src_info: return "DW_AT_src_info";
5844     case DW_AT_mac_info: return "DW_AT_mac_info";
5845     case DW_AT_src_coords: return "DW_AT_src_coords";
5846     case DW_AT_body_begin: return "DW_AT_body_begin";
5847     case DW_AT_body_end: return "DW_AT_body_end";
5848     default:
5849       {
5850         static char buffer [100];
5851
5852         sprintf (buffer, _("Unknown AT value: %lx"), attribute);
5853         return buffer;
5854       }
5855     }
5856 }
5857
5858 static char *
5859 get_FORM_name (form)
5860      unsigned long form;
5861 {
5862   switch (form)
5863     {
5864     case DW_FORM_addr: return "DW_FORM_addr";
5865     case DW_FORM_block2: return "DW_FORM_block2";
5866     case DW_FORM_block4: return "DW_FORM_block4";
5867     case DW_FORM_data2: return "DW_FORM_data2";
5868     case DW_FORM_data4: return "DW_FORM_data4";
5869     case DW_FORM_data8: return "DW_FORM_data8";
5870     case DW_FORM_string: return "DW_FORM_string";
5871     case DW_FORM_block: return "DW_FORM_block";
5872     case DW_FORM_block1: return "DW_FORM_block1";
5873     case DW_FORM_data1: return "DW_FORM_data1";
5874     case DW_FORM_flag: return "DW_FORM_flag";
5875     case DW_FORM_sdata: return "DW_FORM_sdata";
5876     case DW_FORM_strp: return "DW_FORM_strp";
5877     case DW_FORM_udata: return "DW_FORM_udata";
5878     case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
5879     case DW_FORM_ref1: return "DW_FORM_ref1";
5880     case DW_FORM_ref2: return "DW_FORM_ref2";
5881     case DW_FORM_ref4: return "DW_FORM_ref4";
5882     case DW_FORM_ref8: return "DW_FORM_ref8";
5883     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
5884     case DW_FORM_indirect: return "DW_FORM_indirect";
5885     default:
5886       {
5887         static char buffer [100];
5888
5889         sprintf (buffer, _("Unknown FORM value: %lx"), form);
5890         return buffer;
5891       }
5892     }
5893 }
5894
5895 /* FIXME:  There are better and more effiecint ways to handle
5896    these structures.  For now though, I just want something that
5897    is simple to implement.  */
5898 typedef struct abbrev_attr
5899 {
5900   unsigned long        attribute;
5901   unsigned long        form;
5902   struct abbrev_attr * next;
5903 }
5904 abbrev_attr;
5905
5906 typedef struct abbrev_entry
5907 {
5908   unsigned long          entry;
5909   unsigned long          tag;
5910   int                    children;
5911   struct abbrev_attr *   first_attr;
5912   struct abbrev_attr *   last_attr;
5913   struct abbrev_entry *  next;
5914 }
5915 abbrev_entry;
5916
5917 static abbrev_entry * first_abbrev = NULL;
5918 static abbrev_entry * last_abbrev = NULL;
5919
5920 static void
5921 free_abbrevs PARAMS ((void))
5922 {
5923   abbrev_entry * abbrev;
5924
5925   for (abbrev = first_abbrev; abbrev;)
5926     {
5927       abbrev_entry * next = abbrev->next;
5928       abbrev_attr  * attr;
5929
5930       for (attr = abbrev->first_attr; attr;)
5931         {
5932           abbrev_attr * next = attr->next;
5933
5934           free (attr);
5935           attr = next;
5936         }
5937
5938       free (abbrev);
5939       abbrev = next;
5940     }
5941
5942   last_abbrev = first_abbrev = NULL;
5943 }
5944
5945 static void
5946 add_abbrev (number, tag, children)
5947      unsigned long number;
5948      unsigned long tag;
5949      int           children;
5950 {
5951   abbrev_entry * entry;
5952
5953   entry = (abbrev_entry *) malloc (sizeof (* entry));
5954
5955   if (entry == NULL)
5956     /* ugg */
5957     return;
5958
5959   entry->entry      = number;
5960   entry->tag        = tag;
5961   entry->children   = children;
5962   entry->first_attr = NULL;
5963   entry->last_attr  = NULL;
5964   entry->next       = NULL;
5965
5966   if (first_abbrev == NULL)
5967     first_abbrev = entry;
5968   else
5969     last_abbrev->next = entry;
5970
5971   last_abbrev = entry;
5972 }
5973
5974 static void
5975 add_abbrev_attr (attribute, form)
5976      unsigned long attribute;
5977      unsigned long form;
5978 {
5979   abbrev_attr * attr;
5980
5981   attr = (abbrev_attr *) malloc (sizeof (* attr));
5982
5983   if (attr == NULL)
5984     /* ugg */
5985     return;
5986
5987   attr->attribute = attribute;
5988   attr->form      = form;
5989   attr->next      = NULL;
5990
5991   if (last_abbrev->first_attr == NULL)
5992     last_abbrev->first_attr = attr;
5993   else
5994     last_abbrev->last_attr->next = attr;
5995
5996   last_abbrev->last_attr = attr;
5997 }
5998
5999 /* Processes the (partial) contents of a .debug_abbrev section.
6000    Returns NULL if the end of the section was encountered.
6001    Returns the address after the last byte read if the end of
6002    an abbreviation set was found.  */
6003
6004 static unsigned char *
6005 process_abbrev_section (start, end)
6006      unsigned char * start;
6007      unsigned char * end;
6008 {
6009   if (first_abbrev != NULL)
6010     return NULL;
6011
6012   while (start < end)
6013     {
6014       int           bytes_read;
6015       unsigned long entry;
6016       unsigned long tag;
6017       unsigned long attribute;
6018       int           children;
6019
6020       entry = read_leb128 (start, & bytes_read, 0);
6021       start += bytes_read;
6022
6023       /* A single zero is supposed to end the section according
6024          to the standard.  If there's more, then signal that to
6025          the caller.  */
6026       if (entry == 0)
6027         return start == end ? NULL : start;
6028
6029       tag = read_leb128 (start, & bytes_read, 0);
6030       start += bytes_read;
6031
6032       children = * start ++;
6033
6034       add_abbrev (entry, tag, children);
6035
6036       do
6037         {
6038           unsigned long form;
6039
6040           attribute = read_leb128 (start, & bytes_read, 0);
6041           start += bytes_read;
6042
6043           form = read_leb128 (start, & bytes_read, 0);
6044           start += bytes_read;
6045
6046           if (attribute != 0)
6047             add_abbrev_attr (attribute, form);
6048         }
6049       while (attribute != 0);
6050     }
6051
6052   return NULL;
6053 }
6054
6055
6056 static int
6057 display_debug_abbrev (section, start, file)
6058      Elf32_Internal_Shdr * section;
6059      unsigned char *       start;
6060      FILE *                file ATTRIBUTE_UNUSED;
6061 {
6062   abbrev_entry *  entry;
6063   unsigned char * end = start + section->sh_size;
6064
6065   printf (_("Contents of the %s section:\n\n"), SECTION_NAME (section));
6066
6067   do
6068     {
6069       start = process_abbrev_section (start, end);
6070
6071       printf (_("  Number TAG\n"));
6072
6073       for (entry = first_abbrev; entry; entry = entry->next)
6074         {
6075           abbrev_attr * attr;
6076
6077           printf (_("   %ld      %s    [%s]\n"),
6078                   entry->entry,
6079                   get_TAG_name (entry->tag),
6080                   entry->children ? _("has children") : _("no children"));
6081
6082           for (attr = entry->first_attr; attr; attr = attr->next)
6083             {
6084               printf (_("    %-18s %s\n"),
6085                       get_AT_name (attr->attribute),
6086                       get_FORM_name (attr->form));
6087             }
6088         }
6089     }
6090   while (start);
6091
6092   printf ("\n");
6093
6094   return 1;
6095 }
6096
6097
6098 static unsigned char *
6099 display_block (data, length)
6100      unsigned char * data;
6101      unsigned long   length;
6102 {
6103   printf (_(" %lu byte block: "), length);
6104
6105   while (length --)
6106     printf ("%lx ", (unsigned long) byte_get (data ++, 1));
6107
6108   return data;
6109 }
6110
6111 static void
6112 decode_location_expression (data, pointer_size, length)
6113      unsigned char * data;
6114      unsigned int    pointer_size;
6115      unsigned long   length;
6116 {
6117   unsigned        op;
6118   int             bytes_read;
6119   unsigned long   uvalue;
6120   unsigned char * end = data + length;
6121
6122   while (data < end)
6123     {
6124       op = * data ++;
6125
6126       switch (op)
6127         {
6128         case DW_OP_addr:
6129           printf ("DW_OP_addr: %lx",
6130                   (unsigned long) byte_get (data, pointer_size));
6131           data += pointer_size;
6132           break;
6133         case DW_OP_deref:
6134           printf ("DW_OP_deref");
6135           break;
6136         case DW_OP_const1u:
6137           printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6138           break;
6139         case DW_OP_const1s:
6140           printf ("DW_OP_const1s: %ld", (long) byte_get (data++, 1));
6141           break;
6142         case DW_OP_const2u:
6143           printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6144           data += 2;
6145           break;
6146         case DW_OP_const2s:
6147           printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
6148           data += 2;
6149           break;
6150         case DW_OP_const4u:
6151           printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6152           data += 4;
6153           break;
6154         case DW_OP_const4s:
6155           printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
6156           data += 4;
6157           break;
6158         case DW_OP_const8u:
6159           printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6160                   (unsigned long) byte_get (data + 4, 4));
6161           data += 8;
6162           break;
6163         case DW_OP_const8s:
6164           printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6165                   (long) byte_get (data + 4, 4));
6166           data += 8;
6167           break;
6168         case DW_OP_constu:
6169           printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6170           data += bytes_read;
6171           break;
6172         case DW_OP_consts:
6173           printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6174           data += bytes_read;
6175           break;
6176         case DW_OP_dup:
6177           printf ("DW_OP_dup");
6178           break;
6179         case DW_OP_drop:
6180           printf ("DW_OP_drop");
6181           break;
6182         case DW_OP_over:
6183           printf ("DW_OP_over");
6184           break;
6185         case DW_OP_pick:
6186           printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6187           break;
6188         case DW_OP_swap:
6189           printf ("DW_OP_swap");
6190           break;
6191         case DW_OP_rot:
6192           printf ("DW_OP_rot");
6193           break;
6194         case DW_OP_xderef:
6195           printf ("DW_OP_xderef");
6196           break;
6197         case DW_OP_abs:
6198           printf ("DW_OP_abs");
6199           break;
6200         case DW_OP_and:
6201           printf ("DW_OP_and");
6202           break;
6203         case DW_OP_div:
6204           printf ("DW_OP_div");
6205           break;
6206         case DW_OP_minus:
6207           printf ("DW_OP_minus");
6208           break;
6209         case DW_OP_mod:
6210           printf ("DW_OP_mod");
6211           break;
6212         case DW_OP_mul:
6213           printf ("DW_OP_mul");
6214           break;
6215         case DW_OP_neg:
6216           printf ("DW_OP_neg");
6217           break;
6218         case DW_OP_not:
6219           printf ("DW_OP_not");
6220           break;
6221         case DW_OP_or:
6222           printf ("DW_OP_or");
6223           break;
6224         case DW_OP_plus:
6225           printf ("DW_OP_plus");
6226           break;
6227         case DW_OP_plus_uconst:
6228           printf ("DW_OP_plus_uconst: %lu",
6229                   read_leb128 (data, &bytes_read, 0));
6230           data += bytes_read;
6231           break;
6232         case DW_OP_shl:
6233           printf ("DW_OP_shl");
6234           break;
6235         case DW_OP_shr:
6236           printf ("DW_OP_shr");
6237           break;
6238         case DW_OP_shra:
6239           printf ("DW_OP_shra");
6240           break;
6241         case DW_OP_xor:
6242           printf ("DW_OP_xor");
6243           break;
6244         case DW_OP_bra:
6245           printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
6246           data += 2;
6247           break;
6248         case DW_OP_eq:
6249           printf ("DW_OP_eq");
6250           break;
6251         case DW_OP_ge:
6252           printf ("DW_OP_ge");
6253           break;
6254         case DW_OP_gt:
6255           printf ("DW_OP_gt");
6256           break;
6257         case DW_OP_le:
6258           printf ("DW_OP_le");
6259           break;
6260         case DW_OP_lt:
6261           printf ("DW_OP_lt");
6262           break;
6263         case DW_OP_ne:
6264           printf ("DW_OP_ne");
6265           break;
6266         case DW_OP_skip:
6267           printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
6268           data += 2;
6269           break;
6270
6271         case DW_OP_lit0:
6272         case DW_OP_lit1:
6273         case DW_OP_lit2:
6274         case DW_OP_lit3:
6275         case DW_OP_lit4:
6276         case DW_OP_lit5:
6277         case DW_OP_lit6:
6278         case DW_OP_lit7:
6279         case DW_OP_lit8:
6280         case DW_OP_lit9:
6281         case DW_OP_lit10:
6282         case DW_OP_lit11:
6283         case DW_OP_lit12:
6284         case DW_OP_lit13:
6285         case DW_OP_lit14:
6286         case DW_OP_lit15:
6287         case DW_OP_lit16:
6288         case DW_OP_lit17:
6289         case DW_OP_lit18:
6290         case DW_OP_lit19:
6291         case DW_OP_lit20:
6292         case DW_OP_lit21:
6293         case DW_OP_lit22:
6294         case DW_OP_lit23:
6295         case DW_OP_lit24:
6296         case DW_OP_lit25:
6297         case DW_OP_lit26:
6298         case DW_OP_lit27:
6299         case DW_OP_lit28:
6300         case DW_OP_lit29:
6301         case DW_OP_lit30:
6302         case DW_OP_lit31:
6303           printf ("DW_OP_lit%d", op - DW_OP_lit0);
6304           break;
6305
6306         case DW_OP_reg0:
6307         case DW_OP_reg1:
6308         case DW_OP_reg2:
6309         case DW_OP_reg3:
6310         case DW_OP_reg4:
6311         case DW_OP_reg5:
6312         case DW_OP_reg6:
6313         case DW_OP_reg7:
6314         case DW_OP_reg8:
6315         case DW_OP_reg9:
6316         case DW_OP_reg10:
6317         case DW_OP_reg11:
6318         case DW_OP_reg12:
6319         case DW_OP_reg13:
6320         case DW_OP_reg14:
6321         case DW_OP_reg15:
6322         case DW_OP_reg16:
6323         case DW_OP_reg17:
6324         case DW_OP_reg18:
6325         case DW_OP_reg19:
6326         case DW_OP_reg20:
6327         case DW_OP_reg21:
6328         case DW_OP_reg22:
6329         case DW_OP_reg23:
6330         case DW_OP_reg24:
6331         case DW_OP_reg25:
6332         case DW_OP_reg26:
6333         case DW_OP_reg27:
6334         case DW_OP_reg28:
6335         case DW_OP_reg29:
6336         case DW_OP_reg30:
6337         case DW_OP_reg31:
6338           printf ("DW_OP_reg%d", op - DW_OP_reg0);
6339           break;
6340
6341         case DW_OP_breg0:
6342         case DW_OP_breg1:
6343         case DW_OP_breg2:
6344         case DW_OP_breg3:
6345         case DW_OP_breg4:
6346         case DW_OP_breg5:
6347         case DW_OP_breg6:
6348         case DW_OP_breg7:
6349         case DW_OP_breg8:
6350         case DW_OP_breg9:
6351         case DW_OP_breg10:
6352         case DW_OP_breg11:
6353         case DW_OP_breg12:
6354         case DW_OP_breg13:
6355         case DW_OP_breg14:
6356         case DW_OP_breg15:
6357         case DW_OP_breg16:
6358         case DW_OP_breg17:
6359         case DW_OP_breg18:
6360         case DW_OP_breg19:
6361         case DW_OP_breg20:
6362         case DW_OP_breg21:
6363         case DW_OP_breg22:
6364         case DW_OP_breg23:
6365         case DW_OP_breg24:
6366         case DW_OP_breg25:
6367         case DW_OP_breg26:
6368         case DW_OP_breg27:
6369         case DW_OP_breg28:
6370         case DW_OP_breg29:
6371         case DW_OP_breg30:
6372         case DW_OP_breg31:
6373           printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
6374                   read_leb128 (data, &bytes_read, 1));
6375           data += bytes_read;
6376           break;
6377
6378         case DW_OP_regx:
6379           printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
6380           data += bytes_read;
6381           break;
6382         case DW_OP_fbreg:
6383           printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
6384           data += bytes_read;
6385           break;
6386         case DW_OP_bregx:
6387           uvalue = read_leb128 (data, &bytes_read, 0);
6388           data += bytes_read;
6389           printf ("DW_OP_bregx: %lu %ld", uvalue,
6390                   read_leb128 (data, &bytes_read, 1));
6391           data += bytes_read;
6392           break;
6393         case DW_OP_piece:
6394           printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
6395           data += bytes_read;
6396           break;
6397         case DW_OP_deref_size:
6398           printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
6399           break;
6400         case DW_OP_xderef_size:
6401           printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
6402           break;
6403         case DW_OP_nop:
6404           printf ("DW_OP_nop");
6405           break;
6406
6407         default:
6408           if (op >= DW_OP_lo_user
6409               && op <= DW_OP_hi_user)
6410             printf (_("(User defined location op)"));
6411           else
6412             printf (_("(Unknown location op)"));
6413           /* No way to tell where the next op is, so just bail.  */
6414           return;
6415         }
6416     }
6417 }
6418
6419
6420 static unsigned char *
6421 read_and_display_attr (attribute, form, data, cu_offset, pointer_size)
6422      unsigned long   attribute;
6423      unsigned long   form;
6424      unsigned char * data;
6425      unsigned long   cu_offset;
6426      unsigned long   pointer_size;
6427 {
6428   unsigned long   uvalue = 0;
6429   unsigned char * block_start = NULL;
6430   int             bytes_read;
6431
6432   printf ("     %-18s:", get_AT_name (attribute));
6433
6434   switch (form)
6435     {
6436     default:
6437       break;
6438
6439     case DW_FORM_ref_addr:
6440     case DW_FORM_addr:
6441       uvalue = byte_get (data, pointer_size);
6442       data += pointer_size;
6443       break;
6444
6445     case DW_FORM_ref1:
6446     case DW_FORM_flag:
6447     case DW_FORM_data1:
6448       uvalue = byte_get (data ++, 1);
6449       break;
6450
6451     case DW_FORM_ref2:
6452     case DW_FORM_data2:
6453       uvalue = byte_get (data, 2);
6454       data += 2;
6455       break;
6456
6457     case DW_FORM_ref4:
6458     case DW_FORM_data4:
6459       uvalue = byte_get (data, 4);
6460       data += 4;
6461       break;
6462
6463     case DW_FORM_sdata:
6464       uvalue = read_leb128 (data, & bytes_read, 1);
6465       data += bytes_read;
6466       break;
6467
6468     case DW_FORM_ref_udata:
6469     case DW_FORM_udata:
6470       uvalue = read_leb128 (data, & bytes_read, 0);
6471       data += bytes_read;
6472       break;
6473     }
6474
6475   switch (form)
6476     {
6477     case DW_FORM_ref_addr:
6478       printf (" <#%lx>", uvalue);
6479       break;
6480
6481     case DW_FORM_ref1:
6482     case DW_FORM_ref2:
6483     case DW_FORM_ref4:
6484     case DW_FORM_ref_udata:
6485       printf (" <%lx>", uvalue + cu_offset);
6486       break;
6487
6488     case DW_FORM_addr:
6489       printf (" %#lx", uvalue);
6490
6491     case DW_FORM_flag:
6492     case DW_FORM_data1:
6493     case DW_FORM_data2:
6494     case DW_FORM_data4:
6495     case DW_FORM_sdata:
6496     case DW_FORM_udata:
6497       printf (" %ld", uvalue);
6498       break;
6499
6500     case DW_FORM_ref8:
6501     case DW_FORM_data8:
6502       uvalue = byte_get (data, 4);
6503       printf (" %lx", uvalue);
6504       printf (" %lx", (unsigned long) byte_get (data + 4, 4));
6505       data += 8;
6506       break;
6507
6508     case DW_FORM_string:
6509       printf (" %s", data);
6510       data += strlen ((char *) data) + 1;
6511       break;
6512
6513     case DW_FORM_block:
6514       uvalue = read_leb128 (data, & bytes_read, 0);
6515       block_start = data + bytes_read;
6516       data = display_block (block_start, uvalue);
6517       break;
6518
6519     case DW_FORM_block1:
6520       uvalue = byte_get (data, 1);
6521       block_start = data + 1;
6522       data = display_block (block_start, uvalue);
6523       break;
6524
6525     case DW_FORM_block2:
6526       uvalue = byte_get (data, 2);
6527       block_start = data + 2;
6528       data = display_block (block_start, uvalue);
6529       break;
6530
6531     case DW_FORM_block4:
6532       uvalue = byte_get (data, 4);
6533       block_start = data + 4;
6534       data = display_block (block_start, uvalue);
6535       break;
6536
6537     case DW_FORM_strp:
6538     case DW_FORM_indirect:
6539       warn (_("Unable to handle FORM: %d"), form);
6540       break;
6541
6542     default:
6543       warn (_("Unrecognised form: %d"), form);
6544       break;
6545     }
6546
6547   /* For some attributes we can display futher information.  */
6548
6549   printf ("\t");
6550
6551   switch (attribute)
6552     {
6553     case DW_AT_inline:
6554       switch (uvalue)
6555         {
6556         case DW_INL_not_inlined:          printf (_("(not inlined)")); break;
6557         case DW_INL_inlined:              printf (_("(inlined)")); break;
6558         case DW_INL_declared_not_inlined: printf (_("(declared as inline but ignored)")); break;
6559         case DW_INL_declared_inlined:     printf (_("(declared as inline and inlined)")); break;
6560         default: printf (_("  (Unknown inline attribute value: %lx)"), uvalue); break;
6561         }
6562       break;
6563
6564     case DW_AT_language:
6565       switch (uvalue)
6566         {
6567         case DW_LANG_C:              printf ("(non-ANSI C)"); break;
6568         case DW_LANG_C89:            printf ("(ANSI C)"); break;
6569         case DW_LANG_C_plus_plus:    printf ("(C++)"); break;
6570         case DW_LANG_Fortran77:      printf ("(FORTRAN 77)"); break;
6571         case DW_LANG_Fortran90:      printf ("(Fortran 90)"); break;
6572         case DW_LANG_Modula2:        printf ("(Modula 2)"); break;
6573         case DW_LANG_Pascal83:       printf ("(ANSI Pascal)"); break;
6574         case DW_LANG_Ada83:          printf ("(Ada)"); break;
6575         case DW_LANG_Cobol74:        printf ("(Cobol 74)"); break;
6576         case DW_LANG_Cobol85:        printf ("(Cobol 85)"); break;
6577         case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
6578         default:                     printf ("(Unknown: %lx)", uvalue); break;
6579         }
6580       break;
6581
6582     case DW_AT_encoding:
6583       switch (uvalue)
6584         {
6585         case DW_ATE_void:            printf ("(void)"); break;
6586         case DW_ATE_address:         printf ("(machine address)"); break;
6587         case DW_ATE_boolean:         printf ("(boolean)"); break;
6588         case DW_ATE_complex_float:   printf ("(complex float)"); break;
6589         case DW_ATE_float:           printf ("(float)"); break;
6590         case DW_ATE_signed:          printf ("(signed)"); break;
6591         case DW_ATE_signed_char:     printf ("(signed char)"); break;
6592         case DW_ATE_unsigned:        printf ("(unsigned)"); break;
6593         case DW_ATE_unsigned_char:   printf ("(unsigned char)"); break;
6594         default:
6595           if (uvalue >= DW_ATE_lo_user
6596               && uvalue <= DW_ATE_hi_user)
6597             printf ("(user defined type)");
6598           else
6599             printf ("(unknown type)");
6600           break;
6601         }
6602       break;
6603
6604     case DW_AT_accessibility:
6605       switch (uvalue)
6606         {
6607         case DW_ACCESS_public:          printf ("(public)"); break;
6608         case DW_ACCESS_protected:       printf ("(protected)"); break;
6609         case DW_ACCESS_private:         printf ("(private)"); break;
6610         default:                        printf ("(unknown accessibility)"); break;
6611         }
6612       break;
6613
6614     case DW_AT_visibility:
6615       switch (uvalue)
6616         {
6617         case DW_VIS_local:      printf ("(local)"); break;
6618         case DW_VIS_exported:   printf ("(exported)"); break;
6619         case DW_VIS_qualified:  printf ("(qualified)"); break;
6620         default:                printf ("(unknown visibility)"); break;
6621         }
6622       break;
6623
6624     case DW_AT_virtuality:
6625       switch (uvalue)
6626         {
6627         case DW_VIRTUALITY_none:        printf ("(none)"); break;
6628         case DW_VIRTUALITY_virtual:     printf ("(virtual)"); break;
6629         case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
6630         default:                        printf ("(unknown virtuality)"); break;
6631         }
6632       break;
6633
6634     case DW_AT_identifier_case:
6635       switch (uvalue)
6636         {
6637         case DW_ID_case_sensitive:      printf ("(case_sensitive)"); break;
6638         case DW_ID_up_case:             printf ("(up_case)"); break;
6639         case DW_ID_down_case:           printf ("(down_case)"); break;
6640         case DW_ID_case_insensitive:    printf ("(case_insensitive)"); break;
6641         default:                        printf ("(unknown case)"); break;
6642         }
6643       break;
6644
6645     case DW_AT_calling_convention:
6646       switch (uvalue)
6647         {
6648         case DW_CC_normal:      printf ("(normal)"); break;
6649         case DW_CC_program:     printf ("(program)"); break;
6650         case DW_CC_nocall:      printf ("(nocall)"); break;
6651         default:
6652           if (uvalue >= DW_CC_lo_user
6653               && uvalue <= DW_CC_hi_user)
6654             printf ("(user defined)");
6655           else
6656             printf ("(unknown convention)");
6657         }
6658       break;
6659
6660     case DW_AT_frame_base:
6661     case DW_AT_location:
6662     case DW_AT_data_member_location:
6663     case DW_AT_vtable_elem_location:
6664       if (block_start)
6665         {
6666           printf ("(");
6667           decode_location_expression (block_start, pointer_size, uvalue);
6668           printf (")");
6669         }
6670       break;
6671
6672     default:
6673       break;
6674     }
6675
6676   printf ("\n");
6677   return data;
6678 }
6679
6680 static int
6681 display_debug_info (section, start, file)
6682      Elf32_Internal_Shdr * section;
6683      unsigned char *       start;
6684      FILE *                file;
6685 {
6686   unsigned char * end = start + section->sh_size;
6687   unsigned char * section_begin = start;
6688
6689   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6690
6691   while (start < end)
6692     {
6693       DWARF2_External_CompUnit * external;
6694       DWARF2_Internal_CompUnit   compunit;
6695       unsigned char *            tags;
6696       int                        i;
6697       int                        level;
6698       unsigned long              cu_offset;
6699
6700       external = (DWARF2_External_CompUnit *) start;
6701
6702       compunit.cu_length        = BYTE_GET (external->cu_length);
6703       compunit.cu_version       = BYTE_GET (external->cu_version);
6704       compunit.cu_abbrev_offset = BYTE_GET (external->cu_abbrev_offset);
6705       compunit.cu_pointer_size  = BYTE_GET (external->cu_pointer_size);
6706
6707       tags = start + sizeof (* external);
6708       cu_offset = start - section_begin;
6709       start += compunit.cu_length + sizeof (external->cu_length);
6710
6711       printf (_("  Compilation Unit @ %lx:\n"), cu_offset);
6712       printf (_("   Length:        %ld\n"), compunit.cu_length);
6713       printf (_("   Version:       %d\n"), compunit.cu_version);
6714       printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
6715       printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
6716
6717       if (compunit.cu_version != 2)
6718         {
6719           warn (_("Only version 2 DWARF debug information is currently supported.\n"));
6720           continue;
6721         }
6722
6723       if (first_abbrev != NULL)
6724         free_abbrevs ();
6725
6726       /* Read in the abbrevs used by this compilation unit.  */
6727
6728       {
6729         Elf32_Internal_Shdr * sec;
6730         unsigned char *       begin;
6731
6732         /* Locate the .debug_abbrev section and process it.  */
6733         for (i = 0, sec = section_headers;
6734              i < elf_header.e_shnum;
6735              i ++, sec ++)
6736           if (strcmp (SECTION_NAME (sec), ".debug_abbrev") == 0)
6737             break;
6738
6739         if (i == -1 || sec->sh_size == 0)
6740           {
6741             warn (_("Unable to locate .debug_abbrev section!\n"));
6742             return 0;
6743           }
6744
6745         GET_DATA_ALLOC (sec->sh_offset, sec->sh_size, begin, unsigned char *,
6746                         "debug_abbrev section data");
6747
6748         process_abbrev_section (begin + compunit.cu_abbrev_offset,
6749                                 begin + sec->sh_size);
6750
6751         free (begin);
6752       }
6753
6754       level = 0;
6755       while (tags < start)
6756         {
6757           int            bytes_read;
6758           unsigned long  abbrev_number;
6759           abbrev_entry * entry;
6760           abbrev_attr  * attr;
6761
6762           abbrev_number = read_leb128 (tags, & bytes_read, 0);
6763           tags += bytes_read;
6764
6765           /* A null DIE marks the end of a list of children.  */
6766           if (abbrev_number == 0)
6767             {
6768               --level;
6769               continue;
6770             }
6771
6772           /* Scan through the abbreviation list until we reach the
6773              correct entry.  */
6774           for (entry = first_abbrev;
6775                entry && entry->entry != abbrev_number;
6776                entry = entry->next)
6777             continue;
6778
6779           if (entry == NULL)
6780             {
6781               warn (_("Unable to locate entry %lu in the abbreviation table\n"),
6782                     abbrev_number);
6783               return 0;
6784             }
6785
6786           printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
6787                   level, tags - section_begin - bytes_read,
6788                   abbrev_number,
6789                   get_TAG_name (entry->tag));
6790
6791           for (attr = entry->first_attr; attr; attr = attr->next)
6792             tags = read_and_display_attr (attr->attribute,
6793                                           attr->form,
6794                                           tags, cu_offset,
6795                                           compunit.cu_pointer_size);
6796
6797           if (entry->children)
6798             ++level;
6799         }
6800     }
6801
6802   printf ("\n");
6803
6804   return 1;
6805 }
6806
6807 static int
6808 display_debug_aranges (section, start, file)
6809      Elf32_Internal_Shdr * section;
6810      unsigned char *       start;
6811      FILE *                file ATTRIBUTE_UNUSED;
6812 {
6813   unsigned char * end = start + section->sh_size;
6814
6815   printf (_("The section %s contains:\n\n"), SECTION_NAME (section));
6816
6817   while (start < end)
6818     {
6819       DWARF2_External_ARange * external;
6820       DWARF2_Internal_ARange   arange;
6821       unsigned char *          ranges;
6822       unsigned long            length;
6823       unsigned long            address;
6824       int                      excess;
6825
6826       external = (DWARF2_External_ARange *) start;
6827
6828       arange.ar_length       = BYTE_GET (external->ar_length);
6829       arange.ar_version      = BYTE_GET (external->ar_version);
6830       arange.ar_info_offset  = BYTE_GET (external->ar_info_offset);
6831       arange.ar_pointer_size = BYTE_GET (external->ar_pointer_size);
6832       arange.ar_segment_size = BYTE_GET (external->ar_segment_size);
6833
6834       if (arange.ar_version != 2)
6835         {
6836           warn (_("Only DWARF 2 aranges are currently supported.\n"));
6837           break;
6838         }
6839
6840       printf (_("  Length:                   %ld\n"), arange.ar_length);
6841       printf (_("  Version:                  %d\n"), arange.ar_version);
6842       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
6843       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
6844       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
6845
6846       printf (_("\n    Address  Length\n"));
6847
6848       ranges = start + sizeof (* external);
6849
6850       /* Must pad to an alignment boundary that is twice the pointer size.  */
6851       excess = sizeof (* external) % (2 * arange.ar_pointer_size);
6852       if (excess)
6853         ranges += (2 * arange.ar_pointer_size) - excess;
6854
6855       for (;;)
6856         {
6857           address = byte_get (ranges, arange.ar_pointer_size);
6858
6859           ranges += arange.ar_pointer_size;
6860
6861           length  = byte_get (ranges, arange.ar_pointer_size);
6862
6863           ranges += arange.ar_pointer_size;
6864
6865           /* A pair of zeros marks the end of the list.  */
6866           if (address == 0 && length == 0)
6867             break;
6868
6869           printf ("    %8.8lx %lu\n", address, length);
6870         }
6871
6872       start += arange.ar_length + sizeof (external->ar_length);
6873     }
6874
6875   printf ("\n");
6876
6877   return 1;
6878 }
6879
6880 typedef struct Frame_Chunk
6881 {
6882   struct Frame_Chunk * next;
6883   unsigned char *      chunk_start;
6884   int                  ncols;
6885   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
6886   short int *          col_type;
6887   int *                col_offset;
6888   char *               augmentation;
6889   unsigned int         code_factor;
6890   unsigned int         data_factor;
6891   unsigned long        pc_begin;
6892   unsigned long        pc_range;
6893   int                  cfa_reg;
6894   int                  cfa_offset;
6895   int                  ra;
6896 }
6897 Frame_Chunk;
6898
6899 /* A marker for a col_type that means this column was never referenced
6900    in the frame info.  */
6901 #define DW_CFA_unreferenced (-1)
6902
6903 static void
6904 frame_need_space (fc, reg)
6905      Frame_Chunk * fc;
6906      int reg;
6907 {
6908   int prev = fc->ncols;
6909
6910   if (reg < fc->ncols)
6911     return;
6912
6913   fc->ncols = reg + 1;
6914   fc->col_type = (short int *) xrealloc (fc->col_type,
6915                                          fc->ncols * sizeof (short int));
6916   fc->col_offset = (int *) xrealloc (fc->col_offset,
6917                                      fc->ncols * sizeof (int));
6918
6919   while (prev < fc->ncols)
6920     {
6921       fc->col_type[prev] = DW_CFA_unreferenced;
6922       fc->col_offset[prev] = 0;
6923       prev++;
6924     }
6925 }
6926
6927 static void
6928 frame_display_row (fc, need_col_headers, max_regs)
6929      Frame_Chunk * fc;
6930      int *         need_col_headers;
6931      int *         max_regs;
6932 {
6933   int r;
6934   char tmp[100];
6935
6936   if (* max_regs < fc->ncols)
6937     * max_regs = fc->ncols;
6938
6939   if (* need_col_headers)
6940     {
6941       * need_col_headers = 0;
6942
6943       printf ("   LOC   CFA      ");
6944
6945       for (r = 0; r < * max_regs; r++)
6946         if (fc->col_type[r] != DW_CFA_unreferenced)
6947           {
6948             if (r == fc->ra)
6949               printf ("ra   ");
6950             else
6951               printf ("r%-4d", r);
6952           }
6953
6954       printf ("\n");
6955     }
6956
6957   printf ("%08x ", (unsigned int) fc->pc_begin);
6958   sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
6959   printf ("%-8s ", tmp);
6960
6961   for (r = 0; r < fc->ncols; r++)
6962     {
6963       if (fc->col_type[r] != DW_CFA_unreferenced)
6964         {
6965           switch (fc->col_type[r])
6966             {
6967             case DW_CFA_undefined:
6968               strcpy (tmp, "u");
6969               break;
6970             case DW_CFA_same_value:
6971               strcpy (tmp, "s");
6972               break;
6973             case DW_CFA_offset:
6974               sprintf (tmp, "c%+d", fc->col_offset[r]);
6975               break;
6976             case DW_CFA_register:
6977               sprintf (tmp, "r%d", fc->col_offset[r]);
6978               break;
6979             default:
6980               strcpy (tmp, "n/a");
6981               break;
6982             }
6983           printf ("%-5s", tmp);
6984         }
6985     }
6986   printf ("\n");
6987 }
6988
6989 #define GET(N)  byte_get (start, N); start += N
6990 #define LEB()   read_leb128 (start, & length_return, 0); start += length_return
6991 #define SLEB()  read_leb128 (start, & length_return, 1); start += length_return
6992
6993 static int
6994 display_debug_frames (section, start, file)
6995      Elf32_Internal_Shdr * section;
6996      unsigned char *       start;
6997      FILE *                file ATTRIBUTE_UNUSED;
6998 {
6999   unsigned char * end = start + section->sh_size;
7000   unsigned char * section_start = start;
7001   Frame_Chunk *   chunks = 0;
7002   Frame_Chunk *   remembered_state = 0;
7003   Frame_Chunk *   rs;
7004   int             is_eh = (strcmp (SECTION_NAME (section), ".eh_frame") == 0);
7005   int             length_return;
7006   int             max_regs = 0;
7007
7008   printf (_("The section %s contains:\n"), SECTION_NAME (section));
7009
7010   while (start < end)
7011     {
7012       unsigned char * saved_start;
7013       unsigned char * block_end;
7014       unsigned long   length;
7015       unsigned long   cie_id;
7016       Frame_Chunk *   fc;
7017       Frame_Chunk *   cie;
7018       int             need_col_headers = 1;
7019
7020       saved_start = start;
7021       length = byte_get (start, 4); start += 4;
7022
7023       if (length == 0)
7024         return 1;
7025
7026       block_end = saved_start + length + 4;
7027       cie_id = byte_get (start, 4); start += 4;
7028
7029       printf ("\n%08x %08lx %08lx ", saved_start - section_start, length, cie_id);
7030
7031       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
7032         {
7033           fc = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7034           memset (fc, 0, sizeof (Frame_Chunk));
7035
7036           fc->next = chunks;
7037           chunks = fc;
7038           fc->chunk_start = saved_start;
7039           fc->ncols = 0;
7040           fc->col_type = (short int *) xmalloc (sizeof (short int));
7041           fc->col_offset = (int *) xmalloc (sizeof (int));
7042           frame_need_space (fc, max_regs-1);
7043
7044           start ++; /* version */
7045           fc->augmentation = start;
7046
7047           while (* start)
7048             start++;
7049
7050           start++; /* skip past NUL */
7051
7052           if (fc->augmentation[0] == 'z')
7053             {
7054               int xtra;
7055               fc->code_factor = LEB ();
7056               fc->data_factor = SLEB ();
7057               fc->ra = byte_get (start, 1); start += 1;
7058               xtra = LEB ();
7059               printf ("skipping %d extra bytes\n", xtra);
7060               start += xtra;
7061             }
7062           else if (strcmp (fc->augmentation, "eh") == 0)
7063             {
7064               start += 4;
7065               fc->code_factor = LEB ();
7066               fc->data_factor = SLEB ();
7067               fc->ra = byte_get (start, 1); start += 1;
7068             }
7069           else
7070             {
7071               fc->code_factor = LEB ();
7072               fc->data_factor = SLEB ();
7073               fc->ra = byte_get (start, 1); start += 1;
7074             }
7075           cie = fc;
7076           printf ("CIE \"%s\" cf=%d df=%d ra=%d\n",
7077                   fc->augmentation, fc->code_factor, fc->data_factor, fc->ra);
7078
7079           frame_need_space (fc, fc->ra);
7080         }
7081       else
7082         {
7083           unsigned char *    look_for;
7084           static Frame_Chunk fde_fc;
7085
7086           fc = & fde_fc;
7087           memset (fc, 0, sizeof (Frame_Chunk));
7088
7089           look_for = is_eh ? start-4-cie_id : (unsigned char *) cie_id;
7090
7091           fc->pc_begin = byte_get (start, 4); start += 4;
7092           fc->pc_range = byte_get (start, 4); start += 4;
7093
7094           for (cie=chunks; cie && (cie->chunk_start != look_for); cie = cie->next);
7095           if (!cie)
7096             {
7097               warn ("Invalid CIE pointer %08x in FDE at %08x\n", cie_id, saved_start);
7098               start = block_end;
7099               fc->ncols = 0;
7100               fc->col_type = (short int *) xmalloc (sizeof (short int));
7101               fc->col_offset = (int *) xmalloc (sizeof (int));
7102               frame_need_space (fc, max_regs - 1);
7103               cie = fc;
7104               fc->augmentation = "";
7105             }
7106           else
7107             {
7108               fc->ncols = cie->ncols;
7109               fc->col_type = (short int *) xmalloc (fc->ncols * sizeof (short int));
7110               fc->col_offset = (int *) xmalloc (fc->ncols * sizeof (int));
7111               memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
7112               memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
7113               fc->augmentation = cie->augmentation;
7114               fc->code_factor = cie->code_factor;
7115               fc->data_factor = cie->data_factor;
7116               fc->cfa_reg = cie->cfa_reg;
7117               fc->cfa_offset = cie->cfa_offset;
7118               fc->ra = cie->ra;
7119               frame_need_space (fc, max_regs-1);
7120             }
7121
7122           if (cie->augmentation[0] == 'z')
7123             {
7124               unsigned long l = LEB ();
7125               start += l;
7126             }
7127
7128           printf ("FDE cie=%08x pc=%08lx..%08lx\n",
7129                   cie->chunk_start-section_start, fc->pc_begin,
7130                   fc->pc_begin + fc->pc_range);
7131         }
7132
7133       /* At this point, fc is the current chunk, cie (if any) is set, and we're
7134          about to interpret instructions for the chunk.  */
7135
7136       /* This exists for readelf maintainers.  */
7137 #define FDEBUG 0
7138
7139       {
7140         /* Start by making a pass over the chunk, allocating storage
7141            and taking note of what registers are used.  */
7142         unsigned char * tmp = start;
7143
7144         while (start < block_end)
7145           {
7146             unsigned op, opa;
7147             unsigned long reg;
7148             bfd_vma vma;
7149             
7150             op = * start ++;
7151             opa = op & 0x3f;
7152             if (op & 0xc0)
7153               op &= 0xc0;
7154             
7155             /* Warning: if you add any more cases to this switch, be
7156                sure to add them to the corresponding switch below.  */
7157             switch (op)
7158               {
7159               case DW_CFA_advance_loc:
7160                 break;
7161               case DW_CFA_offset:
7162                 LEB ();
7163                 frame_need_space (fc, opa);
7164                 fc->col_type[opa] = DW_CFA_undefined;
7165                 break;
7166               case DW_CFA_restore:
7167                 frame_need_space (fc, opa);
7168                 fc->col_type[opa] = DW_CFA_undefined;
7169                 break;
7170               case DW_CFA_set_loc:
7171                 start += sizeof (vma);
7172                 break;
7173               case DW_CFA_advance_loc1:
7174                 start += 1;
7175                 break;
7176               case DW_CFA_advance_loc2:
7177                 start += 2;
7178                 break;
7179               case DW_CFA_advance_loc4:
7180                 start += 4;
7181                 break;
7182               case DW_CFA_offset_extended:
7183                 reg = LEB (); LEB ();
7184                 frame_need_space (fc, reg);
7185                 fc->col_type[reg] = DW_CFA_undefined;
7186                 break;
7187               case DW_CFA_restore_extended:
7188                 reg = LEB ();
7189                 frame_need_space (fc, reg);
7190                 fc->col_type[reg] = DW_CFA_undefined;
7191                 break;
7192               case DW_CFA_undefined:
7193                 reg = LEB ();
7194                 frame_need_space (fc, reg);
7195                 fc->col_type[reg] = DW_CFA_undefined;
7196                 break;
7197               case DW_CFA_same_value:
7198                 reg = LEB ();
7199                 frame_need_space (fc, reg);
7200                 fc->col_type[reg] = DW_CFA_undefined;
7201                 break;
7202               case DW_CFA_register:
7203                 reg = LEB (); LEB ();
7204                 frame_need_space (fc, reg);
7205                 fc->col_type[reg] = DW_CFA_undefined;
7206                 break;
7207               case DW_CFA_def_cfa:
7208                 LEB (); LEB ();
7209                 break;
7210               case DW_CFA_def_cfa_register:
7211                 LEB ();
7212                 break;
7213               case DW_CFA_def_cfa_offset:
7214                 LEB ();
7215                 break;
7216 #ifndef DW_CFA_GNU_args_size
7217 #define DW_CFA_GNU_args_size 0x2e
7218 #endif
7219               case DW_CFA_GNU_args_size:
7220                 LEB ();
7221                 break;          
7222 #ifndef DW_CFA_GNU_negative_offset_extended
7223 #define DW_CFA_GNU_negative_offset_extended 0x2f
7224 #endif
7225               case DW_CFA_GNU_negative_offset_extended:
7226                 reg = LEB (); LEB ();      
7227                 frame_need_space (fc, reg);
7228                 fc->col_type[reg] = DW_CFA_undefined;
7229                 
7230               default:
7231                 break;
7232               }
7233           }
7234         start = tmp;
7235       }
7236
7237       /* Now we know what registers are used, make a second pass over
7238          the chunk, this time actually printing out the info.  */
7239
7240       while (start < block_end)
7241         {
7242           unsigned op, opa;
7243           unsigned long ul, reg, roffs;
7244           long l, ofs;
7245           bfd_vma vma;
7246
7247           op = * start ++;
7248           opa = op & 0x3f;
7249           if (op & 0xc0)
7250             op &= 0xc0;
7251
7252             /* Warning: if you add any more cases to this switch, be
7253                sure to add them to the corresponding switch above.  */
7254           switch (op)
7255             {
7256             case DW_CFA_advance_loc:
7257               frame_display_row (fc, &need_col_headers, &max_regs);
7258 #if FDEBUG
7259               printf ("  DW_CFA_advance_loc: %08x = %08x + %d*%d\n",
7260                       fc->pc_begin + opa * fc->code_factor, fc->pc_begin, opa, fc->code_factor);
7261 #endif
7262               fc->pc_begin += opa * fc->code_factor;
7263               break;
7264
7265             case DW_CFA_offset:
7266               roffs = LEB ();
7267 #if FDEBUG
7268               printf ("  DW_CFA_offset: r%d = cfa[%d*%d]\n", opa, roffs, fc->data_factor);
7269 #endif
7270               fc->col_type[opa] = DW_CFA_offset;
7271               fc->col_offset[opa] = roffs * fc->data_factor;
7272               break;
7273
7274             case DW_CFA_restore:
7275 #if FDEBUG
7276               printf ("  DW_CFA_restore: r%d\n", opa);
7277 #endif
7278               fc->col_type[opa] = cie->col_type[opa];
7279               fc->col_offset[opa] = cie->col_offset[opa];
7280               break;
7281
7282             case DW_CFA_set_loc:
7283               frame_display_row (fc, &need_col_headers, &max_regs);
7284               vma = byte_get (start, sizeof (vma)); start += sizeof (vma);
7285 #if FDEBUG
7286               printf ("  DW_CFA_set_loc: %08x\n", vma);
7287 #endif
7288               fc->pc_begin = vma;
7289               break;
7290
7291             case DW_CFA_advance_loc1:
7292               frame_display_row (fc, &need_col_headers, &max_regs);
7293               ofs = byte_get (start, 1); start += 1;
7294 #if FDEBUG
7295               printf ("  DW_CFA_advance_loc1: %08x = %08x + %d*%d\n",
7296                       fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7297 #endif
7298               fc->pc_begin += ofs * fc->code_factor;
7299               break;
7300
7301             case DW_CFA_advance_loc2:
7302               frame_display_row (fc, &need_col_headers, &max_regs);
7303               ofs = byte_get (start, 2); start += 2;
7304 #if FDEBUG
7305               printf ("  DW_CFA_advance_loc2: %08x = %08x + %d*%d\n",
7306                       fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7307 #endif
7308               fc->pc_begin += ofs * fc->code_factor;
7309               break;
7310
7311             case DW_CFA_advance_loc4:
7312               frame_display_row (fc, &need_col_headers, &max_regs);
7313               ofs = byte_get (start, 4); start += 4;
7314 #if FDEBUG
7315               printf ("  DW_CFA_advance_loc4: %08x = %08x + %d*%d\n",
7316                       fc->pc_begin + ofs * fc->code_factor, fc->pc_begin, ofs, fc->code_factor);
7317 #endif
7318               fc->pc_begin += ofs * fc->code_factor;
7319               break;
7320
7321             case DW_CFA_offset_extended:
7322               reg = LEB ();
7323               roffs = LEB ();
7324 #if FDEBUG
7325               printf ("  DW_CFA_offset_extended: r%d = cfa[%d*%d]\n", reg, roffs, fc->data_factor);
7326 #endif
7327               fc->col_type[reg] = DW_CFA_offset;
7328               fc->col_offset[reg] = roffs * fc->data_factor;
7329               break;
7330
7331             case DW_CFA_restore_extended:
7332               reg = LEB ();
7333 #if FDEBUG
7334               printf ("  DW_CFA_restore_extended: r%d\n", reg);
7335 #endif
7336               fc->col_type[reg] = cie->col_type[reg];
7337               fc->col_offset[reg] = cie->col_offset[reg];
7338               break;
7339
7340             case DW_CFA_undefined:
7341               reg = LEB ();
7342 #if FDEBUG
7343               printf ("  DW_CFA_undefined: r%d\n", reg);
7344 #endif
7345               fc->col_type[reg] = DW_CFA_undefined;
7346               fc->col_offset[reg] = 0;
7347               break;
7348
7349             case DW_CFA_same_value:
7350               reg = LEB ();
7351 #if FDEBUG
7352               printf ("  DW_CFA_same_value: r%d\n", reg);
7353 #endif
7354               fc->col_type[reg] = DW_CFA_same_value;
7355               fc->col_offset[reg] = 0;
7356               break;
7357
7358             case DW_CFA_register:
7359               reg = LEB ();
7360               roffs = LEB ();
7361 #if FDEBUG
7362               printf ("  DW_CFA_register: r%d\n", reg);
7363 #endif
7364               fc->col_type[reg] = DW_CFA_register;
7365               fc->col_offset[reg] = roffs;
7366               break;
7367
7368             case DW_CFA_remember_state:
7369 #if FDEBUG
7370               printf ("  DW_CFA_remember_state\n");
7371 #endif
7372               rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk));
7373               rs->ncols = fc->ncols;
7374               rs->col_type = (short int *) xmalloc (rs->ncols * sizeof (short int));
7375               rs->col_offset = (int *) xmalloc (rs->ncols * sizeof (int));
7376               memcpy (rs->col_type, fc->col_type, rs->ncols);
7377               memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
7378               rs->next = remembered_state;
7379               remembered_state = rs;
7380               break;
7381
7382             case DW_CFA_restore_state:
7383 #if FDEBUG
7384               printf ("  DW_CFA_restore_state\n");
7385 #endif
7386               rs = remembered_state;
7387               remembered_state = rs->next;
7388               frame_need_space (fc, rs->ncols-1);
7389               memcpy (fc->col_type, rs->col_type, rs->ncols);
7390               memcpy (fc->col_offset, rs->col_offset, rs->ncols * sizeof (int));
7391               free (rs->col_type);
7392               free (rs->col_offset);
7393               free (rs);
7394               break;
7395
7396             case DW_CFA_def_cfa:
7397               fc->cfa_reg = LEB ();
7398               fc->cfa_offset = LEB ();
7399 #if FDEBUG
7400               printf ("  DW_CFA_def_cfa: reg %d ofs %d\n", fc->cfa_reg, fc->cfa_offset);
7401 #endif
7402               break;
7403
7404             case DW_CFA_def_cfa_register:
7405               fc->cfa_reg = LEB ();
7406 #if FDEBUG
7407               printf ("  DW_CFA_def_cfa_reg: %d\n", fc->cfa_reg);
7408 #endif
7409               break;
7410
7411             case DW_CFA_def_cfa_offset:
7412               fc->cfa_offset = LEB ();
7413 #if FDEBUG
7414               printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
7415 #endif
7416               break;
7417
7418             case DW_CFA_nop:
7419 #if FDEBUG
7420               printf ("  DW_CFA_nop\n");
7421 #endif
7422               break;
7423
7424 #ifndef DW_CFA_GNU_window_save
7425 #define DW_CFA_GNU_window_save 0x2d
7426 #endif
7427             case DW_CFA_GNU_window_save:
7428 #if FDEBUG
7429               printf ("  DW_CFA_GNU_window_save\n");
7430 #endif
7431               break;
7432
7433 #ifndef DW_CFA_GNU_args_size
7434 #define DW_CFA_GNU_args_size 0x2e
7435 #endif
7436             case DW_CFA_GNU_args_size:
7437               ul = LEB ();
7438 #if FDEBUG
7439               printf ("  DW_CFA_GNU_args_size: %d\n", ul);
7440 #endif
7441               break;
7442
7443 #ifndef DW_CFA_GNU_negative_offset_extended
7444 #define DW_CFA_GNU_negative_offset_extended 0x2f
7445 #endif
7446             case DW_CFA_GNU_negative_offset_extended:
7447               reg = LEB ();
7448               l = - LEB ();
7449               frame_need_space (fc, reg);
7450 #if FDEBUG
7451               printf ("  DW_CFA_GNU_negative_offset_extended: r%d = cfa[%d*%d]\n", reg, l, fc->data_factor);
7452 #endif
7453               fc->col_type[reg] = DW_CFA_offset;
7454               fc->col_offset[reg] = l * fc->data_factor;
7455               break;
7456
7457             default:
7458               fprintf (stderr, "unsupported or unknown DW_CFA_%d\n", op);
7459               start = block_end;
7460             }
7461         }
7462
7463       frame_display_row (fc, &need_col_headers, &max_regs);
7464
7465       start = block_end;
7466     }
7467
7468   printf ("\n");
7469
7470   return 1;
7471 }
7472
7473 #undef GET
7474 #undef LEB
7475 #undef SLEB
7476
7477 static int
7478 display_debug_not_supported (section, start, file)
7479      Elf32_Internal_Shdr * section;
7480      unsigned char *       start ATTRIBUTE_UNUSED;
7481      FILE *                file ATTRIBUTE_UNUSED;
7482 {
7483   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
7484             SECTION_NAME (section));
7485
7486   return 1;
7487 }
7488
7489 /* Pre-scan the .debug_info section to record the size of address.
7490    When dumping the .debug_line, we use that size information, assuming
7491    that all compilation units have the same address size.  */
7492 static int
7493 prescan_debug_info (section, start, file)
7494      Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
7495      unsigned char *       start;
7496      FILE *                file ATTRIBUTE_UNUSED;
7497 {
7498   DWARF2_External_CompUnit * external;
7499
7500   external = (DWARF2_External_CompUnit *) start;
7501
7502   debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
7503   return 0;
7504 }
7505
7506   /* A structure containing the name of a debug section and a pointer
7507      to a function that can decode it.  The third field is a prescan
7508      function to be run over the section before displaying any of the
7509      sections.  */
7510 struct
7511 {
7512   char * name;
7513   int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7514   int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
7515 }
7516 debug_displays[] =
7517 {
7518   { ".debug_info",        display_debug_info, prescan_debug_info },
7519   { ".debug_abbrev",      display_debug_abbrev, NULL },
7520   { ".debug_line",        display_debug_lines, NULL },
7521   { ".debug_aranges",     display_debug_aranges, NULL },
7522   { ".debug_pubnames",    display_debug_pubnames, NULL },
7523   { ".debug_frame",       display_debug_frames, NULL },
7524   { ".eh_frame",          display_debug_frames, NULL },
7525   { ".debug_macinfo",     display_debug_not_supported, NULL },
7526   { ".debug_frame",       display_debug_not_supported, NULL },
7527   { ".debug_str",         display_debug_not_supported, NULL },
7528   { ".debug_static_func", display_debug_not_supported, NULL },
7529   { ".debug_static_vars", display_debug_not_supported, NULL },
7530   { ".debug_types",       display_debug_not_supported, NULL },
7531   { ".debug_weaknames",   display_debug_not_supported, NULL }
7532 };
7533
7534 static int
7535 display_debug_section (section, file)
7536      Elf32_Internal_Shdr * section;
7537      FILE * file;
7538 {
7539   char *          name = SECTION_NAME (section);
7540   bfd_size_type   length;
7541   unsigned char * start;
7542   int             i;
7543
7544   length = section->sh_size;
7545   if (length == 0)
7546     {
7547       printf (_("\nSection '%s' has no debugging data.\n"), name);
7548       return 0;
7549     }
7550
7551   GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7552                   "debug section data");
7553
7554   /* See if we know how to display the contents of this section.  */
7555   if (strncmp (name, ".gnu.linkonce.wi.", 17) == 0)
7556     name = ".debug_info";  
7557
7558   for (i = NUM_ELEM (debug_displays); i--;)
7559     if (strcmp (debug_displays[i].name, name) == 0)
7560       {
7561         debug_displays[i].display (section, start, file);
7562         break;
7563       }
7564
7565   if (i == -1)
7566     printf (_("Unrecognised debug section: %s\n"), name);
7567
7568   free (start);
7569
7570   /* If we loaded in the abbrev section at some point,
7571      we must release it here.  */
7572   if (first_abbrev != NULL)
7573     free_abbrevs ();
7574
7575   return 1;
7576 }
7577
7578 static int
7579 process_section_contents (file)
7580      FILE * file;
7581 {
7582   Elf32_Internal_Shdr * section;
7583   unsigned int          i;
7584
7585   if (! do_dump)
7586     return 1;
7587
7588   /* Pre-scan the debug sections to find some debug information not
7589      present in some of them.  For the .debug_line, we must find out the
7590      size of address (specified in .debug_info and .debug_aranges).  */
7591   for (i = 0, section = section_headers;
7592        i < elf_header.e_shnum && i < num_dump_sects;
7593        i ++, section ++)
7594     {
7595       char *    name = SECTION_NAME (section);
7596       int       j;
7597
7598       if (section->sh_size == 0)
7599         continue;
7600
7601       /* See if there is some pre-scan operation for this section.  */
7602       for (j = NUM_ELEM (debug_displays); j--;)
7603         if (strcmp (debug_displays[j].name, name) == 0)
7604           {
7605             if (debug_displays[j].prescan != NULL)
7606               {
7607                 bfd_size_type   length;
7608                 unsigned char * start;
7609
7610                 length = section->sh_size;
7611                 GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
7612                                 "debug section data");
7613
7614                 debug_displays[j].prescan (section, start, file);
7615                 free (start);
7616               }
7617
7618             break;
7619           }
7620     }
7621
7622   for (i = 0, section = section_headers;
7623        i < elf_header.e_shnum && i < num_dump_sects;
7624        i ++, section ++)
7625     {
7626 #ifdef SUPPORT_DISASSEMBLY
7627       if (dump_sects[i] & DISASS_DUMP)
7628         disassemble_section (section, file);
7629 #endif
7630       if (dump_sects[i] & HEX_DUMP)
7631         dump_section (section, file);
7632
7633       if (dump_sects[i] & DEBUG_DUMP)
7634         display_debug_section (section, file);
7635     }
7636
7637   if (i < num_dump_sects)
7638     warn (_("Some sections were not dumped because they do not exist!\n"));
7639
7640   return 1;
7641 }
7642
7643 static void
7644 process_mips_fpe_exception (mask)
7645      int mask;
7646 {
7647   if (mask)
7648     {
7649       int first = 1;
7650       if (mask & OEX_FPU_INEX)
7651         fputs ("INEX", stdout), first = 0;
7652       if (mask & OEX_FPU_UFLO)
7653         printf ("%sUFLO", first ? "" : "|"), first = 0;
7654       if (mask & OEX_FPU_OFLO)
7655         printf ("%sOFLO", first ? "" : "|"), first = 0;
7656       if (mask & OEX_FPU_DIV0)
7657         printf ("%sDIV0", first ? "" : "|"), first = 0;
7658       if (mask & OEX_FPU_INVAL)
7659         printf ("%sINVAL", first ? "" : "|");
7660     }
7661   else
7662     fputs ("0", stdout);
7663 }
7664
7665 static int
7666 process_mips_specific (file)
7667      FILE * file;
7668 {
7669   Elf_Internal_Dyn * entry;
7670   size_t liblist_offset = 0;
7671   size_t liblistno = 0;
7672   size_t conflictsno = 0;
7673   size_t options_offset = 0;
7674   size_t conflicts_offset = 0;
7675
7676   /* We have a lot of special sections.  Thanks SGI!  */
7677   if (dynamic_segment == NULL)
7678     /* No information available.  */
7679     return 0;
7680
7681   for (entry = dynamic_segment; entry->d_tag != DT_NULL; ++entry)
7682     switch (entry->d_tag)
7683       {
7684       case DT_MIPS_LIBLIST:
7685         liblist_offset = entry->d_un.d_val - loadaddr;
7686         break;
7687       case DT_MIPS_LIBLISTNO:
7688         liblistno = entry->d_un.d_val;
7689         break;
7690       case DT_MIPS_OPTIONS:
7691         options_offset = entry->d_un.d_val - loadaddr;
7692         break;
7693       case DT_MIPS_CONFLICT:
7694         conflicts_offset = entry->d_un.d_val - loadaddr;
7695         break;
7696       case DT_MIPS_CONFLICTNO:
7697         conflictsno = entry->d_un.d_val;
7698         break;
7699       default:
7700         break;
7701       }
7702
7703   if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
7704     {
7705       Elf32_External_Lib * elib;
7706       size_t cnt;
7707
7708       GET_DATA_ALLOC (liblist_offset, liblistno * sizeof (Elf32_External_Lib),
7709                       elib, Elf32_External_Lib *, "liblist");
7710
7711       printf ("\nSection '.liblist' contains %lu entries:\n",
7712               (unsigned long) liblistno);
7713       fputs ("     Library              Time Stamp          Checksum   Version Flags\n",
7714              stdout);
7715
7716       for (cnt = 0; cnt < liblistno; ++cnt)
7717         {
7718           Elf32_Lib liblist;
7719           time_t time;
7720           char timebuf[20];
7721           struct tm * tmp;
7722
7723           liblist.l_name = BYTE_GET (elib[cnt].l_name);
7724           time = BYTE_GET (elib[cnt].l_time_stamp);
7725           liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
7726           liblist.l_version = BYTE_GET (elib[cnt].l_version);
7727           liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
7728
7729           tmp = gmtime (&time);
7730           sprintf (timebuf, "%04u-%02u-%02uT%02u:%02u:%02u",
7731                    tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7732                    tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7733
7734           printf ("%3lu: %-20s %s %#10lx %-7ld", (unsigned long) cnt,
7735                   dynamic_strings + liblist.l_name, timebuf,
7736                   liblist.l_checksum, liblist.l_version);
7737
7738           if (liblist.l_flags == 0)
7739             puts (" NONE");
7740           else
7741             {
7742               static const struct
7743               {
7744                 const char * name;
7745                 int bit;
7746               }
7747               l_flags_vals[] =
7748               {
7749                 { " EXACT_MATCH", LL_EXACT_MATCH },
7750                 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
7751                 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
7752                 { " EXPORTS", LL_EXPORTS },
7753                 { " DELAY_LOAD", LL_DELAY_LOAD },
7754                 { " DELTA", LL_DELTA }
7755               };
7756               int flags = liblist.l_flags;
7757               size_t fcnt;
7758
7759               for (fcnt = 0;
7760                    fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
7761                    ++fcnt)
7762                 if ((flags & l_flags_vals[fcnt].bit) != 0)
7763                   {
7764                     fputs (l_flags_vals[fcnt].name, stdout);
7765                     flags ^= l_flags_vals[fcnt].bit;
7766                   }
7767               if (flags != 0)
7768                 printf (" %#x", (unsigned int) flags);
7769
7770               puts ("");
7771             }
7772         }
7773
7774       free (elib);
7775     }
7776
7777   if (options_offset != 0)
7778     {
7779       Elf_External_Options * eopt;
7780       Elf_Internal_Shdr *    sect = section_headers;
7781       Elf_Internal_Options * iopt;
7782       Elf_Internal_Options * option;
7783       size_t offset;
7784       int cnt;
7785
7786       /* Find the section header so that we get the size.  */
7787       while (sect->sh_type != SHT_MIPS_OPTIONS)
7788         ++ sect;
7789
7790       GET_DATA_ALLOC (options_offset, sect->sh_size, eopt,
7791                       Elf_External_Options *, "options");
7792
7793       iopt = (Elf_Internal_Options *) malloc ((sect->sh_size / sizeof (eopt))
7794                                               * sizeof (* iopt));
7795       if (iopt == NULL)
7796         {
7797           error (_("Out of memory"));
7798           return 0;
7799         }
7800
7801       offset = cnt = 0;
7802       option = iopt;
7803
7804       while (offset < sect->sh_size)
7805         {
7806           Elf_External_Options * eoption;
7807
7808           eoption = (Elf_External_Options *) ((char *) eopt + offset);
7809
7810           option->kind = BYTE_GET (eoption->kind);
7811           option->size = BYTE_GET (eoption->size);
7812           option->section = BYTE_GET (eoption->section);
7813           option->info = BYTE_GET (eoption->info);
7814
7815           offset += option->size;
7816
7817           ++option;
7818           ++cnt;
7819         }
7820
7821       printf (_("\nSection '%s' contains %d entries:\n"),
7822               SECTION_NAME (sect), cnt);
7823
7824       option = iopt;
7825
7826       while (cnt-- > 0)
7827         {
7828           size_t len;
7829
7830           switch (option->kind)
7831             {
7832             case ODK_NULL:
7833               /* This shouldn't happen.  */
7834               printf (" NULL       %d %lx", option->section, option->info);
7835               break;
7836             case ODK_REGINFO:
7837               printf (" REGINFO    ");
7838               if (elf_header.e_machine == EM_MIPS)
7839                 {
7840                   /* 32bit form.  */
7841                   Elf32_External_RegInfo * ereg;
7842                   Elf32_RegInfo            reginfo;
7843
7844                   ereg = (Elf32_External_RegInfo *) (option + 1);
7845                   reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
7846                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7847                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7848                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7849                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7850                   reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
7851
7852                   printf ("GPR %08lx  GP 0x%lx\n",
7853                           reginfo.ri_gprmask,
7854                           (unsigned long) reginfo.ri_gp_value);
7855                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
7856                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7857                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7858                 }
7859               else
7860                 {
7861                   /* 64 bit form.  */
7862                   Elf64_External_RegInfo * ereg;
7863                   Elf64_Internal_RegInfo reginfo;
7864
7865                   ereg = (Elf64_External_RegInfo *) (option + 1);
7866                   reginfo.ri_gprmask    = BYTE_GET (ereg->ri_gprmask);
7867                   reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
7868                   reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
7869                   reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
7870                   reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
7871                   reginfo.ri_gp_value   = BYTE_GET8 (ereg->ri_gp_value);
7872
7873                   printf ("GPR %08lx  GP 0x",
7874                           reginfo.ri_gprmask);
7875                   printf_vma (reginfo.ri_gp_value);
7876                   printf ("\n");
7877
7878                   printf ("            CPR0 %08lx  CPR1 %08lx  CPR2 %08lx  CPR3 %08lx\n",
7879                           reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
7880                           reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
7881                 }
7882               ++option;
7883               continue;
7884             case ODK_EXCEPTIONS:
7885               fputs (" EXCEPTIONS fpe_min(", stdout);
7886               process_mips_fpe_exception (option->info & OEX_FPU_MIN);
7887               fputs (") fpe_max(", stdout);
7888               process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
7889               fputs (")", stdout);
7890
7891               if (option->info & OEX_PAGE0)
7892                 fputs (" PAGE0", stdout);
7893               if (option->info & OEX_SMM)
7894                 fputs (" SMM", stdout);
7895               if (option->info & OEX_FPDBUG)
7896                 fputs (" FPDBUG", stdout);
7897               if (option->info & OEX_DISMISS)
7898                 fputs (" DISMISS", stdout);
7899               break;
7900             case ODK_PAD:
7901               fputs (" PAD       ", stdout);
7902               if (option->info & OPAD_PREFIX)
7903                 fputs (" PREFIX", stdout);
7904               if (option->info & OPAD_POSTFIX)
7905                 fputs (" POSTFIX", stdout);
7906               if (option->info & OPAD_SYMBOL)
7907                 fputs (" SYMBOL", stdout);
7908               break;
7909             case ODK_HWPATCH:
7910               fputs (" HWPATCH   ", stdout);
7911               if (option->info & OHW_R4KEOP)
7912                 fputs (" R4KEOP", stdout);
7913               if (option->info & OHW_R8KPFETCH)
7914                 fputs (" R8KPFETCH", stdout);
7915               if (option->info & OHW_R5KEOP)
7916                 fputs (" R5KEOP", stdout);
7917               if (option->info & OHW_R5KCVTL)
7918                 fputs (" R5KCVTL", stdout);
7919               break;
7920             case ODK_FILL:
7921               fputs (" FILL       ", stdout);
7922               /* XXX Print content of info word?  */
7923               break;
7924             case ODK_TAGS:
7925               fputs (" TAGS       ", stdout);
7926               /* XXX Print content of info word?  */
7927               break;
7928             case ODK_HWAND:
7929               fputs (" HWAND     ", stdout);
7930               if (option->info & OHWA0_R4KEOP_CHECKED)
7931                 fputs (" R4KEOP_CHECKED", stdout);
7932               if (option->info & OHWA0_R4KEOP_CLEAN)
7933                 fputs (" R4KEOP_CLEAN", stdout);
7934               break;
7935             case ODK_HWOR:
7936               fputs (" HWOR      ", stdout);
7937               if (option->info & OHWA0_R4KEOP_CHECKED)
7938                 fputs (" R4KEOP_CHECKED", stdout);
7939               if (option->info & OHWA0_R4KEOP_CLEAN)
7940                 fputs (" R4KEOP_CLEAN", stdout);
7941               break;
7942             case ODK_GP_GROUP:
7943               printf (" GP_GROUP  %#06lx  self-contained %#06lx",
7944                       option->info & OGP_GROUP,
7945                       (option->info & OGP_SELF) >> 16);
7946               break;
7947             case ODK_IDENT:
7948               printf (" IDENT     %#06lx  self-contained %#06lx",
7949                       option->info & OGP_GROUP,
7950                       (option->info & OGP_SELF) >> 16);
7951               break;
7952             default:
7953               /* This shouldn't happen.  */
7954               printf (" %3d ???     %d %lx",
7955                       option->kind, option->section, option->info);
7956               break;
7957             }
7958
7959           len = sizeof (* eopt);
7960           while (len < option->size)
7961             if (((char *) option)[len] >= ' '
7962                 && ((char *) option)[len] < 0x7f)
7963               printf ("%c", ((char *) option)[len++]);
7964             else
7965               printf ("\\%03o", ((char *) option)[len++]);
7966
7967           fputs ("\n", stdout);
7968           ++option;
7969         }
7970
7971       free (eopt);
7972     }
7973
7974   if (conflicts_offset != 0 && conflictsno != 0)
7975     {
7976       Elf32_External_Conflict * econf32;
7977       Elf64_External_Conflict * econf64;
7978       Elf32_Conflict * iconf;
7979       size_t cnt;
7980
7981       if (dynamic_symbols == NULL)
7982         {
7983           error (_("conflict list with without table"));
7984           return 0;
7985         }
7986
7987       iconf = (Elf32_Conflict *) malloc (conflictsno * sizeof (* iconf));
7988       if (iconf == NULL)
7989         {
7990           error (_("Out of memory"));
7991           return 0;
7992         }
7993
7994       if (is_32bit_elf)
7995         {
7996           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf32),
7997                           econf32, Elf32_External_Conflict *, "conflict");
7998
7999           for (cnt = 0; cnt < conflictsno; ++cnt)
8000             iconf[cnt] = BYTE_GET (econf32[cnt]);
8001         }
8002       else
8003         {
8004           GET_DATA_ALLOC (conflicts_offset, conflictsno * sizeof (* econf64),
8005                           econf64, Elf64_External_Conflict *, "conflict");
8006
8007           for (cnt = 0; cnt < conflictsno; ++cnt)
8008             iconf[cnt] = BYTE_GET (econf64[cnt]);
8009         }
8010
8011       printf (_("\nSection '.conflict' contains %d entries:\n"), conflictsno);
8012       puts (_("  Num:    Index       Value  Name"));
8013
8014       for (cnt = 0; cnt < conflictsno; ++cnt)
8015         {
8016           Elf_Internal_Sym * psym = &dynamic_symbols[iconf[cnt]];
8017
8018           printf ("%5lu: %8lu  ", (unsigned long) cnt, iconf[cnt]);
8019           print_vma (psym->st_value, FULL_HEX);
8020           printf ("  %s\n", dynamic_strings + psym->st_name);
8021         }
8022
8023       free (iconf);
8024     }
8025
8026   return 1;
8027 }
8028
8029 static char *
8030 get_note_type (e_type)
8031      unsigned e_type;
8032 {
8033   static char buff[64];
8034
8035   switch (e_type)
8036     {
8037     case NT_PRSTATUS:   return _("NT_PRSTATUS (prstatus structure)");
8038     case NT_FPREGSET:   return _("NT_FPREGSET (floating point registers)");
8039     case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
8040     case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
8041     case NT_PRXFPREG:   return _("NT_PRXFPREG (user_xfpregs structure)");
8042     case NT_PSTATUS:    return _("NT_PSTATUS (pstatus structure)");
8043     case NT_FPREGS:     return _("NT_FPREGS (floating point registers)");
8044     case NT_PSINFO:     return _("NT_PSINFO (psinfo structure)");
8045     case NT_LWPSTATUS:  return _("NT_LWPSTATUS (lwpstatus_t structure)");
8046     case NT_LWPSINFO:   return _("NT_LWPSINFO (lwpsinfo_t structure)");
8047     case NT_WIN32PSTATUS: return _("NT_WIN32PSTATUS (win32_pstatus strcuture)");
8048     default:
8049       sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
8050       return buff;
8051     }
8052 }
8053
8054 /* Note that by the ELF standard, the name field is already null byte
8055    terminated, and namesz includes the terminating null byte.
8056    I.E. the value of namesz for the name "FSF" is 4.
8057
8058    If the value of namesz is zero, there is no name present. */
8059 static int
8060 process_note (pnote)
8061   Elf32_Internal_Note * pnote;
8062 {
8063   printf ("  %s\t\t0x%08lx\t%s\n",
8064           pnote->namesz ? pnote->namedata : "(NONE)",
8065           pnote->descsz, get_note_type (pnote->type));
8066   return 1;
8067 }
8068
8069
8070 static int
8071 process_corefile_note_segment (file, offset, length)
8072      FILE * file;
8073      bfd_vma offset;
8074      bfd_vma length;
8075 {
8076   Elf_External_Note *  pnotes;
8077   Elf_External_Note *  external;
8078   int                  res = 1;
8079
8080   if (length <= 0)
8081     return 0;
8082
8083   GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
8084
8085   external = pnotes;
8086
8087   printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
8088           (unsigned long) offset, (unsigned long) length);
8089   printf (_("  Owner\t\tData size\tDescription\n"));
8090
8091   while (external < (Elf_External_Note *)((char *) pnotes + length))
8092     {
8093       Elf32_Internal_Note inote;
8094       char * temp = NULL;
8095
8096       inote.type     = BYTE_GET (external->type);
8097       inote.namesz   = BYTE_GET (external->namesz);
8098       inote.namedata = external->name;
8099       inote.descsz   = BYTE_GET (external->descsz);
8100       inote.descdata = inote.namedata + align_power (inote.namesz, 2);
8101       inote.descpos  = offset + (inote.descdata - (char *) pnotes);
8102
8103       external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
8104
8105       /* Verify that name is null terminated.  It appears that at least
8106          one version of Linux (RedHat 6.0) generates corefiles that don't
8107          comply with the ELF spec by failing to include the null byte in
8108          namesz.  */
8109       if (inote.namedata[inote.namesz] != '\0')
8110         {
8111           temp = malloc (inote.namesz + 1);
8112
8113           if (temp == NULL)
8114             {
8115               error (_("Out of memory\n"));
8116               res = 0;
8117               break;
8118             }
8119
8120           strncpy (temp, inote.namedata, inote.namesz);
8121           temp[inote.namesz] = 0;
8122
8123           /* warn (_("'%s' NOTE name not properly null terminated\n"), temp);  */
8124           inote.namedata = temp;
8125         }
8126
8127       res &= process_note (& inote);
8128
8129       if (temp != NULL)
8130         {
8131           free (temp);
8132           temp = NULL;
8133         }
8134     }
8135
8136   free (pnotes);
8137
8138   return res;
8139 }
8140
8141 static int
8142 process_corefile_note_segments (file)
8143      FILE * file;
8144 {
8145   Elf_Internal_Phdr * program_headers;
8146   Elf_Internal_Phdr * segment;
8147   unsigned int        i;
8148   int                 res = 1;
8149
8150   program_headers = (Elf_Internal_Phdr *) malloc
8151     (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
8152
8153   if (program_headers == NULL)
8154     {
8155       error (_("Out of memory\n"));
8156       return 0;
8157     }
8158
8159   if (is_32bit_elf)
8160     i = get_32bit_program_headers (file, program_headers);
8161   else
8162     i = get_64bit_program_headers (file, program_headers);
8163
8164   if (i == 0)
8165     {
8166       free (program_headers);
8167       return 0;
8168     }
8169
8170   for (i = 0, segment = program_headers;
8171        i < elf_header.e_phnum;
8172        i ++, segment ++)
8173     {
8174       if (segment->p_type == PT_NOTE)
8175         res &= process_corefile_note_segment (file,
8176                                               (bfd_vma) segment->p_offset,
8177                                               (bfd_vma) segment->p_filesz);
8178     }
8179
8180   free (program_headers);
8181
8182   return res;
8183 }
8184
8185 static int
8186 process_corefile_contents (file)
8187      FILE * file;
8188 {
8189   /* If we have not been asked to display the notes then do nothing.  */
8190   if (! do_notes)
8191     return 1;
8192
8193   /* If file is not a core file then exit.  */
8194   if (elf_header.e_type != ET_CORE)
8195     return 1;
8196
8197   /* No program headers means no NOTE segment.  */
8198   if (elf_header.e_phnum == 0)
8199     {
8200       printf (_("No note segments present in the core file.\n"));
8201       return 1;
8202    }
8203
8204   return process_corefile_note_segments (file);
8205 }
8206
8207 static int
8208 process_arch_specific (file)
8209      FILE * file;
8210 {
8211   if (! do_arch)
8212     return 1;
8213
8214   switch (elf_header.e_machine)
8215     {
8216     case EM_MIPS:
8217     case EM_MIPS_RS4_BE:
8218       return process_mips_specific (file);
8219       break;
8220     default:
8221       break;
8222     }
8223   return 1;
8224 }
8225
8226 static int
8227 get_file_header (file)
8228      FILE * file;
8229 {
8230   /* Read in the identity array.  */
8231   if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
8232     return 0;
8233
8234   /* Determine how to read the rest of the header.  */
8235   switch (elf_header.e_ident [EI_DATA])
8236     {
8237     default: /* fall through */
8238     case ELFDATANONE: /* fall through */
8239     case ELFDATA2LSB: byte_get = byte_get_little_endian; break;
8240     case ELFDATA2MSB: byte_get = byte_get_big_endian; break;
8241     }
8242
8243   /* For now we only support 32 bit and 64 bit ELF files.  */
8244   is_32bit_elf = (elf_header.e_ident [EI_CLASS] != ELFCLASS64);
8245
8246   /* Read in the rest of the header.  */
8247   if (is_32bit_elf)
8248     {
8249       Elf32_External_Ehdr ehdr32;
8250
8251       if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
8252         return 0;
8253
8254       elf_header.e_type      = BYTE_GET (ehdr32.e_type);
8255       elf_header.e_machine   = BYTE_GET (ehdr32.e_machine);
8256       elf_header.e_version   = BYTE_GET (ehdr32.e_version);
8257       elf_header.e_entry     = BYTE_GET (ehdr32.e_entry);
8258       elf_header.e_phoff     = BYTE_GET (ehdr32.e_phoff);
8259       elf_header.e_shoff     = BYTE_GET (ehdr32.e_shoff);
8260       elf_header.e_flags     = BYTE_GET (ehdr32.e_flags);
8261       elf_header.e_ehsize    = BYTE_GET (ehdr32.e_ehsize);
8262       elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
8263       elf_header.e_phnum     = BYTE_GET (ehdr32.e_phnum);
8264       elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
8265       elf_header.e_shnum     = BYTE_GET (ehdr32.e_shnum);
8266       elf_header.e_shstrndx  = BYTE_GET (ehdr32.e_shstrndx);
8267     }
8268   else
8269     {
8270       Elf64_External_Ehdr ehdr64;
8271
8272       /* If we have been compiled with sizeof (bfd_vma) == 4, then
8273          we will not be able to cope with the 64bit data found in
8274          64 ELF files.  Detect this now and abort before we start
8275          overwritting things.  */
8276       if (sizeof (bfd_vma) < 8)
8277         {
8278           error (_("This instance of readelf has been built without support for a\n"));
8279           error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
8280           return 0;
8281         }
8282
8283       if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
8284         return 0;
8285
8286       elf_header.e_type      = BYTE_GET (ehdr64.e_type);
8287       elf_header.e_machine   = BYTE_GET (ehdr64.e_machine);
8288       elf_header.e_version   = BYTE_GET (ehdr64.e_version);
8289       elf_header.e_entry     = BYTE_GET8 (ehdr64.e_entry);
8290       elf_header.e_phoff     = BYTE_GET8 (ehdr64.e_phoff);
8291       elf_header.e_shoff     = BYTE_GET8 (ehdr64.e_shoff);
8292       elf_header.e_flags     = BYTE_GET (ehdr64.e_flags);
8293       elf_header.e_ehsize    = BYTE_GET (ehdr64.e_ehsize);
8294       elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
8295       elf_header.e_phnum     = BYTE_GET (ehdr64.e_phnum);
8296       elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
8297       elf_header.e_shnum     = BYTE_GET (ehdr64.e_shnum);
8298       elf_header.e_shstrndx  = BYTE_GET (ehdr64.e_shstrndx);
8299     }
8300
8301   return 1;
8302 }
8303
8304 static void
8305 process_file (file_name)
8306      char * file_name;
8307 {
8308   FILE *       file;
8309   struct stat  statbuf;
8310   unsigned int i;
8311
8312   if (stat (file_name, & statbuf) < 0)
8313     {
8314       error (_("Cannot stat input file %s.\n"), file_name);
8315       return;
8316     }
8317
8318   file = fopen (file_name, "rb");
8319   if (file == NULL)
8320     {
8321       error (_("Input file %s not found.\n"), file_name);
8322       return;
8323     }
8324
8325   if (! get_file_header (file))
8326     {
8327       error (_("%s: Failed to read file header\n"), file_name);
8328       fclose (file);
8329       return;
8330     }
8331
8332   /* Initialise per file variables.  */
8333   for (i = NUM_ELEM (version_info); i--;)
8334     version_info[i] = 0;
8335
8336   for (i = NUM_ELEM (dynamic_info); i--;)
8337     dynamic_info[i] = 0;
8338
8339   /* Process the file.  */
8340   if (show_name)
8341     printf (_("\nFile: %s\n"), file_name);
8342
8343   if (! process_file_header ())
8344     {
8345       fclose (file);
8346       return;
8347     }
8348
8349   process_section_headers (file);
8350
8351   process_program_headers (file);
8352
8353   process_dynamic_segment (file);
8354
8355   process_relocs (file);
8356
8357   process_unwind (file);
8358
8359   process_symbol_table (file);
8360
8361   process_syminfo (file);
8362
8363   process_version_sections (file);
8364
8365   process_section_contents (file);
8366
8367   process_corefile_contents (file);
8368
8369   process_arch_specific (file);
8370
8371   fclose (file);
8372
8373   if (section_headers)
8374     {
8375       free (section_headers);
8376       section_headers = NULL;
8377     }
8378
8379   if (string_table)
8380     {
8381       free (string_table);
8382       string_table = NULL;
8383       string_table_length = 0;
8384     }
8385
8386   if (dynamic_strings)
8387     {
8388       free (dynamic_strings);
8389       dynamic_strings = NULL;
8390     }
8391
8392   if (dynamic_symbols)
8393     {
8394       free (dynamic_symbols);
8395       dynamic_symbols = NULL;
8396       num_dynamic_syms = 0;
8397     }
8398
8399   if (dynamic_syminfo)
8400     {
8401       free (dynamic_syminfo);
8402       dynamic_syminfo = NULL;
8403     }
8404 }
8405
8406 #ifdef SUPPORT_DISASSEMBLY
8407 /* Needed by the i386 disassembler.  For extra credit, someone could
8408    fix this so that we insert symbolic addresses here, esp for GOT/PLT
8409    symbols */
8410
8411 void
8412 print_address (unsigned int addr, FILE * outfile)
8413 {
8414   fprintf (outfile,"0x%8.8x", addr);
8415 }
8416
8417 /* Needed by the i386 disassembler. */
8418 void
8419 db_task_printsym (unsigned int addr)
8420 {
8421   print_address (addr, stderr);
8422 }
8423 #endif
8424
8425 int
8426 main (argc, argv)
8427      int     argc;
8428      char ** argv;
8429 {
8430 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
8431   setlocale (LC_MESSAGES, "");
8432 #endif
8433   bindtextdomain (PACKAGE, LOCALEDIR);
8434   textdomain (PACKAGE);
8435
8436   parse_args (argc, argv);
8437
8438   if (optind < (argc - 1))
8439     show_name = 1;
8440
8441   while (optind < argc)
8442     process_file (argv [optind ++]);
8443
8444   if (dump_sects != NULL)
8445     free (dump_sects);
8446
8447   return 0;
8448 }