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