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