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