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