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