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