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