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