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