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