]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Fix testcases compilation failures due to unused variables.
[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
4378 printf (" [%2u] %-17.17s %-15.15s ",
4fbb74a6 4379 i,
595cf52e
L
4380 SECTION_NAME (section),
4381 get_section_type_name (section->sh_type));
252b5132 4382
f7a99963
NC
4383 if (is_32bit_elf)
4384 {
4385 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4386
f7a99963
NC
4387 printf ( " %6.6lx %6.6lx %2.2lx",
4388 (unsigned long) section->sh_offset,
4389 (unsigned long) section->sh_size,
4390 (unsigned long) section->sh_entsize);
d1133906 4391
5477e8a0
L
4392 if (do_section_details)
4393 fputs (" ", stdout);
4394 else
4395 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4396
72de5009
AM
4397 printf ("%2u %3u %2lu\n",
4398 section->sh_link,
4399 section->sh_info,
f7a99963
NC
4400 (unsigned long) section->sh_addralign);
4401 }
d974e256
JJ
4402 else if (do_wide)
4403 {
4404 print_vma (section->sh_addr, LONG_HEX);
4405
4406 if ((long) section->sh_offset == section->sh_offset)
4407 printf (" %6.6lx", (unsigned long) section->sh_offset);
4408 else
4409 {
4410 putchar (' ');
4411 print_vma (section->sh_offset, LONG_HEX);
4412 }
4413
4414 if ((unsigned long) section->sh_size == section->sh_size)
4415 printf (" %6.6lx", (unsigned long) section->sh_size);
4416 else
4417 {
4418 putchar (' ');
4419 print_vma (section->sh_size, LONG_HEX);
4420 }
4421
4422 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4423 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4424 else
4425 {
4426 putchar (' ');
4427 print_vma (section->sh_entsize, LONG_HEX);
4428 }
4429
5477e8a0
L
4430 if (do_section_details)
4431 fputs (" ", stdout);
4432 else
4433 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4434
72de5009 4435 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4436
4437 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4438 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4439 else
4440 {
4441 print_vma (section->sh_addralign, DEC);
4442 putchar ('\n');
4443 }
4444 }
5477e8a0 4445 else if (do_section_details)
595cf52e 4446 {
5477e8a0 4447 printf (" %-15.15s ",
595cf52e 4448 get_section_type_name (section->sh_type));
595cf52e
L
4449 print_vma (section->sh_addr, LONG_HEX);
4450 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4451 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4452 else
4453 {
4454 printf (" ");
4455 print_vma (section->sh_offset, LONG_HEX);
4456 }
72de5009 4457 printf (" %u\n ", section->sh_link);
595cf52e 4458 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4459 putchar (' ');
595cf52e
L
4460 print_vma (section->sh_entsize, LONG_HEX);
4461
72de5009
AM
4462 printf (" %-16u %lu\n",
4463 section->sh_info,
595cf52e
L
4464 (unsigned long) section->sh_addralign);
4465 }
f7a99963
NC
4466 else
4467 {
4468 putchar (' ');
4469 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4470 if ((long) section->sh_offset == section->sh_offset)
4471 printf (" %8.8lx", (unsigned long) section->sh_offset);
4472 else
4473 {
4474 printf (" ");
4475 print_vma (section->sh_offset, LONG_HEX);
4476 }
f7a99963
NC
4477 printf ("\n ");
4478 print_vma (section->sh_size, LONG_HEX);
4479 printf (" ");
4480 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4481
d1133906 4482 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4483
72de5009
AM
4484 printf (" %2u %3u %lu\n",
4485 section->sh_link,
4486 section->sh_info,
f7a99963
NC
4487 (unsigned long) section->sh_addralign);
4488 }
5477e8a0
L
4489
4490 if (do_section_details)
4491 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4492 }
4493
5477e8a0
L
4494 if (!do_section_details)
4495 printf (_("Key to Flags:\n\
e3c8793a
NC
4496 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4497 I (info), L (link order), G (group), x (unknown)\n\
4498 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4499
252b5132
RH
4500 return 1;
4501}
4502
f5842774
L
4503static const char *
4504get_group_flags (unsigned int flags)
4505{
4506 static char buff[32];
4507 switch (flags)
4508 {
4509 case GRP_COMDAT:
4510 return "COMDAT";
4511
4512 default:
e9e44622 4513 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4514 break;
4515 }
4516 return buff;
4517}
4518
4519static int
4520process_section_groups (FILE *file)
4521{
4522 Elf_Internal_Shdr *section;
4523 unsigned int i;
e4b17d5c 4524 struct group *group;
d1f5c6e3
L
4525 Elf_Internal_Shdr *symtab_sec, *strtab_sec;
4526 Elf_Internal_Sym *symtab;
4527 char *strtab;
c256ffe7 4528 size_t strtab_size;
d1f5c6e3
L
4529
4530 /* Don't process section groups unless needed. */
4531 if (!do_unwind && !do_section_groups)
4532 return 1;
f5842774
L
4533
4534 if (elf_header.e_shnum == 0)
4535 {
4536 if (do_section_groups)
d1f5c6e3 4537 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4538
4539 return 1;
4540 }
4541
4542 if (section_headers == NULL)
4543 {
4544 error (_("Section headers are not available!\n"));
4545 abort ();
4546 }
4547
e4b17d5c
L
4548 section_headers_groups = calloc (elf_header.e_shnum,
4549 sizeof (struct group *));
4550
4551 if (section_headers_groups == NULL)
4552 {
4553 error (_("Out of memory\n"));
4554 return 0;
4555 }
4556
f5842774 4557 /* Scan the sections for the group section. */
d1f5c6e3 4558 group_count = 0;
f5842774
L
4559 for (i = 0, section = section_headers;
4560 i < elf_header.e_shnum;
4561 i++, section++)
e4b17d5c
L
4562 if (section->sh_type == SHT_GROUP)
4563 group_count++;
4564
d1f5c6e3
L
4565 if (group_count == 0)
4566 {
4567 if (do_section_groups)
4568 printf (_("\nThere are no section groups in this file.\n"));
4569
4570 return 1;
4571 }
4572
e4b17d5c
L
4573 section_groups = calloc (group_count, sizeof (struct group));
4574
4575 if (section_groups == NULL)
4576 {
4577 error (_("Out of memory\n"));
4578 return 0;
4579 }
4580
d1f5c6e3
L
4581 symtab_sec = NULL;
4582 strtab_sec = NULL;
4583 symtab = NULL;
4584 strtab = NULL;
c256ffe7 4585 strtab_size = 0;
e4b17d5c
L
4586 for (i = 0, section = section_headers, group = section_groups;
4587 i < elf_header.e_shnum;
4588 i++, section++)
f5842774
L
4589 {
4590 if (section->sh_type == SHT_GROUP)
4591 {
4592 char *name = SECTION_NAME (section);
dc3c06c2
AM
4593 char *group_name;
4594 unsigned char *start, *indices;
f5842774 4595 unsigned int entry, j, size;
d1f5c6e3 4596 Elf_Internal_Shdr *sec;
f5842774 4597 Elf_Internal_Sym *sym;
f5842774
L
4598
4599 /* Get the symbol table. */
4fbb74a6
AM
4600 if (section->sh_link >= elf_header.e_shnum
4601 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4602 != SHT_SYMTAB))
f5842774
L
4603 {
4604 error (_("Bad sh_link in group section `%s'\n"), name);
4605 continue;
4606 }
d1f5c6e3
L
4607
4608 if (symtab_sec != sec)
4609 {
4610 symtab_sec = sec;
4611 if (symtab)
4612 free (symtab);
4613 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4614 }
f5842774
L
4615
4616 sym = symtab + section->sh_info;
4617
4618 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4619 {
4fbb74a6
AM
4620 if (sym->st_shndx == 0
4621 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4622 {
4623 error (_("Bad sh_info in group section `%s'\n"), name);
4624 continue;
4625 }
ba2685cc 4626
4fbb74a6 4627 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
4628 strtab_sec = NULL;
4629 if (strtab)
4630 free (strtab);
f5842774 4631 strtab = NULL;
c256ffe7 4632 strtab_size = 0;
f5842774
L
4633 }
4634 else
4635 {
4636 /* Get the string table. */
4fbb74a6 4637 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
4638 {
4639 strtab_sec = NULL;
4640 if (strtab)
4641 free (strtab);
4642 strtab = NULL;
4643 strtab_size = 0;
4644 }
4645 else if (strtab_sec
4fbb74a6 4646 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
4647 {
4648 strtab_sec = sec;
4649 if (strtab)
4650 free (strtab);
4651 strtab = get_data (NULL, file, strtab_sec->sh_offset,
c256ffe7 4652 1, strtab_sec->sh_size,
d1f5c6e3 4653 _("string table"));
c256ffe7 4654 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4655 }
c256ffe7
JJ
4656 group_name = sym->st_name < strtab_size
4657 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4658 }
4659
4660 start = get_data (NULL, file, section->sh_offset,
c256ffe7 4661 1, section->sh_size, _("section data"));
f5842774
L
4662
4663 indices = start;
4664 size = (section->sh_size / section->sh_entsize) - 1;
4665 entry = byte_get (indices, 4);
4666 indices += 4;
e4b17d5c
L
4667
4668 if (do_section_groups)
4669 {
391cb864
L
4670 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4671 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4672
e4b17d5c
L
4673 printf (_(" [Index] Name\n"));
4674 }
4675
4676 group->group_index = i;
4677
f5842774
L
4678 for (j = 0; j < size; j++)
4679 {
e4b17d5c
L
4680 struct group_list *g;
4681
f5842774
L
4682 entry = byte_get (indices, 4);
4683 indices += 4;
4684
4fbb74a6 4685 if (entry >= elf_header.e_shnum)
391cb864
L
4686 {
4687 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4688 entry, i, elf_header.e_shnum - 1);
4689 continue;
4690 }
391cb864 4691
4fbb74a6 4692 if (section_headers_groups [entry] != NULL)
e4b17d5c 4693 {
d1f5c6e3
L
4694 if (entry)
4695 {
391cb864
L
4696 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4697 entry, i,
4fbb74a6 4698 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4699 continue;
4700 }
4701 else
4702 {
4703 /* Intel C/C++ compiler may put section 0 in a
4704 section group. We just warn it the first time
4705 and ignore it afterwards. */
4706 static int warned = 0;
4707 if (!warned)
4708 {
4709 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 4710 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4711 warned++;
4712 }
4713 }
e4b17d5c
L
4714 }
4715
4fbb74a6 4716 section_headers_groups [entry] = group;
e4b17d5c
L
4717
4718 if (do_section_groups)
4719 {
4fbb74a6 4720 sec = section_headers + entry;
c256ffe7 4721 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4722 }
4723
e4b17d5c
L
4724 g = xmalloc (sizeof (struct group_list));
4725 g->section_index = entry;
4726 g->next = group->root;
4727 group->root = g;
f5842774
L
4728 }
4729
f5842774
L
4730 if (start)
4731 free (start);
e4b17d5c
L
4732
4733 group++;
f5842774
L
4734 }
4735 }
4736
d1f5c6e3
L
4737 if (symtab)
4738 free (symtab);
4739 if (strtab)
4740 free (strtab);
f5842774
L
4741 return 1;
4742}
4743
85b1c36d 4744static struct
566b0d53
L
4745{
4746 const char *name;
4747 int reloc;
4748 int size;
4749 int rela;
4750} dynamic_relocations [] =
4751{
4752 { "REL", DT_REL, DT_RELSZ, FALSE },
4753 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4754 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4755};
4756
252b5132 4757/* Process the reloc section. */
18bd398b 4758
252b5132 4759static int
d3ba0551 4760process_relocs (FILE *file)
252b5132 4761{
b34976b6
AM
4762 unsigned long rel_size;
4763 unsigned long rel_offset;
252b5132
RH
4764
4765
4766 if (!do_reloc)
4767 return 1;
4768
4769 if (do_using_dynamic)
4770 {
566b0d53
L
4771 int is_rela;
4772 const char *name;
4773 int has_dynamic_reloc;
4774 unsigned int i;
0de14b54 4775
566b0d53 4776 has_dynamic_reloc = 0;
252b5132 4777
566b0d53 4778 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4779 {
566b0d53
L
4780 is_rela = dynamic_relocations [i].rela;
4781 name = dynamic_relocations [i].name;
4782 rel_size = dynamic_info [dynamic_relocations [i].size];
4783 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4784
566b0d53
L
4785 has_dynamic_reloc |= rel_size;
4786
4787 if (is_rela == UNKNOWN)
aa903cfb 4788 {
566b0d53
L
4789 if (dynamic_relocations [i].reloc == DT_JMPREL)
4790 switch (dynamic_info[DT_PLTREL])
4791 {
4792 case DT_REL:
4793 is_rela = FALSE;
4794 break;
4795 case DT_RELA:
4796 is_rela = TRUE;
4797 break;
4798 }
aa903cfb 4799 }
252b5132 4800
566b0d53
L
4801 if (rel_size)
4802 {
4803 printf
4804 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4805 name, rel_offset, rel_size);
252b5132 4806
d93f0186
NC
4807 dump_relocations (file,
4808 offset_from_vma (file, rel_offset, rel_size),
4809 rel_size,
566b0d53 4810 dynamic_symbols, num_dynamic_syms,
d79b3d50 4811 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4812 }
252b5132 4813 }
566b0d53
L
4814
4815 if (! has_dynamic_reloc)
252b5132
RH
4816 printf (_("\nThere are no dynamic relocations in this file.\n"));
4817 }
4818 else
4819 {
b34976b6
AM
4820 Elf_Internal_Shdr *section;
4821 unsigned long i;
4822 int found = 0;
252b5132
RH
4823
4824 for (i = 0, section = section_headers;
4825 i < elf_header.e_shnum;
b34976b6 4826 i++, section++)
252b5132
RH
4827 {
4828 if ( section->sh_type != SHT_RELA
4829 && section->sh_type != SHT_REL)
4830 continue;
4831
4832 rel_offset = section->sh_offset;
4833 rel_size = section->sh_size;
4834
4835 if (rel_size)
4836 {
b34976b6 4837 Elf_Internal_Shdr *strsec;
b34976b6 4838 int is_rela;
103f02d3 4839
252b5132
RH
4840 printf (_("\nRelocation section "));
4841
4842 if (string_table == NULL)
19936277 4843 printf ("%d", section->sh_name);
252b5132 4844 else
3a1a2036 4845 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4846
4847 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4848 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4849
d79b3d50
NC
4850 is_rela = section->sh_type == SHT_RELA;
4851
4fbb74a6
AM
4852 if (section->sh_link != 0
4853 && section->sh_link < elf_header.e_shnum)
af3fc3bc 4854 {
b34976b6 4855 Elf_Internal_Shdr *symsec;
d79b3d50
NC
4856 Elf_Internal_Sym *symtab;
4857 unsigned long nsyms;
c256ffe7 4858 unsigned long strtablen = 0;
d79b3d50 4859 char *strtab = NULL;
57346661 4860
4fbb74a6 4861 symsec = section_headers + section->sh_link;
08d8fa11
JJ
4862 if (symsec->sh_type != SHT_SYMTAB
4863 && symsec->sh_type != SHT_DYNSYM)
4864 continue;
4865
af3fc3bc 4866 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4867 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4868
af3fc3bc
AM
4869 if (symtab == NULL)
4870 continue;
252b5132 4871
4fbb74a6
AM
4872 if (symsec->sh_link != 0
4873 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 4874 {
4fbb74a6 4875 strsec = section_headers + symsec->sh_link;
103f02d3 4876
c256ffe7
JJ
4877 strtab = get_data (NULL, file, strsec->sh_offset,
4878 1, strsec->sh_size,
4879 _("string table"));
4880 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4881 }
252b5132 4882
d79b3d50
NC
4883 dump_relocations (file, rel_offset, rel_size,
4884 symtab, nsyms, strtab, strtablen, is_rela);
4885 if (strtab)
4886 free (strtab);
4887 free (symtab);
4888 }
4889 else
4890 dump_relocations (file, rel_offset, rel_size,
4891 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4892
4893 found = 1;
4894 }
4895 }
4896
4897 if (! found)
4898 printf (_("\nThere are no relocations in this file.\n"));
4899 }
4900
4901 return 1;
4902}
4903
57346661
AM
4904/* Process the unwind section. */
4905
4d6ed7c8
NC
4906#include "unwind-ia64.h"
4907
4908/* An absolute address consists of a section and an offset. If the
4909 section is NULL, the offset itself is the address, otherwise, the
4910 address equals to LOAD_ADDRESS(section) + offset. */
4911
4912struct absaddr
4913 {
4914 unsigned short section;
4915 bfd_vma offset;
4916 };
4917
1949de15
L
4918#define ABSADDR(a) \
4919 ((a).section \
4920 ? section_headers [(a).section].sh_addr + (a).offset \
4921 : (a).offset)
4922
57346661 4923struct ia64_unw_aux_info
4d6ed7c8 4924 {
57346661 4925 struct ia64_unw_table_entry
4d6ed7c8 4926 {
b34976b6
AM
4927 struct absaddr start;
4928 struct absaddr end;
4929 struct absaddr info;
4d6ed7c8 4930 }
b34976b6
AM
4931 *table; /* Unwind table. */
4932 unsigned long table_len; /* Length of unwind table. */
4933 unsigned char *info; /* Unwind info. */
4934 unsigned long info_size; /* Size of unwind info. */
4935 bfd_vma info_addr; /* starting address of unwind info. */
4936 bfd_vma seg_base; /* Starting address of segment. */
4937 Elf_Internal_Sym *symtab; /* The symbol table. */
4938 unsigned long nsyms; /* Number of symbols. */
4939 char *strtab; /* The string table. */
4940 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4941 };
4942
4d6ed7c8 4943static void
57346661
AM
4944find_symbol_for_address (Elf_Internal_Sym *symtab,
4945 unsigned long nsyms,
4946 const char *strtab,
4947 unsigned long strtab_size,
d3ba0551
AM
4948 struct absaddr addr,
4949 const char **symname,
4950 bfd_vma *offset)
4d6ed7c8 4951{
d3ba0551 4952 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4953 Elf_Internal_Sym *sym, *best = NULL;
4954 unsigned long i;
4955
57346661 4956 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4957 {
4958 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4959 && sym->st_name != 0
4960 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4961 && addr.offset >= sym->st_value
4962 && addr.offset - sym->st_value < dist)
4963 {
4964 best = sym;
4965 dist = addr.offset - sym->st_value;
4966 if (!dist)
4967 break;
4968 }
4969 }
4970 if (best)
4971 {
57346661
AM
4972 *symname = (best->st_name >= strtab_size
4973 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4974 *offset = dist;
4975 return;
4976 }
4977 *symname = NULL;
4978 *offset = addr.offset;
4979}
4980
4981static void
57346661 4982dump_ia64_unwind (struct ia64_unw_aux_info *aux)
4d6ed7c8 4983{
57346661 4984 struct ia64_unw_table_entry *tp;
4d6ed7c8 4985 int in_body;
7036c0e1 4986
4d6ed7c8
NC
4987 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4988 {
4989 bfd_vma stamp;
4990 bfd_vma offset;
b34976b6
AM
4991 const unsigned char *dp;
4992 const unsigned char *head;
4993 const char *procname;
4d6ed7c8 4994
57346661
AM
4995 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4996 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4997
4998 fputs ("\n<", stdout);
4999
5000 if (procname)
5001 {
5002 fputs (procname, stdout);
5003
5004 if (offset)
5005 printf ("+%lx", (unsigned long) offset);
5006 }
5007
5008 fputs (">: [", stdout);
5009 print_vma (tp->start.offset, PREFIX_HEX);
5010 fputc ('-', stdout);
5011 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5012 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5013 (unsigned long) (tp->info.offset - aux->seg_base));
5014
1949de15 5015 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5016 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5017
86f55779 5018 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5019 (unsigned) UNW_VER (stamp),
5020 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5021 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5022 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5023 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5024
5025 if (UNW_VER (stamp) != 1)
5026 {
5027 printf ("\tUnknown version.\n");
5028 continue;
5029 }
5030
5031 in_body = 0;
89fac5e3 5032 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5033 dp = unw_decode (dp, in_body, & in_body);
5034 }
5035}
5036
5037static int
d3ba0551 5038slurp_ia64_unwind_table (FILE *file,
57346661 5039 struct ia64_unw_aux_info *aux,
d3ba0551 5040 Elf_Internal_Shdr *sec)
4d6ed7c8 5041{
89fac5e3 5042 unsigned long size, nrelas, i;
d93f0186 5043 Elf_Internal_Phdr *seg;
57346661 5044 struct ia64_unw_table_entry *tep;
c8286bd1 5045 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
5046 Elf_Internal_Rela *rela, *rp;
5047 unsigned char *table, *tp;
5048 Elf_Internal_Sym *sym;
5049 const char *relname;
4d6ed7c8 5050
4d6ed7c8
NC
5051 /* First, find the starting address of the segment that includes
5052 this section: */
5053
5054 if (elf_header.e_phnum)
5055 {
d93f0186 5056 if (! get_program_headers (file))
4d6ed7c8 5057 return 0;
4d6ed7c8 5058
d93f0186
NC
5059 for (seg = program_headers;
5060 seg < program_headers + elf_header.e_phnum;
5061 ++seg)
4d6ed7c8
NC
5062 {
5063 if (seg->p_type != PT_LOAD)
5064 continue;
5065
5066 if (sec->sh_addr >= seg->p_vaddr
5067 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5068 {
5069 aux->seg_base = seg->p_vaddr;
5070 break;
5071 }
5072 }
4d6ed7c8
NC
5073 }
5074
5075 /* Second, build the unwind table from the contents of the unwind section: */
5076 size = sec->sh_size;
c256ffe7 5077 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
a6e9f9df
AM
5078 if (!table)
5079 return 0;
4d6ed7c8 5080
c256ffe7 5081 aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3
RS
5082 tep = aux->table;
5083 for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
4d6ed7c8
NC
5084 {
5085 tep->start.section = SHN_UNDEF;
5086 tep->end.section = SHN_UNDEF;
5087 tep->info.section = SHN_UNDEF;
5088 if (is_32bit_elf)
5089 {
5090 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5091 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5092 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
5093 }
5094 else
5095 {
66543521
AM
5096 tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
5097 tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
5098 tep->info.offset = BYTE_GET ((unsigned char *) tp + 16);
4d6ed7c8
NC
5099 }
5100 tep->start.offset += aux->seg_base;
5101 tep->end.offset += aux->seg_base;
5102 tep->info.offset += aux->seg_base;
5103 }
5104 free (table);
5105
41e92641 5106 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5107 for (relsec = section_headers;
5108 relsec < section_headers + elf_header.e_shnum;
5109 ++relsec)
5110 {
5111 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5112 || relsec->sh_info >= elf_header.e_shnum
5113 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5114 continue;
5115
5116 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5117 & rela, & nrelas))
5118 return 0;
5119
5120 for (rp = rela; rp < rela + nrelas; ++rp)
5121 {
aca88567
NC
5122 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5123 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5124
0112cd26 5125 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5126 {
e5fb9629 5127 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5128 continue;
5129 }
5130
89fac5e3 5131 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5132
89fac5e3 5133 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5134 {
5135 case 0:
5136 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5137 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5138 break;
5139 case 1:
5140 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5141 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5142 break;
5143 case 2:
5144 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5145 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5146 break;
5147 default:
5148 break;
5149 }
5150 }
5151
5152 free (rela);
5153 }
5154
89fac5e3 5155 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5156 return 1;
5157}
5158
5159static int
57346661 5160ia64_process_unwind (FILE *file)
4d6ed7c8 5161{
c8286bd1 5162 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
89fac5e3 5163 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5164 struct ia64_unw_aux_info aux;
f1467e33 5165
4d6ed7c8
NC
5166 memset (& aux, 0, sizeof (aux));
5167
4d6ed7c8
NC
5168 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5169 {
c256ffe7 5170 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5171 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5172 {
5173 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5174 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5175
4fbb74a6 5176 strsec = section_headers + sec->sh_link;
d3ba0551 5177 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5178 1, strsec->sh_size, _("string table"));
5179 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5180 }
5181 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5182 unwcount++;
5183 }
5184
5185 if (!unwcount)
5186 printf (_("\nThere are no unwind sections in this file.\n"));
5187
5188 while (unwcount-- > 0)
5189 {
5190 char *suffix;
5191 size_t len, len2;
5192
5193 for (i = unwstart, sec = section_headers + unwstart;
5194 i < elf_header.e_shnum; ++i, ++sec)
5195 if (sec->sh_type == SHT_IA_64_UNWIND)
5196 {
5197 unwsec = sec;
5198 break;
5199 }
5200
5201 unwstart = i + 1;
5202 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5203
e4b17d5c
L
5204 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5205 {
5206 /* We need to find which section group it is in. */
5207 struct group_list *g = section_headers_groups [i]->root;
5208
5209 for (; g != NULL; g = g->next)
5210 {
4fbb74a6 5211 sec = section_headers + g->section_index;
18bd398b
NC
5212
5213 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5214 break;
e4b17d5c
L
5215 }
5216
5217 if (g == NULL)
5218 i = elf_header.e_shnum;
5219 }
18bd398b 5220 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5221 {
18bd398b 5222 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5223 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5224 suffix = SECTION_NAME (unwsec) + len;
5225 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5226 ++i, ++sec)
18bd398b
NC
5227 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5228 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5229 break;
5230 }
5231 else
5232 {
5233 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5234 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5235 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5236 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5237 suffix = "";
18bd398b 5238 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5239 suffix = SECTION_NAME (unwsec) + len;
5240 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5241 ++i, ++sec)
18bd398b
NC
5242 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5243 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5244 break;
5245 }
5246
5247 if (i == elf_header.e_shnum)
5248 {
5249 printf (_("\nCould not find unwind info section for "));
5250
5251 if (string_table == NULL)
5252 printf ("%d", unwsec->sh_name);
5253 else
3a1a2036 5254 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5255 }
5256 else
4d6ed7c8
NC
5257 {
5258 aux.info_size = sec->sh_size;
5259 aux.info_addr = sec->sh_addr;
c256ffe7 5260 aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
d3ba0551 5261 _("unwind info"));
4d6ed7c8 5262
579f31ac 5263 printf (_("\nUnwind section "));
4d6ed7c8 5264
579f31ac
JJ
5265 if (string_table == NULL)
5266 printf ("%d", unwsec->sh_name);
5267 else
3a1a2036 5268 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5269
579f31ac 5270 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5271 (unsigned long) unwsec->sh_offset,
89fac5e3 5272 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5273
579f31ac 5274 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5275
579f31ac
JJ
5276 if (aux.table_len > 0)
5277 dump_ia64_unwind (& aux);
5278
5279 if (aux.table)
5280 free ((char *) aux.table);
5281 if (aux.info)
5282 free ((char *) aux.info);
5283 aux.table = NULL;
5284 aux.info = NULL;
5285 }
4d6ed7c8 5286 }
4d6ed7c8 5287
4d6ed7c8
NC
5288 if (aux.symtab)
5289 free (aux.symtab);
5290 if (aux.strtab)
5291 free ((char *) aux.strtab);
5292
5293 return 1;
5294}
5295
57346661
AM
5296struct hppa_unw_aux_info
5297 {
5298 struct hppa_unw_table_entry
5299 {
5300 struct absaddr start;
5301 struct absaddr end;
5302 unsigned int Cannot_unwind:1; /* 0 */
5303 unsigned int Millicode:1; /* 1 */
5304 unsigned int Millicode_save_sr0:1; /* 2 */
5305 unsigned int Region_description:2; /* 3..4 */
5306 unsigned int reserved1:1; /* 5 */
5307 unsigned int Entry_SR:1; /* 6 */
5308 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5309 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5310 unsigned int Args_stored:1; /* 16 */
5311 unsigned int Variable_Frame:1; /* 17 */
5312 unsigned int Separate_Package_Body:1; /* 18 */
5313 unsigned int Frame_Extension_Millicode:1; /* 19 */
5314 unsigned int Stack_Overflow_Check:1; /* 20 */
5315 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5316 unsigned int Ada_Region:1; /* 22 */
5317 unsigned int cxx_info:1; /* 23 */
5318 unsigned int cxx_try_catch:1; /* 24 */
5319 unsigned int sched_entry_seq:1; /* 25 */
5320 unsigned int reserved2:1; /* 26 */
5321 unsigned int Save_SP:1; /* 27 */
5322 unsigned int Save_RP:1; /* 28 */
5323 unsigned int Save_MRP_in_frame:1; /* 29 */
5324 unsigned int extn_ptr_defined:1; /* 30 */
5325 unsigned int Cleanup_defined:1; /* 31 */
5326
5327 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5328 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5329 unsigned int Large_frame:1; /* 2 */
5330 unsigned int Pseudo_SP_Set:1; /* 3 */
5331 unsigned int reserved4:1; /* 4 */
5332 unsigned int Total_frame_size:27; /* 5..31 */
5333 }
5334 *table; /* Unwind table. */
5335 unsigned long table_len; /* Length of unwind table. */
5336 bfd_vma seg_base; /* Starting address of segment. */
5337 Elf_Internal_Sym *symtab; /* The symbol table. */
5338 unsigned long nsyms; /* Number of symbols. */
5339 char *strtab; /* The string table. */
5340 unsigned long strtab_size; /* Size of string table. */
5341 };
5342
5343static void
5344dump_hppa_unwind (struct hppa_unw_aux_info *aux)
5345{
57346661
AM
5346 struct hppa_unw_table_entry *tp;
5347
57346661
AM
5348 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5349 {
5350 bfd_vma offset;
5351 const char *procname;
5352
5353 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5354 aux->strtab_size, tp->start, &procname,
5355 &offset);
5356
5357 fputs ("\n<", stdout);
5358
5359 if (procname)
5360 {
5361 fputs (procname, stdout);
5362
5363 if (offset)
5364 printf ("+%lx", (unsigned long) offset);
5365 }
5366
5367 fputs (">: [", stdout);
5368 print_vma (tp->start.offset, PREFIX_HEX);
5369 fputc ('-', stdout);
5370 print_vma (tp->end.offset, PREFIX_HEX);
5371 printf ("]\n\t");
5372
18bd398b
NC
5373#define PF(_m) if (tp->_m) printf (#_m " ");
5374#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5375 PF(Cannot_unwind);
5376 PF(Millicode);
5377 PF(Millicode_save_sr0);
18bd398b 5378 /* PV(Region_description); */
57346661
AM
5379 PF(Entry_SR);
5380 PV(Entry_FR);
5381 PV(Entry_GR);
5382 PF(Args_stored);
5383 PF(Variable_Frame);
5384 PF(Separate_Package_Body);
5385 PF(Frame_Extension_Millicode);
5386 PF(Stack_Overflow_Check);
5387 PF(Two_Instruction_SP_Increment);
5388 PF(Ada_Region);
5389 PF(cxx_info);
5390 PF(cxx_try_catch);
5391 PF(sched_entry_seq);
5392 PF(Save_SP);
5393 PF(Save_RP);
5394 PF(Save_MRP_in_frame);
5395 PF(extn_ptr_defined);
5396 PF(Cleanup_defined);
5397 PF(MPE_XL_interrupt_marker);
5398 PF(HP_UX_interrupt_marker);
5399 PF(Large_frame);
5400 PF(Pseudo_SP_Set);
5401 PV(Total_frame_size);
5402#undef PF
5403#undef PV
5404 }
5405
18bd398b 5406 printf ("\n");
57346661
AM
5407}
5408
5409static int
5410slurp_hppa_unwind_table (FILE *file,
5411 struct hppa_unw_aux_info *aux,
5412 Elf_Internal_Shdr *sec)
5413{
1c0751b2 5414 unsigned long size, unw_ent_size, nentries, nrelas, i;
57346661
AM
5415 Elf_Internal_Phdr *seg;
5416 struct hppa_unw_table_entry *tep;
5417 Elf_Internal_Shdr *relsec;
5418 Elf_Internal_Rela *rela, *rp;
5419 unsigned char *table, *tp;
5420 Elf_Internal_Sym *sym;
5421 const char *relname;
5422
57346661
AM
5423 /* First, find the starting address of the segment that includes
5424 this section. */
5425
5426 if (elf_header.e_phnum)
5427 {
5428 if (! get_program_headers (file))
5429 return 0;
5430
5431 for (seg = program_headers;
5432 seg < program_headers + elf_header.e_phnum;
5433 ++seg)
5434 {
5435 if (seg->p_type != PT_LOAD)
5436 continue;
5437
5438 if (sec->sh_addr >= seg->p_vaddr
5439 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5440 {
5441 aux->seg_base = seg->p_vaddr;
5442 break;
5443 }
5444 }
5445 }
5446
5447 /* Second, build the unwind table from the contents of the unwind
5448 section. */
5449 size = sec->sh_size;
c256ffe7 5450 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
57346661
AM
5451 if (!table)
5452 return 0;
5453
1c0751b2
DA
5454 unw_ent_size = 16;
5455 nentries = size / unw_ent_size;
5456 size = unw_ent_size * nentries;
57346661 5457
1c0751b2 5458 tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5459
1c0751b2 5460 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5461 {
5462 unsigned int tmp1, tmp2;
5463
5464 tep->start.section = SHN_UNDEF;
5465 tep->end.section = SHN_UNDEF;
5466
1c0751b2
DA
5467 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5468 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5469 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5470 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5471
5472 tep->start.offset += aux->seg_base;
5473 tep->end.offset += aux->seg_base;
57346661
AM
5474
5475 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5476 tep->Millicode = (tmp1 >> 30) & 0x1;
5477 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5478 tep->Region_description = (tmp1 >> 27) & 0x3;
5479 tep->reserved1 = (tmp1 >> 26) & 0x1;
5480 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5481 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5482 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5483 tep->Args_stored = (tmp1 >> 15) & 0x1;
5484 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5485 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5486 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5487 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5488 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5489 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5490 tep->cxx_info = (tmp1 >> 8) & 0x1;
5491 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5492 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5493 tep->reserved2 = (tmp1 >> 5) & 0x1;
5494 tep->Save_SP = (tmp1 >> 4) & 0x1;
5495 tep->Save_RP = (tmp1 >> 3) & 0x1;
5496 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5497 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5498 tep->Cleanup_defined = tmp1 & 0x1;
5499
5500 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5501 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5502 tep->Large_frame = (tmp2 >> 29) & 0x1;
5503 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5504 tep->reserved4 = (tmp2 >> 27) & 0x1;
5505 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5506 }
5507 free (table);
5508
5509 /* Third, apply any relocations to the unwind table. */
57346661
AM
5510 for (relsec = section_headers;
5511 relsec < section_headers + elf_header.e_shnum;
5512 ++relsec)
5513 {
5514 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5515 || relsec->sh_info >= elf_header.e_shnum
5516 || section_headers + relsec->sh_info != sec)
57346661
AM
5517 continue;
5518
5519 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5520 & rela, & nrelas))
5521 return 0;
5522
5523 for (rp = rela; rp < rela + nrelas; ++rp)
5524 {
aca88567
NC
5525 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
5526 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
5527
5528 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5529 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5530 {
5531 warn (_("Skipping unexpected relocation type %s\n"), relname);
5532 continue;
5533 }
5534
5535 i = rp->r_offset / unw_ent_size;
5536
89fac5e3 5537 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5538 {
5539 case 0:
5540 aux->table[i].start.section = sym->st_shndx;
5541 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5542 break;
5543 case 1:
5544 aux->table[i].end.section = sym->st_shndx;
5545 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5546 break;
5547 default:
5548 break;
5549 }
5550 }
5551
5552 free (rela);
5553 }
5554
1c0751b2 5555 aux->table_len = nentries;
57346661
AM
5556
5557 return 1;
5558}
5559
5560static int
5561hppa_process_unwind (FILE *file)
5562{
57346661 5563 struct hppa_unw_aux_info aux;
18bd398b
NC
5564 Elf_Internal_Shdr *unwsec = NULL;
5565 Elf_Internal_Shdr *strsec;
5566 Elf_Internal_Shdr *sec;
18bd398b 5567 unsigned long i;
57346661
AM
5568
5569 memset (& aux, 0, sizeof (aux));
5570
c256ffe7
JJ
5571 if (string_table == NULL)
5572 return 1;
57346661
AM
5573
5574 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5575 {
c256ffe7 5576 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5577 && sec->sh_link < elf_header.e_shnum)
57346661
AM
5578 {
5579 aux.nsyms = sec->sh_size / sec->sh_entsize;
5580 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5581
4fbb74a6 5582 strsec = section_headers + sec->sh_link;
57346661 5583 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5584 1, strsec->sh_size, _("string table"));
5585 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5586 }
18bd398b 5587 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5588 unwsec = sec;
5589 }
5590
5591 if (!unwsec)
5592 printf (_("\nThere are no unwind sections in this file.\n"));
5593
5594 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5595 {
18bd398b 5596 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5597 {
57346661
AM
5598 printf (_("\nUnwind section "));
5599 printf (_("'%s'"), SECTION_NAME (sec));
5600
5601 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5602 (unsigned long) sec->sh_offset,
89fac5e3 5603 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5604
5605 slurp_hppa_unwind_table (file, &aux, sec);
5606 if (aux.table_len > 0)
5607 dump_hppa_unwind (&aux);
5608
5609 if (aux.table)
5610 free ((char *) aux.table);
5611 aux.table = NULL;
5612 }
5613 }
5614
5615 if (aux.symtab)
5616 free (aux.symtab);
5617 if (aux.strtab)
5618 free ((char *) aux.strtab);
5619
5620 return 1;
5621}
5622
5623static int
5624process_unwind (FILE *file)
5625{
5626 struct unwind_handler {
5627 int machtype;
5628 int (*handler)(FILE *file);
5629 } handlers[] = {
5630 { EM_IA_64, ia64_process_unwind },
5631 { EM_PARISC, hppa_process_unwind },
5632 { 0, 0 }
5633 };
5634 int i;
5635
5636 if (!do_unwind)
5637 return 1;
5638
5639 for (i = 0; handlers[i].handler != NULL; i++)
5640 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5641 return handlers[i].handler (file);
57346661
AM
5642
5643 printf (_("\nThere are no unwind sections in this file.\n"));
5644 return 1;
5645}
5646
252b5132 5647static void
b2d38a17 5648dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
5649{
5650 switch (entry->d_tag)
5651 {
5652 case DT_MIPS_FLAGS:
5653 if (entry->d_un.d_val == 0)
5654 printf ("NONE\n");
5655 else
5656 {
5657 static const char * opts[] =
5658 {
5659 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5660 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5661 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5662 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5663 "RLD_ORDER_SAFE"
5664 };
5665 unsigned int cnt;
5666 int first = 1;
60bca95a 5667 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
5668 if (entry->d_un.d_val & (1 << cnt))
5669 {
5670 printf ("%s%s", first ? "" : " ", opts[cnt]);
5671 first = 0;
5672 }
5673 puts ("");
5674 }
5675 break;
103f02d3 5676
252b5132 5677 case DT_MIPS_IVERSION:
d79b3d50
NC
5678 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5679 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5680 else
d79b3d50 5681 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5682 break;
103f02d3 5683
252b5132
RH
5684 case DT_MIPS_TIME_STAMP:
5685 {
5686 char timebuf[20];
b34976b6 5687 struct tm *tmp;
50da7a9c 5688
252b5132 5689 time_t time = entry->d_un.d_val;
50da7a9c 5690 tmp = gmtime (&time);
e9e44622
JJ
5691 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5692 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5693 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5694 printf ("Time Stamp: %s\n", timebuf);
5695 }
5696 break;
103f02d3 5697
252b5132
RH
5698 case DT_MIPS_RLD_VERSION:
5699 case DT_MIPS_LOCAL_GOTNO:
5700 case DT_MIPS_CONFLICTNO:
5701 case DT_MIPS_LIBLISTNO:
5702 case DT_MIPS_SYMTABNO:
5703 case DT_MIPS_UNREFEXTNO:
5704 case DT_MIPS_HIPAGENO:
5705 case DT_MIPS_DELTA_CLASS_NO:
5706 case DT_MIPS_DELTA_INSTANCE_NO:
5707 case DT_MIPS_DELTA_RELOC_NO:
5708 case DT_MIPS_DELTA_SYM_NO:
5709 case DT_MIPS_DELTA_CLASSSYM_NO:
5710 case DT_MIPS_COMPACT_SIZE:
5711 printf ("%ld\n", (long) entry->d_un.d_ptr);
5712 break;
103f02d3
UD
5713
5714 default:
0af1713e 5715 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
5716 }
5717}
5718
5719
5720static void
b2d38a17 5721dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
5722{
5723 switch (entry->d_tag)
5724 {
5725 case DT_HP_DLD_FLAGS:
5726 {
5727 static struct
5728 {
5729 long int bit;
b34976b6 5730 const char *str;
5e220199
NC
5731 }
5732 flags[] =
5733 {
5734 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5735 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5736 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5737 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5738 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5739 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5740 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5741 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5742 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5743 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
5744 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
5745 { DT_HP_GST, "HP_GST" },
5746 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
5747 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
5748 { DT_HP_NODELETE, "HP_NODELETE" },
5749 { DT_HP_GROUP, "HP_GROUP" },
5750 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 5751 };
103f02d3 5752 int first = 1;
5e220199 5753 size_t cnt;
f7a99963 5754 bfd_vma val = entry->d_un.d_val;
103f02d3 5755
60bca95a 5756 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 5757 if (val & flags[cnt].bit)
30800947
NC
5758 {
5759 if (! first)
5760 putchar (' ');
5761 fputs (flags[cnt].str, stdout);
5762 first = 0;
5763 val ^= flags[cnt].bit;
5764 }
76da6bbe 5765
103f02d3 5766 if (val != 0 || first)
f7a99963
NC
5767 {
5768 if (! first)
5769 putchar (' ');
5770 print_vma (val, HEX);
5771 }
103f02d3
UD
5772 }
5773 break;
76da6bbe 5774
252b5132 5775 default:
f7a99963
NC
5776 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5777 break;
252b5132 5778 }
35b1837e 5779 putchar ('\n');
252b5132
RH
5780}
5781
ecc51f48 5782static void
b2d38a17 5783dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
5784{
5785 switch (entry->d_tag)
5786 {
0de14b54 5787 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5788 /* First 3 slots reserved. */
ecc51f48
NC
5789 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5790 printf (" -- ");
5791 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5792 break;
5793
5794 default:
5795 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5796 break;
ecc51f48 5797 }
bdf4d63a 5798 putchar ('\n');
ecc51f48
NC
5799}
5800
252b5132 5801static int
b2d38a17 5802get_32bit_dynamic_section (FILE *file)
252b5132 5803{
fb514b26 5804 Elf32_External_Dyn *edyn, *ext;
b34976b6 5805 Elf_Internal_Dyn *entry;
103f02d3 5806
c256ffe7 5807 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5808 _("dynamic section"));
a6e9f9df
AM
5809 if (!edyn)
5810 return 0;
103f02d3 5811
ba2685cc
AM
5812/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5813 might not have the luxury of section headers. Look for the DT_NULL
5814 terminator to determine the number of entries. */
5815 for (ext = edyn, dynamic_nent = 0;
5816 (char *) ext < (char *) edyn + dynamic_size;
5817 ext++)
5818 {
5819 dynamic_nent++;
5820 if (BYTE_GET (ext->d_tag) == DT_NULL)
5821 break;
5822 }
252b5132 5823
c256ffe7 5824 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5825 if (dynamic_section == NULL)
252b5132 5826 {
9ea033b2
NC
5827 error (_("Out of memory\n"));
5828 free (edyn);
5829 return 0;
5830 }
252b5132 5831
fb514b26 5832 for (ext = edyn, entry = dynamic_section;
ba2685cc 5833 entry < dynamic_section + dynamic_nent;
fb514b26 5834 ext++, entry++)
9ea033b2 5835 {
fb514b26
AM
5836 entry->d_tag = BYTE_GET (ext->d_tag);
5837 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5838 }
5839
9ea033b2
NC
5840 free (edyn);
5841
5842 return 1;
5843}
5844
5845static int
b2d38a17 5846get_64bit_dynamic_section (FILE *file)
9ea033b2 5847{
fb514b26 5848 Elf64_External_Dyn *edyn, *ext;
b34976b6 5849 Elf_Internal_Dyn *entry;
103f02d3 5850
c256ffe7 5851 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5852 _("dynamic section"));
a6e9f9df
AM
5853 if (!edyn)
5854 return 0;
103f02d3 5855
ba2685cc
AM
5856/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5857 might not have the luxury of section headers. Look for the DT_NULL
5858 terminator to determine the number of entries. */
5859 for (ext = edyn, dynamic_nent = 0;
5860 (char *) ext < (char *) edyn + dynamic_size;
5861 ext++)
5862 {
5863 dynamic_nent++;
66543521 5864 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5865 break;
5866 }
252b5132 5867
c256ffe7 5868 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5869 if (dynamic_section == NULL)
252b5132
RH
5870 {
5871 error (_("Out of memory\n"));
5872 free (edyn);
5873 return 0;
5874 }
5875
fb514b26 5876 for (ext = edyn, entry = dynamic_section;
ba2685cc 5877 entry < dynamic_section + dynamic_nent;
fb514b26 5878 ext++, entry++)
252b5132 5879 {
66543521
AM
5880 entry->d_tag = BYTE_GET (ext->d_tag);
5881 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5882 }
5883
5884 free (edyn);
5885
9ea033b2
NC
5886 return 1;
5887}
5888
e9e44622
JJ
5889static void
5890print_dynamic_flags (bfd_vma flags)
d1133906 5891{
e9e44622 5892 int first = 1;
13ae64f3 5893
d1133906
NC
5894 while (flags)
5895 {
5896 bfd_vma flag;
5897
5898 flag = flags & - flags;
5899 flags &= ~ flag;
5900
e9e44622
JJ
5901 if (first)
5902 first = 0;
5903 else
5904 putc (' ', stdout);
13ae64f3 5905
d1133906
NC
5906 switch (flag)
5907 {
e9e44622
JJ
5908 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5909 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5910 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5911 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5912 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5913 default: fputs ("unknown", stdout); break;
d1133906
NC
5914 }
5915 }
e9e44622 5916 puts ("");
d1133906
NC
5917}
5918
b2d38a17
NC
5919/* Parse and display the contents of the dynamic section. */
5920
9ea033b2 5921static int
b2d38a17 5922process_dynamic_section (FILE *file)
9ea033b2 5923{
b34976b6 5924 Elf_Internal_Dyn *entry;
9ea033b2
NC
5925
5926 if (dynamic_size == 0)
5927 {
5928 if (do_dynamic)
b2d38a17 5929 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5930
5931 return 1;
5932 }
5933
5934 if (is_32bit_elf)
5935 {
b2d38a17 5936 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5937 return 0;
5938 }
b2d38a17 5939 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5940 return 0;
5941
252b5132
RH
5942 /* Find the appropriate symbol table. */
5943 if (dynamic_symbols == NULL)
5944 {
86dba8ee
AM
5945 for (entry = dynamic_section;
5946 entry < dynamic_section + dynamic_nent;
5947 ++entry)
252b5132 5948 {
c8286bd1 5949 Elf_Internal_Shdr section;
252b5132
RH
5950
5951 if (entry->d_tag != DT_SYMTAB)
5952 continue;
5953
5954 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5955
5956 /* Since we do not know how big the symbol table is,
5957 we default to reading in the entire file (!) and
5958 processing that. This is overkill, I know, but it
e3c8793a 5959 should work. */
d93f0186 5960 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5961
fb52b2f4
NC
5962 if (archive_file_offset != 0)
5963 section.sh_size = archive_file_size - section.sh_offset;
5964 else
5965 {
5966 if (fseek (file, 0, SEEK_END))
591a748a 5967 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
5968
5969 section.sh_size = ftell (file) - section.sh_offset;
5970 }
252b5132 5971
9ea033b2 5972 if (is_32bit_elf)
9ad5cbcf 5973 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5974 else
9ad5cbcf 5975 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5976
9ad5cbcf 5977 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5978 if (num_dynamic_syms < 1)
252b5132
RH
5979 {
5980 error (_("Unable to determine the number of symbols to load\n"));
5981 continue;
5982 }
5983
9ad5cbcf 5984 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5985 }
5986 }
5987
5988 /* Similarly find a string table. */
5989 if (dynamic_strings == NULL)
5990 {
86dba8ee
AM
5991 for (entry = dynamic_section;
5992 entry < dynamic_section + dynamic_nent;
5993 ++entry)
252b5132
RH
5994 {
5995 unsigned long offset;
b34976b6 5996 long str_tab_len;
252b5132
RH
5997
5998 if (entry->d_tag != DT_STRTAB)
5999 continue;
6000
6001 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
6002
6003 /* Since we do not know how big the string table is,
6004 we default to reading in the entire file (!) and
6005 processing that. This is overkill, I know, but it
e3c8793a 6006 should work. */
252b5132 6007
d93f0186 6008 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
6009
6010 if (archive_file_offset != 0)
6011 str_tab_len = archive_file_size - offset;
6012 else
6013 {
6014 if (fseek (file, 0, SEEK_END))
6015 error (_("Unable to seek to end of file\n"));
6016 str_tab_len = ftell (file) - offset;
6017 }
252b5132
RH
6018
6019 if (str_tab_len < 1)
6020 {
6021 error
6022 (_("Unable to determine the length of the dynamic string table\n"));
6023 continue;
6024 }
6025
c256ffe7 6026 dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
d3ba0551 6027 _("dynamic string table"));
d79b3d50 6028 dynamic_strings_length = str_tab_len;
252b5132
RH
6029 break;
6030 }
6031 }
6032
6033 /* And find the syminfo section if available. */
6034 if (dynamic_syminfo == NULL)
6035 {
3e8bba36 6036 unsigned long syminsz = 0;
252b5132 6037
86dba8ee
AM
6038 for (entry = dynamic_section;
6039 entry < dynamic_section + dynamic_nent;
6040 ++entry)
252b5132
RH
6041 {
6042 if (entry->d_tag == DT_SYMINENT)
6043 {
6044 /* Note: these braces are necessary to avoid a syntax
6045 error from the SunOS4 C compiler. */
6046 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
6047 }
6048 else if (entry->d_tag == DT_SYMINSZ)
6049 syminsz = entry->d_un.d_val;
6050 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
6051 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
6052 syminsz);
252b5132
RH
6053 }
6054
6055 if (dynamic_syminfo_offset != 0 && syminsz != 0)
6056 {
86dba8ee 6057 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 6058 Elf_Internal_Syminfo *syminfo;
252b5132
RH
6059
6060 /* There is a syminfo section. Read the data. */
c256ffe7
JJ
6061 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
6062 syminsz, _("symbol information"));
a6e9f9df
AM
6063 if (!extsyminfo)
6064 return 0;
252b5132 6065
d3ba0551 6066 dynamic_syminfo = malloc (syminsz);
252b5132
RH
6067 if (dynamic_syminfo == NULL)
6068 {
6069 error (_("Out of memory\n"));
6070 return 0;
6071 }
6072
6073 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
6074 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
6075 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
6076 ++syminfo, ++extsym)
252b5132 6077 {
86dba8ee
AM
6078 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
6079 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
6080 }
6081
6082 free (extsyminfo);
6083 }
6084 }
6085
6086 if (do_dynamic && dynamic_addr)
86dba8ee
AM
6087 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
6088 dynamic_addr, dynamic_nent);
252b5132
RH
6089 if (do_dynamic)
6090 printf (_(" Tag Type Name/Value\n"));
6091
86dba8ee
AM
6092 for (entry = dynamic_section;
6093 entry < dynamic_section + dynamic_nent;
6094 entry++)
252b5132
RH
6095 {
6096 if (do_dynamic)
f7a99963 6097 {
b34976b6 6098 const char *dtype;
e699b9ff 6099
f7a99963
NC
6100 putchar (' ');
6101 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
6102 dtype = get_dynamic_type (entry->d_tag);
6103 printf (" (%s)%*s", dtype,
6104 ((is_32bit_elf ? 27 : 19)
6105 - (int) strlen (dtype)),
f7a99963
NC
6106 " ");
6107 }
252b5132
RH
6108
6109 switch (entry->d_tag)
6110 {
d1133906
NC
6111 case DT_FLAGS:
6112 if (do_dynamic)
e9e44622 6113 print_dynamic_flags (entry->d_un.d_val);
d1133906 6114 break;
76da6bbe 6115
252b5132
RH
6116 case DT_AUXILIARY:
6117 case DT_FILTER:
019148e4
L
6118 case DT_CONFIG:
6119 case DT_DEPAUDIT:
6120 case DT_AUDIT:
252b5132
RH
6121 if (do_dynamic)
6122 {
019148e4 6123 switch (entry->d_tag)
b34976b6 6124 {
019148e4
L
6125 case DT_AUXILIARY:
6126 printf (_("Auxiliary library"));
6127 break;
6128
6129 case DT_FILTER:
6130 printf (_("Filter library"));
6131 break;
6132
b34976b6 6133 case DT_CONFIG:
019148e4
L
6134 printf (_("Configuration file"));
6135 break;
6136
6137 case DT_DEPAUDIT:
6138 printf (_("Dependency audit library"));
6139 break;
6140
6141 case DT_AUDIT:
6142 printf (_("Audit library"));
6143 break;
6144 }
252b5132 6145
d79b3d50
NC
6146 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6147 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6148 else
f7a99963
NC
6149 {
6150 printf (": ");
6151 print_vma (entry->d_un.d_val, PREFIX_HEX);
6152 putchar ('\n');
6153 }
252b5132
RH
6154 }
6155 break;
6156
dcefbbbd 6157 case DT_FEATURE:
252b5132
RH
6158 if (do_dynamic)
6159 {
6160 printf (_("Flags:"));
86f55779 6161
252b5132
RH
6162 if (entry->d_un.d_val == 0)
6163 printf (_(" None\n"));
6164 else
6165 {
6166 unsigned long int val = entry->d_un.d_val;
86f55779 6167
252b5132
RH
6168 if (val & DTF_1_PARINIT)
6169 {
6170 printf (" PARINIT");
6171 val ^= DTF_1_PARINIT;
6172 }
dcefbbbd
L
6173 if (val & DTF_1_CONFEXP)
6174 {
6175 printf (" CONFEXP");
6176 val ^= DTF_1_CONFEXP;
6177 }
252b5132
RH
6178 if (val != 0)
6179 printf (" %lx", val);
6180 puts ("");
6181 }
6182 }
6183 break;
6184
6185 case DT_POSFLAG_1:
6186 if (do_dynamic)
6187 {
6188 printf (_("Flags:"));
86f55779 6189
252b5132
RH
6190 if (entry->d_un.d_val == 0)
6191 printf (_(" None\n"));
6192 else
6193 {
6194 unsigned long int val = entry->d_un.d_val;
86f55779 6195
252b5132
RH
6196 if (val & DF_P1_LAZYLOAD)
6197 {
6198 printf (" LAZYLOAD");
6199 val ^= DF_P1_LAZYLOAD;
6200 }
6201 if (val & DF_P1_GROUPPERM)
6202 {
6203 printf (" GROUPPERM");
6204 val ^= DF_P1_GROUPPERM;
6205 }
6206 if (val != 0)
6207 printf (" %lx", val);
6208 puts ("");
6209 }
6210 }
6211 break;
6212
6213 case DT_FLAGS_1:
6214 if (do_dynamic)
6215 {
6216 printf (_("Flags:"));
6217 if (entry->d_un.d_val == 0)
6218 printf (_(" None\n"));
6219 else
6220 {
6221 unsigned long int val = entry->d_un.d_val;
86f55779 6222
252b5132
RH
6223 if (val & DF_1_NOW)
6224 {
6225 printf (" NOW");
6226 val ^= DF_1_NOW;
6227 }
6228 if (val & DF_1_GLOBAL)
6229 {
6230 printf (" GLOBAL");
6231 val ^= DF_1_GLOBAL;
6232 }
6233 if (val & DF_1_GROUP)
6234 {
6235 printf (" GROUP");
6236 val ^= DF_1_GROUP;
6237 }
6238 if (val & DF_1_NODELETE)
6239 {
6240 printf (" NODELETE");
6241 val ^= DF_1_NODELETE;
6242 }
6243 if (val & DF_1_LOADFLTR)
6244 {
6245 printf (" LOADFLTR");
6246 val ^= DF_1_LOADFLTR;
6247 }
6248 if (val & DF_1_INITFIRST)
6249 {
6250 printf (" INITFIRST");
6251 val ^= DF_1_INITFIRST;
6252 }
6253 if (val & DF_1_NOOPEN)
6254 {
6255 printf (" NOOPEN");
6256 val ^= DF_1_NOOPEN;
6257 }
6258 if (val & DF_1_ORIGIN)
6259 {
6260 printf (" ORIGIN");
6261 val ^= DF_1_ORIGIN;
6262 }
6263 if (val & DF_1_DIRECT)
6264 {
6265 printf (" DIRECT");
6266 val ^= DF_1_DIRECT;
6267 }
6268 if (val & DF_1_TRANS)
6269 {
6270 printf (" TRANS");
6271 val ^= DF_1_TRANS;
6272 }
6273 if (val & DF_1_INTERPOSE)
6274 {
6275 printf (" INTERPOSE");
6276 val ^= DF_1_INTERPOSE;
6277 }
f7db6139 6278 if (val & DF_1_NODEFLIB)
dcefbbbd 6279 {
f7db6139
L
6280 printf (" NODEFLIB");
6281 val ^= DF_1_NODEFLIB;
dcefbbbd
L
6282 }
6283 if (val & DF_1_NODUMP)
6284 {
6285 printf (" NODUMP");
6286 val ^= DF_1_NODUMP;
6287 }
6288 if (val & DF_1_CONLFAT)
6289 {
6290 printf (" CONLFAT");
6291 val ^= DF_1_CONLFAT;
6292 }
252b5132
RH
6293 if (val != 0)
6294 printf (" %lx", val);
6295 puts ("");
6296 }
6297 }
6298 break;
6299
6300 case DT_PLTREL:
566b0d53 6301 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6302 if (do_dynamic)
6303 puts (get_dynamic_type (entry->d_un.d_val));
6304 break;
6305
6306 case DT_NULL :
6307 case DT_NEEDED :
6308 case DT_PLTGOT :
6309 case DT_HASH :
6310 case DT_STRTAB :
6311 case DT_SYMTAB :
6312 case DT_RELA :
6313 case DT_INIT :
6314 case DT_FINI :
6315 case DT_SONAME :
6316 case DT_RPATH :
6317 case DT_SYMBOLIC:
6318 case DT_REL :
6319 case DT_DEBUG :
6320 case DT_TEXTREL :
6321 case DT_JMPREL :
019148e4 6322 case DT_RUNPATH :
252b5132
RH
6323 dynamic_info[entry->d_tag] = entry->d_un.d_val;
6324
6325 if (do_dynamic)
6326 {
b34976b6 6327 char *name;
252b5132 6328
d79b3d50
NC
6329 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6330 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6331 else
d79b3d50 6332 name = NULL;
252b5132
RH
6333
6334 if (name)
6335 {
6336 switch (entry->d_tag)
6337 {
6338 case DT_NEEDED:
6339 printf (_("Shared library: [%s]"), name);
6340
18bd398b 6341 if (streq (name, program_interpreter))
f7a99963 6342 printf (_(" program interpreter"));
252b5132
RH
6343 break;
6344
6345 case DT_SONAME:
f7a99963 6346 printf (_("Library soname: [%s]"), name);
252b5132
RH
6347 break;
6348
6349 case DT_RPATH:
f7a99963 6350 printf (_("Library rpath: [%s]"), name);
252b5132
RH
6351 break;
6352
019148e4
L
6353 case DT_RUNPATH:
6354 printf (_("Library runpath: [%s]"), name);
6355 break;
6356
252b5132 6357 default:
f7a99963
NC
6358 print_vma (entry->d_un.d_val, PREFIX_HEX);
6359 break;
252b5132
RH
6360 }
6361 }
6362 else
f7a99963
NC
6363 print_vma (entry->d_un.d_val, PREFIX_HEX);
6364
6365 putchar ('\n');
252b5132
RH
6366 }
6367 break;
6368
6369 case DT_PLTRELSZ:
6370 case DT_RELASZ :
6371 case DT_STRSZ :
6372 case DT_RELSZ :
6373 case DT_RELAENT :
6374 case DT_SYMENT :
6375 case DT_RELENT :
566b0d53 6376 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6377 case DT_PLTPADSZ:
6378 case DT_MOVEENT :
6379 case DT_MOVESZ :
6380 case DT_INIT_ARRAYSZ:
6381 case DT_FINI_ARRAYSZ:
047b2264
JJ
6382 case DT_GNU_CONFLICTSZ:
6383 case DT_GNU_LIBLISTSZ:
252b5132 6384 if (do_dynamic)
f7a99963
NC
6385 {
6386 print_vma (entry->d_un.d_val, UNSIGNED);
6387 printf (" (bytes)\n");
6388 }
252b5132
RH
6389 break;
6390
6391 case DT_VERDEFNUM:
6392 case DT_VERNEEDNUM:
6393 case DT_RELACOUNT:
6394 case DT_RELCOUNT:
6395 if (do_dynamic)
f7a99963
NC
6396 {
6397 print_vma (entry->d_un.d_val, UNSIGNED);
6398 putchar ('\n');
6399 }
252b5132
RH
6400 break;
6401
6402 case DT_SYMINSZ:
6403 case DT_SYMINENT:
6404 case DT_SYMINFO:
6405 case DT_USED:
6406 case DT_INIT_ARRAY:
6407 case DT_FINI_ARRAY:
6408 if (do_dynamic)
6409 {
d79b3d50
NC
6410 if (entry->d_tag == DT_USED
6411 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6412 {
d79b3d50 6413 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6414
b34976b6 6415 if (*name)
252b5132
RH
6416 {
6417 printf (_("Not needed object: [%s]\n"), name);
6418 break;
6419 }
6420 }
103f02d3 6421
f7a99963
NC
6422 print_vma (entry->d_un.d_val, PREFIX_HEX);
6423 putchar ('\n');
252b5132
RH
6424 }
6425 break;
6426
6427 case DT_BIND_NOW:
6428 /* The value of this entry is ignored. */
35b1837e
AM
6429 if (do_dynamic)
6430 putchar ('\n');
252b5132 6431 break;
103f02d3 6432
047b2264
JJ
6433 case DT_GNU_PRELINKED:
6434 if (do_dynamic)
6435 {
b34976b6 6436 struct tm *tmp;
047b2264
JJ
6437 time_t time = entry->d_un.d_val;
6438
6439 tmp = gmtime (&time);
6440 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6441 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6442 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6443
6444 }
6445 break;
6446
fdc90cb4
JJ
6447 case DT_GNU_HASH:
6448 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
6449 if (do_dynamic)
6450 {
6451 print_vma (entry->d_un.d_val, PREFIX_HEX);
6452 putchar ('\n');
6453 }
6454 break;
6455
252b5132
RH
6456 default:
6457 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6458 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6459 entry->d_un.d_val;
6460
6461 if (do_dynamic)
6462 {
6463 switch (elf_header.e_machine)
6464 {
6465 case EM_MIPS:
4fe85591 6466 case EM_MIPS_RS3_LE:
b2d38a17 6467 dynamic_section_mips_val (entry);
252b5132 6468 break;
103f02d3 6469 case EM_PARISC:
b2d38a17 6470 dynamic_section_parisc_val (entry);
103f02d3 6471 break;
ecc51f48 6472 case EM_IA_64:
b2d38a17 6473 dynamic_section_ia64_val (entry);
ecc51f48 6474 break;
252b5132 6475 default:
f7a99963
NC
6476 print_vma (entry->d_un.d_val, PREFIX_HEX);
6477 putchar ('\n');
252b5132
RH
6478 }
6479 }
6480 break;
6481 }
6482 }
6483
6484 return 1;
6485}
6486
6487static char *
d3ba0551 6488get_ver_flags (unsigned int flags)
252b5132 6489{
b34976b6 6490 static char buff[32];
252b5132
RH
6491
6492 buff[0] = 0;
6493
6494 if (flags == 0)
6495 return _("none");
6496
6497 if (flags & VER_FLG_BASE)
6498 strcat (buff, "BASE ");
6499
6500 if (flags & VER_FLG_WEAK)
6501 {
6502 if (flags & VER_FLG_BASE)
6503 strcat (buff, "| ");
6504
6505 strcat (buff, "WEAK ");
6506 }
6507
6508 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6509 strcat (buff, "| <unknown>");
6510
6511 return buff;
6512}
6513
6514/* Display the contents of the version sections. */
6515static int
d3ba0551 6516process_version_sections (FILE *file)
252b5132 6517{
b34976b6
AM
6518 Elf_Internal_Shdr *section;
6519 unsigned i;
6520 int found = 0;
252b5132
RH
6521
6522 if (! do_version)
6523 return 1;
6524
6525 for (i = 0, section = section_headers;
6526 i < elf_header.e_shnum;
b34976b6 6527 i++, section++)
252b5132
RH
6528 {
6529 switch (section->sh_type)
6530 {
6531 case SHT_GNU_verdef:
6532 {
b34976b6
AM
6533 Elf_External_Verdef *edefs;
6534 unsigned int idx;
6535 unsigned int cnt;
54806181 6536 char *endbuf;
252b5132
RH
6537
6538 found = 1;
6539
6540 printf
72de5009 6541 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
6542 SECTION_NAME (section), section->sh_info);
6543
6544 printf (_(" Addr: 0x"));
6545 printf_vma (section->sh_addr);
72de5009 6546 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6547 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
6548 section->sh_link < elf_header.e_shnum
6549 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 6550 : "<corrupt>");
252b5132 6551
c256ffe7
JJ
6552 edefs = get_data (NULL, file, section->sh_offset, 1,
6553 section->sh_size,
d3ba0551 6554 _("version definition section"));
54806181 6555 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
6556 if (!edefs)
6557 break;
252b5132 6558
b34976b6 6559 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6560 {
b34976b6
AM
6561 char *vstart;
6562 Elf_External_Verdef *edef;
6563 Elf_Internal_Verdef ent;
6564 Elf_External_Verdaux *eaux;
6565 Elf_Internal_Verdaux aux;
6566 int j;
6567 int isum;
103f02d3 6568
252b5132 6569 vstart = ((char *) edefs) + idx;
54806181
AM
6570 if (vstart + sizeof (*edef) > endbuf)
6571 break;
252b5132
RH
6572
6573 edef = (Elf_External_Verdef *) vstart;
6574
6575 ent.vd_version = BYTE_GET (edef->vd_version);
6576 ent.vd_flags = BYTE_GET (edef->vd_flags);
6577 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6578 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6579 ent.vd_hash = BYTE_GET (edef->vd_hash);
6580 ent.vd_aux = BYTE_GET (edef->vd_aux);
6581 ent.vd_next = BYTE_GET (edef->vd_next);
6582
6583 printf (_(" %#06x: Rev: %d Flags: %s"),
6584 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6585
6586 printf (_(" Index: %d Cnt: %d "),
6587 ent.vd_ndx, ent.vd_cnt);
6588
6589 vstart += ent.vd_aux;
6590
6591 eaux = (Elf_External_Verdaux *) vstart;
6592
6593 aux.vda_name = BYTE_GET (eaux->vda_name);
6594 aux.vda_next = BYTE_GET (eaux->vda_next);
6595
d79b3d50
NC
6596 if (VALID_DYNAMIC_NAME (aux.vda_name))
6597 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6598 else
6599 printf (_("Name index: %ld\n"), aux.vda_name);
6600
6601 isum = idx + ent.vd_aux;
6602
b34976b6 6603 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6604 {
6605 isum += aux.vda_next;
6606 vstart += aux.vda_next;
6607
6608 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
6609 if (vstart + sizeof (*eaux) > endbuf)
6610 break;
252b5132
RH
6611
6612 aux.vda_name = BYTE_GET (eaux->vda_name);
6613 aux.vda_next = BYTE_GET (eaux->vda_next);
6614
d79b3d50 6615 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6616 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6617 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6618 else
6619 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6620 isum, j, aux.vda_name);
6621 }
54806181
AM
6622 if (j < ent.vd_cnt)
6623 printf (_(" Version def aux past end of section\n"));
252b5132
RH
6624
6625 idx += ent.vd_next;
6626 }
54806181
AM
6627 if (cnt < section->sh_info)
6628 printf (_(" Version definition past end of section\n"));
252b5132
RH
6629
6630 free (edefs);
6631 }
6632 break;
103f02d3 6633
252b5132
RH
6634 case SHT_GNU_verneed:
6635 {
b34976b6
AM
6636 Elf_External_Verneed *eneed;
6637 unsigned int idx;
6638 unsigned int cnt;
54806181 6639 char *endbuf;
252b5132
RH
6640
6641 found = 1;
6642
72de5009 6643 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
6644 SECTION_NAME (section), section->sh_info);
6645
6646 printf (_(" Addr: 0x"));
6647 printf_vma (section->sh_addr);
72de5009 6648 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6649 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
6650 section->sh_link < elf_header.e_shnum
6651 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 6652 : "<corrupt>");
252b5132 6653
c256ffe7
JJ
6654 eneed = get_data (NULL, file, section->sh_offset, 1,
6655 section->sh_size,
d3ba0551 6656 _("version need section"));
54806181 6657 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
6658 if (!eneed)
6659 break;
252b5132
RH
6660
6661 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6662 {
b34976b6
AM
6663 Elf_External_Verneed *entry;
6664 Elf_Internal_Verneed ent;
6665 int j;
6666 int isum;
6667 char *vstart;
252b5132
RH
6668
6669 vstart = ((char *) eneed) + idx;
54806181
AM
6670 if (vstart + sizeof (*entry) > endbuf)
6671 break;
252b5132
RH
6672
6673 entry = (Elf_External_Verneed *) vstart;
6674
6675 ent.vn_version = BYTE_GET (entry->vn_version);
6676 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6677 ent.vn_file = BYTE_GET (entry->vn_file);
6678 ent.vn_aux = BYTE_GET (entry->vn_aux);
6679 ent.vn_next = BYTE_GET (entry->vn_next);
6680
6681 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6682
d79b3d50
NC
6683 if (VALID_DYNAMIC_NAME (ent.vn_file))
6684 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6685 else
6686 printf (_(" File: %lx"), ent.vn_file);
6687
6688 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6689
6690 vstart += ent.vn_aux;
6691
6692 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6693 {
b34976b6
AM
6694 Elf_External_Vernaux *eaux;
6695 Elf_Internal_Vernaux aux;
252b5132 6696
54806181
AM
6697 if (vstart + sizeof (*eaux) > endbuf)
6698 break;
252b5132
RH
6699 eaux = (Elf_External_Vernaux *) vstart;
6700
6701 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6702 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6703 aux.vna_other = BYTE_GET (eaux->vna_other);
6704 aux.vna_name = BYTE_GET (eaux->vna_name);
6705 aux.vna_next = BYTE_GET (eaux->vna_next);
6706
d79b3d50 6707 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6708 printf (_(" %#06x: Name: %s"),
d79b3d50 6709 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6710 else
ecc2063b 6711 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6712 isum, aux.vna_name);
6713
6714 printf (_(" Flags: %s Version: %d\n"),
6715 get_ver_flags (aux.vna_flags), aux.vna_other);
6716
6717 isum += aux.vna_next;
6718 vstart += aux.vna_next;
6719 }
54806181
AM
6720 if (j < ent.vn_cnt)
6721 printf (_(" Version need aux past end of section\n"));
252b5132
RH
6722
6723 idx += ent.vn_next;
6724 }
54806181
AM
6725 if (cnt < section->sh_info)
6726 printf (_(" Version need past end of section\n"));
103f02d3 6727
252b5132
RH
6728 free (eneed);
6729 }
6730 break;
6731
6732 case SHT_GNU_versym:
6733 {
b34976b6
AM
6734 Elf_Internal_Shdr *link_section;
6735 int total;
6736 int cnt;
6737 unsigned char *edata;
6738 unsigned short *data;
6739 char *strtab;
6740 Elf_Internal_Sym *symbols;
6741 Elf_Internal_Shdr *string_sec;
d3ba0551 6742 long off;
252b5132 6743
4fbb74a6 6744 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6745 break;
6746
4fbb74a6 6747 link_section = section_headers + section->sh_link;
08d8fa11 6748 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 6749
4fbb74a6 6750 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6751 break;
6752
252b5132
RH
6753 found = 1;
6754
9ad5cbcf 6755 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6756
4fbb74a6 6757 string_sec = section_headers + link_section->sh_link;
252b5132 6758
c256ffe7 6759 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 6760 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6761 if (!strtab)
6762 break;
252b5132
RH
6763
6764 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6765 SECTION_NAME (section), total);
6766
6767 printf (_(" Addr: "));
6768 printf_vma (section->sh_addr);
72de5009 6769 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6770 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6771 SECTION_NAME (link_section));
6772
d3ba0551
AM
6773 off = offset_from_vma (file,
6774 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6775 total * sizeof (short));
c256ffe7 6776 edata = get_data (NULL, file, off, total, sizeof (short),
d3ba0551 6777 _("version symbol data"));
a6e9f9df
AM
6778 if (!edata)
6779 {
6780 free (strtab);
6781 break;
6782 }
252b5132 6783
c256ffe7 6784 data = cmalloc (total, sizeof (short));
252b5132
RH
6785
6786 for (cnt = total; cnt --;)
b34976b6
AM
6787 data[cnt] = byte_get (edata + cnt * sizeof (short),
6788 sizeof (short));
252b5132
RH
6789
6790 free (edata);
6791
6792 for (cnt = 0; cnt < total; cnt += 4)
6793 {
6794 int j, nn;
00d93f34 6795 int check_def, check_need;
b34976b6 6796 char *name;
252b5132
RH
6797
6798 printf (" %03x:", cnt);
6799
6800 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6801 switch (data[cnt + j])
252b5132
RH
6802 {
6803 case 0:
6804 fputs (_(" 0 (*local*) "), stdout);
6805 break;
6806
6807 case 1:
6808 fputs (_(" 1 (*global*) "), stdout);
6809 break;
6810
6811 default:
b34976b6
AM
6812 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6813 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6814
00d93f34
JJ
6815 check_def = 1;
6816 check_need = 1;
4fbb74a6
AM
6817 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
6818 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 6819 != SHT_NOBITS)
252b5132 6820 {
b34976b6 6821 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6822 check_def = 0;
6823 else
6824 check_need = 0;
252b5132 6825 }
00d93f34
JJ
6826
6827 if (check_need
b34976b6 6828 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6829 {
b34976b6
AM
6830 Elf_Internal_Verneed ivn;
6831 unsigned long offset;
252b5132 6832
d93f0186
NC
6833 offset = offset_from_vma
6834 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6835 sizeof (Elf_External_Verneed));
252b5132 6836
b34976b6 6837 do
252b5132 6838 {
b34976b6
AM
6839 Elf_Internal_Vernaux ivna;
6840 Elf_External_Verneed evn;
6841 Elf_External_Vernaux evna;
6842 unsigned long a_off;
252b5132 6843
c256ffe7 6844 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6845 _("version need"));
252b5132
RH
6846
6847 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6848 ivn.vn_next = BYTE_GET (evn.vn_next);
6849
6850 a_off = offset + ivn.vn_aux;
6851
6852 do
6853 {
a6e9f9df 6854 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6855 1, _("version need aux (2)"));
252b5132
RH
6856
6857 ivna.vna_next = BYTE_GET (evna.vna_next);
6858 ivna.vna_other = BYTE_GET (evna.vna_other);
6859
6860 a_off += ivna.vna_next;
6861 }
b34976b6 6862 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6863 && ivna.vna_next != 0);
6864
b34976b6 6865 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6866 {
6867 ivna.vna_name = BYTE_GET (evna.vna_name);
6868
54806181
AM
6869 if (ivna.vna_name >= string_sec->sh_size)
6870 name = _("*invalid*");
6871 else
6872 name = strtab + ivna.vna_name;
252b5132 6873 nn += printf ("(%s%-*s",
16062207
ILT
6874 name,
6875 12 - (int) strlen (name),
252b5132 6876 ")");
00d93f34 6877 check_def = 0;
252b5132
RH
6878 break;
6879 }
6880
6881 offset += ivn.vn_next;
6882 }
6883 while (ivn.vn_next);
6884 }
00d93f34 6885
b34976b6
AM
6886 if (check_def && data[cnt + j] != 0x8001
6887 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6888 {
b34976b6
AM
6889 Elf_Internal_Verdef ivd;
6890 Elf_External_Verdef evd;
6891 unsigned long offset;
252b5132 6892
d93f0186
NC
6893 offset = offset_from_vma
6894 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6895 sizeof evd);
252b5132
RH
6896
6897 do
6898 {
c256ffe7 6899 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6900 _("version def"));
252b5132
RH
6901
6902 ivd.vd_next = BYTE_GET (evd.vd_next);
6903 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6904
6905 offset += ivd.vd_next;
6906 }
b34976b6 6907 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6908 && ivd.vd_next != 0);
6909
b34976b6 6910 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6911 {
b34976b6
AM
6912 Elf_External_Verdaux evda;
6913 Elf_Internal_Verdaux ivda;
252b5132
RH
6914
6915 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6916
a6e9f9df
AM
6917 get_data (&evda, file,
6918 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6919 sizeof (evda), 1,
6920 _("version def aux"));
252b5132
RH
6921
6922 ivda.vda_name = BYTE_GET (evda.vda_name);
6923
54806181
AM
6924 if (ivda.vda_name >= string_sec->sh_size)
6925 name = _("*invalid*");
6926 else
6927 name = strtab + ivda.vda_name;
252b5132 6928 nn += printf ("(%s%-*s",
16062207
ILT
6929 name,
6930 12 - (int) strlen (name),
252b5132
RH
6931 ")");
6932 }
6933 }
6934
6935 if (nn < 18)
6936 printf ("%*c", 18 - nn, ' ');
6937 }
6938
6939 putchar ('\n');
6940 }
6941
6942 free (data);
6943 free (strtab);
6944 free (symbols);
6945 }
6946 break;
103f02d3 6947
252b5132
RH
6948 default:
6949 break;
6950 }
6951 }
6952
6953 if (! found)
6954 printf (_("\nNo version information found in this file.\n"));
6955
6956 return 1;
6957}
6958
d1133906 6959static const char *
d3ba0551 6960get_symbol_binding (unsigned int binding)
252b5132 6961{
b34976b6 6962 static char buff[32];
252b5132
RH
6963
6964 switch (binding)
6965 {
b34976b6
AM
6966 case STB_LOCAL: return "LOCAL";
6967 case STB_GLOBAL: return "GLOBAL";
6968 case STB_WEAK: return "WEAK";
252b5132
RH
6969 default:
6970 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
6971 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
6972 binding);
252b5132 6973 else if (binding >= STB_LOOS && binding <= STB_HIOS)
e9e44622 6974 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
252b5132 6975 else
e9e44622 6976 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
6977 return buff;
6978 }
6979}
6980
d1133906 6981static const char *
d3ba0551 6982get_symbol_type (unsigned int type)
252b5132 6983{
b34976b6 6984 static char buff[32];
252b5132
RH
6985
6986 switch (type)
6987 {
b34976b6
AM
6988 case STT_NOTYPE: return "NOTYPE";
6989 case STT_OBJECT: return "OBJECT";
6990 case STT_FUNC: return "FUNC";
6991 case STT_SECTION: return "SECTION";
6992 case STT_FILE: return "FILE";
6993 case STT_COMMON: return "COMMON";
6994 case STT_TLS: return "TLS";
15ab5209
DB
6995 case STT_RELC: return "RELC";
6996 case STT_SRELC: return "SRELC";
252b5132
RH
6997 default:
6998 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6999 {
7000 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
7001 return "THUMB_FUNC";
7002
351b4b40 7003 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
7004 return "REGISTER";
7005
7006 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
7007 return "PARISC_MILLI";
7008
e9e44622 7009 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 7010 }
252b5132 7011 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
7012 {
7013 if (elf_header.e_machine == EM_PARISC)
7014 {
7015 if (type == STT_HP_OPAQUE)
7016 return "HP_OPAQUE";
7017 if (type == STT_HP_STUB)
7018 return "HP_STUB";
7019 }
7020
e9e44622 7021 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 7022 }
252b5132 7023 else
e9e44622 7024 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
7025 return buff;
7026 }
7027}
7028
d1133906 7029static const char *
d3ba0551 7030get_symbol_visibility (unsigned int visibility)
d1133906
NC
7031{
7032 switch (visibility)
7033 {
b34976b6
AM
7034 case STV_DEFAULT: return "DEFAULT";
7035 case STV_INTERNAL: return "INTERNAL";
7036 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
7037 case STV_PROTECTED: return "PROTECTED";
7038 default: abort ();
7039 }
7040}
7041
5e2b0d47
NC
7042static const char *
7043get_mips_symbol_other (unsigned int other)
7044{
7045 switch (other)
7046 {
7047 case STO_OPTIONAL: return "OPTIONAL";
7048 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
7049 case STO_MIPS_PLT: return "MIPS PLT";
7050 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
7051 default: return NULL;
7052 }
7053}
7054
7055static const char *
7056get_symbol_other (unsigned int other)
7057{
7058 const char * result = NULL;
7059 static char buff [32];
7060
7061 if (other == 0)
7062 return "";
7063
7064 switch (elf_header.e_machine)
7065 {
7066 case EM_MIPS:
7067 result = get_mips_symbol_other (other);
7068 default:
7069 break;
7070 }
7071
7072 if (result)
7073 return result;
7074
7075 snprintf (buff, sizeof buff, _("<other>: %x"), other);
7076 return buff;
7077}
7078
d1133906 7079static const char *
d3ba0551 7080get_symbol_index_type (unsigned int type)
252b5132 7081{
b34976b6 7082 static char buff[32];
5cf1065c 7083
252b5132
RH
7084 switch (type)
7085 {
b34976b6
AM
7086 case SHN_UNDEF: return "UND";
7087 case SHN_ABS: return "ABS";
7088 case SHN_COMMON: return "COM";
252b5132 7089 default:
9ce701e2
L
7090 if (type == SHN_IA_64_ANSI_COMMON
7091 && elf_header.e_machine == EM_IA_64
7092 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
7093 return "ANSI_COM";
3b22753a
L
7094 else if (elf_header.e_machine == EM_X86_64
7095 && type == SHN_X86_64_LCOMMON)
7096 return "LARGE_COM";
172553c7
TS
7097 else if (type == SHN_MIPS_SCOMMON
7098 && elf_header.e_machine == EM_MIPS)
7099 return "SCOM";
7100 else if (type == SHN_MIPS_SUNDEFINED
7101 && elf_header.e_machine == EM_MIPS)
7102 return "SUND";
9ce701e2 7103 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 7104 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 7105 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
7106 sprintf (buff, "OS [0x%04x]", type & 0xffff);
7107 else if (type >= SHN_LORESERVE)
7108 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 7109 else
232e7cb8 7110 sprintf (buff, "%3d", type);
5cf1065c 7111 break;
252b5132 7112 }
5cf1065c
NC
7113
7114 return buff;
252b5132
RH
7115}
7116
66543521
AM
7117static bfd_vma *
7118get_dynamic_data (FILE *file, unsigned int number, unsigned int ent_size)
252b5132 7119{
b34976b6 7120 unsigned char *e_data;
66543521 7121 bfd_vma *i_data;
252b5132 7122
c256ffe7 7123 e_data = cmalloc (number, ent_size);
252b5132
RH
7124
7125 if (e_data == NULL)
7126 {
7127 error (_("Out of memory\n"));
7128 return NULL;
7129 }
7130
66543521 7131 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
7132 {
7133 error (_("Unable to read in dynamic data\n"));
7134 return NULL;
7135 }
7136
c256ffe7 7137 i_data = cmalloc (number, sizeof (*i_data));
252b5132
RH
7138
7139 if (i_data == NULL)
7140 {
7141 error (_("Out of memory\n"));
7142 free (e_data);
7143 return NULL;
7144 }
7145
7146 while (number--)
66543521 7147 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7148
7149 free (e_data);
7150
7151 return i_data;
7152}
7153
6bd1a22c
L
7154static void
7155print_dynamic_symbol (bfd_vma si, unsigned long hn)
7156{
7157 Elf_Internal_Sym *psym;
7158 int n;
7159
7160 psym = dynamic_symbols + si;
7161
7162 n = print_vma (si, DEC_5);
7163 if (n < 5)
7164 fputs (" " + n, stdout);
7165 printf (" %3lu: ", hn);
7166 print_vma (psym->st_value, LONG_HEX);
7167 putchar (' ');
7168 print_vma (psym->st_size, DEC_5);
7169
7170 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7171 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7172 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
7173 /* Check to see if any other bits in the st_other field are set.
7174 Note - displaying this information disrupts the layout of the
7175 table being generated, but for the moment this case is very
7176 rare. */
7177 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7178 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
7179 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
7180 if (VALID_DYNAMIC_NAME (psym->st_name))
7181 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7182 else
7183 printf (" <corrupt: %14ld>", psym->st_name);
7184 putchar ('\n');
7185}
7186
e3c8793a 7187/* Dump the symbol table. */
252b5132 7188static int
d3ba0551 7189process_symbol_table (FILE *file)
252b5132 7190{
b34976b6 7191 Elf_Internal_Shdr *section;
66543521
AM
7192 bfd_vma nbuckets = 0;
7193 bfd_vma nchains = 0;
7194 bfd_vma *buckets = NULL;
7195 bfd_vma *chains = NULL;
fdc90cb4
JJ
7196 bfd_vma ngnubuckets = 0;
7197 bfd_vma *gnubuckets = NULL;
7198 bfd_vma *gnuchains = NULL;
6bd1a22c 7199 bfd_vma gnusymidx = 0;
252b5132
RH
7200
7201 if (! do_syms && !do_histogram)
7202 return 1;
7203
6bd1a22c
L
7204 if (dynamic_info[DT_HASH]
7205 && (do_histogram
7206 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7207 {
66543521
AM
7208 unsigned char nb[8];
7209 unsigned char nc[8];
7210 int hash_ent_size = 4;
7211
7212 if ((elf_header.e_machine == EM_ALPHA
7213 || elf_header.e_machine == EM_S390
7214 || elf_header.e_machine == EM_S390_OLD)
7215 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
7216 hash_ent_size = 8;
7217
fb52b2f4
NC
7218 if (fseek (file,
7219 (archive_file_offset
7220 + offset_from_vma (file, dynamic_info[DT_HASH],
7221 sizeof nb + sizeof nc)),
d93f0186 7222 SEEK_SET))
252b5132 7223 {
591a748a 7224 error (_("Unable to seek to start of dynamic information\n"));
252b5132
RH
7225 return 0;
7226 }
7227
66543521 7228 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
7229 {
7230 error (_("Failed to read in number of buckets\n"));
7231 return 0;
7232 }
7233
66543521 7234 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
7235 {
7236 error (_("Failed to read in number of chains\n"));
7237 return 0;
7238 }
7239
66543521
AM
7240 nbuckets = byte_get (nb, hash_ent_size);
7241 nchains = byte_get (nc, hash_ent_size);
252b5132 7242
66543521
AM
7243 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
7244 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132
RH
7245
7246 if (buckets == NULL || chains == NULL)
7247 return 0;
7248 }
7249
6bd1a22c
L
7250 if (dynamic_info_DT_GNU_HASH
7251 && (do_histogram
7252 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7253 {
6bd1a22c
L
7254 unsigned char nb[16];
7255 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
7256 bfd_vma buckets_vma;
7257
7258 if (fseek (file,
7259 (archive_file_offset
7260 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
7261 sizeof nb)),
7262 SEEK_SET))
7263 {
7264 error (_("Unable to seek to start of dynamic information\n"));
7265 return 0;
7266 }
252b5132 7267
6bd1a22c
L
7268 if (fread (nb, 16, 1, file) != 1)
7269 {
7270 error (_("Failed to read in number of buckets\n"));
7271 return 0;
7272 }
7273
7274 ngnubuckets = byte_get (nb, 4);
7275 gnusymidx = byte_get (nb + 4, 4);
7276 bitmaskwords = byte_get (nb + 8, 4);
7277 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 7278 if (is_32bit_elf)
6bd1a22c 7279 buckets_vma += bitmaskwords * 4;
f7a99963 7280 else
6bd1a22c 7281 buckets_vma += bitmaskwords * 8;
252b5132 7282
6bd1a22c
L
7283 if (fseek (file,
7284 (archive_file_offset
7285 + offset_from_vma (file, buckets_vma, 4)),
7286 SEEK_SET))
252b5132 7287 {
6bd1a22c
L
7288 error (_("Unable to seek to start of dynamic information\n"));
7289 return 0;
7290 }
7291
7292 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 7293
6bd1a22c
L
7294 if (gnubuckets == NULL)
7295 return 0;
7296
7297 for (i = 0; i < ngnubuckets; i++)
7298 if (gnubuckets[i] != 0)
7299 {
7300 if (gnubuckets[i] < gnusymidx)
7301 return 0;
7302
7303 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
7304 maxchain = gnubuckets[i];
7305 }
7306
7307 if (maxchain == 0xffffffff)
7308 return 0;
7309
7310 maxchain -= gnusymidx;
7311
7312 if (fseek (file,
7313 (archive_file_offset
7314 + offset_from_vma (file, buckets_vma
7315 + 4 * (ngnubuckets + maxchain), 4)),
7316 SEEK_SET))
7317 {
7318 error (_("Unable to seek to start of dynamic information\n"));
7319 return 0;
7320 }
7321
7322 do
7323 {
7324 if (fread (nb, 4, 1, file) != 1)
252b5132 7325 {
6bd1a22c
L
7326 error (_("Failed to determine last chain length\n"));
7327 return 0;
7328 }
252b5132 7329
6bd1a22c
L
7330 if (maxchain + 1 == 0)
7331 return 0;
252b5132 7332
6bd1a22c
L
7333 ++maxchain;
7334 }
7335 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 7336
6bd1a22c
L
7337 if (fseek (file,
7338 (archive_file_offset
7339 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
7340 SEEK_SET))
7341 {
7342 error (_("Unable to seek to start of dynamic information\n"));
7343 return 0;
7344 }
7345
7346 gnuchains = get_dynamic_data (file, maxchain, 4);
7347
7348 if (gnuchains == NULL)
7349 return 0;
7350 }
7351
7352 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
7353 && do_syms
7354 && do_using_dynamic
7355 && dynamic_strings != NULL)
7356 {
7357 unsigned long hn;
7358
7359 if (dynamic_info[DT_HASH])
7360 {
7361 bfd_vma si;
7362
7363 printf (_("\nSymbol table for image:\n"));
7364 if (is_32bit_elf)
7365 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7366 else
7367 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7368
7369 for (hn = 0; hn < nbuckets; hn++)
7370 {
7371 if (! buckets[hn])
7372 continue;
7373
7374 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
7375 print_dynamic_symbol (si, hn);
252b5132
RH
7376 }
7377 }
6bd1a22c
L
7378
7379 if (dynamic_info_DT_GNU_HASH)
7380 {
7381 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
7382 if (is_32bit_elf)
7383 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7384 else
7385 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7386
7387 for (hn = 0; hn < ngnubuckets; ++hn)
7388 if (gnubuckets[hn] != 0)
7389 {
7390 bfd_vma si = gnubuckets[hn];
7391 bfd_vma off = si - gnusymidx;
7392
7393 do
7394 {
7395 print_dynamic_symbol (si, hn);
7396 si++;
7397 }
7398 while ((gnuchains[off++] & 1) == 0);
7399 }
7400 }
252b5132
RH
7401 }
7402 else if (do_syms && !do_using_dynamic)
7403 {
b34976b6 7404 unsigned int i;
252b5132
RH
7405
7406 for (i = 0, section = section_headers;
7407 i < elf_header.e_shnum;
7408 i++, section++)
7409 {
b34976b6 7410 unsigned int si;
c256ffe7
JJ
7411 char *strtab = NULL;
7412 unsigned long int strtab_size = 0;
b34976b6
AM
7413 Elf_Internal_Sym *symtab;
7414 Elf_Internal_Sym *psym;
252b5132
RH
7415
7416
7417 if ( section->sh_type != SHT_SYMTAB
7418 && section->sh_type != SHT_DYNSYM)
7419 continue;
7420
7421 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
7422 SECTION_NAME (section),
7423 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 7424 if (is_32bit_elf)
ca47b30c 7425 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 7426 else
ca47b30c 7427 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 7428
9ad5cbcf 7429 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
7430 if (symtab == NULL)
7431 continue;
7432
7433 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
7434 {
7435 strtab = string_table;
7436 strtab_size = string_table_length;
7437 }
4fbb74a6 7438 else if (section->sh_link < elf_header.e_shnum)
252b5132 7439 {
b34976b6 7440 Elf_Internal_Shdr *string_sec;
252b5132 7441
4fbb74a6 7442 string_sec = section_headers + section->sh_link;
252b5132 7443
d3ba0551 7444 strtab = get_data (NULL, file, string_sec->sh_offset,
c256ffe7
JJ
7445 1, string_sec->sh_size, _("string table"));
7446 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
7447 }
7448
7449 for (si = 0, psym = symtab;
7450 si < section->sh_size / section->sh_entsize;
b34976b6 7451 si++, psym++)
252b5132 7452 {
5e220199 7453 printf ("%6d: ", si);
f7a99963
NC
7454 print_vma (psym->st_value, LONG_HEX);
7455 putchar (' ');
7456 print_vma (psym->st_size, DEC_5);
d1133906
NC
7457 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7458 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7459 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
7460 /* Check to see if any other bits in the st_other field are set.
7461 Note - displaying this information disrupts the layout of the
7462 table being generated, but for the moment this case is very rare. */
7463 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7464 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 7465 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
7466 print_symbol (25, psym->st_name < strtab_size
7467 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
7468
7469 if (section->sh_type == SHT_DYNSYM &&
b34976b6 7470 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 7471 {
b34976b6
AM
7472 unsigned char data[2];
7473 unsigned short vers_data;
7474 unsigned long offset;
7475 int is_nobits;
7476 int check_def;
252b5132 7477
d93f0186
NC
7478 offset = offset_from_vma
7479 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7480 sizeof data + si * sizeof (vers_data));
252b5132 7481
a6e9f9df 7482 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 7483 sizeof (data), 1, _("version data"));
252b5132
RH
7484
7485 vers_data = byte_get (data, 2);
7486
4fbb74a6
AM
7487 is_nobits = (psym->st_shndx < elf_header.e_shnum
7488 && section_headers[psym->st_shndx].sh_type
c256ffe7 7489 == SHT_NOBITS);
252b5132
RH
7490
7491 check_def = (psym->st_shndx != SHN_UNDEF);
7492
7493 if ((vers_data & 0x8000) || vers_data > 1)
7494 {
b34976b6 7495 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 7496 && (is_nobits || ! check_def))
252b5132 7497 {
b34976b6
AM
7498 Elf_External_Verneed evn;
7499 Elf_Internal_Verneed ivn;
7500 Elf_Internal_Vernaux ivna;
252b5132
RH
7501
7502 /* We must test both. */
d93f0186
NC
7503 offset = offset_from_vma
7504 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7505 sizeof evn);
252b5132 7506
252b5132
RH
7507 do
7508 {
b34976b6 7509 unsigned long vna_off;
252b5132 7510
c256ffe7 7511 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7512 _("version need"));
dd27201e
L
7513
7514 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7515 ivn.vn_next = BYTE_GET (evn.vn_next);
7516
252b5132
RH
7517 vna_off = offset + ivn.vn_aux;
7518
7519 do
7520 {
b34976b6 7521 Elf_External_Vernaux evna;
252b5132 7522
a6e9f9df 7523 get_data (&evna, file, vna_off,
c256ffe7 7524 sizeof (evna), 1,
a6e9f9df 7525 _("version need aux (3)"));
252b5132
RH
7526
7527 ivna.vna_other = BYTE_GET (evna.vna_other);
7528 ivna.vna_next = BYTE_GET (evna.vna_next);
7529 ivna.vna_name = BYTE_GET (evna.vna_name);
7530
7531 vna_off += ivna.vna_next;
7532 }
7533 while (ivna.vna_other != vers_data
7534 && ivna.vna_next != 0);
7535
7536 if (ivna.vna_other == vers_data)
7537 break;
7538
7539 offset += ivn.vn_next;
7540 }
7541 while (ivn.vn_next != 0);
7542
7543 if (ivna.vna_other == vers_data)
7544 {
7545 printf ("@%s (%d)",
c256ffe7
JJ
7546 ivna.vna_name < strtab_size
7547 ? strtab + ivna.vna_name : "<corrupt>",
7548 ivna.vna_other);
252b5132
RH
7549 check_def = 0;
7550 }
7551 else if (! is_nobits)
591a748a 7552 error (_("bad dynamic symbol\n"));
252b5132
RH
7553 else
7554 check_def = 1;
7555 }
7556
7557 if (check_def)
7558 {
00d93f34 7559 if (vers_data != 0x8001
b34976b6 7560 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7561 {
b34976b6
AM
7562 Elf_Internal_Verdef ivd;
7563 Elf_Internal_Verdaux ivda;
7564 Elf_External_Verdaux evda;
7565 unsigned long offset;
252b5132 7566
d93f0186
NC
7567 offset = offset_from_vma
7568 (file,
7569 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7570 sizeof (Elf_External_Verdef));
252b5132
RH
7571
7572 do
7573 {
b34976b6 7574 Elf_External_Verdef evd;
252b5132 7575
a6e9f9df 7576 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 7577 1, _("version def"));
252b5132 7578
b34976b6
AM
7579 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7580 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
7581 ivd.vd_next = BYTE_GET (evd.vd_next);
7582
7583 offset += ivd.vd_next;
7584 }
7585 while (ivd.vd_ndx != (vers_data & 0x7fff)
7586 && ivd.vd_next != 0);
7587
7588 offset -= ivd.vd_next;
7589 offset += ivd.vd_aux;
7590
a6e9f9df 7591 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7592 1, _("version def aux"));
252b5132
RH
7593
7594 ivda.vda_name = BYTE_GET (evda.vda_name);
7595
7596 if (psym->st_name != ivda.vda_name)
7597 printf ((vers_data & 0x8000)
7598 ? "@%s" : "@@%s",
c256ffe7
JJ
7599 ivda.vda_name < strtab_size
7600 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7601 }
7602 }
7603 }
7604 }
7605
7606 putchar ('\n');
7607 }
7608
7609 free (symtab);
7610 if (strtab != string_table)
7611 free (strtab);
7612 }
7613 }
7614 else if (do_syms)
7615 printf
7616 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7617
7618 if (do_histogram && buckets != NULL)
7619 {
66543521
AM
7620 unsigned long *lengths;
7621 unsigned long *counts;
7622 unsigned long hn;
7623 bfd_vma si;
7624 unsigned long maxlength = 0;
7625 unsigned long nzero_counts = 0;
7626 unsigned long nsyms = 0;
252b5132 7627
66543521
AM
7628 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7629 (unsigned long) nbuckets);
252b5132
RH
7630 printf (_(" Length Number %% of total Coverage\n"));
7631
66543521 7632 lengths = calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7633 if (lengths == NULL)
7634 {
591a748a 7635 error (_("Out of memory\n"));
252b5132
RH
7636 return 0;
7637 }
7638 for (hn = 0; hn < nbuckets; ++hn)
7639 {
f7a99963 7640 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7641 {
b34976b6 7642 ++nsyms;
252b5132 7643 if (maxlength < ++lengths[hn])
b34976b6 7644 ++maxlength;
252b5132
RH
7645 }
7646 }
7647
66543521 7648 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7649 if (counts == NULL)
7650 {
591a748a 7651 error (_("Out of memory\n"));
252b5132
RH
7652 return 0;
7653 }
7654
7655 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7656 ++counts[lengths[hn]];
252b5132 7657
103f02d3 7658 if (nbuckets > 0)
252b5132 7659 {
66543521
AM
7660 unsigned long i;
7661 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7662 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7663 for (i = 1; i <= maxlength; ++i)
103f02d3 7664 {
66543521
AM
7665 nzero_counts += counts[i] * i;
7666 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7667 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7668 (nzero_counts * 100.0) / nsyms);
7669 }
252b5132
RH
7670 }
7671
7672 free (counts);
7673 free (lengths);
7674 }
7675
7676 if (buckets != NULL)
7677 {
7678 free (buckets);
7679 free (chains);
7680 }
7681
fdc90cb4
JJ
7682 if (do_histogram && dynamic_info_DT_GNU_HASH)
7683 {
fdc90cb4
JJ
7684 unsigned long *lengths;
7685 unsigned long *counts;
7686 unsigned long hn;
7687 unsigned long maxlength = 0;
7688 unsigned long nzero_counts = 0;
7689 unsigned long nsyms = 0;
fdc90cb4
JJ
7690
7691 lengths = calloc (ngnubuckets, sizeof (*lengths));
7692 if (lengths == NULL)
7693 {
591a748a 7694 error (_("Out of memory\n"));
fdc90cb4
JJ
7695 return 0;
7696 }
7697
7698 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
7699 (unsigned long) ngnubuckets);
7700 printf (_(" Length Number %% of total Coverage\n"));
7701
7702 for (hn = 0; hn < ngnubuckets; ++hn)
7703 if (gnubuckets[hn] != 0)
7704 {
7705 bfd_vma off, length = 1;
7706
6bd1a22c 7707 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
7708 (gnuchains[off] & 1) == 0; ++off)
7709 ++length;
7710 lengths[hn] = length;
7711 if (length > maxlength)
7712 maxlength = length;
7713 nsyms += length;
7714 }
7715
7716 counts = calloc (maxlength + 1, sizeof (*counts));
7717 if (counts == NULL)
7718 {
591a748a 7719 error (_("Out of memory\n"));
fdc90cb4
JJ
7720 return 0;
7721 }
7722
7723 for (hn = 0; hn < ngnubuckets; ++hn)
7724 ++counts[lengths[hn]];
7725
7726 if (ngnubuckets > 0)
7727 {
7728 unsigned long j;
7729 printf (" 0 %-10lu (%5.1f%%)\n",
7730 counts[0], (counts[0] * 100.0) / ngnubuckets);
7731 for (j = 1; j <= maxlength; ++j)
7732 {
7733 nzero_counts += counts[j] * j;
7734 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7735 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
7736 (nzero_counts * 100.0) / nsyms);
7737 }
7738 }
7739
7740 free (counts);
7741 free (lengths);
7742 free (gnubuckets);
7743 free (gnuchains);
7744 }
7745
252b5132
RH
7746 return 1;
7747}
7748
7749static int
d3ba0551 7750process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 7751{
b4c96d0d 7752 unsigned int i;
252b5132
RH
7753
7754 if (dynamic_syminfo == NULL
7755 || !do_dynamic)
7756 /* No syminfo, this is ok. */
7757 return 1;
7758
7759 /* There better should be a dynamic symbol section. */
7760 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7761 return 0;
7762
7763 if (dynamic_addr)
7764 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7765 dynamic_syminfo_offset, dynamic_syminfo_nent);
7766
7767 printf (_(" Num: Name BoundTo Flags\n"));
7768 for (i = 0; i < dynamic_syminfo_nent; ++i)
7769 {
7770 unsigned short int flags = dynamic_syminfo[i].si_flags;
7771
31104126 7772 printf ("%4d: ", i);
d79b3d50
NC
7773 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7774 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7775 else
7776 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7777 putchar (' ');
252b5132
RH
7778
7779 switch (dynamic_syminfo[i].si_boundto)
7780 {
7781 case SYMINFO_BT_SELF:
7782 fputs ("SELF ", stdout);
7783 break;
7784 case SYMINFO_BT_PARENT:
7785 fputs ("PARENT ", stdout);
7786 break;
7787 default:
7788 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7789 && dynamic_syminfo[i].si_boundto < dynamic_nent
7790 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7791 {
d79b3d50 7792 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7793 putchar (' ' );
7794 }
252b5132
RH
7795 else
7796 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7797 break;
7798 }
7799
7800 if (flags & SYMINFO_FLG_DIRECT)
7801 printf (" DIRECT");
7802 if (flags & SYMINFO_FLG_PASSTHRU)
7803 printf (" PASSTHRU");
7804 if (flags & SYMINFO_FLG_COPY)
7805 printf (" COPY");
7806 if (flags & SYMINFO_FLG_LAZYLOAD)
7807 printf (" LAZYLOAD");
7808
7809 puts ("");
7810 }
7811
7812 return 1;
7813}
7814
7815#ifdef SUPPORT_DISASSEMBLY
18bd398b 7816static int
d3ba0551 7817disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
7818{
7819 printf (_("\nAssembly dump of section %s\n"),
7820 SECTION_NAME (section));
7821
7822 /* XXX -- to be done --- XXX */
7823
7824 return 1;
7825}
7826#endif
7827
7828static int
09c11c86
NC
7829dump_section_as_strings (Elf_Internal_Shdr *section, FILE *file)
7830{
7831 Elf_Internal_Shdr *relsec;
7832 bfd_size_type num_bytes;
7833 bfd_vma addr;
7834 char *data;
7835 char *end;
7836 char *start;
7837 char *name = SECTION_NAME (section);
7838 bfd_boolean some_strings_shown;
7839
7840 num_bytes = section->sh_size;
7841
7842 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
7843 {
7844 printf (_("\nSection '%s' has no data to dump.\n"), name);
7845 return 0;
7846 }
7847
7848 addr = section->sh_addr;
7849
7850 start = get_data (NULL, file, section->sh_offset, 1, num_bytes,
7851 _("section data"));
7852 if (!start)
7853 return 0;
7854
7855 printf (_("\nString dump of section '%s':\n"), name);
7856
7857 /* If the section being dumped has relocations against it the user might
7858 be expecting these relocations to have been applied. Check for this
7859 case and issue a warning message in order to avoid confusion.
7860 FIXME: Maybe we ought to have an option that dumps a section with
7861 relocs applied ? */
7862 for (relsec = section_headers;
7863 relsec < section_headers + elf_header.e_shnum;
7864 ++relsec)
7865 {
7866 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
7867 || relsec->sh_info >= elf_header.e_shnum
7868 || section_headers + relsec->sh_info != section
09c11c86 7869 || relsec->sh_size == 0
4fbb74a6 7870 || relsec->sh_link >= elf_header.e_shnum)
09c11c86
NC
7871 continue;
7872
7873 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
7874 break;
7875 }
7876
7877 data = start;
7878 end = start + num_bytes;
7879 some_strings_shown = FALSE;
7880
7881 while (data < end)
7882 {
7883 while (!ISPRINT (* data))
7884 if (++ data >= end)
7885 break;
7886
7887 if (data < end)
7888 {
6e3d6dc1 7889#ifndef __MSVCRT__
6f08d80e 7890 printf (" [%6tx] %s\n", data - start, data);
6e3d6dc1
NC
7891#else
7892 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
7893#endif
09c11c86
NC
7894 data += strlen (data);
7895 some_strings_shown = TRUE;
7896 }
7897 }
7898
7899 if (! some_strings_shown)
7900 printf (_(" No strings found in this section."));
7901
7902 free (start);
7903
7904 putchar ('\n');
7905 return 1;
7906}
7907
7908
7909static int
7910dump_section_as_bytes (Elf_Internal_Shdr *section, FILE *file)
252b5132 7911{
4b78141a 7912 Elf_Internal_Shdr *relsec;
b34976b6
AM
7913 bfd_size_type bytes;
7914 bfd_vma addr;
7915 unsigned char *data;
7916 unsigned char *start;
252b5132
RH
7917
7918 bytes = section->sh_size;
7919
e69f2d21 7920 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
7921 {
7922 printf (_("\nSection '%s' has no data to dump.\n"),
7923 SECTION_NAME (section));
7924 return 0;
7925 }
7926 else
7927 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
7928
7929 addr = section->sh_addr;
7930
c256ffe7
JJ
7931 start = get_data (NULL, file, section->sh_offset, 1, bytes,
7932 _("section data"));
a6e9f9df
AM
7933 if (!start)
7934 return 0;
252b5132 7935
4b78141a
NC
7936 /* If the section being dumped has relocations against it the user might
7937 be expecting these relocations to have been applied. Check for this
7938 case and issue a warning message in order to avoid confusion.
7939 FIXME: Maybe we ought to have an option that dumps a section with
7940 relocs applied ? */
7941 for (relsec = section_headers;
7942 relsec < section_headers + elf_header.e_shnum;
7943 ++relsec)
7944 {
35d9dd2f 7945 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
7946 || relsec->sh_info >= elf_header.e_shnum
7947 || section_headers + relsec->sh_info != section
4b78141a 7948 || relsec->sh_size == 0
4fbb74a6 7949 || relsec->sh_link >= elf_header.e_shnum)
4b78141a
NC
7950 continue;
7951
7952 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
7953 break;
7954 }
1118d252 7955
252b5132
RH
7956 data = start;
7957
7958 while (bytes)
7959 {
7960 int j;
7961 int k;
7962 int lbytes;
7963
7964 lbytes = (bytes > 16 ? 16 : bytes);
7965
148d3c43 7966 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 7967
20414cab 7968 for (j = 0; j < 16; j++)
252b5132 7969 {
20414cab
AM
7970 if (j < lbytes)
7971 printf ("%2.2x", data[j]);
7972 else
7973 printf (" ");
252b5132 7974
20414cab
AM
7975 if ((j & 3) == 3)
7976 printf (" ");
252b5132
RH
7977 }
7978
7979 for (j = 0; j < lbytes; j++)
7980 {
b34976b6 7981 k = data[j];
9376f0c7 7982 if (k >= ' ' && k < 0x7f)
252b5132
RH
7983 printf ("%c", k);
7984 else
7985 printf (".");
7986 }
7987
7988 putchar ('\n');
7989
7990 data += lbytes;
7991 addr += lbytes;
7992 bytes -= lbytes;
7993 }
7994
7995 free (start);
7996
4b78141a 7997 putchar ('\n');
252b5132
RH
7998 return 1;
7999}
8000
aca88567
NC
8001/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
8002 DWARF debug sections. This is a target specific test. Note - we do not
8003 go through the whole including-target-headers-multiple-times route, (as
8004 we have already done with <elf/h8.h>) because this would become very
8005 messy and even then this function would have to contain target specific
8006 information (the names of the relocs instead of their numeric values).
8007 FIXME: This is not the correct way to solve this problem. The proper way
8008 is to have target specific reloc sizing and typing functions created by
8009 the reloc-macros.h header, in the same way that it already creates the
8010 reloc naming functions. */
8011
8012static bfd_boolean
8013is_32bit_abs_reloc (unsigned int reloc_type)
8014{
8015 switch (elf_header.e_machine)
8016 {
41e92641
NC
8017 case EM_386:
8018 case EM_486:
8019 return reloc_type == 1; /* R_386_32. */
aca88567
NC
8020 case EM_68K:
8021 return reloc_type == 1; /* R_68K_32. */
8022 case EM_860:
8023 return reloc_type == 1; /* R_860_32. */
8024 case EM_ALPHA:
8025 return reloc_type == 1; /* XXX Is this right ? */
41e92641
NC
8026 case EM_ARC:
8027 return reloc_type == 1; /* R_ARC_32. */
8028 case EM_ARM:
8029 return reloc_type == 2; /* R_ARM_ABS32 */
aca88567
NC
8030 case EM_AVR_OLD:
8031 case EM_AVR:
8032 return reloc_type == 1;
8033 case EM_BLACKFIN:
8034 return reloc_type == 0x12; /* R_byte4_data. */
8035 case EM_CRIS:
8036 return reloc_type == 3; /* R_CRIS_32. */
8037 case EM_CR16:
6c03b1ed 8038 case EM_CR16_OLD:
aca88567
NC
8039 return reloc_type == 3; /* R_CR16_NUM32. */
8040 case EM_CRX:
8041 return reloc_type == 15; /* R_CRX_NUM32. */
8042 case EM_CYGNUS_FRV:
8043 return reloc_type == 1;
41e92641
NC
8044 case EM_CYGNUS_D10V:
8045 case EM_D10V:
8046 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
8047 case EM_CYGNUS_D30V:
8048 case EM_D30V:
8049 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
8050 case EM_DLX:
8051 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
8052 case EM_CYGNUS_FR30:
8053 case EM_FR30:
8054 return reloc_type == 3; /* R_FR30_32. */
8055 case EM_H8S:
8056 case EM_H8_300:
8057 case EM_H8_300H:
8058 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
8059 case EM_IA_64:
8060 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
8061 case EM_IP2K_OLD:
8062 case EM_IP2K:
8063 return reloc_type == 2; /* R_IP2K_32. */
8064 case EM_IQ2000:
8065 return reloc_type == 2; /* R_IQ2000_32. */
ff7eeb89 8066 case EM_M32C_OLD:
aca88567
NC
8067 case EM_M32C:
8068 return reloc_type == 3; /* R_M32C_32. */
8069 case EM_M32R:
8070 return reloc_type == 34; /* R_M32R_32_RELA. */
8071 case EM_MCORE:
8072 return reloc_type == 1; /* R_MCORE_ADDR32. */
8073 case EM_CYGNUS_MEP:
8074 return reloc_type == 4; /* R_MEP_32. */
8075 case EM_MIPS:
8076 return reloc_type == 2; /* R_MIPS_32. */
8077 case EM_MMIX:
8078 return reloc_type == 4; /* R_MMIX_32. */
8079 case EM_CYGNUS_MN10200:
8080 case EM_MN10200:
8081 return reloc_type == 1; /* R_MN10200_32. */
8082 case EM_CYGNUS_MN10300:
8083 case EM_MN10300:
8084 return reloc_type == 1; /* R_MN10300_32. */
8085 case EM_MSP430_OLD:
8086 case EM_MSP430:
8087 return reloc_type == 1; /* R_MSP43_32. */
8088 case EM_MT:
8089 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
8090 case EM_ALTERA_NIOS2:
8091 case EM_NIOS32:
8092 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
8093 case EM_OPENRISC:
8094 case EM_OR32:
8095 return reloc_type == 1; /* R_OR32_32. */
aca88567
NC
8096 case EM_PARISC:
8097 return reloc_type == 1; /* R_PARISC_DIR32. */
8098 case EM_PJ:
8099 case EM_PJ_OLD:
8100 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
8101 case EM_PPC64:
8102 return reloc_type == 1; /* R_PPC64_ADDR32. */
8103 case EM_PPC:
8104 return reloc_type == 1; /* R_PPC_ADDR32. */
8105 case EM_S370:
8106 return reloc_type == 1; /* R_I370_ADDR31. */
8107 case EM_S390_OLD:
8108 case EM_S390:
8109 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
8110 case EM_SCORE:
8111 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
8112 case EM_SH:
8113 return reloc_type == 1; /* R_SH_DIR32. */
8114 case EM_SPARC32PLUS:
8115 case EM_SPARCV9:
8116 case EM_SPARC:
8117 return reloc_type == 3 /* R_SPARC_32. */
8118 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
8119 case EM_SPU:
8120 return reloc_type == 6; /* R_SPU_ADDR32 */
aca88567
NC
8121 case EM_CYGNUS_V850:
8122 case EM_V850:
8123 return reloc_type == 6; /* R_V850_ABS32. */
8124 case EM_VAX:
8125 return reloc_type == 1; /* R_VAX_32. */
8126 case EM_X86_64:
8127 return reloc_type == 10; /* R_X86_64_32. */
8128 case EM_XSTORMY16:
8129 return reloc_type == 1; /* R_XSTROMY16_32. */
8130 case EM_XTENSA_OLD:
8131 case EM_XTENSA:
8132 return reloc_type == 1; /* R_XTENSA_32. */
4b78141a 8133
aca88567
NC
8134 default:
8135 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
8136 elf_header.e_machine);
8137 abort ();
8138 }
8139}
8140
8141/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8142 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
8143
8144static bfd_boolean
8145is_32bit_pcrel_reloc (unsigned int reloc_type)
8146{
8147 switch (elf_header.e_machine)
8148 {
41e92641
NC
8149 case EM_386:
8150 case EM_486:
3e0873ac 8151 return reloc_type == 2; /* R_386_PC32. */
aca88567 8152 case EM_68K:
3e0873ac 8153 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
8154 case EM_ALPHA:
8155 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 8156 case EM_ARM:
3e0873ac 8157 return reloc_type == 3; /* R_ARM_REL32 */
aca88567 8158 case EM_PARISC:
85acf597 8159 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
8160 case EM_PPC:
8161 return reloc_type == 26; /* R_PPC_REL32. */
8162 case EM_PPC64:
3e0873ac 8163 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
8164 case EM_S390_OLD:
8165 case EM_S390:
3e0873ac 8166 return reloc_type == 5; /* R_390_PC32. */
aca88567 8167 case EM_SH:
3e0873ac 8168 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
8169 case EM_SPARC32PLUS:
8170 case EM_SPARCV9:
8171 case EM_SPARC:
3e0873ac 8172 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
8173 case EM_SPU:
8174 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 8175 case EM_X86_64:
3e0873ac 8176 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
8177 case EM_XTENSA_OLD:
8178 case EM_XTENSA:
8179 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
8180 default:
8181 /* Do not abort or issue an error message here. Not all targets use
8182 pc-relative 32-bit relocs in their DWARF debug information and we
8183 have already tested for target coverage in is_32bit_abs_reloc. A
41e92641
NC
8184 more helpful warning message will be generated by
8185 debug_apply_relocations anyway, so just return. */
aca88567
NC
8186 return FALSE;
8187 }
8188}
8189
8190/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8191 a 64-bit absolute RELA relocation used in DWARF debug sections. */
8192
8193static bfd_boolean
8194is_64bit_abs_reloc (unsigned int reloc_type)
8195{
8196 switch (elf_header.e_machine)
8197 {
8198 case EM_ALPHA:
8199 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
8200 case EM_IA_64:
8201 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
8202 case EM_PARISC:
8203 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
8204 case EM_PPC64:
8205 return reloc_type == 38; /* R_PPC64_ADDR64. */
8206 case EM_SPARC32PLUS:
8207 case EM_SPARCV9:
8208 case EM_SPARC:
8209 return reloc_type == 54; /* R_SPARC_UA64. */
8210 case EM_X86_64:
8211 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
8212 case EM_S390_OLD:
8213 case EM_S390:
8214 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
8215 case EM_MIPS:
8216 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
8217 default:
8218 return FALSE;
8219 }
8220}
8221
85acf597
RH
8222/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
8223 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
8224
8225static bfd_boolean
8226is_64bit_pcrel_reloc (unsigned int reloc_type)
8227{
8228 switch (elf_header.e_machine)
8229 {
8230 case EM_ALPHA:
8231 return reloc_type == 11; /* R_ALPHA_SREL64 */
8232 case EM_IA_64:
8233 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
8234 case EM_PARISC:
8235 return reloc_type == 72; /* R_PARISC_PCREL64 */
8236 case EM_PPC64:
8237 return reloc_type == 44; /* R_PPC64_REL64 */
8238 case EM_SPARC32PLUS:
8239 case EM_SPARCV9:
8240 case EM_SPARC:
8241 return reloc_type == 46; /* R_SPARC_DISP64 */
8242 case EM_X86_64:
8243 return reloc_type == 24; /* R_X86_64_PC64 */
8244 case EM_S390_OLD:
8245 case EM_S390:
8246 return reloc_type == 23; /* R_S390_PC64 */
8247 default:
8248 return FALSE;
8249 }
8250}
8251
aca88567
NC
8252/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8253 a 16-bit absolute RELA relocation used in DWARF debug sections. */
8254
8255static bfd_boolean
8256is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
8257{
8258 switch (elf_header.e_machine)
8259 {
aca88567
NC
8260 case EM_AVR_OLD:
8261 case EM_AVR:
8262 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
8263 case EM_CYGNUS_D10V:
8264 case EM_D10V:
8265 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
8266 case EM_H8S:
8267 case EM_H8_300:
8268 case EM_H8_300H:
aca88567
NC
8269 return reloc_type == R_H8_DIR16;
8270 case EM_IP2K_OLD:
8271 case EM_IP2K:
8272 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 8273 case EM_M32C_OLD:
f4236fe4
DD
8274 case EM_M32C:
8275 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
8276 case EM_MSP430_OLD:
8277 case EM_MSP430:
8278 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
8279 case EM_ALTERA_NIOS2:
8280 case EM_NIOS32:
8281 return reloc_type == 9; /* R_NIOS_16. */
4b78141a 8282 default:
aca88567 8283 return FALSE;
4b78141a
NC
8284 }
8285}
8286
1b315056
CS
8287/* Uncompresses a section that was compressed using zlib, in place.
8288 * This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
8289
8290static int
8291uncompress_section_contents (unsigned char **buffer, dwarf_size_type *size)
8292{
8293#ifndef HAVE_ZLIB_H
8294 /* These are just to quiet gcc. */
8295 buffer = 0;
8296 size = 0;
8297 return FALSE;
8298#else
8299 dwarf_size_type compressed_size = *size;
8300 unsigned char* compressed_buffer = *buffer;
8301 dwarf_size_type uncompressed_size;
8302 unsigned char* uncompressed_buffer;
8303 z_stream strm;
8304 int rc;
8305 dwarf_size_type header_size = 12;
8306
8307 /* Read the zlib header. In this case, it should be "ZLIB" followed
8308 by the uncompressed section size, 8 bytes in big-endian order. */
8309 if (compressed_size < header_size
8310 || ! streq ((char*) compressed_buffer, "ZLIB"))
8311 return 0;
8312 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
8313 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
8314 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
8315 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
8316 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
8317 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
8318 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
8319 uncompressed_size += compressed_buffer[11];
8320
8321 /* It is possible the section consists of several compressed
8322 buffers concatenated together, so we uncompress in a loop. */
8323 strm.zalloc = NULL;
8324 strm.zfree = NULL;
8325 strm.opaque = NULL;
8326 strm.avail_in = compressed_size - header_size;
8327 strm.next_in = (Bytef*) compressed_buffer + header_size;
8328 strm.avail_out = uncompressed_size;
8329 uncompressed_buffer = xmalloc (uncompressed_size);
8330
8331 rc = inflateInit (&strm);
8332 while (strm.avail_in > 0)
8333 {
8334 if (rc != Z_OK)
8335 goto fail;
8336 strm.next_out = ((Bytef*) uncompressed_buffer
8337 + (uncompressed_size - strm.avail_out));
8338 rc = inflate (&strm, Z_FINISH);
8339 if (rc != Z_STREAM_END)
8340 goto fail;
8341 rc = inflateReset (&strm);
8342 }
8343 rc = inflateEnd (&strm);
8344 if (rc != Z_OK
8345 || strm.avail_out != 0)
8346 goto fail;
8347
8348 free (compressed_buffer);
8349 *buffer = uncompressed_buffer;
8350 *size = uncompressed_size;
8351 return 1;
8352
8353 fail:
8354 free (uncompressed_buffer);
8355 return 0;
8356#endif /* HAVE_ZLIB_H */
8357}
8358
41e92641 8359/* Apply relocations to a debug section. */
d9296b18 8360
41e92641
NC
8361static void
8362debug_apply_relocations (void *file,
8363 Elf_Internal_Shdr *section,
8364 unsigned char *start)
d9296b18 8365{
1007acb3
L
8366 Elf_Internal_Shdr *relsec;
8367 unsigned char *end = start + section->sh_size;
18bd398b 8368
41e92641
NC
8369 if (elf_header.e_type != ET_REL)
8370 return;
6528d0cb 8371
41e92641 8372 /* Find the reloc section associated with the debug section. */
5b18a4bc
NC
8373 for (relsec = section_headers;
8374 relsec < section_headers + elf_header.e_shnum;
8375 ++relsec)
252b5132 8376 {
41e92641
NC
8377 bfd_boolean is_rela;
8378 unsigned long num_relocs;
8379 Elf_Internal_Rela *relocs, *rp;
5b18a4bc
NC
8380 Elf_Internal_Shdr *symsec;
8381 Elf_Internal_Sym *symtab;
8382 Elf_Internal_Sym *sym;
252b5132 8383
41e92641 8384 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
8385 || relsec->sh_info >= elf_header.e_shnum
8386 || section_headers + relsec->sh_info != section
c256ffe7 8387 || relsec->sh_size == 0
4fbb74a6 8388 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 8389 continue;
428409d5 8390
41e92641
NC
8391 is_rela = relsec->sh_type == SHT_RELA;
8392
8393 if (is_rela)
8394 {
8395 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8396 & relocs, & num_relocs))
8397 return;
8398 }
8399 else
8400 {
8401 if (!slurp_rel_relocs (file, relsec->sh_offset, relsec->sh_size,
8402 & relocs, & num_relocs))
8403 return;
8404 }
8405
8406 /* SH uses RELA but uses in place value instead of the addend field. */
8407 if (elf_header.e_machine == EM_SH)
8408 is_rela = FALSE;
428409d5 8409
4fbb74a6 8410 symsec = section_headers + relsec->sh_link;
5b18a4bc 8411 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 8412
41e92641 8413 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 8414 {
41e92641
NC
8415 bfd_vma addend;
8416 unsigned int reloc_type;
8417 unsigned int reloc_size;
8418 unsigned char * loc;
4b78141a 8419
aca88567 8420 reloc_type = get_reloc_type (rp->r_info);
41e92641 8421
aca88567
NC
8422 if (is_32bit_abs_reloc (reloc_type)
8423 || is_32bit_pcrel_reloc (reloc_type))
8424 reloc_size = 4;
85acf597
RH
8425 else if (is_64bit_abs_reloc (reloc_type)
8426 || is_64bit_pcrel_reloc (reloc_type))
aca88567
NC
8427 reloc_size = 8;
8428 else if (is_16bit_abs_reloc (reloc_type))
8429 reloc_size = 2;
8430 else
4b78141a 8431 {
41e92641 8432 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 8433 reloc_type, SECTION_NAME (section));
4b78141a
NC
8434 continue;
8435 }
103f02d3 8436
700dd8b7
L
8437 loc = start + rp->r_offset;
8438 if ((loc + reloc_size) > end)
8439 {
8440 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
8441 (unsigned long) rp->r_offset,
8442 SECTION_NAME (section));
8443 continue;
8444 }
103f02d3 8445
41e92641
NC
8446 sym = symtab + get_reloc_symindex (rp->r_info);
8447
8448 /* If the reloc has a symbol associated with it,
8449 make sure that it is of an appropriate type. */
aca88567
NC
8450 if (sym != symtab
8451 && ELF_ST_TYPE (sym->st_info) != STT_SECTION
8452 /* Relocations against symbols without type can happen.
8453 Gcc -feliminate-dwarf2-dups may generate symbols
8454 without type for debug info. */
8455 && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
8456 /* Relocations against object symbols can happen,
8457 eg when referencing a global array. For an
8458 example of this see the _clz.o binary in libgcc.a. */
8459 && ELF_ST_TYPE (sym->st_info) != STT_OBJECT)
5b18a4bc 8460 {
41e92641 8461 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 8462 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 8463 (long int)(rp - relocs),
41e92641 8464 SECTION_NAME (relsec));
aca88567 8465 continue;
5b18a4bc 8466 }
252b5132 8467
41e92641
NC
8468 addend = is_rela ? rp->r_addend : byte_get (loc, reloc_size);
8469
85acf597
RH
8470 if (is_32bit_pcrel_reloc (reloc_type)
8471 || is_64bit_pcrel_reloc (reloc_type))
8472 {
8473 /* On HPPA, all pc-relative relocations are biased by 8. */
8474 if (elf_header.e_machine == EM_PARISC)
8475 addend -= 8;
8476 byte_put (loc, (addend + sym->st_value) - rp->r_offset,
8477 reloc_size);
8478 }
41e92641
NC
8479 else
8480 byte_put (loc, addend + sym->st_value, reloc_size);
5b18a4bc 8481 }
252b5132 8482
5b18a4bc 8483 free (symtab);
41e92641 8484 free (relocs);
5b18a4bc
NC
8485 break;
8486 }
5b18a4bc 8487}
103f02d3 8488
d966045b
DJ
8489static int
8490load_specific_debug_section (enum dwarf_section_display_enum debug,
8491 Elf_Internal_Shdr *sec, void *file)
1007acb3 8492{
19e6b90e 8493 struct dwarf_section *section = &debug_displays [debug].section;
19e6b90e 8494 char buf [64];
1b315056 8495 int section_is_compressed;
1007acb3 8496
19e6b90e
L
8497 /* If it is already loaded, do nothing. */
8498 if (section->start != NULL)
8499 return 1;
1007acb3 8500
a71cc8e0 8501 section_is_compressed = section->name == section->compressed_name;
1007acb3 8502
19e6b90e
L
8503 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
8504 section->address = sec->sh_addr;
8505 section->size = sec->sh_size;
8506 section->start = get_data (NULL, file, sec->sh_offset, 1,
8507 sec->sh_size, buf);
1b315056
CS
8508 if (section->start == NULL)
8509 return 0;
8510
8511 if (section_is_compressed)
8512 if (! uncompress_section_contents (&section->start, &section->size))
8513 return 0;
1007acb3 8514
19e6b90e 8515 if (debug_displays [debug].relocate)
41e92641 8516 debug_apply_relocations (file, sec, section->start);
1007acb3 8517
1b315056 8518 return 1;
1007acb3
L
8519}
8520
d966045b
DJ
8521int
8522load_debug_section (enum dwarf_section_display_enum debug, void *file)
8523{
8524 struct dwarf_section *section = &debug_displays [debug].section;
8525 Elf_Internal_Shdr *sec;
8526
8527 /* Locate the debug section. */
8528 sec = find_section (section->uncompressed_name);
8529 if (sec != NULL)
8530 section->name = section->uncompressed_name;
8531 else
8532 {
8533 sec = find_section (section->compressed_name);
8534 if (sec != NULL)
8535 section->name = section->compressed_name;
8536 }
8537 if (sec == NULL)
8538 return 0;
8539
8540 return load_specific_debug_section (debug, sec, file);
8541}
8542
19e6b90e
L
8543void
8544free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 8545{
19e6b90e 8546 struct dwarf_section *section = &debug_displays [debug].section;
1007acb3 8547
19e6b90e
L
8548 if (section->start == NULL)
8549 return;
1007acb3 8550
19e6b90e
L
8551 free ((char *) section->start);
8552 section->start = NULL;
8553 section->address = 0;
8554 section->size = 0;
1007acb3
L
8555}
8556
1007acb3 8557static int
19e6b90e 8558display_debug_section (Elf_Internal_Shdr *section, FILE *file)
1007acb3 8559{
19e6b90e
L
8560 char *name = SECTION_NAME (section);
8561 bfd_size_type length;
8562 int result = 1;
8563 enum dwarf_section_display_enum i;
1007acb3 8564
19e6b90e
L
8565 length = section->sh_size;
8566 if (length == 0)
1007acb3 8567 {
19e6b90e
L
8568 printf (_("\nSection '%s' has no debugging data.\n"), name);
8569 return 0;
1007acb3
L
8570 }
8571
0112cd26 8572 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 8573 name = ".debug_info";
1007acb3 8574
19e6b90e
L
8575 /* See if we know how to display the contents of this section. */
8576 for (i = 0; i < max; i++)
1b315056
CS
8577 if (streq (debug_displays[i].section.uncompressed_name, name)
8578 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e
L
8579 {
8580 struct dwarf_section *sec = &debug_displays [i].section;
d966045b
DJ
8581 int secondary = (section != find_section (name));
8582
8583 if (secondary)
8584 free_debug_section (i);
1007acb3 8585
d966045b
DJ
8586 if (streq (debug_displays[i].section.uncompressed_name, name))
8587 sec->name = sec->uncompressed_name;
8588 else
8589 sec->name = sec->compressed_name;
8590 if (load_specific_debug_section (i, section, file))
19e6b90e
L
8591 {
8592 result &= debug_displays[i].display (sec, file);
1007acb3 8593
d966045b 8594 if (secondary || (i != info && i != abbrev))
19e6b90e
L
8595 free_debug_section (i);
8596 }
1007acb3 8597
19e6b90e
L
8598 break;
8599 }
1007acb3 8600
19e6b90e 8601 if (i == max)
1007acb3 8602 {
19e6b90e
L
8603 printf (_("Unrecognized debug section: %s\n"), name);
8604 result = 0;
1007acb3
L
8605 }
8606
19e6b90e 8607 return result;
5b18a4bc 8608}
103f02d3 8609
aef1f6d0
DJ
8610/* Set DUMP_SECTS for all sections where dumps were requested
8611 based on section name. */
8612
8613static void
8614initialise_dumps_byname (void)
8615{
8616 struct dump_list_entry *cur;
8617
8618 for (cur = dump_sects_byname; cur; cur = cur->next)
8619 {
8620 unsigned int i;
8621 int any;
8622
8623 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
8624 if (streq (SECTION_NAME (section_headers + i), cur->name))
8625 {
09c11c86 8626 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
8627 any = 1;
8628 }
8629
8630 if (!any)
8631 warn (_("Section '%s' was not dumped because it does not exist!\n"),
8632 cur->name);
8633 }
8634}
8635
5b18a4bc 8636static void
19e6b90e 8637process_section_contents (FILE *file)
5b18a4bc 8638{
19e6b90e
L
8639 Elf_Internal_Shdr *section;
8640 unsigned int i;
103f02d3 8641
19e6b90e
L
8642 if (! do_dump)
8643 return;
103f02d3 8644
aef1f6d0
DJ
8645 initialise_dumps_byname ();
8646
19e6b90e
L
8647 for (i = 0, section = section_headers;
8648 i < elf_header.e_shnum && i < num_dump_sects;
8649 i++, section++)
8650 {
8651#ifdef SUPPORT_DISASSEMBLY
8652 if (dump_sects[i] & DISASS_DUMP)
8653 disassemble_section (section, file);
8654#endif
8655 if (dump_sects[i] & HEX_DUMP)
09c11c86 8656 dump_section_as_bytes (section, file);
103f02d3 8657
19e6b90e
L
8658 if (dump_sects[i] & DEBUG_DUMP)
8659 display_debug_section (section, file);
09c11c86
NC
8660
8661 if (dump_sects[i] & STRING_DUMP)
8662 dump_section_as_strings (section, file);
5b18a4bc 8663 }
103f02d3 8664
19e6b90e
L
8665 /* Check to see if the user requested a
8666 dump of a section that does not exist. */
8667 while (i++ < num_dump_sects)
8668 if (dump_sects[i])
8669 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 8670}
103f02d3 8671
5b18a4bc 8672static void
19e6b90e 8673process_mips_fpe_exception (int mask)
5b18a4bc 8674{
19e6b90e
L
8675 if (mask)
8676 {
8677 int first = 1;
8678 if (mask & OEX_FPU_INEX)
8679 fputs ("INEX", stdout), first = 0;
8680 if (mask & OEX_FPU_UFLO)
8681 printf ("%sUFLO", first ? "" : "|"), first = 0;
8682 if (mask & OEX_FPU_OFLO)
8683 printf ("%sOFLO", first ? "" : "|"), first = 0;
8684 if (mask & OEX_FPU_DIV0)
8685 printf ("%sDIV0", first ? "" : "|"), first = 0;
8686 if (mask & OEX_FPU_INVAL)
8687 printf ("%sINVAL", first ? "" : "|");
8688 }
5b18a4bc 8689 else
19e6b90e 8690 fputs ("0", stdout);
5b18a4bc 8691}
103f02d3 8692
11c1ff18
PB
8693/* ARM EABI attributes section. */
8694typedef struct
8695{
8696 int tag;
8697 const char *name;
8698 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
8699 int type;
8700 const char **table;
8701} arm_attr_public_tag;
8702
8703static const char *arm_attr_tag_CPU_arch[] =
8704 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
8705 "v6K", "v7"};
8706static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
8707static const char *arm_attr_tag_THUMB_ISA_use[] =
8708 {"No", "Thumb-1", "Thumb-2"};
b1cc4aeb
PB
8709static const char *arm_attr_tag_VFP_arch[] =
8710 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"};
11c1ff18
PB
8711static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
8712static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
8713static const char *arm_attr_tag_ABI_PCS_config[] =
8714 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
8715 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
8716static const char *arm_attr_tag_ABI_PCS_R9_use[] =
8717 {"V6", "SB", "TLS", "Unused"};
8718static const char *arm_attr_tag_ABI_PCS_RW_data[] =
8719 {"Absolute", "PC-relative", "SB-relative", "None"};
8720static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
8721 {"Absolute", "PC-relative", "None"};
8722static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
8723 {"None", "direct", "GOT-indirect"};
8724static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
8725 {"None", "??? 1", "2", "??? 3", "4"};
8726static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
8727static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
8728static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
8729static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
8730static const char *arm_attr_tag_ABI_FP_number_model[] =
8731 {"Unused", "Finite", "RTABI", "IEEE 754"};
8732static const char *arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
8733static const char *arm_attr_tag_ABI_align8_preserved[] =
8734 {"No", "Yes, except leaf SP", "Yes"};
8735static const char *arm_attr_tag_ABI_enum_size[] =
8736 {"Unused", "small", "int", "forced to int"};
8737static const char *arm_attr_tag_ABI_HardFP_use[] =
8738 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
8739static const char *arm_attr_tag_ABI_VFP_args[] =
8740 {"AAPCS", "VFP registers", "custom"};
8741static const char *arm_attr_tag_ABI_WMMX_args[] =
8742 {"AAPCS", "WMMX registers", "custom"};
8743static const char *arm_attr_tag_ABI_optimization_goals[] =
8744 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8745 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
8746static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
8747 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8748 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
8749
8750#define LOOKUP(id, name) \
8751 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 8752static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
8753{
8754 {4, "CPU_raw_name", 1, NULL},
8755 {5, "CPU_name", 1, NULL},
8756 LOOKUP(6, CPU_arch),
8757 {7, "CPU_arch_profile", 0, NULL},
8758 LOOKUP(8, ARM_ISA_use),
8759 LOOKUP(9, THUMB_ISA_use),
8760 LOOKUP(10, VFP_arch),
8761 LOOKUP(11, WMMX_arch),
8762 LOOKUP(12, NEON_arch),
8763 LOOKUP(13, ABI_PCS_config),
8764 LOOKUP(14, ABI_PCS_R9_use),
8765 LOOKUP(15, ABI_PCS_RW_data),
8766 LOOKUP(16, ABI_PCS_RO_DATA),
8767 LOOKUP(17, ABI_PCS_GOT_use),
8768 LOOKUP(18, ABI_PCS_wchar_t),
8769 LOOKUP(19, ABI_FP_rounding),
8770 LOOKUP(20, ABI_FP_denormal),
8771 LOOKUP(21, ABI_FP_exceptions),
8772 LOOKUP(22, ABI_FP_user_exceptions),
8773 LOOKUP(23, ABI_FP_number_model),
8774 LOOKUP(24, ABI_align8_needed),
8775 LOOKUP(25, ABI_align8_preserved),
8776 LOOKUP(26, ABI_enum_size),
8777 LOOKUP(27, ABI_HardFP_use),
8778 LOOKUP(28, ABI_VFP_args),
8779 LOOKUP(29, ABI_WMMX_args),
8780 LOOKUP(30, ABI_optimization_goals),
8781 LOOKUP(31, ABI_FP_optimization_goals),
8782 {32, "compatibility", 0, NULL}
8783};
8784#undef LOOKUP
8785
8786/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
8787 bytes read. */
8788static unsigned int
8789read_uleb128 (unsigned char *p, unsigned int *plen)
8790{
8791 unsigned char c;
8792 unsigned int val;
8793 int shift;
8794 int len;
8795
8796 val = 0;
8797 shift = 0;
8798 len = 0;
8799 do
8800 {
8801 c = *(p++);
8802 len++;
8803 val |= ((unsigned int)c & 0x7f) << shift;
8804 shift += 7;
8805 }
8806 while (c & 0x80);
8807
8808 *plen = len;
8809 return val;
8810}
8811
8812static unsigned char *
8813display_arm_attribute (unsigned char *p)
8814{
8815 int tag;
8816 unsigned int len;
8817 int val;
8818 arm_attr_public_tag *attr;
8819 unsigned i;
8820 int type;
8821
8822 tag = read_uleb128 (p, &len);
8823 p += len;
8824 attr = NULL;
8825 for (i = 0; i < ARRAY_SIZE(arm_attr_public_tags); i++)
8826 {
8827 if (arm_attr_public_tags[i].tag == tag)
8828 {
8829 attr = &arm_attr_public_tags[i];
8830 break;
8831 }
8832 }
8833
8834 if (attr)
8835 {
8836 printf (" Tag_%s: ", attr->name);
8837 switch (attr->type)
8838 {
8839 case 0:
8840 switch (tag)
8841 {
8842 case 7: /* Tag_CPU_arch_profile. */
8843 val = read_uleb128 (p, &len);
8844 p += len;
8845 switch (val)
8846 {
8847 case 0: printf ("None\n"); break;
8848 case 'A': printf ("Application\n"); break;
8849 case 'R': printf ("Realtime\n"); break;
8850 case 'M': printf ("Microcontroller\n"); break;
8851 default: printf ("??? (%d)\n", val); break;
8852 }
8853 break;
8854
8855 case 32: /* Tag_compatibility. */
8856 val = read_uleb128 (p, &len);
8857 p += len;
8858 printf ("flag = %d, vendor = %s\n", val, p);
8859 p += strlen((char *)p) + 1;
8860 break;
8861
8862 default:
8863 abort();
8864 }
8865 return p;
8866
8867 case 1:
8868 case 2:
8869 type = attr->type;
8870 break;
8871
8872 default:
8873 assert (attr->type & 0x80);
8874 val = read_uleb128 (p, &len);
8875 p += len;
8876 type = attr->type & 0x7f;
8877 if (val >= type)
8878 printf ("??? (%d)\n", val);
8879 else
8880 printf ("%s\n", attr->table[val]);
8881 return p;
8882 }
8883 }
8884 else
8885 {
8886 if (tag & 1)
8887 type = 1; /* String. */
8888 else
8889 type = 2; /* uleb128. */
8890 printf (" Tag_unknown_%d: ", tag);
8891 }
8892
8893 if (type == 1)
8894 {
8895 printf ("\"%s\"\n", p);
8896 p += strlen((char *)p) + 1;
8897 }
8898 else
8899 {
8900 val = read_uleb128 (p, &len);
8901 p += len;
8902 printf ("%d (0x%x)\n", val, val);
8903 }
8904
8905 return p;
8906}
8907
104d59d1 8908static unsigned char *
60bca95a
NC
8909display_gnu_attribute (unsigned char * p,
8910 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
8911{
8912 int tag;
8913 unsigned int len;
8914 int val;
8915 int type;
8916
8917 tag = read_uleb128 (p, &len);
8918 p += len;
8919
8920 /* Tag_compatibility is the only generic GNU attribute defined at
8921 present. */
8922 if (tag == 32)
8923 {
8924 val = read_uleb128 (p, &len);
8925 p += len;
8926 printf ("flag = %d, vendor = %s\n", val, p);
60bca95a 8927 p += strlen ((char *) p) + 1;
104d59d1
JM
8928 return p;
8929 }
8930
8931 if ((tag & 2) == 0 && display_proc_gnu_attribute)
8932 return display_proc_gnu_attribute (p, tag);
8933
8934 if (tag & 1)
8935 type = 1; /* String. */
8936 else
8937 type = 2; /* uleb128. */
8938 printf (" Tag_unknown_%d: ", tag);
8939
8940 if (type == 1)
8941 {
8942 printf ("\"%s\"\n", p);
60bca95a 8943 p += strlen ((char *) p) + 1;
104d59d1
JM
8944 }
8945 else
8946 {
8947 val = read_uleb128 (p, &len);
8948 p += len;
8949 printf ("%d (0x%x)\n", val, val);
8950 }
8951
8952 return p;
8953}
8954
34c8bcba
JM
8955static unsigned char *
8956display_power_gnu_attribute (unsigned char *p, int tag)
8957{
8958 int type;
8959 unsigned int len;
8960 int val;
8961
8962 if (tag == Tag_GNU_Power_ABI_FP)
8963 {
8964 val = read_uleb128 (p, &len);
8965 p += len;
8966 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 8967
34c8bcba
JM
8968 switch (val)
8969 {
8970 case 0:
8971 printf ("Hard or soft float\n");
8972 break;
8973 case 1:
8974 printf ("Hard float\n");
8975 break;
8976 case 2:
8977 printf ("Soft float\n");
8978 break;
3c7b9897
AM
8979 case 3:
8980 printf ("Single-precision hard float\n");
8981 break;
34c8bcba
JM
8982 default:
8983 printf ("??? (%d)\n", val);
8984 break;
8985 }
8986 return p;
8987 }
8988
c6e65352
DJ
8989 if (tag == Tag_GNU_Power_ABI_Vector)
8990 {
8991 val = read_uleb128 (p, &len);
8992 p += len;
8993 printf (" Tag_GNU_Power_ABI_Vector: ");
8994 switch (val)
8995 {
8996 case 0:
8997 printf ("Any\n");
8998 break;
8999 case 1:
9000 printf ("Generic\n");
9001 break;
9002 case 2:
9003 printf ("AltiVec\n");
9004 break;
9005 case 3:
9006 printf ("SPE\n");
9007 break;
9008 default:
9009 printf ("??? (%d)\n", val);
9010 break;
9011 }
9012 return p;
9013 }
9014
34c8bcba
JM
9015 if (tag & 1)
9016 type = 1; /* String. */
9017 else
9018 type = 2; /* uleb128. */
9019 printf (" Tag_unknown_%d: ", tag);
9020
9021 if (type == 1)
9022 {
9023 printf ("\"%s\"\n", p);
60bca95a 9024 p += strlen ((char *) p) + 1;
34c8bcba
JM
9025 }
9026 else
9027 {
9028 val = read_uleb128 (p, &len);
9029 p += len;
9030 printf ("%d (0x%x)\n", val, val);
9031 }
9032
9033 return p;
9034}
9035
2cf19d5c
JM
9036static unsigned char *
9037display_mips_gnu_attribute (unsigned char *p, int tag)
9038{
9039 int type;
9040 unsigned int len;
9041 int val;
9042
9043 if (tag == Tag_GNU_MIPS_ABI_FP)
9044 {
9045 val = read_uleb128 (p, &len);
9046 p += len;
9047 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 9048
2cf19d5c
JM
9049 switch (val)
9050 {
9051 case 0:
9052 printf ("Hard or soft float\n");
9053 break;
9054 case 1:
9055 printf ("Hard float (-mdouble-float)\n");
9056 break;
9057 case 2:
9058 printf ("Hard float (-msingle-float)\n");
9059 break;
9060 case 3:
9061 printf ("Soft float\n");
9062 break;
42554f6a
TS
9063 case 4:
9064 printf ("64-bit float (-mips32r2 -mfp64)\n");
9065 break;
2cf19d5c
JM
9066 default:
9067 printf ("??? (%d)\n", val);
9068 break;
9069 }
9070 return p;
9071 }
9072
9073 if (tag & 1)
9074 type = 1; /* String. */
9075 else
9076 type = 2; /* uleb128. */
9077 printf (" Tag_unknown_%d: ", tag);
9078
9079 if (type == 1)
9080 {
9081 printf ("\"%s\"\n", p);
60bca95a 9082 p += strlen ((char *) p) + 1;
2cf19d5c
JM
9083 }
9084 else
9085 {
9086 val = read_uleb128 (p, &len);
9087 p += len;
9088 printf ("%d (0x%x)\n", val, val);
9089 }
9090
9091 return p;
9092}
9093
11c1ff18 9094static int
60bca95a
NC
9095process_attributes (FILE * file,
9096 const char * public_name,
104d59d1 9097 unsigned int proc_type,
60bca95a
NC
9098 unsigned char * (* display_pub_attribute) (unsigned char *),
9099 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18
PB
9100{
9101 Elf_Internal_Shdr *sect;
9102 unsigned char *contents;
9103 unsigned char *p;
9104 unsigned char *end;
9105 bfd_vma section_len;
9106 bfd_vma len;
9107 unsigned i;
9108
9109 /* Find the section header so that we get the size. */
9110 for (i = 0, sect = section_headers;
9111 i < elf_header.e_shnum;
9112 i++, sect++)
9113 {
104d59d1 9114 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
9115 continue;
9116
9117 contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
9118 _("attributes"));
60bca95a 9119 if (contents == NULL)
11c1ff18 9120 continue;
60bca95a 9121
11c1ff18
PB
9122 p = contents;
9123 if (*p == 'A')
9124 {
9125 len = sect->sh_size - 1;
9126 p++;
60bca95a 9127
11c1ff18
PB
9128 while (len > 0)
9129 {
9130 int namelen;
9131 bfd_boolean public_section;
104d59d1 9132 bfd_boolean gnu_section;
11c1ff18
PB
9133
9134 section_len = byte_get (p, 4);
9135 p += 4;
60bca95a 9136
11c1ff18
PB
9137 if (section_len > len)
9138 {
9139 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 9140 (int) section_len, (int) len);
11c1ff18
PB
9141 section_len = len;
9142 }
60bca95a 9143
11c1ff18
PB
9144 len -= section_len;
9145 printf ("Attribute Section: %s\n", p);
60bca95a
NC
9146
9147 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
9148 public_section = TRUE;
9149 else
9150 public_section = FALSE;
60bca95a
NC
9151
9152 if (streq ((char *) p, "gnu"))
104d59d1
JM
9153 gnu_section = TRUE;
9154 else
9155 gnu_section = FALSE;
60bca95a
NC
9156
9157 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
9158 p += namelen;
9159 section_len -= namelen + 4;
60bca95a 9160
11c1ff18
PB
9161 while (section_len > 0)
9162 {
9163 int tag = *(p++);
9164 int val;
9165 bfd_vma size;
60bca95a 9166
11c1ff18
PB
9167 size = byte_get (p, 4);
9168 if (size > section_len)
9169 {
9170 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 9171 (int) size, (int) section_len);
11c1ff18
PB
9172 size = section_len;
9173 }
60bca95a 9174
11c1ff18
PB
9175 section_len -= size;
9176 end = p + size - 1;
9177 p += 4;
60bca95a 9178
11c1ff18
PB
9179 switch (tag)
9180 {
9181 case 1:
9182 printf ("File Attributes\n");
9183 break;
9184 case 2:
9185 printf ("Section Attributes:");
9186 goto do_numlist;
9187 case 3:
9188 printf ("Symbol Attributes:");
9189 do_numlist:
9190 for (;;)
9191 {
9192 unsigned int i;
60bca95a 9193
11c1ff18
PB
9194 val = read_uleb128 (p, &i);
9195 p += i;
9196 if (val == 0)
9197 break;
9198 printf (" %d", val);
9199 }
9200 printf ("\n");
9201 break;
9202 default:
9203 printf ("Unknown tag: %d\n", tag);
9204 public_section = FALSE;
9205 break;
9206 }
60bca95a 9207
11c1ff18
PB
9208 if (public_section)
9209 {
9210 while (p < end)
104d59d1
JM
9211 p = display_pub_attribute (p);
9212 }
9213 else if (gnu_section)
9214 {
9215 while (p < end)
9216 p = display_gnu_attribute (p,
9217 display_proc_gnu_attribute);
11c1ff18
PB
9218 }
9219 else
9220 {
9221 /* ??? Do something sensible, like dump hex. */
9222 printf (" Unknown section contexts\n");
9223 p = end;
9224 }
9225 }
9226 }
9227 }
9228 else
60bca95a 9229 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 9230
60bca95a 9231 free (contents);
11c1ff18
PB
9232 }
9233 return 1;
9234}
9235
104d59d1
JM
9236static int
9237process_arm_specific (FILE *file)
9238{
9239 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
9240 display_arm_attribute, NULL);
9241}
9242
34c8bcba
JM
9243static int
9244process_power_specific (FILE *file)
9245{
9246 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
9247 display_power_gnu_attribute);
9248}
9249
ccb4c951
RS
9250/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
9251 Print the Address, Access and Initial fields of an entry at VMA ADDR
9252 and return the VMA of the next entry. */
9253
9254static bfd_vma
9255print_mips_got_entry (unsigned char *data, bfd_vma pltgot, bfd_vma addr)
9256{
9257 printf (" ");
9258 print_vma (addr, LONG_HEX);
9259 printf (" ");
9260 if (addr < pltgot + 0xfff0)
9261 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
9262 else
9263 printf ("%10s", "");
9264 printf (" ");
9265 if (data == NULL)
9266 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
9267 else
9268 {
9269 bfd_vma entry;
9270
9271 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
9272 print_vma (entry, LONG_HEX);
9273 }
9274 return addr + (is_32bit_elf ? 4 : 8);
9275}
9276
861fb55a
DJ
9277/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
9278 PLTGOT. Print the Address and Initial fields of an entry at VMA
9279 ADDR and return the VMA of the next entry. */
9280
9281static bfd_vma
9282print_mips_pltgot_entry (unsigned char *data, bfd_vma pltgot, bfd_vma addr)
9283{
9284 printf (" ");
9285 print_vma (addr, LONG_HEX);
9286 printf (" ");
9287 if (data == NULL)
9288 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
9289 else
9290 {
9291 bfd_vma entry;
9292
9293 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
9294 print_vma (entry, LONG_HEX);
9295 }
9296 return addr + (is_32bit_elf ? 4 : 8);
9297}
9298
19e6b90e
L
9299static int
9300process_mips_specific (FILE *file)
5b18a4bc 9301{
19e6b90e
L
9302 Elf_Internal_Dyn *entry;
9303 size_t liblist_offset = 0;
9304 size_t liblistno = 0;
9305 size_t conflictsno = 0;
9306 size_t options_offset = 0;
9307 size_t conflicts_offset = 0;
861fb55a
DJ
9308 size_t pltrelsz = 0;
9309 size_t pltrel = 0;
ccb4c951 9310 bfd_vma pltgot = 0;
861fb55a
DJ
9311 bfd_vma mips_pltgot = 0;
9312 bfd_vma jmprel = 0;
ccb4c951
RS
9313 bfd_vma local_gotno = 0;
9314 bfd_vma gotsym = 0;
9315 bfd_vma symtabno = 0;
103f02d3 9316
2cf19d5c
JM
9317 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
9318 display_mips_gnu_attribute);
9319
19e6b90e
L
9320 /* We have a lot of special sections. Thanks SGI! */
9321 if (dynamic_section == NULL)
9322 /* No information available. */
9323 return 0;
252b5132 9324
b2d38a17 9325 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
9326 switch (entry->d_tag)
9327 {
9328 case DT_MIPS_LIBLIST:
d93f0186
NC
9329 liblist_offset
9330 = offset_from_vma (file, entry->d_un.d_val,
9331 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9332 break;
9333 case DT_MIPS_LIBLISTNO:
9334 liblistno = entry->d_un.d_val;
9335 break;
9336 case DT_MIPS_OPTIONS:
d93f0186 9337 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9338 break;
9339 case DT_MIPS_CONFLICT:
d93f0186
NC
9340 conflicts_offset
9341 = offset_from_vma (file, entry->d_un.d_val,
9342 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9343 break;
9344 case DT_MIPS_CONFLICTNO:
9345 conflictsno = entry->d_un.d_val;
9346 break;
ccb4c951 9347 case DT_PLTGOT:
861fb55a
DJ
9348 pltgot = entry->d_un.d_ptr;
9349 break;
ccb4c951
RS
9350 case DT_MIPS_LOCAL_GOTNO:
9351 local_gotno = entry->d_un.d_val;
9352 break;
9353 case DT_MIPS_GOTSYM:
9354 gotsym = entry->d_un.d_val;
9355 break;
9356 case DT_MIPS_SYMTABNO:
9357 symtabno = entry->d_un.d_val;
9358 break;
861fb55a
DJ
9359 case DT_MIPS_PLTGOT:
9360 mips_pltgot = entry->d_un.d_ptr;
9361 break;
9362 case DT_PLTREL:
9363 pltrel = entry->d_un.d_val;
9364 break;
9365 case DT_PLTRELSZ:
9366 pltrelsz = entry->d_un.d_val;
9367 break;
9368 case DT_JMPREL:
9369 jmprel = entry->d_un.d_ptr;
9370 break;
252b5132
RH
9371 default:
9372 break;
9373 }
9374
9375 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9376 {
b34976b6 9377 Elf32_External_Lib *elib;
252b5132
RH
9378 size_t cnt;
9379
d3ba0551 9380 elib = get_data (NULL, file, liblist_offset,
c256ffe7 9381 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 9382 _("liblist"));
a6e9f9df 9383 if (elib)
252b5132 9384 {
a6e9f9df
AM
9385 printf ("\nSection '.liblist' contains %lu entries:\n",
9386 (unsigned long) liblistno);
9387 fputs (" Library Time Stamp Checksum Version Flags\n",
9388 stdout);
9389
9390 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9391 {
a6e9f9df
AM
9392 Elf32_Lib liblist;
9393 time_t time;
9394 char timebuf[20];
b34976b6 9395 struct tm *tmp;
a6e9f9df
AM
9396
9397 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9398 time = BYTE_GET (elib[cnt].l_time_stamp);
9399 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9400 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9401 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9402
9403 tmp = gmtime (&time);
e9e44622
JJ
9404 snprintf (timebuf, sizeof (timebuf),
9405 "%04u-%02u-%02uT%02u:%02u:%02u",
9406 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9407 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 9408
31104126 9409 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
9410 if (VALID_DYNAMIC_NAME (liblist.l_name))
9411 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
9412 else
9413 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
9414 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9415 liblist.l_version);
a6e9f9df
AM
9416
9417 if (liblist.l_flags == 0)
9418 puts (" NONE");
9419 else
9420 {
9421 static const struct
252b5132 9422 {
b34976b6 9423 const char *name;
a6e9f9df 9424 int bit;
252b5132 9425 }
a6e9f9df
AM
9426 l_flags_vals[] =
9427 {
9428 { " EXACT_MATCH", LL_EXACT_MATCH },
9429 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9430 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9431 { " EXPORTS", LL_EXPORTS },
9432 { " DELAY_LOAD", LL_DELAY_LOAD },
9433 { " DELTA", LL_DELTA }
9434 };
9435 int flags = liblist.l_flags;
9436 size_t fcnt;
9437
60bca95a 9438 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
9439 if ((flags & l_flags_vals[fcnt].bit) != 0)
9440 {
9441 fputs (l_flags_vals[fcnt].name, stdout);
9442 flags ^= l_flags_vals[fcnt].bit;
9443 }
9444 if (flags != 0)
9445 printf (" %#x", (unsigned int) flags);
252b5132 9446
a6e9f9df
AM
9447 puts ("");
9448 }
252b5132 9449 }
252b5132 9450
a6e9f9df
AM
9451 free (elib);
9452 }
252b5132
RH
9453 }
9454
9455 if (options_offset != 0)
9456 {
b34976b6
AM
9457 Elf_External_Options *eopt;
9458 Elf_Internal_Shdr *sect = section_headers;
9459 Elf_Internal_Options *iopt;
9460 Elf_Internal_Options *option;
252b5132
RH
9461 size_t offset;
9462 int cnt;
9463
9464 /* Find the section header so that we get the size. */
9465 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 9466 ++sect;
252b5132 9467
c256ffe7 9468 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 9469 _("options"));
a6e9f9df 9470 if (eopt)
252b5132 9471 {
c256ffe7 9472 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
a6e9f9df
AM
9473 if (iopt == NULL)
9474 {
591a748a 9475 error (_("Out of memory\n"));
a6e9f9df
AM
9476 return 0;
9477 }
76da6bbe 9478
a6e9f9df
AM
9479 offset = cnt = 0;
9480 option = iopt;
252b5132 9481
a6e9f9df
AM
9482 while (offset < sect->sh_size)
9483 {
b34976b6 9484 Elf_External_Options *eoption;
252b5132 9485
a6e9f9df 9486 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 9487
a6e9f9df
AM
9488 option->kind = BYTE_GET (eoption->kind);
9489 option->size = BYTE_GET (eoption->size);
9490 option->section = BYTE_GET (eoption->section);
9491 option->info = BYTE_GET (eoption->info);
76da6bbe 9492
a6e9f9df 9493 offset += option->size;
252b5132 9494
a6e9f9df
AM
9495 ++option;
9496 ++cnt;
9497 }
252b5132 9498
a6e9f9df
AM
9499 printf (_("\nSection '%s' contains %d entries:\n"),
9500 SECTION_NAME (sect), cnt);
76da6bbe 9501
a6e9f9df 9502 option = iopt;
252b5132 9503
a6e9f9df 9504 while (cnt-- > 0)
252b5132 9505 {
a6e9f9df
AM
9506 size_t len;
9507
9508 switch (option->kind)
252b5132 9509 {
a6e9f9df
AM
9510 case ODK_NULL:
9511 /* This shouldn't happen. */
9512 printf (" NULL %d %lx", option->section, option->info);
9513 break;
9514 case ODK_REGINFO:
9515 printf (" REGINFO ");
9516 if (elf_header.e_machine == EM_MIPS)
9517 {
9518 /* 32bit form. */
b34976b6
AM
9519 Elf32_External_RegInfo *ereg;
9520 Elf32_RegInfo reginfo;
a6e9f9df
AM
9521
9522 ereg = (Elf32_External_RegInfo *) (option + 1);
9523 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9524 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9525 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9526 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9527 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9528 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
9529
9530 printf ("GPR %08lx GP 0x%lx\n",
9531 reginfo.ri_gprmask,
9532 (unsigned long) reginfo.ri_gp_value);
9533 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9534 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9535 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9536 }
9537 else
9538 {
9539 /* 64 bit form. */
b34976b6 9540 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
9541 Elf64_Internal_RegInfo reginfo;
9542
9543 ereg = (Elf64_External_RegInfo *) (option + 1);
9544 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9545 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9546 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9547 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9548 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 9549 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
9550
9551 printf ("GPR %08lx GP 0x",
9552 reginfo.ri_gprmask);
9553 printf_vma (reginfo.ri_gp_value);
9554 printf ("\n");
9555
9556 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9557 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9558 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9559 }
9560 ++option;
9561 continue;
9562 case ODK_EXCEPTIONS:
9563 fputs (" EXCEPTIONS fpe_min(", stdout);
9564 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
9565 fputs (") fpe_max(", stdout);
9566 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
9567 fputs (")", stdout);
9568
9569 if (option->info & OEX_PAGE0)
9570 fputs (" PAGE0", stdout);
9571 if (option->info & OEX_SMM)
9572 fputs (" SMM", stdout);
9573 if (option->info & OEX_FPDBUG)
9574 fputs (" FPDBUG", stdout);
9575 if (option->info & OEX_DISMISS)
9576 fputs (" DISMISS", stdout);
9577 break;
9578 case ODK_PAD:
9579 fputs (" PAD ", stdout);
9580 if (option->info & OPAD_PREFIX)
9581 fputs (" PREFIX", stdout);
9582 if (option->info & OPAD_POSTFIX)
9583 fputs (" POSTFIX", stdout);
9584 if (option->info & OPAD_SYMBOL)
9585 fputs (" SYMBOL", stdout);
9586 break;
9587 case ODK_HWPATCH:
9588 fputs (" HWPATCH ", stdout);
9589 if (option->info & OHW_R4KEOP)
9590 fputs (" R4KEOP", stdout);
9591 if (option->info & OHW_R8KPFETCH)
9592 fputs (" R8KPFETCH", stdout);
9593 if (option->info & OHW_R5KEOP)
9594 fputs (" R5KEOP", stdout);
9595 if (option->info & OHW_R5KCVTL)
9596 fputs (" R5KCVTL", stdout);
9597 break;
9598 case ODK_FILL:
9599 fputs (" FILL ", stdout);
9600 /* XXX Print content of info word? */
9601 break;
9602 case ODK_TAGS:
9603 fputs (" TAGS ", stdout);
9604 /* XXX Print content of info word? */
9605 break;
9606 case ODK_HWAND:
9607 fputs (" HWAND ", stdout);
9608 if (option->info & OHWA0_R4KEOP_CHECKED)
9609 fputs (" R4KEOP_CHECKED", stdout);
9610 if (option->info & OHWA0_R4KEOP_CLEAN)
9611 fputs (" R4KEOP_CLEAN", stdout);
9612 break;
9613 case ODK_HWOR:
9614 fputs (" HWOR ", stdout);
9615 if (option->info & OHWA0_R4KEOP_CHECKED)
9616 fputs (" R4KEOP_CHECKED", stdout);
9617 if (option->info & OHWA0_R4KEOP_CLEAN)
9618 fputs (" R4KEOP_CLEAN", stdout);
9619 break;
9620 case ODK_GP_GROUP:
9621 printf (" GP_GROUP %#06lx self-contained %#06lx",
9622 option->info & OGP_GROUP,
9623 (option->info & OGP_SELF) >> 16);
9624 break;
9625 case ODK_IDENT:
9626 printf (" IDENT %#06lx self-contained %#06lx",
9627 option->info & OGP_GROUP,
9628 (option->info & OGP_SELF) >> 16);
9629 break;
9630 default:
9631 /* This shouldn't happen. */
9632 printf (" %3d ??? %d %lx",
9633 option->kind, option->section, option->info);
9634 break;
252b5132 9635 }
a6e9f9df 9636
b34976b6 9637 len = sizeof (*eopt);
a6e9f9df
AM
9638 while (len < option->size)
9639 if (((char *) option)[len] >= ' '
9640 && ((char *) option)[len] < 0x7f)
9641 printf ("%c", ((char *) option)[len++]);
9642 else
9643 printf ("\\%03o", ((char *) option)[len++]);
9644
9645 fputs ("\n", stdout);
252b5132 9646 ++option;
252b5132
RH
9647 }
9648
a6e9f9df 9649 free (eopt);
252b5132 9650 }
252b5132
RH
9651 }
9652
9653 if (conflicts_offset != 0 && conflictsno != 0)
9654 {
b34976b6 9655 Elf32_Conflict *iconf;
252b5132
RH
9656 size_t cnt;
9657
9658 if (dynamic_symbols == NULL)
9659 {
591a748a 9660 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
9661 return 0;
9662 }
9663
c256ffe7 9664 iconf = cmalloc (conflictsno, sizeof (*iconf));
252b5132
RH
9665 if (iconf == NULL)
9666 {
591a748a 9667 error (_("Out of memory\n"));
252b5132
RH
9668 return 0;
9669 }
9670
9ea033b2 9671 if (is_32bit_elf)
252b5132 9672 {
b34976b6 9673 Elf32_External_Conflict *econf32;
a6e9f9df 9674
d3ba0551 9675 econf32 = get_data (NULL, file, conflicts_offset,
c256ffe7 9676 conflictsno, sizeof (*econf32), _("conflict"));
a6e9f9df
AM
9677 if (!econf32)
9678 return 0;
252b5132
RH
9679
9680 for (cnt = 0; cnt < conflictsno; ++cnt)
9681 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
9682
9683 free (econf32);
252b5132
RH
9684 }
9685 else
9686 {
b34976b6 9687 Elf64_External_Conflict *econf64;
a6e9f9df 9688
d3ba0551 9689 econf64 = get_data (NULL, file, conflicts_offset,
c256ffe7 9690 conflictsno, sizeof (*econf64), _("conflict"));
a6e9f9df
AM
9691 if (!econf64)
9692 return 0;
252b5132
RH
9693
9694 for (cnt = 0; cnt < conflictsno; ++cnt)
9695 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
9696
9697 free (econf64);
252b5132
RH
9698 }
9699
c7e7ca54
NC
9700 printf (_("\nSection '.conflict' contains %lu entries:\n"),
9701 (unsigned long) conflictsno);
252b5132
RH
9702 puts (_(" Num: Index Value Name"));
9703
9704 for (cnt = 0; cnt < conflictsno; ++cnt)
9705 {
b34976b6 9706 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 9707
b34976b6 9708 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 9709 print_vma (psym->st_value, FULL_HEX);
31104126 9710 putchar (' ');
d79b3d50
NC
9711 if (VALID_DYNAMIC_NAME (psym->st_name))
9712 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9713 else
9714 printf ("<corrupt: %14ld>", psym->st_name);
31104126 9715 putchar ('\n');
252b5132
RH
9716 }
9717
252b5132
RH
9718 free (iconf);
9719 }
9720
ccb4c951
RS
9721 if (pltgot != 0 && local_gotno != 0)
9722 {
9723 bfd_vma entry, local_end, global_end;
bbeee7ea 9724 size_t i, offset;
ccb4c951 9725 unsigned char *data;
bbeee7ea 9726 int addr_size;
ccb4c951
RS
9727
9728 entry = pltgot;
9729 addr_size = (is_32bit_elf ? 4 : 8);
9730 local_end = pltgot + local_gotno * addr_size;
9731 global_end = local_end + (symtabno - gotsym) * addr_size;
9732
9733 offset = offset_from_vma (file, pltgot, global_end - pltgot);
9734 data = get_data (NULL, file, offset, global_end - pltgot, 1, _("GOT"));
9735 printf (_("\nPrimary GOT:\n"));
9736 printf (_(" Canonical gp value: "));
9737 print_vma (pltgot + 0x7ff0, LONG_HEX);
9738 printf ("\n\n");
9739
9740 printf (_(" Reserved entries:\n"));
9741 printf (_(" %*s %10s %*s Purpose\n"),
9742 addr_size * 2, "Address", "Access",
9743 addr_size * 2, "Initial");
9744 entry = print_mips_got_entry (data, pltgot, entry);
9745 printf (" Lazy resolver\n");
9746 if (data
9747 && (byte_get (data + entry - pltgot, addr_size)
9748 >> (addr_size * 8 - 1)) != 0)
9749 {
9750 entry = print_mips_got_entry (data, pltgot, entry);
9751 printf (" Module pointer (GNU extension)\n");
9752 }
9753 printf ("\n");
9754
9755 if (entry < local_end)
9756 {
9757 printf (_(" Local entries:\n"));
9758 printf (_(" %*s %10s %*s\n"),
9759 addr_size * 2, "Address", "Access",
9760 addr_size * 2, "Initial");
9761 while (entry < local_end)
9762 {
9763 entry = print_mips_got_entry (data, pltgot, entry);
9764 printf ("\n");
9765 }
9766 printf ("\n");
9767 }
9768
9769 if (gotsym < symtabno)
9770 {
9771 int sym_width;
9772
9773 printf (_(" Global entries:\n"));
9774 printf (_(" %*s %10s %*s %*s %-7s %3s %s\n"),
9775 addr_size * 2, "Address", "Access",
9776 addr_size * 2, "Initial",
9777 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
9778 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
9779 for (i = gotsym; i < symtabno; i++)
9780 {
9781 Elf_Internal_Sym *psym;
9782
9783 psym = dynamic_symbols + i;
9784 entry = print_mips_got_entry (data, pltgot, entry);
9785 printf (" ");
9786 print_vma (psym->st_value, LONG_HEX);
9787 printf (" %-7s %3s ",
9788 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
9789 get_symbol_index_type (psym->st_shndx));
9790 if (VALID_DYNAMIC_NAME (psym->st_name))
9791 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
9792 else
9793 printf ("<corrupt: %14ld>", psym->st_name);
9794 printf ("\n");
9795 }
9796 printf ("\n");
9797 }
9798
9799 if (data)
9800 free (data);
9801 }
9802
861fb55a
DJ
9803 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
9804 {
9805 bfd_vma entry, end;
9806 size_t offset, rel_offset;
9807 unsigned long count, i;
9808 unsigned char *data;
9809 int addr_size, sym_width;
9810 Elf_Internal_Rela *rels;
9811
9812 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
9813 if (pltrel == DT_RELA)
9814 {
9815 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
9816 return 0;
9817 }
9818 else
9819 {
9820 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
9821 return 0;
9822 }
9823
9824 entry = mips_pltgot;
9825 addr_size = (is_32bit_elf ? 4 : 8);
9826 end = mips_pltgot + (2 + count) * addr_size;
9827
9828 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
9829 data = get_data (NULL, file, offset, end - mips_pltgot, 1, _("PLT GOT"));
9830 printf (_("\nPLT GOT:\n\n"));
9831 printf (_(" Reserved entries:\n"));
9832 printf (_(" %*s %*s Purpose\n"),
9833 addr_size * 2, "Address", addr_size * 2, "Initial");
9834 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
9835 printf (" PLT lazy resolver\n");
9836 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
9837 printf (" Module pointer\n");
9838 printf ("\n");
9839
9840 printf (_(" Entries:\n"));
9841 printf (_(" %*s %*s %*s %-7s %3s %s\n"),
9842 addr_size * 2, "Address",
9843 addr_size * 2, "Initial",
9844 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
9845 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
9846 for (i = 0; i < count; i++)
9847 {
9848 Elf_Internal_Sym *psym;
9849
9850 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
9851 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
9852 printf (" ");
9853 print_vma (psym->st_value, LONG_HEX);
9854 printf (" %-7s %3s ",
9855 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
9856 get_symbol_index_type (psym->st_shndx));
9857 if (VALID_DYNAMIC_NAME (psym->st_name))
9858 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
9859 else
9860 printf ("<corrupt: %14ld>", psym->st_name);
9861 printf ("\n");
9862 }
9863 printf ("\n");
9864
9865 if (data)
9866 free (data);
9867 free (rels);
9868 }
9869
252b5132
RH
9870 return 1;
9871}
9872
047b2264 9873static int
d3ba0551 9874process_gnu_liblist (FILE *file)
047b2264 9875{
b34976b6
AM
9876 Elf_Internal_Shdr *section, *string_sec;
9877 Elf32_External_Lib *elib;
9878 char *strtab;
c256ffe7 9879 size_t strtab_size;
047b2264
JJ
9880 size_t cnt;
9881 unsigned i;
9882
9883 if (! do_arch)
9884 return 0;
9885
9886 for (i = 0, section = section_headers;
9887 i < elf_header.e_shnum;
b34976b6 9888 i++, section++)
047b2264
JJ
9889 {
9890 switch (section->sh_type)
9891 {
9892 case SHT_GNU_LIBLIST:
4fbb74a6 9893 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9894 break;
9895
9896 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 9897 _("liblist"));
047b2264
JJ
9898
9899 if (elib == NULL)
9900 break;
4fbb74a6 9901 string_sec = section_headers + section->sh_link;
047b2264 9902
c256ffe7 9903 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 9904 string_sec->sh_size, _("liblist string table"));
c256ffe7 9905 strtab_size = string_sec->sh_size;
047b2264
JJ
9906
9907 if (strtab == NULL
9908 || section->sh_entsize != sizeof (Elf32_External_Lib))
9909 {
9910 free (elib);
9911 break;
9912 }
9913
9914 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
9915 SECTION_NAME (section),
0af1713e 9916 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264
JJ
9917
9918 puts (" Library Time Stamp Checksum Version Flags");
9919
9920 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
9921 ++cnt)
9922 {
9923 Elf32_Lib liblist;
9924 time_t time;
9925 char timebuf[20];
b34976b6 9926 struct tm *tmp;
047b2264
JJ
9927
9928 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9929 time = BYTE_GET (elib[cnt].l_time_stamp);
9930 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9931 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9932 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9933
9934 tmp = gmtime (&time);
e9e44622
JJ
9935 snprintf (timebuf, sizeof (timebuf),
9936 "%04u-%02u-%02uT%02u:%02u:%02u",
9937 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9938 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9939
9940 printf ("%3lu: ", (unsigned long) cnt);
9941 if (do_wide)
c256ffe7
JJ
9942 printf ("%-20s", liblist.l_name < strtab_size
9943 ? strtab + liblist.l_name : "<corrupt>");
047b2264 9944 else
c256ffe7
JJ
9945 printf ("%-20.20s", liblist.l_name < strtab_size
9946 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
9947 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
9948 liblist.l_version, liblist.l_flags);
9949 }
9950
9951 free (elib);
9952 }
9953 }
9954
9955 return 1;
9956}
9957
9437c45b 9958static const char *
d3ba0551 9959get_note_type (unsigned e_type)
779fe533
NC
9960{
9961 static char buff[64];
103f02d3 9962
1ec5cd37
NC
9963 if (elf_header.e_type == ET_CORE)
9964 switch (e_type)
9965 {
57346661 9966 case NT_AUXV:
1ec5cd37 9967 return _("NT_AUXV (auxiliary vector)");
57346661 9968 case NT_PRSTATUS:
1ec5cd37 9969 return _("NT_PRSTATUS (prstatus structure)");
57346661 9970 case NT_FPREGSET:
1ec5cd37 9971 return _("NT_FPREGSET (floating point registers)");
57346661 9972 case NT_PRPSINFO:
1ec5cd37 9973 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 9974 case NT_TASKSTRUCT:
1ec5cd37 9975 return _("NT_TASKSTRUCT (task structure)");
57346661 9976 case NT_PRXFPREG:
1ec5cd37 9977 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
9978 case NT_PPC_VMX:
9979 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
9980 case NT_PPC_VSX:
9981 return _("NT_PPC_VSX (ppc VSX registers)");
57346661 9982 case NT_PSTATUS:
1ec5cd37 9983 return _("NT_PSTATUS (pstatus structure)");
57346661 9984 case NT_FPREGS:
1ec5cd37 9985 return _("NT_FPREGS (floating point registers)");
57346661 9986 case NT_PSINFO:
1ec5cd37 9987 return _("NT_PSINFO (psinfo structure)");
57346661 9988 case NT_LWPSTATUS:
1ec5cd37 9989 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 9990 case NT_LWPSINFO:
1ec5cd37 9991 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 9992 case NT_WIN32PSTATUS:
1ec5cd37
NC
9993 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9994 default:
9995 break;
9996 }
9997 else
9998 switch (e_type)
9999 {
10000 case NT_VERSION:
10001 return _("NT_VERSION (version)");
10002 case NT_ARCH:
10003 return _("NT_ARCH (architecture)");
10004 default:
10005 break;
10006 }
10007
e9e44622 10008 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 10009 return buff;
779fe533
NC
10010}
10011
1118d252
RM
10012static const char *
10013get_gnu_elf_note_type (unsigned e_type)
10014{
10015 static char buff[64];
10016
10017 switch (e_type)
10018 {
10019 case NT_GNU_ABI_TAG:
10020 return _("NT_GNU_ABI_TAG (ABI version tag)");
10021 case NT_GNU_HWCAP:
10022 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
10023 case NT_GNU_BUILD_ID:
10024 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
10025 case NT_GNU_GOLD_VERSION:
10026 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
10027 default:
10028 break;
10029 }
10030
10031 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
10032 return buff;
10033}
10034
9437c45b 10035static const char *
d3ba0551 10036get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
10037{
10038 static char buff[64];
10039
b4db1224 10040 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10041 {
10042 /* NetBSD core "procinfo" structure. */
10043 return _("NetBSD procinfo structure");
10044 }
10045
10046 /* As of Jan 2002 there are no other machine-independent notes
10047 defined for NetBSD core files. If the note type is less
10048 than the start of the machine-dependent note types, we don't
10049 understand it. */
10050
b4db1224 10051 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 10052 {
e9e44622 10053 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
10054 return buff;
10055 }
10056
10057 switch (elf_header.e_machine)
10058 {
10059 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10060 and PT_GETFPREGS == mach+2. */
10061
10062 case EM_OLD_ALPHA:
10063 case EM_ALPHA:
10064 case EM_SPARC:
10065 case EM_SPARC32PLUS:
10066 case EM_SPARCV9:
10067 switch (e_type)
10068 {
b4db1224
JT
10069 case NT_NETBSDCORE_FIRSTMACH+0:
10070 return _("PT_GETREGS (reg structure)");
10071 case NT_NETBSDCORE_FIRSTMACH+2:
10072 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10073 default:
10074 break;
10075 }
10076 break;
10077
10078 /* On all other arch's, PT_GETREGS == mach+1 and
10079 PT_GETFPREGS == mach+3. */
10080 default:
10081 switch (e_type)
10082 {
b4db1224
JT
10083 case NT_NETBSDCORE_FIRSTMACH+1:
10084 return _("PT_GETREGS (reg structure)");
10085 case NT_NETBSDCORE_FIRSTMACH+3:
10086 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10087 default:
10088 break;
10089 }
10090 }
10091
e9e44622
JJ
10092 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
10093 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10094 return buff;
10095}
10096
6d118b09
NC
10097/* Note that by the ELF standard, the name field is already null byte
10098 terminated, and namesz includes the terminating null byte.
10099 I.E. the value of namesz for the name "FSF" is 4.
10100
e3c8793a 10101 If the value of namesz is zero, there is no name present. */
779fe533 10102static int
d3ba0551 10103process_note (Elf_Internal_Note *pnote)
779fe533 10104{
b15fa79e 10105 const char *name = pnote->namesz ? pnote->namedata : "(NONE)";
9437c45b
JT
10106 const char *nt;
10107
10108 if (pnote->namesz == 0)
1ec5cd37
NC
10109 /* If there is no note name, then use the default set of
10110 note type strings. */
10111 nt = get_note_type (pnote->type);
10112
1118d252
RM
10113 else if (const_strneq (pnote->namedata, "GNU"))
10114 /* GNU-specific object file notes. */
10115 nt = get_gnu_elf_note_type (pnote->type);
10116
0112cd26 10117 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
10118 /* NetBSD-specific core file notes. */
10119 nt = get_netbsd_elfcore_note_type (pnote->type);
10120
b15fa79e
AM
10121 else if (strneq (pnote->namedata, "SPU/", 4))
10122 {
10123 /* SPU-specific core file notes. */
10124 nt = pnote->namedata + 4;
10125 name = "SPU";
10126 }
10127
9437c45b 10128 else
1ec5cd37
NC
10129 /* Don't recognize this note name; just use the default set of
10130 note type strings. */
9437c45b 10131 nt = get_note_type (pnote->type);
9437c45b 10132
b15fa79e 10133 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
10134 return 1;
10135}
10136
6d118b09 10137
779fe533 10138static int
d3ba0551 10139process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 10140{
b34976b6
AM
10141 Elf_External_Note *pnotes;
10142 Elf_External_Note *external;
10143 int res = 1;
103f02d3 10144
779fe533
NC
10145 if (length <= 0)
10146 return 0;
103f02d3 10147
c256ffe7 10148 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
10149 if (!pnotes)
10150 return 0;
779fe533 10151
103f02d3 10152 external = pnotes;
103f02d3 10153
305c7206 10154 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10155 (unsigned long) offset, (unsigned long) length);
779fe533 10156 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10157
6d118b09 10158 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 10159 {
b34976b6
AM
10160 Elf_External_Note *next;
10161 Elf_Internal_Note inote;
10162 char *temp = NULL;
6d118b09
NC
10163
10164 inote.type = BYTE_GET (external->type);
10165 inote.namesz = BYTE_GET (external->namesz);
10166 inote.namedata = external->name;
10167 inote.descsz = BYTE_GET (external->descsz);
10168 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10169 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10170
3e55a963
NC
10171 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
10172
10173 if (((char *) next) > (((char *) pnotes) + length))
10174 {
0fd3a477 10175 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 10176 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 10177 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
10178 inote.type, inote.namesz, inote.descsz);
10179 break;
10180 }
10181
10182 external = next;
6d118b09
NC
10183
10184 /* Verify that name is null terminated. It appears that at least
10185 one version of Linux (RedHat 6.0) generates corefiles that don't
10186 comply with the ELF spec by failing to include the null byte in
10187 namesz. */
10188 if (inote.namedata[inote.namesz] != '\0')
10189 {
10190 temp = malloc (inote.namesz + 1);
76da6bbe 10191
6d118b09
NC
10192 if (temp == NULL)
10193 {
10194 error (_("Out of memory\n"));
10195 res = 0;
10196 break;
10197 }
76da6bbe 10198
6d118b09
NC
10199 strncpy (temp, inote.namedata, inote.namesz);
10200 temp[inote.namesz] = 0;
76da6bbe 10201
6d118b09
NC
10202 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10203 inote.namedata = temp;
10204 }
10205
10206 res &= process_note (& inote);
103f02d3 10207
6d118b09
NC
10208 if (temp != NULL)
10209 {
10210 free (temp);
10211 temp = NULL;
10212 }
779fe533
NC
10213 }
10214
10215 free (pnotes);
103f02d3 10216
779fe533
NC
10217 return res;
10218}
10219
10220static int
d3ba0551 10221process_corefile_note_segments (FILE *file)
779fe533 10222{
b34976b6
AM
10223 Elf_Internal_Phdr *segment;
10224 unsigned int i;
10225 int res = 1;
103f02d3 10226
d93f0186 10227 if (! get_program_headers (file))
779fe533 10228 return 0;
103f02d3 10229
779fe533
NC
10230 for (i = 0, segment = program_headers;
10231 i < elf_header.e_phnum;
b34976b6 10232 i++, segment++)
779fe533
NC
10233 {
10234 if (segment->p_type == PT_NOTE)
103f02d3 10235 res &= process_corefile_note_segment (file,
30800947
NC
10236 (bfd_vma) segment->p_offset,
10237 (bfd_vma) segment->p_filesz);
779fe533 10238 }
103f02d3 10239
779fe533
NC
10240 return res;
10241}
10242
10243static int
1ec5cd37
NC
10244process_note_sections (FILE *file)
10245{
10246 Elf_Internal_Shdr *section;
10247 unsigned long i;
10248 int res = 1;
10249
10250 for (i = 0, section = section_headers;
10251 i < elf_header.e_shnum;
10252 i++, section++)
10253 if (section->sh_type == SHT_NOTE)
10254 res &= process_corefile_note_segment (file,
10255 (bfd_vma) section->sh_offset,
10256 (bfd_vma) section->sh_size);
10257
10258 return res;
10259}
10260
10261static int
10262process_notes (FILE *file)
779fe533
NC
10263{
10264 /* If we have not been asked to display the notes then do nothing. */
10265 if (! do_notes)
10266 return 1;
103f02d3 10267
779fe533 10268 if (elf_header.e_type != ET_CORE)
1ec5cd37 10269 return process_note_sections (file);
103f02d3 10270
779fe533 10271 /* No program headers means no NOTE segment. */
1ec5cd37
NC
10272 if (elf_header.e_phnum > 0)
10273 return process_corefile_note_segments (file);
779fe533 10274
1ec5cd37
NC
10275 printf (_("No note segments present in the core file.\n"));
10276 return 1;
779fe533
NC
10277}
10278
252b5132 10279static int
d3ba0551 10280process_arch_specific (FILE *file)
252b5132 10281{
a952a375
NC
10282 if (! do_arch)
10283 return 1;
10284
252b5132
RH
10285 switch (elf_header.e_machine)
10286 {
11c1ff18
PB
10287 case EM_ARM:
10288 return process_arm_specific (file);
252b5132 10289 case EM_MIPS:
4fe85591 10290 case EM_MIPS_RS3_LE:
252b5132
RH
10291 return process_mips_specific (file);
10292 break;
34c8bcba
JM
10293 case EM_PPC:
10294 return process_power_specific (file);
10295 break;
252b5132
RH
10296 default:
10297 break;
10298 }
10299 return 1;
10300}
10301
10302static int
d3ba0551 10303get_file_header (FILE *file)
252b5132 10304{
9ea033b2
NC
10305 /* Read in the identity array. */
10306 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10307 return 0;
10308
9ea033b2 10309 /* Determine how to read the rest of the header. */
b34976b6 10310 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10311 {
10312 default: /* fall through */
10313 case ELFDATANONE: /* fall through */
adab8cdc
AO
10314 case ELFDATA2LSB:
10315 byte_get = byte_get_little_endian;
10316 byte_put = byte_put_little_endian;
10317 break;
10318 case ELFDATA2MSB:
10319 byte_get = byte_get_big_endian;
10320 byte_put = byte_put_big_endian;
10321 break;
9ea033b2
NC
10322 }
10323
10324 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10325 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10326
10327 /* Read in the rest of the header. */
10328 if (is_32bit_elf)
10329 {
10330 Elf32_External_Ehdr ehdr32;
252b5132 10331
9ea033b2
NC
10332 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10333 return 0;
103f02d3 10334
9ea033b2
NC
10335 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10336 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10337 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10338 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10339 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10340 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10341 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10342 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10343 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10344 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10345 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10346 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10347 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10348 }
252b5132 10349 else
9ea033b2
NC
10350 {
10351 Elf64_External_Ehdr ehdr64;
a952a375
NC
10352
10353 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10354 we will not be able to cope with the 64bit data found in
10355 64 ELF files. Detect this now and abort before we start
50c2245b 10356 overwriting things. */
a952a375
NC
10357 if (sizeof (bfd_vma) < 8)
10358 {
e3c8793a
NC
10359 error (_("This instance of readelf has been built without support for a\n\
1036064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10361 return 0;
10362 }
103f02d3 10363
9ea033b2
NC
10364 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10365 return 0;
103f02d3 10366
9ea033b2
NC
10367 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10368 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10369 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
10370 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
10371 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
10372 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
10373 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10374 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10375 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10376 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10377 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10378 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10379 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10380 }
252b5132 10381
7ece0d85
JJ
10382 if (elf_header.e_shoff)
10383 {
10384 /* There may be some extensions in the first section header. Don't
10385 bomb if we can't read it. */
10386 if (is_32bit_elf)
10387 get_32bit_section_headers (file, 1);
10388 else
10389 get_64bit_section_headers (file, 1);
10390 }
560f3c1c 10391
252b5132
RH
10392 return 1;
10393}
10394
fb52b2f4
NC
10395/* Process one ELF object file according to the command line options.
10396 This file may actually be stored in an archive. The file is
10397 positioned at the start of the ELF object. */
10398
ff78d6d6 10399static int
fb52b2f4 10400process_object (char *file_name, FILE *file)
252b5132 10401{
252b5132
RH
10402 unsigned int i;
10403
252b5132
RH
10404 if (! get_file_header (file))
10405 {
10406 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 10407 return 1;
252b5132
RH
10408 }
10409
10410 /* Initialise per file variables. */
60bca95a 10411 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
10412 version_info[i] = 0;
10413
60bca95a 10414 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
10415 dynamic_info[i] = 0;
10416
10417 /* Process the file. */
10418 if (show_name)
10419 printf (_("\nFile: %s\n"), file_name);
10420
18bd398b
NC
10421 /* Initialise the dump_sects array from the cmdline_dump_sects array.
10422 Note we do this even if cmdline_dump_sects is empty because we
10423 must make sure that the dump_sets array is zeroed out before each
10424 object file is processed. */
10425 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 10426 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
10427
10428 if (num_cmdline_dump_sects > 0)
10429 {
10430 if (num_dump_sects == 0)
10431 /* A sneaky way of allocating the dump_sects array. */
09c11c86 10432 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
10433
10434 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
10435 memcpy (dump_sects, cmdline_dump_sects,
10436 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 10437 }
d70c5fc7 10438
252b5132 10439 if (! process_file_header ())
fb52b2f4 10440 return 1;
252b5132 10441
d1f5c6e3 10442 if (! process_section_headers (file))
2f62977e 10443 {
d1f5c6e3
L
10444 /* Without loaded section headers we cannot process lots of
10445 things. */
2f62977e 10446 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10447
2f62977e
NC
10448 if (! do_using_dynamic)
10449 do_syms = do_reloc = 0;
10450 }
252b5132 10451
d1f5c6e3
L
10452 if (! process_section_groups (file))
10453 {
10454 /* Without loaded section groups we cannot process unwind. */
10455 do_unwind = 0;
10456 }
10457
2f62977e 10458 if (process_program_headers (file))
b2d38a17 10459 process_dynamic_section (file);
252b5132
RH
10460
10461 process_relocs (file);
10462
4d6ed7c8
NC
10463 process_unwind (file);
10464
252b5132
RH
10465 process_symbol_table (file);
10466
10467 process_syminfo (file);
10468
10469 process_version_sections (file);
10470
10471 process_section_contents (file);
f5842774 10472
1ec5cd37 10473 process_notes (file);
103f02d3 10474
047b2264
JJ
10475 process_gnu_liblist (file);
10476
252b5132
RH
10477 process_arch_specific (file);
10478
d93f0186
NC
10479 if (program_headers)
10480 {
10481 free (program_headers);
10482 program_headers = NULL;
10483 }
10484
252b5132
RH
10485 if (section_headers)
10486 {
10487 free (section_headers);
10488 section_headers = NULL;
10489 }
10490
10491 if (string_table)
10492 {
10493 free (string_table);
10494 string_table = NULL;
d40ac9bd 10495 string_table_length = 0;
252b5132
RH
10496 }
10497
10498 if (dynamic_strings)
10499 {
10500 free (dynamic_strings);
10501 dynamic_strings = NULL;
d79b3d50 10502 dynamic_strings_length = 0;
252b5132
RH
10503 }
10504
10505 if (dynamic_symbols)
10506 {
10507 free (dynamic_symbols);
10508 dynamic_symbols = NULL;
19936277 10509 num_dynamic_syms = 0;
252b5132
RH
10510 }
10511
10512 if (dynamic_syminfo)
10513 {
10514 free (dynamic_syminfo);
10515 dynamic_syminfo = NULL;
10516 }
ff78d6d6 10517
e4b17d5c
L
10518 if (section_headers_groups)
10519 {
10520 free (section_headers_groups);
10521 section_headers_groups = NULL;
10522 }
10523
10524 if (section_groups)
10525 {
10526 struct group_list *g, *next;
10527
10528 for (i = 0; i < group_count; i++)
10529 {
10530 for (g = section_groups [i].root; g != NULL; g = next)
10531 {
10532 next = g->next;
10533 free (g);
10534 }
10535 }
10536
10537 free (section_groups);
10538 section_groups = NULL;
10539 }
10540
19e6b90e 10541 free_debug_memory ();
18bd398b 10542
ff78d6d6 10543 return 0;
252b5132
RH
10544}
10545
4145f1d5
NC
10546/* Process an ELF archive.
10547 On entry the file is positioned just after the ARMAG string. */
fb52b2f4
NC
10548
10549static int
10550process_archive (char *file_name, FILE *file)
10551{
10552 struct ar_hdr arhdr;
10553 size_t got;
10554 unsigned long size;
4145f1d5
NC
10555 unsigned long index_num = 0;
10556 unsigned long *index_array = NULL;
10557 char *sym_table = NULL;
10558 unsigned long sym_size = 0;
fb52b2f4
NC
10559 char *longnames = NULL;
10560 unsigned long longnames_size = 0;
10561 size_t file_name_size;
d989285c 10562 int ret;
fb52b2f4
NC
10563
10564 show_name = 1;
10565
10566 got = fread (&arhdr, 1, sizeof arhdr, file);
10567 if (got != sizeof arhdr)
10568 {
10569 if (got == 0)
10570 return 0;
10571
10572 error (_("%s: failed to read archive header\n"), file_name);
10573 return 1;
10574 }
10575
4145f1d5 10576 /* See if this is the archive symbol table. */
317e5c40
AN
10577 if (const_strneq (arhdr.ar_name, "/ ")
10578 || const_strneq (arhdr.ar_name, "/SYM64/ "))
fb52b2f4 10579 {
fb52b2f4 10580 size = strtoul (arhdr.ar_size, NULL, 10);
4145f1d5
NC
10581 size = size + (size & 1);
10582
10583 if (do_archive_index)
fb52b2f4 10584 {
4145f1d5
NC
10585 unsigned long i;
10586 /* A buffer used to hold numbers read in from an archive index.
10587 These are always 4 bytes long and stored in big-endian format. */
10588#define SIZEOF_AR_INDEX_NUMBERS 4
10589 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
10590 unsigned char * index_buffer;
10591
10592 /* Check the size of the archive index. */
10593 if (size < SIZEOF_AR_INDEX_NUMBERS)
10594 {
10595 error (_("%s: the archive index is empty\n"), file_name);
10596 return 1;
10597 }
10598
10599 /* Read the numer of entries in the archive index. */
10600 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
10601 if (got != sizeof (integer_buffer))
10602 {
10603 error (_("%s: failed to read archive index\n"), file_name);
10604 return 1;
10605 }
10606 index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
10607 size -= SIZEOF_AR_INDEX_NUMBERS;
10608
10609 /* Read in the archive index. */
10610 if (size < index_num * SIZEOF_AR_INDEX_NUMBERS)
10611 {
10612 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
10613 file_name, index_num);
10614 return 1;
10615 }
10616 index_buffer = malloc (index_num * SIZEOF_AR_INDEX_NUMBERS);
10617 if (index_buffer == NULL)
10618 {
10619 error (_("Out of memory whilst trying to read archive symbol index\n"));
10620 return 1;
10621 }
10622 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, index_num, file);
10623 if (got != index_num)
10624 {
10625 free (index_buffer);
10626 error (_("%s: failed to read archive index\n"), file_name);
10627 ret = 1;
10628 goto out;
10629 }
10630 size -= index_num * SIZEOF_AR_INDEX_NUMBERS;
10631
10632 /* Convert the index numbers into the host's numeric format. */
10633 index_array = malloc (index_num * sizeof (* index_array));
10634 if (index_array == NULL)
10635 {
10636 free (index_buffer);
10637 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
10638 return 1;
10639 }
10640
10641 for (i = 0; i < index_num; i++)
10642 index_array[i] = byte_get_big_endian ((unsigned char *)(index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
10643 SIZEOF_AR_INDEX_NUMBERS);
10644 free (index_buffer);
10645
10646 /* The remaining space in the header is taken up by the symbol table. */
10647 if (size < 1)
10648 {
10649 error (_("%s: the archive has an index but no symbols\n"), file_name);
10650 ret = 1;
10651 goto out;
10652 }
10653 sym_table = malloc (size);
10654 sym_size = size;
10655 if (sym_table == NULL)
10656 {
10657 error (_("Out of memory whilst trying to read archive index symbol table\n"));
10658 ret = 1;
10659 goto out;
10660 }
10661 got = fread (sym_table, 1, size, file);
10662 if (got != size)
10663 {
10664 error (_("%s: failed to read archive index symbol table\n"), file_name);
10665 ret = 1;
10666 goto out;
10667 }
10668 }
10669 else
10670 {
10671 if (fseek (file, size, SEEK_CUR) != 0)
10672 {
10673 error (_("%s: failed to skip archive symbol table\n"), file_name);
10674 return 1;
10675 }
fb52b2f4
NC
10676 }
10677
4145f1d5 10678 got = fread (& arhdr, 1, sizeof arhdr, file);
fb52b2f4
NC
10679 if (got != sizeof arhdr)
10680 {
10681 if (got == 0)
4145f1d5
NC
10682 {
10683 ret = 0;
10684 goto out;
10685 }
fb52b2f4 10686
4145f1d5
NC
10687 error (_("%s: failed to read archive header following archive index\n"), file_name);
10688 ret = 1;
10689 goto out;
fb52b2f4
NC
10690 }
10691 }
4145f1d5
NC
10692 else if (do_archive_index)
10693 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 10694
0112cd26 10695 if (const_strneq (arhdr.ar_name, "// "))
fb52b2f4
NC
10696 {
10697 /* This is the archive string table holding long member
10698 names. */
10699
10700 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
fb52b2f4
NC
10701 longnames = malloc (longnames_size);
10702 if (longnames == NULL)
10703 {
4145f1d5
NC
10704 error (_("Out of memory reading long symbol names in archive\n"));
10705 ret = 1;
10706 goto out;
fb52b2f4
NC
10707 }
10708
10709 if (fread (longnames, longnames_size, 1, file) != 1)
10710 {
d989285c 10711 free (longnames);
4145f1d5
NC
10712 error (_("%s: failed to read long symbol name string table\n"), file_name);
10713 ret = 1;
10714 goto out;
fb52b2f4
NC
10715 }
10716
10717 if ((longnames_size & 1) != 0)
10718 getc (file);
10719
4145f1d5 10720 got = fread (& arhdr, 1, sizeof arhdr, file);
fb52b2f4
NC
10721 if (got != sizeof arhdr)
10722 {
10723 if (got == 0)
4145f1d5
NC
10724 ret = 0;
10725 else
10726 {
10727 error (_("%s: failed to read archive header following long symbol names\n"), file_name);
10728 ret = 1;
10729 }
10730 goto out;
10731 }
10732 }
fb52b2f4 10733
4145f1d5
NC
10734 if (do_archive_index)
10735 {
10736 if (sym_table == NULL)
10737 error (_("%s: unable to dump the index as none was found\n"), file_name);
10738 else
10739 {
10740 unsigned int i, j, k, l;
10741 char elf_name[16];
10742 unsigned long current_pos;
10743
10744 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
10745 file_name, index_num, sym_size);
10746 current_pos = ftell (file);
10747
10748 for (i = l = 0; i < index_num; i++)
10749 {
10750 if ((i == 0) || ((i > 0) && (index_array[i] != index_array[i - 1])))
10751 {
10752 if (fseek (file, index_array[i], SEEK_SET) != 0)
10753 {
10754 error (_("%s: failed to seek to next file name\n"), file_name);
10755 ret = 1;
10756 goto out;
10757 }
10758 got = fread (elf_name, 1, 16, file);
10759 if (got != 16)
10760 {
10761 error (_("%s: failed to read file name\n"), file_name);
10762 ret = 1;
10763 goto out;
10764 }
10765
10766 if (elf_name[0] == '/')
10767 {
10768 /* We have a long name. */
10769 k = j = strtoul (elf_name + 1, NULL, 10);
10770 while ((j < longnames_size) && (longnames[j] != '/'))
10771 j++;
10772 longnames[j] = '\0';
10773 printf (_("Binary %s contains:\n"), longnames + k);
10774 longnames[j] = '/';
10775 }
10776 else
10777 {
10778 j = 0;
10779 while ((elf_name[j] != '/') && (j < 16))
10780 j++;
10781 elf_name[j] = '\0';
10782 printf(_("Binary %s contains:\n"), elf_name);
10783 }
10784 }
10785 if (l >= sym_size)
10786 {
10787 error (_("%s: end of the symbol table reached before the end of the index\n"),
10788 file_name);
10789 break;
10790 }
10791 printf ("\t%s\n", sym_table + l);
10792 l += strlen (sym_table + l) + 1;
10793 }
10794
10795 if (l < sym_size)
10796 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
10797 file_name);
10798
10799 free (index_array);
10800 index_array = NULL;
10801 free (sym_table);
10802 sym_table = NULL;
10803 if (fseek (file, current_pos, SEEK_SET) != 0)
10804 {
10805 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
10806 return 1;
10807 }
fb52b2f4 10808 }
4145f1d5
NC
10809
10810 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
10811 && !do_segments && !do_header && !do_dump && !do_version
10812 && !do_histogram && !do_debugging && !do_arch && !do_notes
10813 && !do_section_groups)
10814 return 0; /* Archive index only. */
fb52b2f4
NC
10815 }
10816
10817 file_name_size = strlen (file_name);
d989285c 10818 ret = 0;
fb52b2f4
NC
10819
10820 while (1)
10821 {
10822 char *name;
10823 char *nameend;
10824 char *namealc;
10825
10826 if (arhdr.ar_name[0] == '/')
10827 {
10828 unsigned long off;
10829
10830 off = strtoul (arhdr.ar_name + 1, NULL, 10);
10831 if (off >= longnames_size)
10832 {
0fd3a477 10833 error (_("%s: invalid archive string table offset %lu\n"), file_name, off);
d989285c
ILT
10834 ret = 1;
10835 break;
fb52b2f4
NC
10836 }
10837
10838 name = longnames + off;
10839 nameend = memchr (name, '/', longnames_size - off);
10840 }
10841 else
10842 {
10843 name = arhdr.ar_name;
10844 nameend = memchr (name, '/', 16);
10845 }
10846
10847 if (nameend == NULL)
10848 {
0fd3a477 10849 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
10850 ret = 1;
10851 break;
fb52b2f4
NC
10852 }
10853
10854 namealc = malloc (file_name_size + (nameend - name) + 3);
10855 if (namealc == NULL)
10856 {
10857 error (_("Out of memory\n"));
d989285c
ILT
10858 ret = 1;
10859 break;
fb52b2f4
NC
10860 }
10861
10862 memcpy (namealc, file_name, file_name_size);
10863 namealc[file_name_size] = '(';
10864 memcpy (namealc + file_name_size + 1, name, nameend - name);
10865 namealc[file_name_size + 1 + (nameend - name)] = ')';
10866 namealc[file_name_size + 2 + (nameend - name)] = '\0';
10867
10868 archive_file_offset = ftell (file);
10869 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
d70c5fc7 10870
d989285c 10871 ret |= process_object (namealc, file);
fb52b2f4
NC
10872
10873 free (namealc);
10874
10875 if (fseek (file,
10876 (archive_file_offset
10877 + archive_file_size
10878 + (archive_file_size & 1)),
10879 SEEK_SET) != 0)
10880 {
10881 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
10882 ret = 1;
10883 break;
fb52b2f4
NC
10884 }
10885
10886 got = fread (&arhdr, 1, sizeof arhdr, file);
10887 if (got != sizeof arhdr)
10888 {
10889 if (got == 0)
d989285c 10890 break;
fb52b2f4
NC
10891
10892 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
10893 ret = 1;
10894 break;
fb52b2f4
NC
10895 }
10896 }
10897
4145f1d5
NC
10898 out:
10899 if (index_array != NULL)
10900 free (index_array);
10901 if (sym_table != NULL)
10902 free (sym_table);
10903 if (longnames != NULL)
fb52b2f4
NC
10904 free (longnames);
10905
d989285c 10906 return ret;
fb52b2f4
NC
10907}
10908
10909static int
10910process_file (char *file_name)
10911{
10912 FILE *file;
10913 struct stat statbuf;
10914 char armag[SARMAG];
10915 int ret;
10916
10917 if (stat (file_name, &statbuf) < 0)
10918 {
f24ddbdd
NC
10919 if (errno == ENOENT)
10920 error (_("'%s': No such file\n"), file_name);
10921 else
10922 error (_("Could not locate '%s'. System error message: %s\n"),
10923 file_name, strerror (errno));
10924 return 1;
10925 }
10926
10927 if (! S_ISREG (statbuf.st_mode))
10928 {
10929 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
10930 return 1;
10931 }
10932
10933 file = fopen (file_name, "rb");
10934 if (file == NULL)
10935 {
f24ddbdd 10936 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
10937 return 1;
10938 }
10939
10940 if (fread (armag, SARMAG, 1, file) != 1)
10941 {
4145f1d5 10942 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
10943 fclose (file);
10944 return 1;
10945 }
10946
10947 if (memcmp (armag, ARMAG, SARMAG) == 0)
10948 ret = process_archive (file_name, file);
10949 else
10950 {
4145f1d5
NC
10951 if (do_archive_index)
10952 error (_("File %s is not an archive so its index cannot be displayed.\n"),
10953 file_name);
10954
fb52b2f4
NC
10955 rewind (file);
10956 archive_file_size = archive_file_offset = 0;
10957 ret = process_object (file_name, file);
10958 }
10959
10960 fclose (file);
10961
10962 return ret;
10963}
10964
252b5132
RH
10965#ifdef SUPPORT_DISASSEMBLY
10966/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 10967 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 10968 symbols. */
252b5132
RH
10969
10970void
b34976b6 10971print_address (unsigned int addr, FILE *outfile)
252b5132
RH
10972{
10973 fprintf (outfile,"0x%8.8x", addr);
10974}
10975
e3c8793a 10976/* Needed by the i386 disassembler. */
252b5132
RH
10977void
10978db_task_printsym (unsigned int addr)
10979{
10980 print_address (addr, stderr);
10981}
10982#endif
10983
10984int
d3ba0551 10985main (int argc, char **argv)
252b5132 10986{
ff78d6d6
L
10987 int err;
10988
252b5132
RH
10989#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
10990 setlocale (LC_MESSAGES, "");
3882b010
L
10991#endif
10992#if defined (HAVE_SETLOCALE)
10993 setlocale (LC_CTYPE, "");
252b5132
RH
10994#endif
10995 bindtextdomain (PACKAGE, LOCALEDIR);
10996 textdomain (PACKAGE);
10997
869b9d07
MM
10998 expandargv (&argc, &argv);
10999
252b5132
RH
11000 parse_args (argc, argv);
11001
18bd398b 11002 if (num_dump_sects > 0)
59f14fc0 11003 {
18bd398b 11004 /* Make a copy of the dump_sects array. */
09c11c86 11005 cmdline_dump_sects = malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 11006 if (cmdline_dump_sects == NULL)
591a748a 11007 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
11008 else
11009 {
09c11c86
NC
11010 memcpy (cmdline_dump_sects, dump_sects,
11011 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
11012 num_cmdline_dump_sects = num_dump_sects;
11013 }
11014 }
11015
18bd398b
NC
11016 if (optind < (argc - 1))
11017 show_name = 1;
11018
ff78d6d6 11019 err = 0;
252b5132 11020 while (optind < argc)
18bd398b 11021 err |= process_file (argv[optind++]);
252b5132
RH
11022
11023 if (dump_sects != NULL)
11024 free (dump_sects);
59f14fc0
AS
11025 if (cmdline_dump_sects != NULL)
11026 free (cmdline_dump_sects);
252b5132 11027
ff78d6d6 11028 return err;
252b5132 11029}