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