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