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