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