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