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