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