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