Match library name prefixed with sysroot
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
4b95cf5c 2 Copyright (C) 1998-2014 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 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"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
35c08157 134#include "elf/nds32.h"
13761a11 135#include "elf/nios2.h"
73589c9d 136#include "elf/or1k.h"
7d466069 137#include "elf/pj.h"
3b16e843 138#include "elf/ppc.h"
c833c019 139#include "elf/ppc64.h"
99c513f6 140#include "elf/rl78.h"
c7927a3c 141#include "elf/rx.h"
a85d7ed0 142#include "elf/s390.h"
1c0d3aa6 143#include "elf/score.h"
3b16e843
NC
144#include "elf/sh.h"
145#include "elf/sparc.h"
e9f53129 146#include "elf/spu.h"
40b36596 147#include "elf/tic6x.h"
aa137e4d
NC
148#include "elf/tilegx.h"
149#include "elf/tilepro.h"
3b16e843 150#include "elf/v850.h"
179d3252 151#include "elf/vax.h"
3b16e843 152#include "elf/x86-64.h"
c29aca4a 153#include "elf/xc16x.h"
f6c1a2d5 154#include "elf/xgate.h"
93fbbb04 155#include "elf/xstormy16.h"
88da6820 156#include "elf/xtensa.h"
252b5132 157
252b5132 158#include "getopt.h"
566b0d53 159#include "libiberty.h"
09c11c86 160#include "safe-ctype.h"
2cf0635d 161#include "filenames.h"
252b5132 162
15b42fb0
AM
163#ifndef offsetof
164#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
165#endif
166
2cf0635d 167char * program_name = "readelf";
c9c1d674 168static unsigned long archive_file_offset;
85b1c36d 169static unsigned long archive_file_size;
f54498b4 170static bfd_size_type current_file_size;
85b1c36d
BE
171static unsigned long dynamic_addr;
172static bfd_size_type dynamic_size;
8b73c356 173static size_t dynamic_nent;
2cf0635d 174static char * dynamic_strings;
85b1c36d 175static unsigned long dynamic_strings_length;
2cf0635d 176static char * string_table;
85b1c36d
BE
177static unsigned long string_table_length;
178static unsigned long num_dynamic_syms;
2cf0635d
NC
179static Elf_Internal_Sym * dynamic_symbols;
180static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
181static unsigned long dynamic_syminfo_offset;
182static unsigned int dynamic_syminfo_nent;
f8eae8b2 183static char program_interpreter[PATH_MAX];
bb8a0291 184static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 185static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
186static bfd_vma version_info[16];
187static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
188static Elf_Internal_Shdr * section_headers;
189static Elf_Internal_Phdr * program_headers;
190static Elf_Internal_Dyn * dynamic_section;
191static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
192static int show_name;
193static int do_dynamic;
194static int do_syms;
2c610e4b 195static int do_dyn_syms;
85b1c36d
BE
196static int do_reloc;
197static int do_sections;
198static int do_section_groups;
5477e8a0 199static int do_section_details;
85b1c36d
BE
200static int do_segments;
201static int do_unwind;
202static int do_using_dynamic;
203static int do_header;
204static int do_dump;
205static int do_version;
85b1c36d
BE
206static int do_histogram;
207static int do_debugging;
85b1c36d
BE
208static int do_arch;
209static int do_notes;
4145f1d5 210static int do_archive_index;
85b1c36d 211static int is_32bit_elf;
252b5132 212
e4b17d5c
L
213struct group_list
214{
2cf0635d 215 struct group_list * next;
e4b17d5c
L
216 unsigned int section_index;
217};
218
219struct group
220{
2cf0635d 221 struct group_list * root;
e4b17d5c
L
222 unsigned int group_index;
223};
224
85b1c36d 225static size_t group_count;
2cf0635d
NC
226static struct group * section_groups;
227static struct group ** section_headers_groups;
e4b17d5c 228
09c11c86
NC
229
230/* Flag bits indicating particular types of dump. */
231#define HEX_DUMP (1 << 0) /* The -x command line switch. */
232#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
233#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
234#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 235#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
236
237typedef unsigned char dump_type;
238
239/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
240struct dump_list_entry
241{
2cf0635d 242 char * name;
09c11c86 243 dump_type type;
2cf0635d 244 struct dump_list_entry * next;
aef1f6d0 245};
2cf0635d 246static struct dump_list_entry * dump_sects_byname;
aef1f6d0 247
09c11c86
NC
248/* A dynamic array of flags indicating for which sections a dump
249 has been requested via command line switches. */
250static dump_type * cmdline_dump_sects = NULL;
251static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
252
253/* A dynamic array of flags indicating for which sections a dump of
254 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
255 basis and then initialised from the cmdline_dump_sects array,
256 the results of interpreting the -w switch, and the
257 dump_sects_byname list. */
09c11c86
NC
258static dump_type * dump_sects = NULL;
259static unsigned int num_dump_sects = 0;
252b5132 260
252b5132 261
c256ffe7 262/* How to print a vma value. */
843dd992
NC
263typedef enum print_mode
264{
265 HEX,
266 DEC,
267 DEC_5,
268 UNSIGNED,
269 PREFIX_HEX,
270 FULL_HEX,
271 LONG_HEX
272}
273print_mode;
274
bb4d2ac2
L
275/* Versioned symbol info. */
276enum versioned_symbol_info
277{
278 symbol_undefined,
279 symbol_hidden,
280 symbol_public
281};
282
283static const char *get_symbol_version_string
284 (FILE *file, int is_dynsym, const char *strtab,
285 unsigned long int strtab_size, unsigned int si,
286 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
287 unsigned short *vna_other);
288
9c19a809
NC
289#define UNKNOWN -1
290
2b692964
NC
291#define SECTION_NAME(X) \
292 ((X) == NULL ? _("<none>") \
293 : string_table == NULL ? _("<no-name>") \
294 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 295 : string_table + (X)->sh_name))
252b5132 296
ee42cf8c 297#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 298
ba5cdace
NC
299#define GET_ELF_SYMBOLS(file, section, sym_count) \
300 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
301 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 302
d79b3d50
NC
303#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
304/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
305 already been called and verified that the string exists. */
306#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 307
61865e30
NC
308#define REMOVE_ARCH_BITS(ADDR) \
309 do \
310 { \
311 if (elf_header.e_machine == EM_ARM) \
312 (ADDR) &= ~1; \
313 } \
314 while (0)
d79b3d50 315\f
c9c1d674
EG
316/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
317 the offset of the current archive member, if we are examining an archive.
59245841
NC
318 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
319 using malloc and fill that. In either case return the pointer to the start of
320 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
321 and REASON is not NULL then emit an error message using REASON as part of the
322 context. */
59245841 323
c256ffe7 324static void *
c9c1d674 325get_data (void * var, FILE * file, unsigned long offset, size_t size, size_t nmemb,
2cf0635d 326 const char * reason)
a6e9f9df 327{
2cf0635d 328 void * mvar;
c9c1d674 329 size_t amt = size * nmemb;
a6e9f9df 330
c256ffe7 331 if (size == 0 || nmemb == 0)
a6e9f9df
AM
332 return NULL;
333
c9c1d674
EG
334 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
335 attempting to allocate memory when the read is bound to fail. */
336 if (amt > current_file_size
337 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 338 {
049b0c3a 339 if (reason)
c9c1d674
EG
340 error (_("Reading 0x%lx bytes extends past end of file for %s\n"),
341 (unsigned long) amt, reason);
a6e9f9df
AM
342 return NULL;
343 }
344
c9c1d674 345 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
346 {
347 if (reason)
c9c1d674
EG
348 error (_("Unable to seek to 0x%lx for %s\n"),
349 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
350 return NULL;
351 }
352
a6e9f9df
AM
353 mvar = var;
354 if (mvar == NULL)
355 {
c256ffe7
JJ
356 /* Check for overflow. */
357 if (nmemb < (~(size_t) 0 - 1) / size)
358 /* + 1 so that we can '\0' terminate invalid string table sections. */
359 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
360
361 if (mvar == NULL)
362 {
049b0c3a
NC
363 if (reason)
364 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
365 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
366 return NULL;
367 }
c256ffe7 368
c9c1d674 369 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
370 }
371
c256ffe7 372 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 373 {
049b0c3a
NC
374 if (reason)
375 error (_("Unable to read in 0x%lx bytes of %s\n"),
c9c1d674 376 (unsigned long) amt, reason);
a6e9f9df
AM
377 if (mvar != var)
378 free (mvar);
379 return NULL;
380 }
381
382 return mvar;
383}
384
14a91970 385/* Print a VMA value. */
cb8f3167 386
66543521 387static int
14a91970 388print_vma (bfd_vma vma, print_mode mode)
66543521 389{
66543521
AM
390 int nc = 0;
391
14a91970 392 switch (mode)
66543521 393 {
14a91970
AM
394 case FULL_HEX:
395 nc = printf ("0x");
396 /* Drop through. */
66543521 397
14a91970 398 case LONG_HEX:
f7a99963 399#ifdef BFD64
14a91970 400 if (is_32bit_elf)
437c2fb7 401 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 402#endif
14a91970
AM
403 printf_vma (vma);
404 return nc + 16;
b19aac67 405
14a91970
AM
406 case DEC_5:
407 if (vma <= 99999)
408 return printf ("%5" BFD_VMA_FMT "d", vma);
409 /* Drop through. */
66543521 410
14a91970
AM
411 case PREFIX_HEX:
412 nc = printf ("0x");
413 /* Drop through. */
66543521 414
14a91970
AM
415 case HEX:
416 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 417
14a91970
AM
418 case DEC:
419 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 420
14a91970
AM
421 case UNSIGNED:
422 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 423 }
66543521 424 return 0;
f7a99963
NC
425}
426
7bfd842d 427/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 428 multibye characters (assuming the host environment supports them).
31104126 429
7bfd842d
NC
430 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
431
432 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
433 padding as necessary.
171191ba
NC
434
435 Returns the number of emitted characters. */
436
437static unsigned int
7a88bc9c 438print_symbol (int width, const char *symbol)
31104126 439{
171191ba 440 bfd_boolean extra_padding = FALSE;
7bfd842d 441 int num_printed = 0;
3bfcb652 442#ifdef HAVE_MBSTATE_T
7bfd842d 443 mbstate_t state;
3bfcb652 444#endif
7bfd842d 445 int width_remaining;
961c521f 446
7bfd842d 447 if (width < 0)
961c521f 448 {
961c521f
NC
449 /* Keep the width positive. This also helps. */
450 width = - width;
171191ba 451 extra_padding = TRUE;
0b4362b0 452 }
74e1a04b 453 assert (width != 0);
961c521f 454
7bfd842d
NC
455 if (do_wide)
456 /* Set the remaining width to a very large value.
457 This simplifies the code below. */
458 width_remaining = INT_MAX;
459 else
460 width_remaining = width;
cb8f3167 461
3bfcb652 462#ifdef HAVE_MBSTATE_T
7bfd842d
NC
463 /* Initialise the multibyte conversion state. */
464 memset (& state, 0, sizeof (state));
3bfcb652 465#endif
961c521f 466
7bfd842d
NC
467 while (width_remaining)
468 {
469 size_t n;
7bfd842d 470 const char c = *symbol++;
961c521f 471
7bfd842d 472 if (c == 0)
961c521f
NC
473 break;
474
7bfd842d
NC
475 /* Do not print control characters directly as they can affect terminal
476 settings. Such characters usually appear in the names generated
477 by the assembler for local labels. */
478 if (ISCNTRL (c))
961c521f 479 {
7bfd842d 480 if (width_remaining < 2)
961c521f
NC
481 break;
482
7bfd842d
NC
483 printf ("^%c", c + 0x40);
484 width_remaining -= 2;
171191ba 485 num_printed += 2;
961c521f 486 }
7bfd842d
NC
487 else if (ISPRINT (c))
488 {
489 putchar (c);
490 width_remaining --;
491 num_printed ++;
492 }
961c521f
NC
493 else
494 {
3bfcb652
NC
495#ifdef HAVE_MBSTATE_T
496 wchar_t w;
497#endif
7bfd842d
NC
498 /* Let printf do the hard work of displaying multibyte characters. */
499 printf ("%.1s", symbol - 1);
500 width_remaining --;
501 num_printed ++;
502
3bfcb652 503#ifdef HAVE_MBSTATE_T
7bfd842d
NC
504 /* Try to find out how many bytes made up the character that was
505 just printed. Advance the symbol pointer past the bytes that
506 were displayed. */
507 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
508#else
509 n = 1;
510#endif
7bfd842d
NC
511 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
512 symbol += (n - 1);
961c521f 513 }
961c521f 514 }
171191ba 515
7bfd842d 516 if (extra_padding && num_printed < width)
171191ba
NC
517 {
518 /* Fill in the remaining spaces. */
7bfd842d
NC
519 printf ("%-*s", width - num_printed, " ");
520 num_printed = width;
171191ba
NC
521 }
522
523 return num_printed;
31104126
NC
524}
525
74e1a04b
NC
526/* Returns a pointer to a static buffer containing a printable version of
527 the given section's name. Like print_symbol, except that it does not try
528 to print multibyte characters, it just interprets them as hex values. */
529
530static const char *
531printable_section_name (Elf_Internal_Shdr * sec)
532{
533#define MAX_PRINT_SEC_NAME_LEN 128
534 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
535 const char * name = SECTION_NAME (sec);
536 char * buf = sec_name_buf;
537 char c;
538 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
539
540 while ((c = * name ++) != 0)
541 {
542 if (ISCNTRL (c))
543 {
544 if (remaining < 2)
545 break;
546
547 * buf ++ = '^';
548 * buf ++ = c + 0x40;
549 remaining -= 2;
550 }
551 else if (ISPRINT (c))
552 {
553 * buf ++ = c;
554 remaining -= 1;
555 }
556 else
557 {
558 static char hex[17] = "0123456789ABCDEF";
559
560 if (remaining < 4)
561 break;
562 * buf ++ = '<';
563 * buf ++ = hex[(c & 0xf0) >> 4];
564 * buf ++ = hex[c & 0x0f];
565 * buf ++ = '>';
566 remaining -= 4;
567 }
568
569 if (remaining == 0)
570 break;
571 }
572
573 * buf = 0;
574 return sec_name_buf;
575}
576
577static const char *
578printable_section_name_from_index (unsigned long ndx)
579{
580 if (ndx >= elf_header.e_shnum)
581 return _("<corrupt>");
582
583 return printable_section_name (section_headers + ndx);
584}
585
89fac5e3
RS
586/* Return a pointer to section NAME, or NULL if no such section exists. */
587
588static Elf_Internal_Shdr *
2cf0635d 589find_section (const char * name)
89fac5e3
RS
590{
591 unsigned int i;
592
593 for (i = 0; i < elf_header.e_shnum; i++)
594 if (streq (SECTION_NAME (section_headers + i), name))
595 return section_headers + i;
596
597 return NULL;
598}
599
0b6ae522
DJ
600/* Return a pointer to a section containing ADDR, or NULL if no such
601 section exists. */
602
603static Elf_Internal_Shdr *
604find_section_by_address (bfd_vma addr)
605{
606 unsigned int i;
607
608 for (i = 0; i < elf_header.e_shnum; i++)
609 {
610 Elf_Internal_Shdr *sec = section_headers + i;
611 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
612 return sec;
613 }
614
615 return NULL;
616}
617
071436c6
NC
618static Elf_Internal_Shdr *
619find_section_by_type (unsigned int type)
620{
621 unsigned int i;
622
623 for (i = 0; i < elf_header.e_shnum; i++)
624 {
625 Elf_Internal_Shdr *sec = section_headers + i;
626 if (sec->sh_type == type)
627 return sec;
628 }
629
630 return NULL;
631}
632
657d0d47
CC
633/* Return a pointer to section NAME, or NULL if no such section exists,
634 restricted to the list of sections given in SET. */
635
636static Elf_Internal_Shdr *
637find_section_in_set (const char * name, unsigned int * set)
638{
639 unsigned int i;
640
641 if (set != NULL)
642 {
643 while ((i = *set++) > 0)
644 if (streq (SECTION_NAME (section_headers + i), name))
645 return section_headers + i;
646 }
647
648 return find_section (name);
649}
650
0b6ae522
DJ
651/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
652 bytes read. */
653
f6f0e17b
NC
654static inline unsigned long
655read_uleb128 (unsigned char *data,
656 unsigned int *length_return,
657 const unsigned char * const end)
0b6ae522 658{
f6f0e17b 659 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
660}
661
28f997cf
TG
662/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
663 This OS has so many departures from the ELF standard that we test it at
664 many places. */
665
666static inline int
667is_ia64_vms (void)
668{
669 return elf_header.e_machine == EM_IA_64
670 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
671}
672
bcedfee6 673/* Guess the relocation size commonly used by the specific machines. */
252b5132 674
252b5132 675static int
2dc4cec1 676guess_is_rela (unsigned int e_machine)
252b5132 677{
9c19a809 678 switch (e_machine)
252b5132
RH
679 {
680 /* Targets that use REL relocations. */
252b5132
RH
681 case EM_386:
682 case EM_486:
63fcb9e9 683 case EM_960:
e9f53129 684 case EM_ARM:
2b0337b0 685 case EM_D10V:
252b5132 686 case EM_CYGNUS_D10V:
e9f53129 687 case EM_DLX:
252b5132 688 case EM_MIPS:
4fe85591 689 case EM_MIPS_RS3_LE:
e9f53129 690 case EM_CYGNUS_M32R:
1c0d3aa6 691 case EM_SCORE:
f6c1a2d5 692 case EM_XGATE:
9c19a809 693 return FALSE;
103f02d3 694
252b5132
RH
695 /* Targets that use RELA relocations. */
696 case EM_68K:
e9f53129 697 case EM_860:
a06ea964 698 case EM_AARCH64:
cfb8c092 699 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
700 case EM_ALPHA:
701 case EM_ALTERA_NIOS2:
702 case EM_AVR:
703 case EM_AVR_OLD:
704 case EM_BLACKFIN:
60bca95a 705 case EM_CR16:
e9f53129
AM
706 case EM_CRIS:
707 case EM_CRX:
2b0337b0 708 case EM_D30V:
252b5132 709 case EM_CYGNUS_D30V:
2b0337b0 710 case EM_FR30:
252b5132 711 case EM_CYGNUS_FR30:
5c70f934 712 case EM_CYGNUS_FRV:
e9f53129
AM
713 case EM_H8S:
714 case EM_H8_300:
715 case EM_H8_300H:
800eeca4 716 case EM_IA_64:
1e4cf259
NC
717 case EM_IP2K:
718 case EM_IP2K_OLD:
3b36097d 719 case EM_IQ2000:
84e94c90 720 case EM_LATTICEMICO32:
ff7eeb89 721 case EM_M32C_OLD:
49f58d10 722 case EM_M32C:
e9f53129
AM
723 case EM_M32R:
724 case EM_MCORE:
15ab5209 725 case EM_CYGNUS_MEP:
a3c62988 726 case EM_METAG:
e9f53129
AM
727 case EM_MMIX:
728 case EM_MN10200:
729 case EM_CYGNUS_MN10200:
730 case EM_MN10300:
731 case EM_CYGNUS_MN10300:
5506d11a 732 case EM_MOXIE:
e9f53129
AM
733 case EM_MSP430:
734 case EM_MSP430_OLD:
d031aafb 735 case EM_MT:
35c08157 736 case EM_NDS32:
64fd6348 737 case EM_NIOS32:
73589c9d 738 case EM_OR1K:
e9f53129
AM
739 case EM_PPC64:
740 case EM_PPC:
99c513f6 741 case EM_RL78:
c7927a3c 742 case EM_RX:
e9f53129
AM
743 case EM_S390:
744 case EM_S390_OLD:
745 case EM_SH:
746 case EM_SPARC:
747 case EM_SPARC32PLUS:
748 case EM_SPARCV9:
749 case EM_SPU:
40b36596 750 case EM_TI_C6000:
aa137e4d
NC
751 case EM_TILEGX:
752 case EM_TILEPRO:
708e2187 753 case EM_V800:
e9f53129
AM
754 case EM_V850:
755 case EM_CYGNUS_V850:
756 case EM_VAX:
757 case EM_X86_64:
8a9036a4 758 case EM_L1OM:
7a9068fe 759 case EM_K1OM:
e9f53129
AM
760 case EM_XSTORMY16:
761 case EM_XTENSA:
762 case EM_XTENSA_OLD:
7ba29e2a
NC
763 case EM_MICROBLAZE:
764 case EM_MICROBLAZE_OLD:
9c19a809 765 return TRUE;
103f02d3 766
e9f53129
AM
767 case EM_68HC05:
768 case EM_68HC08:
769 case EM_68HC11:
770 case EM_68HC16:
771 case EM_FX66:
772 case EM_ME16:
d1133906 773 case EM_MMA:
d1133906
NC
774 case EM_NCPU:
775 case EM_NDR1:
e9f53129 776 case EM_PCP:
d1133906 777 case EM_ST100:
e9f53129 778 case EM_ST19:
d1133906 779 case EM_ST7:
e9f53129
AM
780 case EM_ST9PLUS:
781 case EM_STARCORE:
d1133906 782 case EM_SVX:
e9f53129 783 case EM_TINYJ:
9c19a809
NC
784 default:
785 warn (_("Don't know about relocations on this machine architecture\n"));
786 return FALSE;
787 }
788}
252b5132 789
9c19a809 790static int
2cf0635d 791slurp_rela_relocs (FILE * file,
d3ba0551
AM
792 unsigned long rel_offset,
793 unsigned long rel_size,
2cf0635d
NC
794 Elf_Internal_Rela ** relasp,
795 unsigned long * nrelasp)
9c19a809 796{
2cf0635d 797 Elf_Internal_Rela * relas;
8b73c356 798 size_t nrelas;
4d6ed7c8 799 unsigned int i;
252b5132 800
4d6ed7c8
NC
801 if (is_32bit_elf)
802 {
2cf0635d 803 Elf32_External_Rela * erelas;
103f02d3 804
3f5e193b 805 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 806 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
807 if (!erelas)
808 return 0;
252b5132 809
4d6ed7c8 810 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 811
3f5e193b
NC
812 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
813 sizeof (Elf_Internal_Rela));
103f02d3 814
4d6ed7c8
NC
815 if (relas == NULL)
816 {
c256ffe7 817 free (erelas);
591a748a 818 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
819 return 0;
820 }
103f02d3 821
4d6ed7c8
NC
822 for (i = 0; i < nrelas; i++)
823 {
824 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
825 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 826 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 827 }
103f02d3 828
4d6ed7c8
NC
829 free (erelas);
830 }
831 else
832 {
2cf0635d 833 Elf64_External_Rela * erelas;
103f02d3 834
3f5e193b 835 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 836 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
837 if (!erelas)
838 return 0;
4d6ed7c8
NC
839
840 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 841
3f5e193b
NC
842 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
843 sizeof (Elf_Internal_Rela));
103f02d3 844
4d6ed7c8
NC
845 if (relas == NULL)
846 {
c256ffe7 847 free (erelas);
591a748a 848 error (_("out of memory parsing relocs\n"));
4d6ed7c8 849 return 0;
9c19a809 850 }
4d6ed7c8
NC
851
852 for (i = 0; i < nrelas; i++)
9c19a809 853 {
66543521
AM
854 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
855 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 856 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
857
858 /* The #ifdef BFD64 below is to prevent a compile time
859 warning. We know that if we do not have a 64 bit data
860 type that we will never execute this code anyway. */
861#ifdef BFD64
862 if (elf_header.e_machine == EM_MIPS
863 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
864 {
865 /* In little-endian objects, r_info isn't really a
866 64-bit little-endian value: it has a 32-bit
867 little-endian symbol index followed by four
868 individual byte fields. Reorder INFO
869 accordingly. */
91d6fa6a
NC
870 bfd_vma inf = relas[i].r_info;
871 inf = (((inf & 0xffffffff) << 32)
872 | ((inf >> 56) & 0xff)
873 | ((inf >> 40) & 0xff00)
874 | ((inf >> 24) & 0xff0000)
875 | ((inf >> 8) & 0xff000000));
876 relas[i].r_info = inf;
861fb55a
DJ
877 }
878#endif /* BFD64 */
4d6ed7c8 879 }
103f02d3 880
4d6ed7c8
NC
881 free (erelas);
882 }
883 *relasp = relas;
884 *nrelasp = nrelas;
885 return 1;
886}
103f02d3 887
4d6ed7c8 888static int
2cf0635d 889slurp_rel_relocs (FILE * file,
d3ba0551
AM
890 unsigned long rel_offset,
891 unsigned long rel_size,
2cf0635d
NC
892 Elf_Internal_Rela ** relsp,
893 unsigned long * nrelsp)
4d6ed7c8 894{
2cf0635d 895 Elf_Internal_Rela * rels;
8b73c356 896 size_t nrels;
4d6ed7c8 897 unsigned int i;
103f02d3 898
4d6ed7c8
NC
899 if (is_32bit_elf)
900 {
2cf0635d 901 Elf32_External_Rel * erels;
103f02d3 902
3f5e193b 903 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 904 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
905 if (!erels)
906 return 0;
103f02d3 907
4d6ed7c8 908 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 909
3f5e193b 910 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 911
4d6ed7c8
NC
912 if (rels == NULL)
913 {
c256ffe7 914 free (erels);
591a748a 915 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
916 return 0;
917 }
918
919 for (i = 0; i < nrels; i++)
920 {
921 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
922 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 923 rels[i].r_addend = 0;
9ea033b2 924 }
4d6ed7c8
NC
925
926 free (erels);
9c19a809
NC
927 }
928 else
929 {
2cf0635d 930 Elf64_External_Rel * erels;
9ea033b2 931
3f5e193b 932 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 933 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
934 if (!erels)
935 return 0;
103f02d3 936
4d6ed7c8 937 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 938
3f5e193b 939 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 940
4d6ed7c8 941 if (rels == NULL)
9c19a809 942 {
c256ffe7 943 free (erels);
591a748a 944 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
945 return 0;
946 }
103f02d3 947
4d6ed7c8
NC
948 for (i = 0; i < nrels; i++)
949 {
66543521
AM
950 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
951 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 952 rels[i].r_addend = 0;
861fb55a
DJ
953
954 /* The #ifdef BFD64 below is to prevent a compile time
955 warning. We know that if we do not have a 64 bit data
956 type that we will never execute this code anyway. */
957#ifdef BFD64
958 if (elf_header.e_machine == EM_MIPS
959 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
960 {
961 /* In little-endian objects, r_info isn't really a
962 64-bit little-endian value: it has a 32-bit
963 little-endian symbol index followed by four
964 individual byte fields. Reorder INFO
965 accordingly. */
91d6fa6a
NC
966 bfd_vma inf = rels[i].r_info;
967 inf = (((inf & 0xffffffff) << 32)
968 | ((inf >> 56) & 0xff)
969 | ((inf >> 40) & 0xff00)
970 | ((inf >> 24) & 0xff0000)
971 | ((inf >> 8) & 0xff000000));
972 rels[i].r_info = inf;
861fb55a
DJ
973 }
974#endif /* BFD64 */
4d6ed7c8 975 }
103f02d3 976
4d6ed7c8
NC
977 free (erels);
978 }
979 *relsp = rels;
980 *nrelsp = nrels;
981 return 1;
982}
103f02d3 983
aca88567
NC
984/* Returns the reloc type extracted from the reloc info field. */
985
986static unsigned int
987get_reloc_type (bfd_vma reloc_info)
988{
989 if (is_32bit_elf)
990 return ELF32_R_TYPE (reloc_info);
991
992 switch (elf_header.e_machine)
993 {
994 case EM_MIPS:
995 /* Note: We assume that reloc_info has already been adjusted for us. */
996 return ELF64_MIPS_R_TYPE (reloc_info);
997
998 case EM_SPARCV9:
999 return ELF64_R_TYPE_ID (reloc_info);
1000
1001 default:
1002 return ELF64_R_TYPE (reloc_info);
1003 }
1004}
1005
1006/* Return the symbol index extracted from the reloc info field. */
1007
1008static bfd_vma
1009get_reloc_symindex (bfd_vma reloc_info)
1010{
1011 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1012}
1013
13761a11
NC
1014static inline bfd_boolean
1015uses_msp430x_relocs (void)
1016{
1017 return
1018 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1019 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1020 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1021 /* TI compiler uses ELFOSABI_NONE. */
1022 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1023}
1024
d3ba0551
AM
1025/* Display the contents of the relocation data found at the specified
1026 offset. */
ee42cf8c 1027
41e92641 1028static void
2cf0635d 1029dump_relocations (FILE * file,
d3ba0551
AM
1030 unsigned long rel_offset,
1031 unsigned long rel_size,
2cf0635d 1032 Elf_Internal_Sym * symtab,
d3ba0551 1033 unsigned long nsyms,
2cf0635d 1034 char * strtab,
d79b3d50 1035 unsigned long strtablen,
bb4d2ac2
L
1036 int is_rela,
1037 int is_dynsym)
4d6ed7c8 1038{
b34976b6 1039 unsigned int i;
2cf0635d 1040 Elf_Internal_Rela * rels;
103f02d3 1041
4d6ed7c8
NC
1042 if (is_rela == UNKNOWN)
1043 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1044
4d6ed7c8
NC
1045 if (is_rela)
1046 {
c8286bd1 1047 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1048 return;
4d6ed7c8
NC
1049 }
1050 else
1051 {
1052 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1053 return;
252b5132
RH
1054 }
1055
410f7a12
L
1056 if (is_32bit_elf)
1057 {
1058 if (is_rela)
2c71103e
NC
1059 {
1060 if (do_wide)
1061 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1062 else
1063 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1064 }
410f7a12 1065 else
2c71103e
NC
1066 {
1067 if (do_wide)
1068 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1069 else
1070 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1071 }
410f7a12 1072 }
252b5132 1073 else
410f7a12
L
1074 {
1075 if (is_rela)
2c71103e
NC
1076 {
1077 if (do_wide)
8beeaeb7 1078 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1079 else
1080 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1081 }
410f7a12 1082 else
2c71103e
NC
1083 {
1084 if (do_wide)
8beeaeb7 1085 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1086 else
1087 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1088 }
410f7a12 1089 }
252b5132
RH
1090
1091 for (i = 0; i < rel_size; i++)
1092 {
2cf0635d 1093 const char * rtype;
b34976b6 1094 bfd_vma offset;
91d6fa6a 1095 bfd_vma inf;
b34976b6
AM
1096 bfd_vma symtab_index;
1097 bfd_vma type;
103f02d3 1098
b34976b6 1099 offset = rels[i].r_offset;
91d6fa6a 1100 inf = rels[i].r_info;
103f02d3 1101
91d6fa6a
NC
1102 type = get_reloc_type (inf);
1103 symtab_index = get_reloc_symindex (inf);
252b5132 1104
410f7a12
L
1105 if (is_32bit_elf)
1106 {
39dbeff8
AM
1107 printf ("%8.8lx %8.8lx ",
1108 (unsigned long) offset & 0xffffffff,
91d6fa6a 1109 (unsigned long) inf & 0xffffffff);
410f7a12
L
1110 }
1111 else
1112 {
39dbeff8
AM
1113#if BFD_HOST_64BIT_LONG
1114 printf (do_wide
1115 ? "%16.16lx %16.16lx "
1116 : "%12.12lx %12.12lx ",
91d6fa6a 1117 offset, inf);
39dbeff8 1118#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1119#ifndef __MSVCRT__
39dbeff8
AM
1120 printf (do_wide
1121 ? "%16.16llx %16.16llx "
1122 : "%12.12llx %12.12llx ",
91d6fa6a 1123 offset, inf);
6e3d6dc1
NC
1124#else
1125 printf (do_wide
1126 ? "%16.16I64x %16.16I64x "
1127 : "%12.12I64x %12.12I64x ",
91d6fa6a 1128 offset, inf);
6e3d6dc1 1129#endif
39dbeff8 1130#else
2c71103e
NC
1131 printf (do_wide
1132 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1133 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1134 _bfd_int64_high (offset),
1135 _bfd_int64_low (offset),
91d6fa6a
NC
1136 _bfd_int64_high (inf),
1137 _bfd_int64_low (inf));
9ea033b2 1138#endif
410f7a12 1139 }
103f02d3 1140
252b5132
RH
1141 switch (elf_header.e_machine)
1142 {
1143 default:
1144 rtype = NULL;
1145 break;
1146
a06ea964
NC
1147 case EM_AARCH64:
1148 rtype = elf_aarch64_reloc_type (type);
1149 break;
1150
2b0337b0 1151 case EM_M32R:
252b5132 1152 case EM_CYGNUS_M32R:
9ea033b2 1153 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1154 break;
1155
1156 case EM_386:
1157 case EM_486:
9ea033b2 1158 rtype = elf_i386_reloc_type (type);
252b5132
RH
1159 break;
1160
ba2685cc
AM
1161 case EM_68HC11:
1162 case EM_68HC12:
1163 rtype = elf_m68hc11_reloc_type (type);
1164 break;
75751cd9 1165
252b5132 1166 case EM_68K:
9ea033b2 1167 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1168 break;
1169
63fcb9e9 1170 case EM_960:
9ea033b2 1171 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1172 break;
1173
adde6300 1174 case EM_AVR:
2b0337b0 1175 case EM_AVR_OLD:
adde6300
AM
1176 rtype = elf_avr_reloc_type (type);
1177 break;
1178
9ea033b2
NC
1179 case EM_OLD_SPARCV9:
1180 case EM_SPARC32PLUS:
1181 case EM_SPARCV9:
252b5132 1182 case EM_SPARC:
9ea033b2 1183 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1184 break;
1185
e9f53129
AM
1186 case EM_SPU:
1187 rtype = elf_spu_reloc_type (type);
1188 break;
1189
708e2187
NC
1190 case EM_V800:
1191 rtype = v800_reloc_type (type);
1192 break;
2b0337b0 1193 case EM_V850:
252b5132 1194 case EM_CYGNUS_V850:
9ea033b2 1195 rtype = v850_reloc_type (type);
252b5132
RH
1196 break;
1197
2b0337b0 1198 case EM_D10V:
252b5132 1199 case EM_CYGNUS_D10V:
9ea033b2 1200 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1201 break;
1202
2b0337b0 1203 case EM_D30V:
252b5132 1204 case EM_CYGNUS_D30V:
9ea033b2 1205 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1206 break;
1207
d172d4ba
NC
1208 case EM_DLX:
1209 rtype = elf_dlx_reloc_type (type);
1210 break;
1211
252b5132 1212 case EM_SH:
9ea033b2 1213 rtype = elf_sh_reloc_type (type);
252b5132
RH
1214 break;
1215
2b0337b0 1216 case EM_MN10300:
252b5132 1217 case EM_CYGNUS_MN10300:
9ea033b2 1218 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1219 break;
1220
2b0337b0 1221 case EM_MN10200:
252b5132 1222 case EM_CYGNUS_MN10200:
9ea033b2 1223 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1224 break;
1225
2b0337b0 1226 case EM_FR30:
252b5132 1227 case EM_CYGNUS_FR30:
9ea033b2 1228 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1229 break;
1230
ba2685cc
AM
1231 case EM_CYGNUS_FRV:
1232 rtype = elf_frv_reloc_type (type);
1233 break;
5c70f934 1234
252b5132 1235 case EM_MCORE:
9ea033b2 1236 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1237 break;
1238
3c3bdf30
NC
1239 case EM_MMIX:
1240 rtype = elf_mmix_reloc_type (type);
1241 break;
1242
5506d11a
AM
1243 case EM_MOXIE:
1244 rtype = elf_moxie_reloc_type (type);
1245 break;
1246
2469cfa2 1247 case EM_MSP430:
13761a11
NC
1248 if (uses_msp430x_relocs ())
1249 {
1250 rtype = elf_msp430x_reloc_type (type);
1251 break;
1252 }
2469cfa2
NC
1253 case EM_MSP430_OLD:
1254 rtype = elf_msp430_reloc_type (type);
1255 break;
1256
35c08157
KLC
1257 case EM_NDS32:
1258 rtype = elf_nds32_reloc_type (type);
1259 break;
1260
252b5132 1261 case EM_PPC:
9ea033b2 1262 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1263 break;
1264
c833c019
AM
1265 case EM_PPC64:
1266 rtype = elf_ppc64_reloc_type (type);
1267 break;
1268
252b5132 1269 case EM_MIPS:
4fe85591 1270 case EM_MIPS_RS3_LE:
9ea033b2 1271 rtype = elf_mips_reloc_type (type);
252b5132
RH
1272 break;
1273
1274 case EM_ALPHA:
9ea033b2 1275 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1276 break;
1277
1278 case EM_ARM:
9ea033b2 1279 rtype = elf_arm_reloc_type (type);
252b5132
RH
1280 break;
1281
584da044 1282 case EM_ARC:
9ea033b2 1283 rtype = elf_arc_reloc_type (type);
252b5132
RH
1284 break;
1285
1286 case EM_PARISC:
69e617ca 1287 rtype = elf_hppa_reloc_type (type);
252b5132 1288 break;
7d466069 1289
b8720f9d
JL
1290 case EM_H8_300:
1291 case EM_H8_300H:
1292 case EM_H8S:
1293 rtype = elf_h8_reloc_type (type);
1294 break;
1295
73589c9d
CS
1296 case EM_OR1K:
1297 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1298 break;
1299
7d466069 1300 case EM_PJ:
2b0337b0 1301 case EM_PJ_OLD:
7d466069
ILT
1302 rtype = elf_pj_reloc_type (type);
1303 break;
800eeca4
JW
1304 case EM_IA_64:
1305 rtype = elf_ia64_reloc_type (type);
1306 break;
1b61cf92
HPN
1307
1308 case EM_CRIS:
1309 rtype = elf_cris_reloc_type (type);
1310 break;
535c37ff
JE
1311
1312 case EM_860:
1313 rtype = elf_i860_reloc_type (type);
1314 break;
bcedfee6
NC
1315
1316 case EM_X86_64:
8a9036a4 1317 case EM_L1OM:
7a9068fe 1318 case EM_K1OM:
bcedfee6
NC
1319 rtype = elf_x86_64_reloc_type (type);
1320 break;
a85d7ed0 1321
35b1837e
AM
1322 case EM_S370:
1323 rtype = i370_reloc_type (type);
1324 break;
1325
53c7db4b
KH
1326 case EM_S390_OLD:
1327 case EM_S390:
1328 rtype = elf_s390_reloc_type (type);
1329 break;
93fbbb04 1330
1c0d3aa6
NC
1331 case EM_SCORE:
1332 rtype = elf_score_reloc_type (type);
1333 break;
1334
93fbbb04
GK
1335 case EM_XSTORMY16:
1336 rtype = elf_xstormy16_reloc_type (type);
1337 break;
179d3252 1338
1fe1f39c
NC
1339 case EM_CRX:
1340 rtype = elf_crx_reloc_type (type);
1341 break;
1342
179d3252
JT
1343 case EM_VAX:
1344 rtype = elf_vax_reloc_type (type);
1345 break;
1e4cf259 1346
cfb8c092
NC
1347 case EM_ADAPTEVA_EPIPHANY:
1348 rtype = elf_epiphany_reloc_type (type);
1349 break;
1350
1e4cf259
NC
1351 case EM_IP2K:
1352 case EM_IP2K_OLD:
1353 rtype = elf_ip2k_reloc_type (type);
1354 break;
3b36097d
SC
1355
1356 case EM_IQ2000:
1357 rtype = elf_iq2000_reloc_type (type);
1358 break;
88da6820
NC
1359
1360 case EM_XTENSA_OLD:
1361 case EM_XTENSA:
1362 rtype = elf_xtensa_reloc_type (type);
1363 break;
a34e3ecb 1364
84e94c90
NC
1365 case EM_LATTICEMICO32:
1366 rtype = elf_lm32_reloc_type (type);
1367 break;
1368
ff7eeb89 1369 case EM_M32C_OLD:
49f58d10
JB
1370 case EM_M32C:
1371 rtype = elf_m32c_reloc_type (type);
1372 break;
1373
d031aafb
NS
1374 case EM_MT:
1375 rtype = elf_mt_reloc_type (type);
a34e3ecb 1376 break;
1d65ded4
CM
1377
1378 case EM_BLACKFIN:
1379 rtype = elf_bfin_reloc_type (type);
1380 break;
15ab5209
DB
1381
1382 case EM_CYGNUS_MEP:
1383 rtype = elf_mep_reloc_type (type);
1384 break;
60bca95a
NC
1385
1386 case EM_CR16:
1387 rtype = elf_cr16_reloc_type (type);
1388 break;
dd24e3da 1389
7ba29e2a
NC
1390 case EM_MICROBLAZE:
1391 case EM_MICROBLAZE_OLD:
1392 rtype = elf_microblaze_reloc_type (type);
1393 break;
c7927a3c 1394
99c513f6
DD
1395 case EM_RL78:
1396 rtype = elf_rl78_reloc_type (type);
1397 break;
1398
c7927a3c
NC
1399 case EM_RX:
1400 rtype = elf_rx_reloc_type (type);
1401 break;
c29aca4a 1402
a3c62988
NC
1403 case EM_METAG:
1404 rtype = elf_metag_reloc_type (type);
1405 break;
1406
c29aca4a
NC
1407 case EM_XC16X:
1408 case EM_C166:
1409 rtype = elf_xc16x_reloc_type (type);
1410 break;
40b36596
JM
1411
1412 case EM_TI_C6000:
1413 rtype = elf_tic6x_reloc_type (type);
1414 break;
aa137e4d
NC
1415
1416 case EM_TILEGX:
1417 rtype = elf_tilegx_reloc_type (type);
1418 break;
1419
1420 case EM_TILEPRO:
1421 rtype = elf_tilepro_reloc_type (type);
1422 break;
f6c1a2d5
NC
1423
1424 case EM_XGATE:
1425 rtype = elf_xgate_reloc_type (type);
1426 break;
36591ba1
SL
1427
1428 case EM_ALTERA_NIOS2:
1429 rtype = elf_nios2_reloc_type (type);
1430 break;
252b5132
RH
1431 }
1432
1433 if (rtype == NULL)
39dbeff8 1434 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1435 else
8beeaeb7 1436 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1437
7ace3541 1438 if (elf_header.e_machine == EM_ALPHA
157c2599 1439 && rtype != NULL
7ace3541
RH
1440 && streq (rtype, "R_ALPHA_LITUSE")
1441 && is_rela)
1442 {
1443 switch (rels[i].r_addend)
1444 {
1445 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1446 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1447 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1448 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1449 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1450 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1451 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1452 default: rtype = NULL;
1453 }
1454 if (rtype)
1455 printf (" (%s)", rtype);
1456 else
1457 {
1458 putchar (' ');
1459 printf (_("<unknown addend: %lx>"),
1460 (unsigned long) rels[i].r_addend);
1461 }
1462 }
1463 else if (symtab_index)
252b5132 1464 {
af3fc3bc 1465 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1466 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1467 else
19936277 1468 {
2cf0635d 1469 Elf_Internal_Sym * psym;
bb4d2ac2
L
1470 const char * version_string;
1471 enum versioned_symbol_info sym_info;
1472 unsigned short vna_other;
19936277 1473
af3fc3bc 1474 psym = symtab + symtab_index;
103f02d3 1475
bb4d2ac2
L
1476 version_string
1477 = get_symbol_version_string (file, is_dynsym,
1478 strtab, strtablen,
1479 symtab_index,
1480 psym,
1481 &sym_info,
1482 &vna_other);
1483
af3fc3bc 1484 printf (" ");
171191ba 1485
d8045f23
NC
1486 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1487 {
1488 const char * name;
1489 unsigned int len;
1490 unsigned int width = is_32bit_elf ? 8 : 14;
1491
1492 /* Relocations against GNU_IFUNC symbols do not use the value
1493 of the symbol as the address to relocate against. Instead
1494 they invoke the function named by the symbol and use its
1495 result as the address for relocation.
1496
1497 To indicate this to the user, do not display the value of
1498 the symbol in the "Symbols's Value" field. Instead show
1499 its name followed by () as a hint that the symbol is
1500 invoked. */
1501
1502 if (strtab == NULL
1503 || psym->st_name == 0
1504 || psym->st_name >= strtablen)
1505 name = "??";
1506 else
1507 name = strtab + psym->st_name;
1508
1509 len = print_symbol (width, name);
bb4d2ac2
L
1510 if (version_string)
1511 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1512 version_string);
d8045f23
NC
1513 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1514 }
1515 else
1516 {
1517 print_vma (psym->st_value, LONG_HEX);
171191ba 1518
d8045f23
NC
1519 printf (is_32bit_elf ? " " : " ");
1520 }
103f02d3 1521
af3fc3bc 1522 if (psym->st_name == 0)
f1ef08cb 1523 {
2cf0635d 1524 const char * sec_name = "<null>";
f1ef08cb
AM
1525 char name_buf[40];
1526
1527 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1528 {
4fbb74a6 1529 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1530 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1531 else if (psym->st_shndx == SHN_ABS)
1532 sec_name = "ABS";
1533 else if (psym->st_shndx == SHN_COMMON)
1534 sec_name = "COMMON";
ac145307
BS
1535 else if ((elf_header.e_machine == EM_MIPS
1536 && psym->st_shndx == SHN_MIPS_SCOMMON)
1537 || (elf_header.e_machine == EM_TI_C6000
1538 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1539 sec_name = "SCOMMON";
1540 else if (elf_header.e_machine == EM_MIPS
1541 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1542 sec_name = "SUNDEF";
8a9036a4 1543 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1544 || elf_header.e_machine == EM_L1OM
1545 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1546 && psym->st_shndx == SHN_X86_64_LCOMMON)
1547 sec_name = "LARGE_COMMON";
9ce701e2
L
1548 else if (elf_header.e_machine == EM_IA_64
1549 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1550 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1551 sec_name = "ANSI_COM";
28f997cf 1552 else if (is_ia64_vms ()
148b93f2
NC
1553 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1554 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1555 else
1556 {
1557 sprintf (name_buf, "<section 0x%x>",
1558 (unsigned int) psym->st_shndx);
1559 sec_name = name_buf;
1560 }
1561 }
1562 print_symbol (22, sec_name);
1563 }
af3fc3bc 1564 else if (strtab == NULL)
d79b3d50 1565 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1566 else if (psym->st_name >= strtablen)
d79b3d50 1567 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1568 else
bb4d2ac2
L
1569 {
1570 print_symbol (22, strtab + psym->st_name);
1571 if (version_string)
1572 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1573 version_string);
1574 }
103f02d3 1575
af3fc3bc 1576 if (is_rela)
171191ba 1577 {
598aaa76 1578 bfd_signed_vma off = rels[i].r_addend;
171191ba 1579
91d6fa6a 1580 if (off < 0)
598aaa76 1581 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1582 else
598aaa76 1583 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1584 }
19936277 1585 }
252b5132 1586 }
1b228002 1587 else if (is_rela)
f7a99963 1588 {
e04d7088
L
1589 bfd_signed_vma off = rels[i].r_addend;
1590
1591 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1592 if (off < 0)
1593 printf ("-%" BFD_VMA_FMT "x", - off);
1594 else
1595 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1596 }
252b5132 1597
157c2599
NC
1598 if (elf_header.e_machine == EM_SPARCV9
1599 && rtype != NULL
1600 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1601 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1602
252b5132 1603 putchar ('\n');
2c71103e 1604
aca88567 1605#ifdef BFD64
53c7db4b 1606 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1607 {
91d6fa6a
NC
1608 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1609 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1610 const char * rtype2 = elf_mips_reloc_type (type2);
1611 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1612
2c71103e
NC
1613 printf (" Type2: ");
1614
1615 if (rtype2 == NULL)
39dbeff8
AM
1616 printf (_("unrecognized: %-7lx"),
1617 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1618 else
1619 printf ("%-17.17s", rtype2);
1620
18bd398b 1621 printf ("\n Type3: ");
2c71103e
NC
1622
1623 if (rtype3 == NULL)
39dbeff8
AM
1624 printf (_("unrecognized: %-7lx"),
1625 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1626 else
1627 printf ("%-17.17s", rtype3);
1628
53c7db4b 1629 putchar ('\n');
2c71103e 1630 }
aca88567 1631#endif /* BFD64 */
252b5132
RH
1632 }
1633
c8286bd1 1634 free (rels);
252b5132
RH
1635}
1636
1637static const char *
d3ba0551 1638get_mips_dynamic_type (unsigned long type)
252b5132
RH
1639{
1640 switch (type)
1641 {
1642 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1643 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1644 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1645 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1646 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1647 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1648 case DT_MIPS_MSYM: return "MIPS_MSYM";
1649 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1650 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1651 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1652 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1653 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1654 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1655 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1656 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1657 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1658 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1659 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1660 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1661 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1662 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1663 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1664 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1665 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1666 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1667 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1668 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1669 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1670 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1671 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1672 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1673 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1674 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1675 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1676 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1677 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1678 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1679 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1680 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1681 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1682 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1683 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1684 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1685 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1686 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1687 default:
1688 return NULL;
1689 }
1690}
1691
9a097730 1692static const char *
d3ba0551 1693get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1694{
1695 switch (type)
1696 {
1697 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1698 default:
1699 return NULL;
1700 }
103f02d3
UD
1701}
1702
7490d522
AM
1703static const char *
1704get_ppc_dynamic_type (unsigned long type)
1705{
1706 switch (type)
1707 {
a7f2871e 1708 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1709 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1710 default:
1711 return NULL;
1712 }
1713}
1714
f1cb7e17 1715static const char *
d3ba0551 1716get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1717{
1718 switch (type)
1719 {
a7f2871e
AM
1720 case DT_PPC64_GLINK: return "PPC64_GLINK";
1721 case DT_PPC64_OPD: return "PPC64_OPD";
1722 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1723 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1724 default:
1725 return NULL;
1726 }
1727}
1728
103f02d3 1729static const char *
d3ba0551 1730get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1731{
1732 switch (type)
1733 {
1734 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1735 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1736 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1737 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1738 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1739 case DT_HP_PREINIT: return "HP_PREINIT";
1740 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1741 case DT_HP_NEEDED: return "HP_NEEDED";
1742 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1743 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1744 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1745 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1746 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1747 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1748 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1749 case DT_HP_FILTERED: return "HP_FILTERED";
1750 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1751 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1752 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1753 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1754 case DT_PLT: return "PLT";
1755 case DT_PLT_SIZE: return "PLT_SIZE";
1756 case DT_DLT: return "DLT";
1757 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1758 default:
1759 return NULL;
1760 }
1761}
9a097730 1762
ecc51f48 1763static const char *
d3ba0551 1764get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1765{
1766 switch (type)
1767 {
148b93f2
NC
1768 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1769 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1770 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1771 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1772 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1773 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1774 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1775 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1776 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1777 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1778 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1779 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1780 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1781 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1782 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1783 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1784 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1785 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1786 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1787 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1788 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1789 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1790 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1791 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1792 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1793 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1794 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1795 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1796 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1797 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1798 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1799 default:
1800 return NULL;
1801 }
1802}
1803
fabcb361
RH
1804static const char *
1805get_alpha_dynamic_type (unsigned long type)
1806{
1807 switch (type)
1808 {
1809 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1810 default:
1811 return NULL;
1812 }
1813}
1814
1c0d3aa6
NC
1815static const char *
1816get_score_dynamic_type (unsigned long type)
1817{
1818 switch (type)
1819 {
1820 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1821 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1822 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1823 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1824 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1825 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1826 default:
1827 return NULL;
1828 }
1829}
1830
40b36596
JM
1831static const char *
1832get_tic6x_dynamic_type (unsigned long type)
1833{
1834 switch (type)
1835 {
1836 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1837 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1838 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1839 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1840 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1841 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1842 default:
1843 return NULL;
1844 }
1845}
1c0d3aa6 1846
36591ba1
SL
1847static const char *
1848get_nios2_dynamic_type (unsigned long type)
1849{
1850 switch (type)
1851 {
1852 case DT_NIOS2_GP: return "NIOS2_GP";
1853 default:
1854 return NULL;
1855 }
1856}
1857
252b5132 1858static const char *
d3ba0551 1859get_dynamic_type (unsigned long type)
252b5132 1860{
e9e44622 1861 static char buff[64];
252b5132
RH
1862
1863 switch (type)
1864 {
1865 case DT_NULL: return "NULL";
1866 case DT_NEEDED: return "NEEDED";
1867 case DT_PLTRELSZ: return "PLTRELSZ";
1868 case DT_PLTGOT: return "PLTGOT";
1869 case DT_HASH: return "HASH";
1870 case DT_STRTAB: return "STRTAB";
1871 case DT_SYMTAB: return "SYMTAB";
1872 case DT_RELA: return "RELA";
1873 case DT_RELASZ: return "RELASZ";
1874 case DT_RELAENT: return "RELAENT";
1875 case DT_STRSZ: return "STRSZ";
1876 case DT_SYMENT: return "SYMENT";
1877 case DT_INIT: return "INIT";
1878 case DT_FINI: return "FINI";
1879 case DT_SONAME: return "SONAME";
1880 case DT_RPATH: return "RPATH";
1881 case DT_SYMBOLIC: return "SYMBOLIC";
1882 case DT_REL: return "REL";
1883 case DT_RELSZ: return "RELSZ";
1884 case DT_RELENT: return "RELENT";
1885 case DT_PLTREL: return "PLTREL";
1886 case DT_DEBUG: return "DEBUG";
1887 case DT_TEXTREL: return "TEXTREL";
1888 case DT_JMPREL: return "JMPREL";
1889 case DT_BIND_NOW: return "BIND_NOW";
1890 case DT_INIT_ARRAY: return "INIT_ARRAY";
1891 case DT_FINI_ARRAY: return "FINI_ARRAY";
1892 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1893 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1894 case DT_RUNPATH: return "RUNPATH";
1895 case DT_FLAGS: return "FLAGS";
2d0e6f43 1896
d1133906
NC
1897 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1898 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1899
05107a46 1900 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1901 case DT_PLTPADSZ: return "PLTPADSZ";
1902 case DT_MOVEENT: return "MOVEENT";
1903 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1904 case DT_FEATURE: return "FEATURE";
252b5132
RH
1905 case DT_POSFLAG_1: return "POSFLAG_1";
1906 case DT_SYMINSZ: return "SYMINSZ";
1907 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1908
252b5132 1909 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1910 case DT_CONFIG: return "CONFIG";
1911 case DT_DEPAUDIT: return "DEPAUDIT";
1912 case DT_AUDIT: return "AUDIT";
1913 case DT_PLTPAD: return "PLTPAD";
1914 case DT_MOVETAB: return "MOVETAB";
252b5132 1915 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1916
252b5132 1917 case DT_VERSYM: return "VERSYM";
103f02d3 1918
67a4f2b7
AO
1919 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1920 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1921 case DT_RELACOUNT: return "RELACOUNT";
1922 case DT_RELCOUNT: return "RELCOUNT";
1923 case DT_FLAGS_1: return "FLAGS_1";
1924 case DT_VERDEF: return "VERDEF";
1925 case DT_VERDEFNUM: return "VERDEFNUM";
1926 case DT_VERNEED: return "VERNEED";
1927 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1928
019148e4 1929 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1930 case DT_USED: return "USED";
1931 case DT_FILTER: return "FILTER";
103f02d3 1932
047b2264
JJ
1933 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1934 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1935 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1936 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1937 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1938 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1939
252b5132
RH
1940 default:
1941 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1942 {
2cf0635d 1943 const char * result;
103f02d3 1944
252b5132
RH
1945 switch (elf_header.e_machine)
1946 {
1947 case EM_MIPS:
4fe85591 1948 case EM_MIPS_RS3_LE:
252b5132
RH
1949 result = get_mips_dynamic_type (type);
1950 break;
9a097730
RH
1951 case EM_SPARCV9:
1952 result = get_sparc64_dynamic_type (type);
1953 break;
7490d522
AM
1954 case EM_PPC:
1955 result = get_ppc_dynamic_type (type);
1956 break;
f1cb7e17
AM
1957 case EM_PPC64:
1958 result = get_ppc64_dynamic_type (type);
1959 break;
ecc51f48
NC
1960 case EM_IA_64:
1961 result = get_ia64_dynamic_type (type);
1962 break;
fabcb361
RH
1963 case EM_ALPHA:
1964 result = get_alpha_dynamic_type (type);
1965 break;
1c0d3aa6
NC
1966 case EM_SCORE:
1967 result = get_score_dynamic_type (type);
1968 break;
40b36596
JM
1969 case EM_TI_C6000:
1970 result = get_tic6x_dynamic_type (type);
1971 break;
36591ba1
SL
1972 case EM_ALTERA_NIOS2:
1973 result = get_nios2_dynamic_type (type);
1974 break;
252b5132
RH
1975 default:
1976 result = NULL;
1977 break;
1978 }
1979
1980 if (result != NULL)
1981 return result;
1982
e9e44622 1983 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1984 }
eec8f817
DA
1985 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1986 || (elf_header.e_machine == EM_PARISC
1987 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1988 {
2cf0635d 1989 const char * result;
103f02d3
UD
1990
1991 switch (elf_header.e_machine)
1992 {
1993 case EM_PARISC:
1994 result = get_parisc_dynamic_type (type);
1995 break;
148b93f2
NC
1996 case EM_IA_64:
1997 result = get_ia64_dynamic_type (type);
1998 break;
103f02d3
UD
1999 default:
2000 result = NULL;
2001 break;
2002 }
2003
2004 if (result != NULL)
2005 return result;
2006
e9e44622
JJ
2007 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2008 type);
103f02d3 2009 }
252b5132 2010 else
e9e44622 2011 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2012
252b5132
RH
2013 return buff;
2014 }
2015}
2016
2017static char *
d3ba0551 2018get_file_type (unsigned e_type)
252b5132 2019{
b34976b6 2020 static char buff[32];
252b5132
RH
2021
2022 switch (e_type)
2023 {
2024 case ET_NONE: return _("NONE (None)");
2025 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2026 case ET_EXEC: return _("EXEC (Executable file)");
2027 case ET_DYN: return _("DYN (Shared object file)");
2028 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2029
2030 default:
2031 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2032 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2033 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2034 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2035 else
e9e44622 2036 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2037 return buff;
2038 }
2039}
2040
2041static char *
d3ba0551 2042get_machine_name (unsigned e_machine)
252b5132 2043{
b34976b6 2044 static char buff[64]; /* XXX */
252b5132
RH
2045
2046 switch (e_machine)
2047 {
c45021f2 2048 case EM_NONE: return _("None");
a06ea964 2049 case EM_AARCH64: return "AArch64";
c45021f2
NC
2050 case EM_M32: return "WE32100";
2051 case EM_SPARC: return "Sparc";
e9f53129 2052 case EM_SPU: return "SPU";
c45021f2
NC
2053 case EM_386: return "Intel 80386";
2054 case EM_68K: return "MC68000";
2055 case EM_88K: return "MC88000";
2056 case EM_486: return "Intel 80486";
2057 case EM_860: return "Intel 80860";
2058 case EM_MIPS: return "MIPS R3000";
2059 case EM_S370: return "IBM System/370";
7036c0e1 2060 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2061 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2062 case EM_PARISC: return "HPPA";
252b5132 2063 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2064 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2065 case EM_960: return "Intel 90860";
2066 case EM_PPC: return "PowerPC";
285d1771 2067 case EM_PPC64: return "PowerPC64";
c45021f2
NC
2068 case EM_FR20: return "Fujitsu FR20";
2069 case EM_RH32: return "TRW RH32";
b34976b6 2070 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2071 case EM_ARM: return "ARM";
2072 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2073 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2074 case EM_SPARCV9: return "Sparc v9";
2075 case EM_TRICORE: return "Siemens Tricore";
584da044 2076 case EM_ARC: return "ARC";
c2dcd04e
NC
2077 case EM_H8_300: return "Renesas H8/300";
2078 case EM_H8_300H: return "Renesas H8/300H";
2079 case EM_H8S: return "Renesas H8S";
2080 case EM_H8_500: return "Renesas H8/500";
30800947 2081 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2082 case EM_MIPS_X: return "Stanford MIPS-X";
2083 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2084 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2085 case EM_CYGNUS_D10V:
2086 case EM_D10V: return "d10v";
2087 case EM_CYGNUS_D30V:
b34976b6 2088 case EM_D30V: return "d30v";
2b0337b0 2089 case EM_CYGNUS_M32R:
26597c86 2090 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2091 case EM_CYGNUS_V850:
708e2187 2092 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2093 case EM_V850: return "Renesas V850";
2b0337b0
AO
2094 case EM_CYGNUS_MN10300:
2095 case EM_MN10300: return "mn10300";
2096 case EM_CYGNUS_MN10200:
2097 case EM_MN10200: return "mn10200";
5506d11a 2098 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2099 case EM_CYGNUS_FR30:
2100 case EM_FR30: return "Fujitsu FR30";
b34976b6 2101 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2102 case EM_PJ_OLD:
b34976b6 2103 case EM_PJ: return "picoJava";
7036c0e1
AJ
2104 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2105 case EM_PCP: return "Siemens PCP";
2106 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2107 case EM_NDR1: return "Denso NDR1 microprocesspr";
2108 case EM_STARCORE: return "Motorola Star*Core processor";
2109 case EM_ME16: return "Toyota ME16 processor";
2110 case EM_ST100: return "STMicroelectronics ST100 processor";
2111 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2112 case EM_PDSP: return "Sony DSP processor";
2113 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2114 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2115 case EM_FX66: return "Siemens FX66 microcontroller";
2116 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2117 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2118 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2119 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2120 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2121 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2122 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2123 case EM_SVX: return "Silicon Graphics SVx";
2124 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2125 case EM_VAX: return "Digital VAX";
2b0337b0 2126 case EM_AVR_OLD:
b34976b6 2127 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2128 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2129 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2130 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2131 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2132 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2133 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2134 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2135 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2136 case EM_L1OM: return "Intel L1OM";
7a9068fe 2137 case EM_K1OM: return "Intel K1OM";
b7498e0e 2138 case EM_S390_OLD:
b34976b6 2139 case EM_S390: return "IBM S/390";
1c0d3aa6 2140 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2141 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2142 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2143 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2144 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2145 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2146 case EM_DLX: return "OpenDLX";
1e4cf259 2147 case EM_IP2K_OLD:
b34976b6 2148 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2149 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2150 case EM_XTENSA_OLD:
2151 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2152 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2153 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2154 case EM_NS32K: return "National Semiconductor 32000 series";
2155 case EM_TPC: return "Tenor Network TPC processor";
2156 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2157 case EM_MAX: return "MAX Processor";
2158 case EM_CR: return "National Semiconductor CompactRISC";
2159 case EM_F2MC16: return "Fujitsu F2MC16";
2160 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2161 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2162 case EM_M32C_OLD:
49f58d10 2163 case EM_M32C: return "Renesas M32c";
d031aafb 2164 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2165 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2166 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2167 case EM_SEP: return "Sharp embedded microprocessor";
2168 case EM_ARCA: return "Arca RISC microprocessor";
2169 case EM_UNICORE: return "Unicore";
2170 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2171 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2172 case EM_NIOS32: return "Altera Nios";
2173 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2174 case EM_C166:
d70c5fc7 2175 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2176 case EM_M16C: return "Renesas M16C series microprocessors";
2177 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2178 case EM_CE: return "Freescale Communication Engine RISC core";
2179 case EM_TSK3000: return "Altium TSK3000 core";
2180 case EM_RS08: return "Freescale RS08 embedded processor";
2181 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2182 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2183 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2184 case EM_SE_C17: return "Seiko Epson C17 family";
2185 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2186 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2187 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2188 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2189 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2190 case EM_R32C: return "Renesas R32C series microprocessors";
2191 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2192 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2193 case EM_8051: return "Intel 8051 and variants";
2194 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2195 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2196 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2197 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2198 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2199 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2200 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2201 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2202 case EM_CR16:
f6c1a2d5 2203 case EM_MICROBLAZE:
7ba29e2a 2204 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2205 case EM_RL78: return "Renesas RL78";
c7927a3c 2206 case EM_RX: return "Renesas RX";
a3c62988 2207 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2208 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2209 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2210 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2211 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2212 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2213 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2214 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2215 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2216 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2217 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2218 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2219 default:
35d9dd2f 2220 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2221 return buff;
2222 }
2223}
2224
f3485b74 2225static void
d3ba0551 2226decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2227{
2228 unsigned eabi;
2229 int unknown = 0;
2230
2231 eabi = EF_ARM_EABI_VERSION (e_flags);
2232 e_flags &= ~ EF_ARM_EABIMASK;
2233
2234 /* Handle "generic" ARM flags. */
2235 if (e_flags & EF_ARM_RELEXEC)
2236 {
2237 strcat (buf, ", relocatable executable");
2238 e_flags &= ~ EF_ARM_RELEXEC;
2239 }
76da6bbe 2240
f3485b74
NC
2241 if (e_flags & EF_ARM_HASENTRY)
2242 {
2243 strcat (buf, ", has entry point");
2244 e_flags &= ~ EF_ARM_HASENTRY;
2245 }
76da6bbe 2246
f3485b74
NC
2247 /* Now handle EABI specific flags. */
2248 switch (eabi)
2249 {
2250 default:
2c71103e 2251 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2252 if (e_flags)
2253 unknown = 1;
2254 break;
2255
2256 case EF_ARM_EABI_VER1:
a5bcd848 2257 strcat (buf, ", Version1 EABI");
f3485b74
NC
2258 while (e_flags)
2259 {
2260 unsigned flag;
76da6bbe 2261
f3485b74
NC
2262 /* Process flags one bit at a time. */
2263 flag = e_flags & - e_flags;
2264 e_flags &= ~ flag;
76da6bbe 2265
f3485b74
NC
2266 switch (flag)
2267 {
a5bcd848 2268 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2269 strcat (buf, ", sorted symbol tables");
2270 break;
76da6bbe 2271
f3485b74
NC
2272 default:
2273 unknown = 1;
2274 break;
2275 }
2276 }
2277 break;
76da6bbe 2278
a5bcd848
PB
2279 case EF_ARM_EABI_VER2:
2280 strcat (buf, ", Version2 EABI");
2281 while (e_flags)
2282 {
2283 unsigned flag;
2284
2285 /* Process flags one bit at a time. */
2286 flag = e_flags & - e_flags;
2287 e_flags &= ~ flag;
2288
2289 switch (flag)
2290 {
2291 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2292 strcat (buf, ", sorted symbol tables");
2293 break;
2294
2295 case EF_ARM_DYNSYMSUSESEGIDX:
2296 strcat (buf, ", dynamic symbols use segment index");
2297 break;
2298
2299 case EF_ARM_MAPSYMSFIRST:
2300 strcat (buf, ", mapping symbols precede others");
2301 break;
2302
2303 default:
2304 unknown = 1;
2305 break;
2306 }
2307 }
2308 break;
2309
d507cf36
PB
2310 case EF_ARM_EABI_VER3:
2311 strcat (buf, ", Version3 EABI");
8cb51566
PB
2312 break;
2313
2314 case EF_ARM_EABI_VER4:
2315 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2316 while (e_flags)
2317 {
2318 unsigned flag;
2319
2320 /* Process flags one bit at a time. */
2321 flag = e_flags & - e_flags;
2322 e_flags &= ~ flag;
2323
2324 switch (flag)
2325 {
2326 case EF_ARM_BE8:
2327 strcat (buf, ", BE8");
2328 break;
2329
2330 case EF_ARM_LE8:
2331 strcat (buf, ", LE8");
2332 break;
2333
2334 default:
2335 unknown = 1;
2336 break;
2337 }
2338 break;
2339 }
2340 break;
3a4a14e9
PB
2341
2342 case EF_ARM_EABI_VER5:
2343 strcat (buf, ", Version5 EABI");
d507cf36
PB
2344 while (e_flags)
2345 {
2346 unsigned flag;
2347
2348 /* Process flags one bit at a time. */
2349 flag = e_flags & - e_flags;
2350 e_flags &= ~ flag;
2351
2352 switch (flag)
2353 {
2354 case EF_ARM_BE8:
2355 strcat (buf, ", BE8");
2356 break;
2357
2358 case EF_ARM_LE8:
2359 strcat (buf, ", LE8");
2360 break;
2361
3bfcb652
NC
2362 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2363 strcat (buf, ", soft-float ABI");
2364 break;
2365
2366 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2367 strcat (buf, ", hard-float ABI");
2368 break;
2369
d507cf36
PB
2370 default:
2371 unknown = 1;
2372 break;
2373 }
2374 }
2375 break;
2376
f3485b74 2377 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2378 strcat (buf, ", GNU EABI");
f3485b74
NC
2379 while (e_flags)
2380 {
2381 unsigned flag;
76da6bbe 2382
f3485b74
NC
2383 /* Process flags one bit at a time. */
2384 flag = e_flags & - e_flags;
2385 e_flags &= ~ flag;
76da6bbe 2386
f3485b74
NC
2387 switch (flag)
2388 {
a5bcd848 2389 case EF_ARM_INTERWORK:
f3485b74
NC
2390 strcat (buf, ", interworking enabled");
2391 break;
76da6bbe 2392
a5bcd848 2393 case EF_ARM_APCS_26:
f3485b74
NC
2394 strcat (buf, ", uses APCS/26");
2395 break;
76da6bbe 2396
a5bcd848 2397 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2398 strcat (buf, ", uses APCS/float");
2399 break;
76da6bbe 2400
a5bcd848 2401 case EF_ARM_PIC:
f3485b74
NC
2402 strcat (buf, ", position independent");
2403 break;
76da6bbe 2404
a5bcd848 2405 case EF_ARM_ALIGN8:
f3485b74
NC
2406 strcat (buf, ", 8 bit structure alignment");
2407 break;
76da6bbe 2408
a5bcd848 2409 case EF_ARM_NEW_ABI:
f3485b74
NC
2410 strcat (buf, ", uses new ABI");
2411 break;
76da6bbe 2412
a5bcd848 2413 case EF_ARM_OLD_ABI:
f3485b74
NC
2414 strcat (buf, ", uses old ABI");
2415 break;
76da6bbe 2416
a5bcd848 2417 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2418 strcat (buf, ", software FP");
2419 break;
76da6bbe 2420
90e01f86
ILT
2421 case EF_ARM_VFP_FLOAT:
2422 strcat (buf, ", VFP");
2423 break;
2424
fde78edd
NC
2425 case EF_ARM_MAVERICK_FLOAT:
2426 strcat (buf, ", Maverick FP");
2427 break;
2428
f3485b74
NC
2429 default:
2430 unknown = 1;
2431 break;
2432 }
2433 }
2434 }
f3485b74
NC
2435
2436 if (unknown)
2b692964 2437 strcat (buf,_(", <unknown>"));
f3485b74
NC
2438}
2439
35c08157
KLC
2440static void
2441decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2442{
2443 unsigned abi;
2444 unsigned arch;
2445 unsigned config;
2446 unsigned version;
2447 int has_fpu = 0;
2448 int r = 0;
2449
2450 static const char *ABI_STRINGS[] =
2451 {
2452 "ABI v0", /* use r5 as return register; only used in N1213HC */
2453 "ABI v1", /* use r0 as return register */
2454 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2455 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2456 "AABI",
2457 "ABI2 FP+"
35c08157
KLC
2458 };
2459 static const char *VER_STRINGS[] =
2460 {
2461 "Andes ELF V1.3 or older",
2462 "Andes ELF V1.3.1",
2463 "Andes ELF V1.4"
2464 };
2465 static const char *ARCH_STRINGS[] =
2466 {
2467 "",
2468 "Andes Star v1.0",
2469 "Andes Star v2.0",
2470 "Andes Star v3.0",
2471 "Andes Star v3.0m"
2472 };
2473
2474 abi = EF_NDS_ABI & e_flags;
2475 arch = EF_NDS_ARCH & e_flags;
2476 config = EF_NDS_INST & e_flags;
2477 version = EF_NDS32_ELF_VERSION & e_flags;
2478
2479 memset (buf, 0, size);
2480
2481 switch (abi)
2482 {
2483 case E_NDS_ABI_V0:
2484 case E_NDS_ABI_V1:
2485 case E_NDS_ABI_V2:
2486 case E_NDS_ABI_V2FP:
2487 case E_NDS_ABI_AABI:
40c7a7cb 2488 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2489 /* In case there are holes in the array. */
2490 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2491 break;
2492
2493 default:
2494 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2495 break;
2496 }
2497
2498 switch (version)
2499 {
2500 case E_NDS32_ELF_VER_1_2:
2501 case E_NDS32_ELF_VER_1_3:
2502 case E_NDS32_ELF_VER_1_4:
2503 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2504 break;
2505
2506 default:
2507 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2508 break;
2509 }
2510
2511 if (E_NDS_ABI_V0 == abi)
2512 {
2513 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2514 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2515 if (arch == E_NDS_ARCH_STAR_V1_0)
2516 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2517 return;
2518 }
2519
2520 switch (arch)
2521 {
2522 case E_NDS_ARCH_STAR_V1_0:
2523 case E_NDS_ARCH_STAR_V2_0:
2524 case E_NDS_ARCH_STAR_V3_0:
2525 case E_NDS_ARCH_STAR_V3_M:
2526 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2527 break;
2528
2529 default:
2530 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2531 /* ARCH version determines how the e_flags are interpreted.
2532 If it is unknown, we cannot proceed. */
2533 return;
2534 }
2535
2536 /* Newer ABI; Now handle architecture specific flags. */
2537 if (arch == E_NDS_ARCH_STAR_V1_0)
2538 {
2539 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2540 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2541
2542 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2543 r += snprintf (buf + r, size -r, ", MAC");
2544
2545 if (config & E_NDS32_HAS_DIV_INST)
2546 r += snprintf (buf + r, size -r, ", DIV");
2547
2548 if (config & E_NDS32_HAS_16BIT_INST)
2549 r += snprintf (buf + r, size -r, ", 16b");
2550 }
2551 else
2552 {
2553 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2554 {
2555 if (version <= E_NDS32_ELF_VER_1_3)
2556 r += snprintf (buf + r, size -r, ", [B8]");
2557 else
2558 r += snprintf (buf + r, size -r, ", EX9");
2559 }
2560
2561 if (config & E_NDS32_HAS_MAC_DX_INST)
2562 r += snprintf (buf + r, size -r, ", MAC_DX");
2563
2564 if (config & E_NDS32_HAS_DIV_DX_INST)
2565 r += snprintf (buf + r, size -r, ", DIV_DX");
2566
2567 if (config & E_NDS32_HAS_16BIT_INST)
2568 {
2569 if (version <= E_NDS32_ELF_VER_1_3)
2570 r += snprintf (buf + r, size -r, ", 16b");
2571 else
2572 r += snprintf (buf + r, size -r, ", IFC");
2573 }
2574 }
2575
2576 if (config & E_NDS32_HAS_EXT_INST)
2577 r += snprintf (buf + r, size -r, ", PERF1");
2578
2579 if (config & E_NDS32_HAS_EXT2_INST)
2580 r += snprintf (buf + r, size -r, ", PERF2");
2581
2582 if (config & E_NDS32_HAS_FPU_INST)
2583 {
2584 has_fpu = 1;
2585 r += snprintf (buf + r, size -r, ", FPU_SP");
2586 }
2587
2588 if (config & E_NDS32_HAS_FPU_DP_INST)
2589 {
2590 has_fpu = 1;
2591 r += snprintf (buf + r, size -r, ", FPU_DP");
2592 }
2593
2594 if (config & E_NDS32_HAS_FPU_MAC_INST)
2595 {
2596 has_fpu = 1;
2597 r += snprintf (buf + r, size -r, ", FPU_MAC");
2598 }
2599
2600 if (has_fpu)
2601 {
2602 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2603 {
2604 case E_NDS32_FPU_REG_8SP_4DP:
2605 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2606 break;
2607 case E_NDS32_FPU_REG_16SP_8DP:
2608 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2609 break;
2610 case E_NDS32_FPU_REG_32SP_16DP:
2611 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2612 break;
2613 case E_NDS32_FPU_REG_32SP_32DP:
2614 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2615 break;
2616 }
2617 }
2618
2619 if (config & E_NDS32_HAS_AUDIO_INST)
2620 r += snprintf (buf + r, size -r, ", AUDIO");
2621
2622 if (config & E_NDS32_HAS_STRING_INST)
2623 r += snprintf (buf + r, size -r, ", STR");
2624
2625 if (config & E_NDS32_HAS_REDUCED_REGS)
2626 r += snprintf (buf + r, size -r, ", 16REG");
2627
2628 if (config & E_NDS32_HAS_VIDEO_INST)
2629 {
2630 if (version <= E_NDS32_ELF_VER_1_3)
2631 r += snprintf (buf + r, size -r, ", VIDEO");
2632 else
2633 r += snprintf (buf + r, size -r, ", SATURATION");
2634 }
2635
2636 if (config & E_NDS32_HAS_ENCRIPT_INST)
2637 r += snprintf (buf + r, size -r, ", ENCRP");
2638
2639 if (config & E_NDS32_HAS_L2C_INST)
2640 r += snprintf (buf + r, size -r, ", L2C");
2641}
2642
252b5132 2643static char *
d3ba0551 2644get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2645{
b34976b6 2646 static char buf[1024];
252b5132
RH
2647
2648 buf[0] = '\0';
76da6bbe 2649
252b5132
RH
2650 if (e_flags)
2651 {
2652 switch (e_machine)
2653 {
2654 default:
2655 break;
2656
f3485b74
NC
2657 case EM_ARM:
2658 decode_ARM_machine_flags (e_flags, buf);
2659 break;
76da6bbe 2660
781303ce
MF
2661 case EM_BLACKFIN:
2662 if (e_flags & EF_BFIN_PIC)
2663 strcat (buf, ", PIC");
2664
2665 if (e_flags & EF_BFIN_FDPIC)
2666 strcat (buf, ", FDPIC");
2667
2668 if (e_flags & EF_BFIN_CODE_IN_L1)
2669 strcat (buf, ", code in L1");
2670
2671 if (e_flags & EF_BFIN_DATA_IN_L1)
2672 strcat (buf, ", data in L1");
2673
2674 break;
2675
ec2dfb42
AO
2676 case EM_CYGNUS_FRV:
2677 switch (e_flags & EF_FRV_CPU_MASK)
2678 {
2679 case EF_FRV_CPU_GENERIC:
2680 break;
2681
2682 default:
2683 strcat (buf, ", fr???");
2684 break;
57346661 2685
ec2dfb42
AO
2686 case EF_FRV_CPU_FR300:
2687 strcat (buf, ", fr300");
2688 break;
2689
2690 case EF_FRV_CPU_FR400:
2691 strcat (buf, ", fr400");
2692 break;
2693 case EF_FRV_CPU_FR405:
2694 strcat (buf, ", fr405");
2695 break;
2696
2697 case EF_FRV_CPU_FR450:
2698 strcat (buf, ", fr450");
2699 break;
2700
2701 case EF_FRV_CPU_FR500:
2702 strcat (buf, ", fr500");
2703 break;
2704 case EF_FRV_CPU_FR550:
2705 strcat (buf, ", fr550");
2706 break;
2707
2708 case EF_FRV_CPU_SIMPLE:
2709 strcat (buf, ", simple");
2710 break;
2711 case EF_FRV_CPU_TOMCAT:
2712 strcat (buf, ", tomcat");
2713 break;
2714 }
1c877e87 2715 break;
ec2dfb42 2716
53c7db4b 2717 case EM_68K:
425c6cb0 2718 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2719 strcat (buf, ", m68000");
425c6cb0 2720 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2721 strcat (buf, ", cpu32");
2722 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2723 strcat (buf, ", fido_a");
425c6cb0 2724 else
266abb8f 2725 {
2cf0635d
NC
2726 char const * isa = _("unknown");
2727 char const * mac = _("unknown mac");
2728 char const * additional = NULL;
0112cd26 2729
c694fd50 2730 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2731 {
c694fd50 2732 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2733 isa = "A";
2734 additional = ", nodiv";
2735 break;
c694fd50 2736 case EF_M68K_CF_ISA_A:
266abb8f
NS
2737 isa = "A";
2738 break;
c694fd50 2739 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2740 isa = "A+";
2741 break;
c694fd50 2742 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2743 isa = "B";
2744 additional = ", nousp";
2745 break;
c694fd50 2746 case EF_M68K_CF_ISA_B:
266abb8f
NS
2747 isa = "B";
2748 break;
f608cd77
NS
2749 case EF_M68K_CF_ISA_C:
2750 isa = "C";
2751 break;
2752 case EF_M68K_CF_ISA_C_NODIV:
2753 isa = "C";
2754 additional = ", nodiv";
2755 break;
266abb8f
NS
2756 }
2757 strcat (buf, ", cf, isa ");
2758 strcat (buf, isa);
0b2e31dc
NS
2759 if (additional)
2760 strcat (buf, additional);
c694fd50 2761 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2762 strcat (buf, ", float");
c694fd50 2763 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2764 {
2765 case 0:
2766 mac = NULL;
2767 break;
c694fd50 2768 case EF_M68K_CF_MAC:
266abb8f
NS
2769 mac = "mac";
2770 break;
c694fd50 2771 case EF_M68K_CF_EMAC:
266abb8f
NS
2772 mac = "emac";
2773 break;
f608cd77
NS
2774 case EF_M68K_CF_EMAC_B:
2775 mac = "emac_b";
2776 break;
266abb8f
NS
2777 }
2778 if (mac)
2779 {
2780 strcat (buf, ", ");
2781 strcat (buf, mac);
2782 }
266abb8f 2783 }
53c7db4b 2784 break;
33c63f9d 2785
252b5132
RH
2786 case EM_PPC:
2787 if (e_flags & EF_PPC_EMB)
2788 strcat (buf, ", emb");
2789
2790 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2791 strcat (buf, _(", relocatable"));
252b5132
RH
2792
2793 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2794 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2795 break;
2796
ee67d69a
AM
2797 case EM_PPC64:
2798 if (e_flags & EF_PPC64_ABI)
2799 {
2800 char abi[] = ", abiv0";
2801
2802 abi[6] += e_flags & EF_PPC64_ABI;
2803 strcat (buf, abi);
2804 }
2805 break;
2806
708e2187
NC
2807 case EM_V800:
2808 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2809 strcat (buf, ", RH850 ABI");
0b4362b0 2810
708e2187
NC
2811 if (e_flags & EF_V800_850E3)
2812 strcat (buf, ", V3 architecture");
2813
2814 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2815 strcat (buf, ", FPU not used");
2816
2817 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2818 strcat (buf, ", regmode: COMMON");
2819
2820 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2821 strcat (buf, ", r4 not used");
2822
2823 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2824 strcat (buf, ", r30 not used");
2825
2826 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2827 strcat (buf, ", r5 not used");
2828
2829 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2830 strcat (buf, ", r2 not used");
2831
2832 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2833 {
2834 switch (e_flags & - e_flags)
2835 {
2836 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2837 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2838 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2839 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2840 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2841 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2842 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2843 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2844 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2845 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2846 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2847 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2848 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2849 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2850 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2851 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2852 default: break;
2853 }
2854 }
2855 break;
2856
2b0337b0 2857 case EM_V850:
252b5132
RH
2858 case EM_CYGNUS_V850:
2859 switch (e_flags & EF_V850_ARCH)
2860 {
78c8d46c
NC
2861 case E_V850E3V5_ARCH:
2862 strcat (buf, ", v850e3v5");
2863 break;
1cd986c5
NC
2864 case E_V850E2V3_ARCH:
2865 strcat (buf, ", v850e2v3");
2866 break;
2867 case E_V850E2_ARCH:
2868 strcat (buf, ", v850e2");
2869 break;
2870 case E_V850E1_ARCH:
2871 strcat (buf, ", v850e1");
8ad30312 2872 break;
252b5132
RH
2873 case E_V850E_ARCH:
2874 strcat (buf, ", v850e");
2875 break;
252b5132
RH
2876 case E_V850_ARCH:
2877 strcat (buf, ", v850");
2878 break;
2879 default:
2b692964 2880 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2881 break;
2882 }
2883 break;
2884
2b0337b0 2885 case EM_M32R:
252b5132
RH
2886 case EM_CYGNUS_M32R:
2887 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2888 strcat (buf, ", m32r");
252b5132
RH
2889 break;
2890
2891 case EM_MIPS:
4fe85591 2892 case EM_MIPS_RS3_LE:
252b5132
RH
2893 if (e_flags & EF_MIPS_NOREORDER)
2894 strcat (buf, ", noreorder");
2895
2896 if (e_flags & EF_MIPS_PIC)
2897 strcat (buf, ", pic");
2898
2899 if (e_flags & EF_MIPS_CPIC)
2900 strcat (buf, ", cpic");
2901
d1bdd336
TS
2902 if (e_flags & EF_MIPS_UCODE)
2903 strcat (buf, ", ugen_reserved");
2904
252b5132
RH
2905 if (e_flags & EF_MIPS_ABI2)
2906 strcat (buf, ", abi2");
2907
43521d43
TS
2908 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2909 strcat (buf, ", odk first");
2910
a5d22d2a
TS
2911 if (e_flags & EF_MIPS_32BITMODE)
2912 strcat (buf, ", 32bitmode");
2913
ba92f887
MR
2914 if (e_flags & EF_MIPS_NAN2008)
2915 strcat (buf, ", nan2008");
2916
fef1b0b3
SE
2917 if (e_flags & EF_MIPS_FP64)
2918 strcat (buf, ", fp64");
2919
156c2f8b
NC
2920 switch ((e_flags & EF_MIPS_MACH))
2921 {
2922 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2923 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2924 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2925 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2926 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2927 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2928 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2929 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2930 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2931 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2932 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2933 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2934 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2935 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2936 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 2937 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 2938 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2939 case 0:
2940 /* We simply ignore the field in this case to avoid confusion:
2941 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2942 extension. */
2943 break;
2b692964 2944 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2945 }
43521d43
TS
2946
2947 switch ((e_flags & EF_MIPS_ABI))
2948 {
2949 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2950 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2951 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2952 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2953 case 0:
2954 /* We simply ignore the field in this case to avoid confusion:
2955 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2956 This means it is likely to be an o32 file, but not for
2957 sure. */
2958 break;
2b692964 2959 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2960 }
2961
2962 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2963 strcat (buf, ", mdmx");
2964
2965 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2966 strcat (buf, ", mips16");
2967
df58fc94
RS
2968 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2969 strcat (buf, ", micromips");
2970
43521d43
TS
2971 switch ((e_flags & EF_MIPS_ARCH))
2972 {
2973 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2974 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2975 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2976 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2977 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2978 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2979 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 2980 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 2981 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2982 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 2983 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 2984 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2985 }
252b5132 2986 break;
351b4b40 2987
35c08157
KLC
2988 case EM_NDS32:
2989 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
2990 break;
2991
ccde1100
AO
2992 case EM_SH:
2993 switch ((e_flags & EF_SH_MACH_MASK))
2994 {
2995 case EF_SH1: strcat (buf, ", sh1"); break;
2996 case EF_SH2: strcat (buf, ", sh2"); break;
2997 case EF_SH3: strcat (buf, ", sh3"); break;
2998 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2999 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3000 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3001 case EF_SH3E: strcat (buf, ", sh3e"); break;
3002 case EF_SH4: strcat (buf, ", sh4"); break;
3003 case EF_SH5: strcat (buf, ", sh5"); break;
3004 case EF_SH2E: strcat (buf, ", sh2e"); break;
3005 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3006 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3007 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3008 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3009 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3010 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3011 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3012 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3013 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3014 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3015 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3016 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3017 }
3018
cec6a5b8
MR
3019 if (e_flags & EF_SH_PIC)
3020 strcat (buf, ", pic");
3021
3022 if (e_flags & EF_SH_FDPIC)
3023 strcat (buf, ", fdpic");
ccde1100 3024 break;
73589c9d
CS
3025
3026 case EM_OR1K:
3027 if (e_flags & EF_OR1K_NODELAY)
3028 strcat (buf, ", no delay");
3029 break;
57346661 3030
351b4b40
RH
3031 case EM_SPARCV9:
3032 if (e_flags & EF_SPARC_32PLUS)
3033 strcat (buf, ", v8+");
3034
3035 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3036 strcat (buf, ", ultrasparcI");
3037
3038 if (e_flags & EF_SPARC_SUN_US3)
3039 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3040
3041 if (e_flags & EF_SPARC_HAL_R1)
3042 strcat (buf, ", halr1");
3043
3044 if (e_flags & EF_SPARC_LEDATA)
3045 strcat (buf, ", ledata");
3046
3047 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3048 strcat (buf, ", tso");
3049
3050 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3051 strcat (buf, ", pso");
3052
3053 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3054 strcat (buf, ", rmo");
3055 break;
7d466069 3056
103f02d3
UD
3057 case EM_PARISC:
3058 switch (e_flags & EF_PARISC_ARCH)
3059 {
3060 case EFA_PARISC_1_0:
3061 strcpy (buf, ", PA-RISC 1.0");
3062 break;
3063 case EFA_PARISC_1_1:
3064 strcpy (buf, ", PA-RISC 1.1");
3065 break;
3066 case EFA_PARISC_2_0:
3067 strcpy (buf, ", PA-RISC 2.0");
3068 break;
3069 default:
3070 break;
3071 }
3072 if (e_flags & EF_PARISC_TRAPNIL)
3073 strcat (buf, ", trapnil");
3074 if (e_flags & EF_PARISC_EXT)
3075 strcat (buf, ", ext");
3076 if (e_flags & EF_PARISC_LSB)
3077 strcat (buf, ", lsb");
3078 if (e_flags & EF_PARISC_WIDE)
3079 strcat (buf, ", wide");
3080 if (e_flags & EF_PARISC_NO_KABP)
3081 strcat (buf, ", no kabp");
3082 if (e_flags & EF_PARISC_LAZYSWAP)
3083 strcat (buf, ", lazyswap");
30800947 3084 break;
76da6bbe 3085
7d466069 3086 case EM_PJ:
2b0337b0 3087 case EM_PJ_OLD:
7d466069
ILT
3088 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3089 strcat (buf, ", new calling convention");
3090
3091 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3092 strcat (buf, ", gnu calling convention");
3093 break;
4d6ed7c8
NC
3094
3095 case EM_IA_64:
3096 if ((e_flags & EF_IA_64_ABI64))
3097 strcat (buf, ", 64-bit");
3098 else
3099 strcat (buf, ", 32-bit");
3100 if ((e_flags & EF_IA_64_REDUCEDFP))
3101 strcat (buf, ", reduced fp model");
3102 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3103 strcat (buf, ", no function descriptors, constant gp");
3104 else if ((e_flags & EF_IA_64_CONS_GP))
3105 strcat (buf, ", constant gp");
3106 if ((e_flags & EF_IA_64_ABSOLUTE))
3107 strcat (buf, ", absolute");
28f997cf
TG
3108 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3109 {
3110 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3111 strcat (buf, ", vms_linkages");
3112 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3113 {
3114 case EF_IA_64_VMS_COMCOD_SUCCESS:
3115 break;
3116 case EF_IA_64_VMS_COMCOD_WARNING:
3117 strcat (buf, ", warning");
3118 break;
3119 case EF_IA_64_VMS_COMCOD_ERROR:
3120 strcat (buf, ", error");
3121 break;
3122 case EF_IA_64_VMS_COMCOD_ABORT:
3123 strcat (buf, ", abort");
3124 break;
3125 default:
3126 abort ();
3127 }
3128 }
4d6ed7c8 3129 break;
179d3252
JT
3130
3131 case EM_VAX:
3132 if ((e_flags & EF_VAX_NONPIC))
3133 strcat (buf, ", non-PIC");
3134 if ((e_flags & EF_VAX_DFLOAT))
3135 strcat (buf, ", D-Float");
3136 if ((e_flags & EF_VAX_GFLOAT))
3137 strcat (buf, ", G-Float");
3138 break;
c7927a3c 3139
4046d87a
NC
3140 case EM_RL78:
3141 if (e_flags & E_FLAG_RL78_G10)
3142 strcat (buf, ", G10");
856ea05c
KP
3143 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3144 strcat (buf, ", 64-bit doubles");
4046d87a 3145 break;
0b4362b0 3146
c7927a3c
NC
3147 case EM_RX:
3148 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3149 strcat (buf, ", 64-bit doubles");
3150 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3151 strcat (buf, ", dsp");
d4cb0ea0 3152 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3153 strcat (buf, ", pid");
708e2187
NC
3154 if (e_flags & E_FLAG_RX_ABI)
3155 strcat (buf, ", RX ABI");
d4cb0ea0 3156 break;
55786da2
AK
3157
3158 case EM_S390:
3159 if (e_flags & EF_S390_HIGH_GPRS)
3160 strcat (buf, ", highgprs");
d4cb0ea0 3161 break;
40b36596
JM
3162
3163 case EM_TI_C6000:
3164 if ((e_flags & EF_C6000_REL))
3165 strcat (buf, ", relocatable module");
d4cb0ea0 3166 break;
13761a11
NC
3167
3168 case EM_MSP430:
3169 strcat (buf, _(": architecture variant: "));
3170 switch (e_flags & EF_MSP430_MACH)
3171 {
3172 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3173 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3174 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3175 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3176 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3177 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3178 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3179 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3180 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3181 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3182 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3183 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3184 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3185 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3186 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3187 default:
3188 strcat (buf, _(": unknown")); break;
3189 }
3190
3191 if (e_flags & ~ EF_MSP430_MACH)
3192 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3193 }
3194 }
3195
3196 return buf;
3197}
3198
252b5132 3199static const char *
d3ba0551
AM
3200get_osabi_name (unsigned int osabi)
3201{
3202 static char buff[32];
3203
3204 switch (osabi)
3205 {
3206 case ELFOSABI_NONE: return "UNIX - System V";
3207 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3208 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3209 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3210 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3211 case ELFOSABI_AIX: return "UNIX - AIX";
3212 case ELFOSABI_IRIX: return "UNIX - IRIX";
3213 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3214 case ELFOSABI_TRU64: return "UNIX - TRU64";
3215 case ELFOSABI_MODESTO: return "Novell - Modesto";
3216 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3217 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3218 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3219 case ELFOSABI_AROS: return "AROS";
11636f9e 3220 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3221 default:
40b36596
JM
3222 if (osabi >= 64)
3223 switch (elf_header.e_machine)
3224 {
3225 case EM_ARM:
3226 switch (osabi)
3227 {
3228 case ELFOSABI_ARM: return "ARM";
3229 default:
3230 break;
3231 }
3232 break;
3233
3234 case EM_MSP430:
3235 case EM_MSP430_OLD:
3236 switch (osabi)
3237 {
3238 case ELFOSABI_STANDALONE: return _("Standalone App");
3239 default:
3240 break;
3241 }
3242 break;
3243
3244 case EM_TI_C6000:
3245 switch (osabi)
3246 {
3247 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3248 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3249 default:
3250 break;
3251 }
3252 break;
3253
3254 default:
3255 break;
3256 }
e9e44622 3257 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3258 return buff;
3259 }
3260}
3261
a06ea964
NC
3262static const char *
3263get_aarch64_segment_type (unsigned long type)
3264{
3265 switch (type)
3266 {
3267 case PT_AARCH64_ARCHEXT:
3268 return "AARCH64_ARCHEXT";
3269 default:
3270 break;
3271 }
3272
3273 return NULL;
3274}
3275
b294bdf8
MM
3276static const char *
3277get_arm_segment_type (unsigned long type)
3278{
3279 switch (type)
3280 {
3281 case PT_ARM_EXIDX:
3282 return "EXIDX";
3283 default:
3284 break;
3285 }
3286
3287 return NULL;
3288}
3289
d3ba0551
AM
3290static const char *
3291get_mips_segment_type (unsigned long type)
252b5132
RH
3292{
3293 switch (type)
3294 {
3295 case PT_MIPS_REGINFO:
3296 return "REGINFO";
3297 case PT_MIPS_RTPROC:
3298 return "RTPROC";
3299 case PT_MIPS_OPTIONS:
3300 return "OPTIONS";
351cdf24
MF
3301 case PT_MIPS_ABIFLAGS:
3302 return "ABIFLAGS";
252b5132
RH
3303 default:
3304 break;
3305 }
3306
3307 return NULL;
3308}
3309
103f02d3 3310static const char *
d3ba0551 3311get_parisc_segment_type (unsigned long type)
103f02d3
UD
3312{
3313 switch (type)
3314 {
3315 case PT_HP_TLS: return "HP_TLS";
3316 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3317 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3318 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3319 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3320 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3321 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3322 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3323 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3324 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3325 case PT_HP_PARALLEL: return "HP_PARALLEL";
3326 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3327 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3328 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3329 case PT_HP_STACK: return "HP_STACK";
3330 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3331 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3332 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3333 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3334 default:
3335 break;
3336 }
3337
3338 return NULL;
3339}
3340
4d6ed7c8 3341static const char *
d3ba0551 3342get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3343{
3344 switch (type)
3345 {
3346 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3347 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3348 case PT_HP_TLS: return "HP_TLS";
3349 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3350 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3351 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3352 default:
3353 break;
3354 }
3355
3356 return NULL;
3357}
3358
40b36596
JM
3359static const char *
3360get_tic6x_segment_type (unsigned long type)
3361{
3362 switch (type)
3363 {
3364 case PT_C6000_PHATTR: return "C6000_PHATTR";
3365 default:
3366 break;
3367 }
3368
3369 return NULL;
3370}
3371
252b5132 3372static const char *
d3ba0551 3373get_segment_type (unsigned long p_type)
252b5132 3374{
b34976b6 3375 static char buff[32];
252b5132
RH
3376
3377 switch (p_type)
3378 {
b34976b6
AM
3379 case PT_NULL: return "NULL";
3380 case PT_LOAD: return "LOAD";
252b5132 3381 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3382 case PT_INTERP: return "INTERP";
3383 case PT_NOTE: return "NOTE";
3384 case PT_SHLIB: return "SHLIB";
3385 case PT_PHDR: return "PHDR";
13ae64f3 3386 case PT_TLS: return "TLS";
252b5132 3387
65765700
JJ
3388 case PT_GNU_EH_FRAME:
3389 return "GNU_EH_FRAME";
2b05f1b7 3390 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3391 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3392
252b5132
RH
3393 default:
3394 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3395 {
2cf0635d 3396 const char * result;
103f02d3 3397
252b5132
RH
3398 switch (elf_header.e_machine)
3399 {
a06ea964
NC
3400 case EM_AARCH64:
3401 result = get_aarch64_segment_type (p_type);
3402 break;
b294bdf8
MM
3403 case EM_ARM:
3404 result = get_arm_segment_type (p_type);
3405 break;
252b5132 3406 case EM_MIPS:
4fe85591 3407 case EM_MIPS_RS3_LE:
252b5132
RH
3408 result = get_mips_segment_type (p_type);
3409 break;
103f02d3
UD
3410 case EM_PARISC:
3411 result = get_parisc_segment_type (p_type);
3412 break;
4d6ed7c8
NC
3413 case EM_IA_64:
3414 result = get_ia64_segment_type (p_type);
3415 break;
40b36596
JM
3416 case EM_TI_C6000:
3417 result = get_tic6x_segment_type (p_type);
3418 break;
252b5132
RH
3419 default:
3420 result = NULL;
3421 break;
3422 }
103f02d3 3423
252b5132
RH
3424 if (result != NULL)
3425 return result;
103f02d3 3426
252b5132
RH
3427 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3428 }
3429 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3430 {
2cf0635d 3431 const char * result;
103f02d3
UD
3432
3433 switch (elf_header.e_machine)
3434 {
3435 case EM_PARISC:
3436 result = get_parisc_segment_type (p_type);
3437 break;
00428cca
AM
3438 case EM_IA_64:
3439 result = get_ia64_segment_type (p_type);
3440 break;
103f02d3
UD
3441 default:
3442 result = NULL;
3443 break;
3444 }
3445
3446 if (result != NULL)
3447 return result;
3448
3449 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3450 }
252b5132 3451 else
e9e44622 3452 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3453
3454 return buff;
3455 }
3456}
3457
3458static const char *
d3ba0551 3459get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3460{
3461 switch (sh_type)
3462 {
b34976b6
AM
3463 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3464 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3465 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3466 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3467 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3468 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3469 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3470 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3471 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3472 case SHT_MIPS_RELD: return "MIPS_RELD";
3473 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3474 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3475 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3476 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3477 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3478 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3479 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3480 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3481 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3482 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3483 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3484 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3485 case SHT_MIPS_LINE: return "MIPS_LINE";
3486 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3487 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3488 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3489 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3490 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3491 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3492 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3493 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3494 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3495 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3496 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3497 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3498 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3499 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3500 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3501 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3502 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3503 default:
3504 break;
3505 }
3506 return NULL;
3507}
3508
103f02d3 3509static const char *
d3ba0551 3510get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3511{
3512 switch (sh_type)
3513 {
3514 case SHT_PARISC_EXT: return "PARISC_EXT";
3515 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3516 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3517 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3518 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3519 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3520 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3521 default:
3522 break;
3523 }
3524 return NULL;
3525}
3526
4d6ed7c8 3527static const char *
d3ba0551 3528get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3529{
18bd398b 3530 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3531 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3532 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3533
4d6ed7c8
NC
3534 switch (sh_type)
3535 {
148b93f2
NC
3536 case SHT_IA_64_EXT: return "IA_64_EXT";
3537 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3538 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3539 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3540 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3541 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3542 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3543 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3544 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3545 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3546 default:
3547 break;
3548 }
3549 return NULL;
3550}
3551
d2b2c203
DJ
3552static const char *
3553get_x86_64_section_type_name (unsigned int sh_type)
3554{
3555 switch (sh_type)
3556 {
3557 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3558 default:
3559 break;
3560 }
3561 return NULL;
3562}
3563
a06ea964
NC
3564static const char *
3565get_aarch64_section_type_name (unsigned int sh_type)
3566{
3567 switch (sh_type)
3568 {
3569 case SHT_AARCH64_ATTRIBUTES:
3570 return "AARCH64_ATTRIBUTES";
3571 default:
3572 break;
3573 }
3574 return NULL;
3575}
3576
40a18ebd
NC
3577static const char *
3578get_arm_section_type_name (unsigned int sh_type)
3579{
3580 switch (sh_type)
3581 {
7f6fed87
NC
3582 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3583 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3584 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3585 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3586 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3587 default:
3588 break;
3589 }
3590 return NULL;
3591}
3592
40b36596
JM
3593static const char *
3594get_tic6x_section_type_name (unsigned int sh_type)
3595{
3596 switch (sh_type)
3597 {
3598 case SHT_C6000_UNWIND:
3599 return "C6000_UNWIND";
3600 case SHT_C6000_PREEMPTMAP:
3601 return "C6000_PREEMPTMAP";
3602 case SHT_C6000_ATTRIBUTES:
3603 return "C6000_ATTRIBUTES";
3604 case SHT_TI_ICODE:
3605 return "TI_ICODE";
3606 case SHT_TI_XREF:
3607 return "TI_XREF";
3608 case SHT_TI_HANDLER:
3609 return "TI_HANDLER";
3610 case SHT_TI_INITINFO:
3611 return "TI_INITINFO";
3612 case SHT_TI_PHATTRS:
3613 return "TI_PHATTRS";
3614 default:
3615 break;
3616 }
3617 return NULL;
3618}
3619
13761a11
NC
3620static const char *
3621get_msp430x_section_type_name (unsigned int sh_type)
3622{
3623 switch (sh_type)
3624 {
3625 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3626 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3627 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3628 default: return NULL;
3629 }
3630}
3631
252b5132 3632static const char *
d3ba0551 3633get_section_type_name (unsigned int sh_type)
252b5132 3634{
b34976b6 3635 static char buff[32];
252b5132
RH
3636
3637 switch (sh_type)
3638 {
3639 case SHT_NULL: return "NULL";
3640 case SHT_PROGBITS: return "PROGBITS";
3641 case SHT_SYMTAB: return "SYMTAB";
3642 case SHT_STRTAB: return "STRTAB";
3643 case SHT_RELA: return "RELA";
3644 case SHT_HASH: return "HASH";
3645 case SHT_DYNAMIC: return "DYNAMIC";
3646 case SHT_NOTE: return "NOTE";
3647 case SHT_NOBITS: return "NOBITS";
3648 case SHT_REL: return "REL";
3649 case SHT_SHLIB: return "SHLIB";
3650 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3651 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3652 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3653 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3654 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3655 case SHT_GROUP: return "GROUP";
3656 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3657 case SHT_GNU_verdef: return "VERDEF";
3658 case SHT_GNU_verneed: return "VERNEED";
3659 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3660 case 0x6ffffff0: return "VERSYM";
3661 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3662 case 0x7ffffffd: return "AUXILIARY";
3663 case 0x7fffffff: return "FILTER";
047b2264 3664 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3665
3666 default:
3667 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3668 {
2cf0635d 3669 const char * result;
252b5132
RH
3670
3671 switch (elf_header.e_machine)
3672 {
3673 case EM_MIPS:
4fe85591 3674 case EM_MIPS_RS3_LE:
252b5132
RH
3675 result = get_mips_section_type_name (sh_type);
3676 break;
103f02d3
UD
3677 case EM_PARISC:
3678 result = get_parisc_section_type_name (sh_type);
3679 break;
4d6ed7c8
NC
3680 case EM_IA_64:
3681 result = get_ia64_section_type_name (sh_type);
3682 break;
d2b2c203 3683 case EM_X86_64:
8a9036a4 3684 case EM_L1OM:
7a9068fe 3685 case EM_K1OM:
d2b2c203
DJ
3686 result = get_x86_64_section_type_name (sh_type);
3687 break;
a06ea964
NC
3688 case EM_AARCH64:
3689 result = get_aarch64_section_type_name (sh_type);
3690 break;
40a18ebd
NC
3691 case EM_ARM:
3692 result = get_arm_section_type_name (sh_type);
3693 break;
40b36596
JM
3694 case EM_TI_C6000:
3695 result = get_tic6x_section_type_name (sh_type);
3696 break;
13761a11
NC
3697 case EM_MSP430:
3698 result = get_msp430x_section_type_name (sh_type);
3699 break;
252b5132
RH
3700 default:
3701 result = NULL;
3702 break;
3703 }
3704
3705 if (result != NULL)
3706 return result;
3707
c91d0dfb 3708 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3709 }
3710 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3711 {
2cf0635d 3712 const char * result;
148b93f2
NC
3713
3714 switch (elf_header.e_machine)
3715 {
3716 case EM_IA_64:
3717 result = get_ia64_section_type_name (sh_type);
3718 break;
3719 default:
3720 result = NULL;
3721 break;
3722 }
3723
3724 if (result != NULL)
3725 return result;
3726
3727 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3728 }
252b5132 3729 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3730 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3731 else
a7dbfd1c
NC
3732 /* This message is probably going to be displayed in a 15
3733 character wide field, so put the hex value first. */
3734 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3735
252b5132
RH
3736 return buff;
3737 }
3738}
3739
2979dc34 3740#define OPTION_DEBUG_DUMP 512
2c610e4b 3741#define OPTION_DYN_SYMS 513
fd2f0033
TT
3742#define OPTION_DWARF_DEPTH 514
3743#define OPTION_DWARF_START 515
4723351a 3744#define OPTION_DWARF_CHECK 516
2979dc34 3745
85b1c36d 3746static struct option options[] =
252b5132 3747{
b34976b6 3748 {"all", no_argument, 0, 'a'},
252b5132
RH
3749 {"file-header", no_argument, 0, 'h'},
3750 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3751 {"headers", no_argument, 0, 'e'},
3752 {"histogram", no_argument, 0, 'I'},
3753 {"segments", no_argument, 0, 'l'},
3754 {"sections", no_argument, 0, 'S'},
252b5132 3755 {"section-headers", no_argument, 0, 'S'},
f5842774 3756 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3757 {"section-details", no_argument, 0, 't'},
595cf52e 3758 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3759 {"symbols", no_argument, 0, 's'},
3760 {"syms", no_argument, 0, 's'},
2c610e4b 3761 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3762 {"relocs", no_argument, 0, 'r'},
3763 {"notes", no_argument, 0, 'n'},
3764 {"dynamic", no_argument, 0, 'd'},
a952a375 3765 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3766 {"version-info", no_argument, 0, 'V'},
3767 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3768 {"unwind", no_argument, 0, 'u'},
4145f1d5 3769 {"archive-index", no_argument, 0, 'c'},
b34976b6 3770 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3771 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3772 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3773#ifdef SUPPORT_DISASSEMBLY
3774 {"instruction-dump", required_argument, 0, 'i'},
3775#endif
cf13d699 3776 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3777
fd2f0033
TT
3778 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3779 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3780 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3781
b34976b6
AM
3782 {"version", no_argument, 0, 'v'},
3783 {"wide", no_argument, 0, 'W'},
3784 {"help", no_argument, 0, 'H'},
3785 {0, no_argument, 0, 0}
252b5132
RH
3786};
3787
3788static void
2cf0635d 3789usage (FILE * stream)
252b5132 3790{
92f01d61
JM
3791 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3792 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3793 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3794 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3795 -h --file-header Display the ELF file header\n\
3796 -l --program-headers Display the program headers\n\
3797 --segments An alias for --program-headers\n\
3798 -S --section-headers Display the sections' header\n\
3799 --sections An alias for --section-headers\n\
f5842774 3800 -g --section-groups Display the section groups\n\
5477e8a0 3801 -t --section-details Display the section details\n\
8b53311e
NC
3802 -e --headers Equivalent to: -h -l -S\n\
3803 -s --syms Display the symbol table\n\
3f08eb35 3804 --symbols An alias for --syms\n\
2c610e4b 3805 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3806 -n --notes Display the core notes (if present)\n\
3807 -r --relocs Display the relocations (if present)\n\
3808 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3809 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3810 -V --version-info Display the version sections (if present)\n\
1b31d05e 3811 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3812 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3813 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3814 -x --hex-dump=<number|name>\n\
3815 Dump the contents of section <number|name> as bytes\n\
3816 -p --string-dump=<number|name>\n\
3817 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3818 -R --relocated-dump=<number|name>\n\
3819 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3820 -w[lLiaprmfFsoRt] or\n\
1ed06042 3821 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3822 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3823 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3824 =addr,=cu_index]\n\
8b53311e 3825 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3826 fprintf (stream, _("\
3827 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3828 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3829 or deeper\n"));
252b5132 3830#ifdef SUPPORT_DISASSEMBLY
92f01d61 3831 fprintf (stream, _("\
09c11c86
NC
3832 -i --instruction-dump=<number|name>\n\
3833 Disassemble the contents of section <number|name>\n"));
252b5132 3834#endif
92f01d61 3835 fprintf (stream, _("\
8b53311e
NC
3836 -I --histogram Display histogram of bucket list lengths\n\
3837 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3838 @<file> Read options from <file>\n\
8b53311e
NC
3839 -H --help Display this information\n\
3840 -v --version Display the version number of readelf\n"));
1118d252 3841
92f01d61
JM
3842 if (REPORT_BUGS_TO[0] && stream == stdout)
3843 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3844
92f01d61 3845 exit (stream == stdout ? 0 : 1);
252b5132
RH
3846}
3847
18bd398b
NC
3848/* Record the fact that the user wants the contents of section number
3849 SECTION to be displayed using the method(s) encoded as flags bits
3850 in TYPE. Note, TYPE can be zero if we are creating the array for
3851 the first time. */
3852
252b5132 3853static void
09c11c86 3854request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3855{
3856 if (section >= num_dump_sects)
3857 {
2cf0635d 3858 dump_type * new_dump_sects;
252b5132 3859
3f5e193b
NC
3860 new_dump_sects = (dump_type *) calloc (section + 1,
3861 sizeof (* dump_sects));
252b5132
RH
3862
3863 if (new_dump_sects == NULL)
591a748a 3864 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3865 else
3866 {
3867 /* Copy current flag settings. */
09c11c86 3868 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3869
3870 free (dump_sects);
3871
3872 dump_sects = new_dump_sects;
3873 num_dump_sects = section + 1;
3874 }
3875 }
3876
3877 if (dump_sects)
b34976b6 3878 dump_sects[section] |= type;
252b5132
RH
3879
3880 return;
3881}
3882
aef1f6d0
DJ
3883/* Request a dump by section name. */
3884
3885static void
2cf0635d 3886request_dump_byname (const char * section, dump_type type)
aef1f6d0 3887{
2cf0635d 3888 struct dump_list_entry * new_request;
aef1f6d0 3889
3f5e193b
NC
3890 new_request = (struct dump_list_entry *)
3891 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3892 if (!new_request)
591a748a 3893 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3894
3895 new_request->name = strdup (section);
3896 if (!new_request->name)
591a748a 3897 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3898
3899 new_request->type = type;
3900
3901 new_request->next = dump_sects_byname;
3902 dump_sects_byname = new_request;
3903}
3904
cf13d699
NC
3905static inline void
3906request_dump (dump_type type)
3907{
3908 int section;
3909 char * cp;
3910
3911 do_dump++;
3912 section = strtoul (optarg, & cp, 0);
3913
3914 if (! *cp && section >= 0)
3915 request_dump_bynumber (section, type);
3916 else
3917 request_dump_byname (optarg, type);
3918}
3919
3920
252b5132 3921static void
2cf0635d 3922parse_args (int argc, char ** argv)
252b5132
RH
3923{
3924 int c;
3925
3926 if (argc < 2)
92f01d61 3927 usage (stderr);
252b5132
RH
3928
3929 while ((c = getopt_long
cf13d699 3930 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3931 {
252b5132
RH
3932 switch (c)
3933 {
3934 case 0:
3935 /* Long options. */
3936 break;
3937 case 'H':
92f01d61 3938 usage (stdout);
252b5132
RH
3939 break;
3940
3941 case 'a':
b34976b6
AM
3942 do_syms++;
3943 do_reloc++;
3944 do_unwind++;
3945 do_dynamic++;
3946 do_header++;
3947 do_sections++;
f5842774 3948 do_section_groups++;
b34976b6
AM
3949 do_segments++;
3950 do_version++;
3951 do_histogram++;
3952 do_arch++;
3953 do_notes++;
252b5132 3954 break;
f5842774
L
3955 case 'g':
3956 do_section_groups++;
3957 break;
5477e8a0 3958 case 't':
595cf52e 3959 case 'N':
5477e8a0
L
3960 do_sections++;
3961 do_section_details++;
595cf52e 3962 break;
252b5132 3963 case 'e':
b34976b6
AM
3964 do_header++;
3965 do_sections++;
3966 do_segments++;
252b5132 3967 break;
a952a375 3968 case 'A':
b34976b6 3969 do_arch++;
a952a375 3970 break;
252b5132 3971 case 'D':
b34976b6 3972 do_using_dynamic++;
252b5132
RH
3973 break;
3974 case 'r':
b34976b6 3975 do_reloc++;
252b5132 3976 break;
4d6ed7c8 3977 case 'u':
b34976b6 3978 do_unwind++;
4d6ed7c8 3979 break;
252b5132 3980 case 'h':
b34976b6 3981 do_header++;
252b5132
RH
3982 break;
3983 case 'l':
b34976b6 3984 do_segments++;
252b5132
RH
3985 break;
3986 case 's':
b34976b6 3987 do_syms++;
252b5132
RH
3988 break;
3989 case 'S':
b34976b6 3990 do_sections++;
252b5132
RH
3991 break;
3992 case 'd':
b34976b6 3993 do_dynamic++;
252b5132 3994 break;
a952a375 3995 case 'I':
b34976b6 3996 do_histogram++;
a952a375 3997 break;
779fe533 3998 case 'n':
b34976b6 3999 do_notes++;
779fe533 4000 break;
4145f1d5
NC
4001 case 'c':
4002 do_archive_index++;
4003 break;
252b5132 4004 case 'x':
cf13d699 4005 request_dump (HEX_DUMP);
aef1f6d0 4006 break;
09c11c86 4007 case 'p':
cf13d699
NC
4008 request_dump (STRING_DUMP);
4009 break;
4010 case 'R':
4011 request_dump (RELOC_DUMP);
09c11c86 4012 break;
252b5132 4013 case 'w':
b34976b6 4014 do_dump++;
252b5132 4015 if (optarg == 0)
613ff48b
CC
4016 {
4017 do_debugging = 1;
4018 dwarf_select_sections_all ();
4019 }
252b5132
RH
4020 else
4021 {
4022 do_debugging = 0;
4cb93e3b 4023 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4024 }
4025 break;
2979dc34 4026 case OPTION_DEBUG_DUMP:
b34976b6 4027 do_dump++;
2979dc34
JJ
4028 if (optarg == 0)
4029 do_debugging = 1;
4030 else
4031 {
2979dc34 4032 do_debugging = 0;
4cb93e3b 4033 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4034 }
4035 break;
fd2f0033
TT
4036 case OPTION_DWARF_DEPTH:
4037 {
4038 char *cp;
4039
4040 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4041 }
4042 break;
4043 case OPTION_DWARF_START:
4044 {
4045 char *cp;
4046
4047 dwarf_start_die = strtoul (optarg, & cp, 0);
4048 }
4049 break;
4723351a
CC
4050 case OPTION_DWARF_CHECK:
4051 dwarf_check = 1;
4052 break;
2c610e4b
L
4053 case OPTION_DYN_SYMS:
4054 do_dyn_syms++;
4055 break;
252b5132
RH
4056#ifdef SUPPORT_DISASSEMBLY
4057 case 'i':
cf13d699
NC
4058 request_dump (DISASS_DUMP);
4059 break;
252b5132
RH
4060#endif
4061 case 'v':
4062 print_version (program_name);
4063 break;
4064 case 'V':
b34976b6 4065 do_version++;
252b5132 4066 break;
d974e256 4067 case 'W':
b34976b6 4068 do_wide++;
d974e256 4069 break;
252b5132 4070 default:
252b5132
RH
4071 /* xgettext:c-format */
4072 error (_("Invalid option '-%c'\n"), c);
4073 /* Drop through. */
4074 case '?':
92f01d61 4075 usage (stderr);
252b5132
RH
4076 }
4077 }
4078
4d6ed7c8 4079 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4080 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4081 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4082 && !do_section_groups && !do_archive_index
4083 && !do_dyn_syms)
92f01d61 4084 usage (stderr);
252b5132
RH
4085 else if (argc < 3)
4086 {
4087 warn (_("Nothing to do.\n"));
92f01d61 4088 usage (stderr);
252b5132
RH
4089 }
4090}
4091
4092static const char *
d3ba0551 4093get_elf_class (unsigned int elf_class)
252b5132 4094{
b34976b6 4095 static char buff[32];
103f02d3 4096
252b5132
RH
4097 switch (elf_class)
4098 {
4099 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4100 case ELFCLASS32: return "ELF32";
4101 case ELFCLASS64: return "ELF64";
ab5e7794 4102 default:
e9e44622 4103 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4104 return buff;
252b5132
RH
4105 }
4106}
4107
4108static const char *
d3ba0551 4109get_data_encoding (unsigned int encoding)
252b5132 4110{
b34976b6 4111 static char buff[32];
103f02d3 4112
252b5132
RH
4113 switch (encoding)
4114 {
4115 case ELFDATANONE: return _("none");
33c63f9d
CM
4116 case ELFDATA2LSB: return _("2's complement, little endian");
4117 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4118 default:
e9e44622 4119 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4120 return buff;
252b5132
RH
4121 }
4122}
4123
252b5132 4124/* Decode the data held in 'elf_header'. */
ee42cf8c 4125
252b5132 4126static int
d3ba0551 4127process_file_header (void)
252b5132 4128{
b34976b6
AM
4129 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4130 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4131 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4132 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4133 {
4134 error
4135 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4136 return 0;
4137 }
4138
2dc4cec1
L
4139 init_dwarf_regnames (elf_header.e_machine);
4140
252b5132
RH
4141 if (do_header)
4142 {
4143 int i;
4144
4145 printf (_("ELF Header:\n"));
4146 printf (_(" Magic: "));
b34976b6
AM
4147 for (i = 0; i < EI_NIDENT; i++)
4148 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4149 printf ("\n");
4150 printf (_(" Class: %s\n"),
b34976b6 4151 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4152 printf (_(" Data: %s\n"),
b34976b6 4153 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4154 printf (_(" Version: %d %s\n"),
b34976b6
AM
4155 elf_header.e_ident[EI_VERSION],
4156 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4157 ? "(current)"
b34976b6 4158 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4159 ? _("<unknown: %lx>")
789be9f7 4160 : "")));
252b5132 4161 printf (_(" OS/ABI: %s\n"),
b34976b6 4162 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4163 printf (_(" ABI Version: %d\n"),
b34976b6 4164 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4165 printf (_(" Type: %s\n"),
4166 get_file_type (elf_header.e_type));
4167 printf (_(" Machine: %s\n"),
4168 get_machine_name (elf_header.e_machine));
4169 printf (_(" Version: 0x%lx\n"),
4170 (unsigned long) elf_header.e_version);
76da6bbe 4171
f7a99963
NC
4172 printf (_(" Entry point address: "));
4173 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4174 printf (_("\n Start of program headers: "));
4175 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4176 printf (_(" (bytes into file)\n Start of section headers: "));
4177 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4178 printf (_(" (bytes into file)\n"));
76da6bbe 4179
252b5132
RH
4180 printf (_(" Flags: 0x%lx%s\n"),
4181 (unsigned long) elf_header.e_flags,
4182 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4183 printf (_(" Size of this header: %ld (bytes)\n"),
4184 (long) elf_header.e_ehsize);
4185 printf (_(" Size of program headers: %ld (bytes)\n"),
4186 (long) elf_header.e_phentsize);
2046a35d 4187 printf (_(" Number of program headers: %ld"),
252b5132 4188 (long) elf_header.e_phnum);
2046a35d
AM
4189 if (section_headers != NULL
4190 && elf_header.e_phnum == PN_XNUM
4191 && section_headers[0].sh_info != 0)
cc5914eb 4192 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4193 putc ('\n', stdout);
252b5132
RH
4194 printf (_(" Size of section headers: %ld (bytes)\n"),
4195 (long) elf_header.e_shentsize);
560f3c1c 4196 printf (_(" Number of section headers: %ld"),
252b5132 4197 (long) elf_header.e_shnum);
4fbb74a6 4198 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4199 printf (" (%ld)", (long) section_headers[0].sh_size);
4200 putc ('\n', stdout);
4201 printf (_(" Section header string table index: %ld"),
252b5132 4202 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4203 if (section_headers != NULL
4204 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4205 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4206 else if (elf_header.e_shstrndx != SHN_UNDEF
4207 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4208 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4209 putc ('\n', stdout);
4210 }
4211
4212 if (section_headers != NULL)
4213 {
2046a35d
AM
4214 if (elf_header.e_phnum == PN_XNUM
4215 && section_headers[0].sh_info != 0)
4216 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4217 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4218 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4219 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4220 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4221 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4222 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4223 free (section_headers);
4224 section_headers = NULL;
252b5132 4225 }
103f02d3 4226
9ea033b2
NC
4227 return 1;
4228}
4229
e0a31db1 4230static bfd_boolean
91d6fa6a 4231get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4232{
2cf0635d
NC
4233 Elf32_External_Phdr * phdrs;
4234 Elf32_External_Phdr * external;
4235 Elf_Internal_Phdr * internal;
b34976b6 4236 unsigned int i;
e0a31db1
NC
4237 unsigned int size = elf_header.e_phentsize;
4238 unsigned int num = elf_header.e_phnum;
4239
4240 /* PR binutils/17531: Cope with unexpected section header sizes. */
4241 if (size == 0 || num == 0)
4242 return FALSE;
4243 if (size < sizeof * phdrs)
4244 {
4245 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4246 return FALSE;
4247 }
4248 if (size > sizeof * phdrs)
4249 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4250
3f5e193b 4251 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4252 size, num, _("program headers"));
4253 if (phdrs == NULL)
4254 return FALSE;
9ea033b2 4255
91d6fa6a 4256 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4257 i < elf_header.e_phnum;
b34976b6 4258 i++, internal++, external++)
252b5132 4259 {
9ea033b2
NC
4260 internal->p_type = BYTE_GET (external->p_type);
4261 internal->p_offset = BYTE_GET (external->p_offset);
4262 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4263 internal->p_paddr = BYTE_GET (external->p_paddr);
4264 internal->p_filesz = BYTE_GET (external->p_filesz);
4265 internal->p_memsz = BYTE_GET (external->p_memsz);
4266 internal->p_flags = BYTE_GET (external->p_flags);
4267 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4268 }
4269
9ea033b2 4270 free (phdrs);
e0a31db1 4271 return TRUE;
252b5132
RH
4272}
4273
e0a31db1 4274static bfd_boolean
91d6fa6a 4275get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4276{
2cf0635d
NC
4277 Elf64_External_Phdr * phdrs;
4278 Elf64_External_Phdr * external;
4279 Elf_Internal_Phdr * internal;
b34976b6 4280 unsigned int i;
e0a31db1
NC
4281 unsigned int size = elf_header.e_phentsize;
4282 unsigned int num = elf_header.e_phnum;
4283
4284 /* PR binutils/17531: Cope with unexpected section header sizes. */
4285 if (size == 0 || num == 0)
4286 return FALSE;
4287 if (size < sizeof * phdrs)
4288 {
4289 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4290 return FALSE;
4291 }
4292 if (size > sizeof * phdrs)
4293 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4294
3f5e193b 4295 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4296 size, num, _("program headers"));
a6e9f9df 4297 if (!phdrs)
e0a31db1 4298 return FALSE;
9ea033b2 4299
91d6fa6a 4300 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4301 i < elf_header.e_phnum;
b34976b6 4302 i++, internal++, external++)
9ea033b2
NC
4303 {
4304 internal->p_type = BYTE_GET (external->p_type);
4305 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4306 internal->p_offset = BYTE_GET (external->p_offset);
4307 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4308 internal->p_paddr = BYTE_GET (external->p_paddr);
4309 internal->p_filesz = BYTE_GET (external->p_filesz);
4310 internal->p_memsz = BYTE_GET (external->p_memsz);
4311 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4312 }
4313
4314 free (phdrs);
e0a31db1 4315 return TRUE;
9ea033b2 4316}
252b5132 4317
d93f0186
NC
4318/* Returns 1 if the program headers were read into `program_headers'. */
4319
4320static int
2cf0635d 4321get_program_headers (FILE * file)
d93f0186 4322{
2cf0635d 4323 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4324
4325 /* Check cache of prior read. */
4326 if (program_headers != NULL)
4327 return 1;
4328
3f5e193b
NC
4329 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4330 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4331
4332 if (phdrs == NULL)
4333 {
8b73c356
NC
4334 error (_("Out of memory reading %u program headers\n"),
4335 elf_header.e_phnum);
d93f0186
NC
4336 return 0;
4337 }
4338
4339 if (is_32bit_elf
4340 ? get_32bit_program_headers (file, phdrs)
4341 : get_64bit_program_headers (file, phdrs))
4342 {
4343 program_headers = phdrs;
4344 return 1;
4345 }
4346
4347 free (phdrs);
4348 return 0;
4349}
4350
2f62977e
NC
4351/* Returns 1 if the program headers were loaded. */
4352
252b5132 4353static int
2cf0635d 4354process_program_headers (FILE * file)
252b5132 4355{
2cf0635d 4356 Elf_Internal_Phdr * segment;
b34976b6 4357 unsigned int i;
252b5132
RH
4358
4359 if (elf_header.e_phnum == 0)
4360 {
82f2dbf7
NC
4361 /* PR binutils/12467. */
4362 if (elf_header.e_phoff != 0)
4363 warn (_("possibly corrupt ELF header - it has a non-zero program"
4364 " header offset, but no program headers"));
4365 else if (do_segments)
252b5132 4366 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4367 return 0;
252b5132
RH
4368 }
4369
4370 if (do_segments && !do_header)
4371 {
f7a99963
NC
4372 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4373 printf (_("Entry point "));
4374 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4375 printf (_("\nThere are %d program headers, starting at offset "),
4376 elf_header.e_phnum);
4377 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4378 printf ("\n");
252b5132
RH
4379 }
4380
d93f0186 4381 if (! get_program_headers (file))
252b5132 4382 return 0;
103f02d3 4383
252b5132
RH
4384 if (do_segments)
4385 {
3a1a2036
NC
4386 if (elf_header.e_phnum > 1)
4387 printf (_("\nProgram Headers:\n"));
4388 else
4389 printf (_("\nProgram Headers:\n"));
76da6bbe 4390
f7a99963
NC
4391 if (is_32bit_elf)
4392 printf
4393 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4394 else if (do_wide)
4395 printf
4396 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4397 else
4398 {
4399 printf
4400 (_(" Type Offset VirtAddr PhysAddr\n"));
4401 printf
4402 (_(" FileSiz MemSiz Flags Align\n"));
4403 }
252b5132
RH
4404 }
4405
252b5132 4406 dynamic_addr = 0;
1b228002 4407 dynamic_size = 0;
252b5132
RH
4408
4409 for (i = 0, segment = program_headers;
4410 i < elf_header.e_phnum;
b34976b6 4411 i++, segment++)
252b5132
RH
4412 {
4413 if (do_segments)
4414 {
103f02d3 4415 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4416
4417 if (is_32bit_elf)
4418 {
4419 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4420 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4421 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4422 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4423 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4424 printf ("%c%c%c ",
4425 (segment->p_flags & PF_R ? 'R' : ' '),
4426 (segment->p_flags & PF_W ? 'W' : ' '),
4427 (segment->p_flags & PF_X ? 'E' : ' '));
4428 printf ("%#lx", (unsigned long) segment->p_align);
4429 }
d974e256
JJ
4430 else if (do_wide)
4431 {
4432 if ((unsigned long) segment->p_offset == segment->p_offset)
4433 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4434 else
4435 {
4436 print_vma (segment->p_offset, FULL_HEX);
4437 putchar (' ');
4438 }
4439
4440 print_vma (segment->p_vaddr, FULL_HEX);
4441 putchar (' ');
4442 print_vma (segment->p_paddr, FULL_HEX);
4443 putchar (' ');
4444
4445 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4446 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4447 else
4448 {
4449 print_vma (segment->p_filesz, FULL_HEX);
4450 putchar (' ');
4451 }
4452
4453 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4454 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4455 else
4456 {
f48e6c45 4457 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4458 }
4459
4460 printf (" %c%c%c ",
4461 (segment->p_flags & PF_R ? 'R' : ' '),
4462 (segment->p_flags & PF_W ? 'W' : ' '),
4463 (segment->p_flags & PF_X ? 'E' : ' '));
4464
4465 if ((unsigned long) segment->p_align == segment->p_align)
4466 printf ("%#lx", (unsigned long) segment->p_align);
4467 else
4468 {
4469 print_vma (segment->p_align, PREFIX_HEX);
4470 }
4471 }
f7a99963
NC
4472 else
4473 {
4474 print_vma (segment->p_offset, FULL_HEX);
4475 putchar (' ');
4476 print_vma (segment->p_vaddr, FULL_HEX);
4477 putchar (' ');
4478 print_vma (segment->p_paddr, FULL_HEX);
4479 printf ("\n ");
4480 print_vma (segment->p_filesz, FULL_HEX);
4481 putchar (' ');
4482 print_vma (segment->p_memsz, FULL_HEX);
4483 printf (" %c%c%c ",
4484 (segment->p_flags & PF_R ? 'R' : ' '),
4485 (segment->p_flags & PF_W ? 'W' : ' '),
4486 (segment->p_flags & PF_X ? 'E' : ' '));
4487 print_vma (segment->p_align, HEX);
4488 }
252b5132
RH
4489 }
4490
f54498b4
NC
4491 if (do_segments)
4492 putc ('\n', stdout);
4493
252b5132
RH
4494 switch (segment->p_type)
4495 {
252b5132
RH
4496 case PT_DYNAMIC:
4497 if (dynamic_addr)
4498 error (_("more than one dynamic segment\n"));
4499
20737c13
AM
4500 /* By default, assume that the .dynamic section is the first
4501 section in the DYNAMIC segment. */
4502 dynamic_addr = segment->p_offset;
4503 dynamic_size = segment->p_filesz;
f54498b4
NC
4504 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4505 if (dynamic_addr + dynamic_size >= current_file_size)
4506 {
4507 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4508 dynamic_addr = dynamic_size = 0;
4509 }
20737c13 4510
b2d38a17
NC
4511 /* Try to locate the .dynamic section. If there is
4512 a section header table, we can easily locate it. */
4513 if (section_headers != NULL)
4514 {
2cf0635d 4515 Elf_Internal_Shdr * sec;
b2d38a17 4516
89fac5e3
RS
4517 sec = find_section (".dynamic");
4518 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4519 {
28f997cf
TG
4520 /* A corresponding .dynamic section is expected, but on
4521 IA-64/OpenVMS it is OK for it to be missing. */
4522 if (!is_ia64_vms ())
4523 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4524 break;
4525 }
4526
42bb2e33 4527 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4528 {
4529 dynamic_size = 0;
4530 break;
4531 }
42bb2e33 4532
b2d38a17
NC
4533 dynamic_addr = sec->sh_offset;
4534 dynamic_size = sec->sh_size;
4535
4536 if (dynamic_addr < segment->p_offset
4537 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4538 warn (_("the .dynamic section is not contained"
4539 " within the dynamic segment\n"));
b2d38a17 4540 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4541 warn (_("the .dynamic section is not the first section"
4542 " in the dynamic segment.\n"));
b2d38a17 4543 }
252b5132
RH
4544 break;
4545
4546 case PT_INTERP:
fb52b2f4
NC
4547 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4548 SEEK_SET))
252b5132
RH
4549 error (_("Unable to find program interpreter name\n"));
4550 else
4551 {
f8eae8b2 4552 char fmt [32];
9495b2e6 4553 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4554
4555 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4556 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4557
252b5132 4558 program_interpreter[0] = 0;
7bd7b3ef
AM
4559 if (fscanf (file, fmt, program_interpreter) <= 0)
4560 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4561
4562 if (do_segments)
f54498b4 4563 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4564 program_interpreter);
4565 }
4566 break;
4567 }
252b5132
RH
4568 }
4569
c256ffe7 4570 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4571 {
4572 printf (_("\n Section to Segment mapping:\n"));
4573 printf (_(" Segment Sections...\n"));
4574
252b5132
RH
4575 for (i = 0; i < elf_header.e_phnum; i++)
4576 {
9ad5cbcf 4577 unsigned int j;
2cf0635d 4578 Elf_Internal_Shdr * section;
252b5132
RH
4579
4580 segment = program_headers + i;
b391a3e3 4581 section = section_headers + 1;
252b5132
RH
4582
4583 printf (" %2.2d ", i);
4584
b34976b6 4585 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4586 {
f4638467
AM
4587 if (!ELF_TBSS_SPECIAL (section, segment)
4588 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4589 printf ("%s ", printable_section_name (section));
252b5132
RH
4590 }
4591
4592 putc ('\n',stdout);
4593 }
4594 }
4595
252b5132
RH
4596 return 1;
4597}
4598
4599
d93f0186
NC
4600/* Find the file offset corresponding to VMA by using the program headers. */
4601
4602static long
2cf0635d 4603offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4604{
2cf0635d 4605 Elf_Internal_Phdr * seg;
d93f0186
NC
4606
4607 if (! get_program_headers (file))
4608 {
4609 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4610 return (long) vma;
4611 }
4612
4613 for (seg = program_headers;
4614 seg < program_headers + elf_header.e_phnum;
4615 ++seg)
4616 {
4617 if (seg->p_type != PT_LOAD)
4618 continue;
4619
4620 if (vma >= (seg->p_vaddr & -seg->p_align)
4621 && vma + size <= seg->p_vaddr + seg->p_filesz)
4622 return vma - seg->p_vaddr + seg->p_offset;
4623 }
4624
4625 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4626 (unsigned long) vma);
d93f0186
NC
4627 return (long) vma;
4628}
4629
4630
049b0c3a
NC
4631/* Allocate memory and load the sections headers into the global pointer
4632 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4633 generate any error messages if the load fails. */
4634
4635static bfd_boolean
4636get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4637{
2cf0635d
NC
4638 Elf32_External_Shdr * shdrs;
4639 Elf_Internal_Shdr * internal;
b34976b6 4640 unsigned int i;
049b0c3a
NC
4641 unsigned int size = elf_header.e_shentsize;
4642 unsigned int num = probe ? 1 : elf_header.e_shnum;
4643
4644 /* PR binutils/17531: Cope with unexpected section header sizes. */
4645 if (size == 0 || num == 0)
4646 return FALSE;
4647 if (size < sizeof * shdrs)
4648 {
4649 if (! probe)
4650 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4651 return FALSE;
4652 }
4653 if (!probe && size > sizeof * shdrs)
4654 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4655
3f5e193b 4656 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4657 size, num,
4658 probe ? NULL : _("section headers"));
4659 if (shdrs == NULL)
4660 return FALSE;
252b5132 4661
049b0c3a
NC
4662 if (section_headers != NULL)
4663 free (section_headers);
3f5e193b
NC
4664 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4665 sizeof (Elf_Internal_Shdr));
252b5132
RH
4666 if (section_headers == NULL)
4667 {
049b0c3a 4668 if (!probe)
8b73c356 4669 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4670 return FALSE;
252b5132
RH
4671 }
4672
4673 for (i = 0, internal = section_headers;
560f3c1c 4674 i < num;
b34976b6 4675 i++, internal++)
252b5132
RH
4676 {
4677 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4678 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4679 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4680 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4681 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4682 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4683 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4684 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4685 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4686 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4687 }
4688
4689 free (shdrs);
049b0c3a 4690 return TRUE;
252b5132
RH
4691}
4692
049b0c3a
NC
4693static bfd_boolean
4694get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4695{
2cf0635d
NC
4696 Elf64_External_Shdr * shdrs;
4697 Elf_Internal_Shdr * internal;
b34976b6 4698 unsigned int i;
049b0c3a
NC
4699 unsigned int size = elf_header.e_shentsize;
4700 unsigned int num = probe ? 1 : elf_header.e_shnum;
4701
4702 /* PR binutils/17531: Cope with unexpected section header sizes. */
4703 if (size == 0 || num == 0)
4704 return FALSE;
4705 if (size < sizeof * shdrs)
4706 {
4707 if (! probe)
4708 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4709 return FALSE;
4710 }
4711 if (! probe && size > sizeof * shdrs)
4712 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4713
3f5e193b 4714 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4715 size, num,
4716 probe ? NULL : _("section headers"));
4717 if (shdrs == NULL)
4718 return FALSE;
9ea033b2 4719
049b0c3a
NC
4720 if (section_headers != NULL)
4721 free (section_headers);
3f5e193b
NC
4722 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4723 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4724 if (section_headers == NULL)
4725 {
049b0c3a 4726 if (! probe)
8b73c356 4727 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4728 return FALSE;
9ea033b2
NC
4729 }
4730
4731 for (i = 0, internal = section_headers;
560f3c1c 4732 i < num;
b34976b6 4733 i++, internal++)
9ea033b2
NC
4734 {
4735 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4736 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4737 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4738 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4739 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4740 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4741 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4742 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4743 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4744 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4745 }
4746
4747 free (shdrs);
049b0c3a 4748 return TRUE;
9ea033b2
NC
4749}
4750
252b5132 4751static Elf_Internal_Sym *
ba5cdace
NC
4752get_32bit_elf_symbols (FILE * file,
4753 Elf_Internal_Shdr * section,
4754 unsigned long * num_syms_return)
252b5132 4755{
ba5cdace 4756 unsigned long number = 0;
dd24e3da 4757 Elf32_External_Sym * esyms = NULL;
ba5cdace 4758 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4759 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4760 Elf_Internal_Sym * psym;
b34976b6 4761 unsigned int j;
252b5132 4762
c9c1d674
EG
4763 if (section->sh_size == 0)
4764 {
4765 if (num_syms_return != NULL)
4766 * num_syms_return = 0;
4767 return NULL;
4768 }
4769
dd24e3da 4770 /* Run some sanity checks first. */
c9c1d674 4771 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4772 {
c9c1d674
EG
4773 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4774 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4775 goto exit_point;
dd24e3da
NC
4776 }
4777
f54498b4
NC
4778 if (section->sh_size > current_file_size)
4779 {
4780 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4781 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4782 goto exit_point;
4783 }
4784
dd24e3da
NC
4785 number = section->sh_size / section->sh_entsize;
4786
4787 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4788 {
c9c1d674
EG
4789 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
4790 section->sh_size, printable_section_name (section), section->sh_entsize);
ba5cdace 4791 goto exit_point;
dd24e3da
NC
4792 }
4793
3f5e193b
NC
4794 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4795 section->sh_size, _("symbols"));
dd24e3da 4796 if (esyms == NULL)
ba5cdace 4797 goto exit_point;
252b5132 4798
9ad5cbcf
AM
4799 shndx = NULL;
4800 if (symtab_shndx_hdr != NULL
4801 && (symtab_shndx_hdr->sh_link
4fbb74a6 4802 == (unsigned long) (section - section_headers)))
9ad5cbcf 4803 {
3f5e193b
NC
4804 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4805 symtab_shndx_hdr->sh_offset,
4806 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4807 _("symbol table section indicies"));
dd24e3da
NC
4808 if (shndx == NULL)
4809 goto exit_point;
c9c1d674
EG
4810 /* PR17531: file: heap-buffer-overflow */
4811 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4812 {
4813 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4814 printable_section_name (symtab_shndx_hdr),
4815 (unsigned long) symtab_shndx_hdr->sh_size,
4816 (unsigned long) section->sh_size);
4817 goto exit_point;
4818 }
9ad5cbcf
AM
4819 }
4820
3f5e193b 4821 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4822
4823 if (isyms == NULL)
4824 {
8b73c356
NC
4825 error (_("Out of memory reading %lu symbols\n"),
4826 (unsigned long) number);
dd24e3da 4827 goto exit_point;
252b5132
RH
4828 }
4829
dd24e3da 4830 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4831 {
4832 psym->st_name = BYTE_GET (esyms[j].st_name);
4833 psym->st_value = BYTE_GET (esyms[j].st_value);
4834 psym->st_size = BYTE_GET (esyms[j].st_size);
4835 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4836 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4837 psym->st_shndx
4838 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4839 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4840 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4841 psym->st_info = BYTE_GET (esyms[j].st_info);
4842 psym->st_other = BYTE_GET (esyms[j].st_other);
4843 }
4844
dd24e3da 4845 exit_point:
ba5cdace 4846 if (shndx != NULL)
9ad5cbcf 4847 free (shndx);
ba5cdace 4848 if (esyms != NULL)
dd24e3da 4849 free (esyms);
252b5132 4850
ba5cdace
NC
4851 if (num_syms_return != NULL)
4852 * num_syms_return = isyms == NULL ? 0 : number;
4853
252b5132
RH
4854 return isyms;
4855}
4856
9ea033b2 4857static Elf_Internal_Sym *
ba5cdace
NC
4858get_64bit_elf_symbols (FILE * file,
4859 Elf_Internal_Shdr * section,
4860 unsigned long * num_syms_return)
9ea033b2 4861{
ba5cdace
NC
4862 unsigned long number = 0;
4863 Elf64_External_Sym * esyms = NULL;
4864 Elf_External_Sym_Shndx * shndx = NULL;
4865 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4866 Elf_Internal_Sym * psym;
b34976b6 4867 unsigned int j;
9ea033b2 4868
c9c1d674
EG
4869 if (section->sh_size == 0)
4870 {
4871 if (num_syms_return != NULL)
4872 * num_syms_return = 0;
4873 return NULL;
4874 }
4875
dd24e3da 4876 /* Run some sanity checks first. */
c9c1d674 4877 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4878 {
c9c1d674
EG
4879 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4880 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4881 goto exit_point;
dd24e3da
NC
4882 }
4883
f54498b4
NC
4884 if (section->sh_size > current_file_size)
4885 {
4886 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4887 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4888 goto exit_point;
4889 }
4890
dd24e3da
NC
4891 number = section->sh_size / section->sh_entsize;
4892
4893 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4894 {
c9c1d674
EG
4895 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
4896 section->sh_size, printable_section_name (section), section->sh_entsize);
ba5cdace 4897 goto exit_point;
dd24e3da
NC
4898 }
4899
3f5e193b
NC
4900 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4901 section->sh_size, _("symbols"));
a6e9f9df 4902 if (!esyms)
ba5cdace 4903 goto exit_point;
9ea033b2 4904
9ad5cbcf
AM
4905 if (symtab_shndx_hdr != NULL
4906 && (symtab_shndx_hdr->sh_link
4fbb74a6 4907 == (unsigned long) (section - section_headers)))
9ad5cbcf 4908 {
3f5e193b
NC
4909 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4910 symtab_shndx_hdr->sh_offset,
4911 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4912 _("symbol table section indicies"));
ba5cdace
NC
4913 if (shndx == NULL)
4914 goto exit_point;
c9c1d674
EG
4915 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4916 {
4917 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4918 printable_section_name (symtab_shndx_hdr),
4919 (unsigned long) symtab_shndx_hdr->sh_size,
4920 (unsigned long) section->sh_size);
4921 goto exit_point;
4922 }
9ad5cbcf
AM
4923 }
4924
3f5e193b 4925 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4926
4927 if (isyms == NULL)
4928 {
8b73c356
NC
4929 error (_("Out of memory reading %lu symbols\n"),
4930 (unsigned long) number);
ba5cdace 4931 goto exit_point;
9ea033b2
NC
4932 }
4933
ba5cdace 4934 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4935 {
4936 psym->st_name = BYTE_GET (esyms[j].st_name);
4937 psym->st_info = BYTE_GET (esyms[j].st_info);
4938 psym->st_other = BYTE_GET (esyms[j].st_other);
4939 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4940
4fbb74a6 4941 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4942 psym->st_shndx
4943 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4944 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4945 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4946
66543521
AM
4947 psym->st_value = BYTE_GET (esyms[j].st_value);
4948 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4949 }
4950
ba5cdace
NC
4951 exit_point:
4952 if (shndx != NULL)
9ad5cbcf 4953 free (shndx);
ba5cdace
NC
4954 if (esyms != NULL)
4955 free (esyms);
4956
4957 if (num_syms_return != NULL)
4958 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4959
4960 return isyms;
4961}
4962
d1133906 4963static const char *
d3ba0551 4964get_elf_section_flags (bfd_vma sh_flags)
d1133906 4965{
5477e8a0 4966 static char buff[1024];
2cf0635d 4967 char * p = buff;
8d5ff12c 4968 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4969 int sindex;
4970 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4971 bfd_vma os_flags = 0;
4972 bfd_vma proc_flags = 0;
4973 bfd_vma unknown_flags = 0;
148b93f2 4974 static const struct
5477e8a0 4975 {
2cf0635d 4976 const char * str;
5477e8a0
L
4977 int len;
4978 }
4979 flags [] =
4980 {
cfcac11d
NC
4981 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4982 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4983 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4984 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4985 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4986 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4987 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4988 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4989 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4990 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4991 /* IA-64 specific. */
4992 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4993 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4994 /* IA-64 OpenVMS specific. */
4995 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4996 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4997 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4998 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4999 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5000 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5001 /* Generic. */
cfcac11d 5002 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5003 /* SPARC specific. */
cfcac11d 5004 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5005 };
5006
5007 if (do_section_details)
5008 {
8d5ff12c
L
5009 sprintf (buff, "[%*.*lx]: ",
5010 field_size, field_size, (unsigned long) sh_flags);
5011 p += field_size + 4;
5477e8a0 5012 }
76da6bbe 5013
d1133906
NC
5014 while (sh_flags)
5015 {
5016 bfd_vma flag;
5017
5018 flag = sh_flags & - sh_flags;
5019 sh_flags &= ~ flag;
76da6bbe 5020
5477e8a0 5021 if (do_section_details)
d1133906 5022 {
5477e8a0
L
5023 switch (flag)
5024 {
91d6fa6a
NC
5025 case SHF_WRITE: sindex = 0; break;
5026 case SHF_ALLOC: sindex = 1; break;
5027 case SHF_EXECINSTR: sindex = 2; break;
5028 case SHF_MERGE: sindex = 3; break;
5029 case SHF_STRINGS: sindex = 4; break;
5030 case SHF_INFO_LINK: sindex = 5; break;
5031 case SHF_LINK_ORDER: sindex = 6; break;
5032 case SHF_OS_NONCONFORMING: sindex = 7; break;
5033 case SHF_GROUP: sindex = 8; break;
5034 case SHF_TLS: sindex = 9; break;
18ae9cc1 5035 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5036
5477e8a0 5037 default:
91d6fa6a 5038 sindex = -1;
cfcac11d 5039 switch (elf_header.e_machine)
148b93f2 5040 {
cfcac11d 5041 case EM_IA_64:
148b93f2 5042 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5043 sindex = 10;
148b93f2 5044 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5045 sindex = 11;
148b93f2
NC
5046#ifdef BFD64
5047 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5048 switch (flag)
5049 {
91d6fa6a
NC
5050 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5051 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5052 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5053 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5054 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5055 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5056 default: break;
5057 }
5058#endif
cfcac11d
NC
5059 break;
5060
caa83f8b
NC
5061 case EM_386:
5062 case EM_486:
5063 case EM_X86_64:
7f502d6c 5064 case EM_L1OM:
7a9068fe 5065 case EM_K1OM:
cfcac11d
NC
5066 case EM_OLD_SPARCV9:
5067 case EM_SPARC32PLUS:
5068 case EM_SPARCV9:
5069 case EM_SPARC:
18ae9cc1 5070 if (flag == SHF_ORDERED)
91d6fa6a 5071 sindex = 19;
cfcac11d
NC
5072 break;
5073 default:
5074 break;
148b93f2 5075 }
5477e8a0
L
5076 }
5077
91d6fa6a 5078 if (sindex != -1)
5477e8a0 5079 {
8d5ff12c
L
5080 if (p != buff + field_size + 4)
5081 {
5082 if (size < (10 + 2))
5083 abort ();
5084 size -= 2;
5085 *p++ = ',';
5086 *p++ = ' ';
5087 }
5088
91d6fa6a
NC
5089 size -= flags [sindex].len;
5090 p = stpcpy (p, flags [sindex].str);
5477e8a0 5091 }
3b22753a 5092 else if (flag & SHF_MASKOS)
8d5ff12c 5093 os_flags |= flag;
d1133906 5094 else if (flag & SHF_MASKPROC)
8d5ff12c 5095 proc_flags |= flag;
d1133906 5096 else
8d5ff12c 5097 unknown_flags |= flag;
5477e8a0
L
5098 }
5099 else
5100 {
5101 switch (flag)
5102 {
5103 case SHF_WRITE: *p = 'W'; break;
5104 case SHF_ALLOC: *p = 'A'; break;
5105 case SHF_EXECINSTR: *p = 'X'; break;
5106 case SHF_MERGE: *p = 'M'; break;
5107 case SHF_STRINGS: *p = 'S'; break;
5108 case SHF_INFO_LINK: *p = 'I'; break;
5109 case SHF_LINK_ORDER: *p = 'L'; break;
5110 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5111 case SHF_GROUP: *p = 'G'; break;
5112 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5113 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5114
5115 default:
8a9036a4 5116 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5117 || elf_header.e_machine == EM_L1OM
5118 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5119 && flag == SHF_X86_64_LARGE)
5120 *p = 'l';
5121 else if (flag & SHF_MASKOS)
5122 {
5123 *p = 'o';
5124 sh_flags &= ~ SHF_MASKOS;
5125 }
5126 else if (flag & SHF_MASKPROC)
5127 {
5128 *p = 'p';
5129 sh_flags &= ~ SHF_MASKPROC;
5130 }
5131 else
5132 *p = 'x';
5133 break;
5134 }
5135 p++;
d1133906
NC
5136 }
5137 }
76da6bbe 5138
8d5ff12c
L
5139 if (do_section_details)
5140 {
5141 if (os_flags)
5142 {
5143 size -= 5 + field_size;
5144 if (p != buff + field_size + 4)
5145 {
5146 if (size < (2 + 1))
5147 abort ();
5148 size -= 2;
5149 *p++ = ',';
5150 *p++ = ' ';
5151 }
5152 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5153 (unsigned long) os_flags);
5154 p += 5 + field_size;
5155 }
5156 if (proc_flags)
5157 {
5158 size -= 7 + field_size;
5159 if (p != buff + field_size + 4)
5160 {
5161 if (size < (2 + 1))
5162 abort ();
5163 size -= 2;
5164 *p++ = ',';
5165 *p++ = ' ';
5166 }
5167 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5168 (unsigned long) proc_flags);
5169 p += 7 + field_size;
5170 }
5171 if (unknown_flags)
5172 {
5173 size -= 10 + field_size;
5174 if (p != buff + field_size + 4)
5175 {
5176 if (size < (2 + 1))
5177 abort ();
5178 size -= 2;
5179 *p++ = ',';
5180 *p++ = ' ';
5181 }
2b692964 5182 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5183 (unsigned long) unknown_flags);
5184 p += 10 + field_size;
5185 }
5186 }
5187
e9e44622 5188 *p = '\0';
d1133906
NC
5189 return buff;
5190}
5191
252b5132 5192static int
2cf0635d 5193process_section_headers (FILE * file)
252b5132 5194{
2cf0635d 5195 Elf_Internal_Shdr * section;
b34976b6 5196 unsigned int i;
252b5132
RH
5197
5198 section_headers = NULL;
5199
5200 if (elf_header.e_shnum == 0)
5201 {
82f2dbf7
NC
5202 /* PR binutils/12467. */
5203 if (elf_header.e_shoff != 0)
5204 warn (_("possibly corrupt ELF file header - it has a non-zero"
5205 " section header offset, but no section headers\n"));
5206 else if (do_sections)
252b5132
RH
5207 printf (_("\nThere are no sections in this file.\n"));
5208
5209 return 1;
5210 }
5211
5212 if (do_sections && !do_header)
9ea033b2 5213 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5214 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5215
9ea033b2
NC
5216 if (is_32bit_elf)
5217 {
049b0c3a 5218 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5219 return 0;
5220 }
049b0c3a 5221 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5222 return 0;
5223
5224 /* Read in the string table, so that we have names to display. */
0b49d371 5225 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5226 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5227 {
4fbb74a6 5228 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5229
c256ffe7
JJ
5230 if (section->sh_size != 0)
5231 {
3f5e193b
NC
5232 string_table = (char *) get_data (NULL, file, section->sh_offset,
5233 1, section->sh_size,
5234 _("string table"));
0de14b54 5235
c256ffe7
JJ
5236 string_table_length = string_table != NULL ? section->sh_size : 0;
5237 }
252b5132
RH
5238 }
5239
5240 /* Scan the sections for the dynamic symbol table
e3c8793a 5241 and dynamic string table and debug sections. */
252b5132
RH
5242 dynamic_symbols = NULL;
5243 dynamic_strings = NULL;
5244 dynamic_syminfo = NULL;
f1ef08cb 5245 symtab_shndx_hdr = NULL;
103f02d3 5246
89fac5e3
RS
5247 eh_addr_size = is_32bit_elf ? 4 : 8;
5248 switch (elf_header.e_machine)
5249 {
5250 case EM_MIPS:
5251 case EM_MIPS_RS3_LE:
5252 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5253 FDE addresses. However, the ABI also has a semi-official ILP32
5254 variant for which the normal FDE address size rules apply.
5255
5256 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5257 section, where XX is the size of longs in bits. Unfortunately,
5258 earlier compilers provided no way of distinguishing ILP32 objects
5259 from LP64 objects, so if there's any doubt, we should assume that
5260 the official LP64 form is being used. */
5261 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5262 && find_section (".gcc_compiled_long32") == NULL)
5263 eh_addr_size = 8;
5264 break;
0f56a26a
DD
5265
5266 case EM_H8_300:
5267 case EM_H8_300H:
5268 switch (elf_header.e_flags & EF_H8_MACH)
5269 {
5270 case E_H8_MACH_H8300:
5271 case E_H8_MACH_H8300HN:
5272 case E_H8_MACH_H8300SN:
5273 case E_H8_MACH_H8300SXN:
5274 eh_addr_size = 2;
5275 break;
5276 case E_H8_MACH_H8300H:
5277 case E_H8_MACH_H8300S:
5278 case E_H8_MACH_H8300SX:
5279 eh_addr_size = 4;
5280 break;
5281 }
f4236fe4
DD
5282 break;
5283
ff7eeb89 5284 case EM_M32C_OLD:
f4236fe4
DD
5285 case EM_M32C:
5286 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5287 {
5288 case EF_M32C_CPU_M16C:
5289 eh_addr_size = 2;
5290 break;
5291 }
5292 break;
89fac5e3
RS
5293 }
5294
76ca31c0
NC
5295#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5296 do \
5297 { \
5298 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5299 if (section->sh_entsize != expected_entsize) \
9dd3a467 5300 { \
76ca31c0
NC
5301 char buf[40]; \
5302 sprintf_vma (buf, section->sh_entsize); \
5303 /* Note: coded this way so that there is a single string for \
5304 translation. */ \
5305 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5306 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5307 (unsigned) expected_entsize); \
9dd3a467 5308 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5309 } \
5310 } \
08d8fa11 5311 while (0)
9dd3a467
NC
5312
5313#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5314 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5315 sizeof (Elf64_External_##type))
5316
252b5132
RH
5317 for (i = 0, section = section_headers;
5318 i < elf_header.e_shnum;
b34976b6 5319 i++, section++)
252b5132 5320 {
2cf0635d 5321 char * name = SECTION_NAME (section);
252b5132
RH
5322
5323 if (section->sh_type == SHT_DYNSYM)
5324 {
5325 if (dynamic_symbols != NULL)
5326 {
5327 error (_("File contains multiple dynamic symbol tables\n"));
5328 continue;
5329 }
5330
08d8fa11 5331 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5332 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5333 }
5334 else if (section->sh_type == SHT_STRTAB
18bd398b 5335 && streq (name, ".dynstr"))
252b5132
RH
5336 {
5337 if (dynamic_strings != NULL)
5338 {
5339 error (_("File contains multiple dynamic string tables\n"));
5340 continue;
5341 }
5342
3f5e193b
NC
5343 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5344 1, section->sh_size,
5345 _("dynamic strings"));
59245841 5346 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5347 }
9ad5cbcf
AM
5348 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5349 {
5350 if (symtab_shndx_hdr != NULL)
5351 {
5352 error (_("File contains multiple symtab shndx tables\n"));
5353 continue;
5354 }
5355 symtab_shndx_hdr = section;
5356 }
08d8fa11
JJ
5357 else if (section->sh_type == SHT_SYMTAB)
5358 CHECK_ENTSIZE (section, i, Sym);
5359 else if (section->sh_type == SHT_GROUP)
5360 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5361 else if (section->sh_type == SHT_REL)
5362 CHECK_ENTSIZE (section, i, Rel);
5363 else if (section->sh_type == SHT_RELA)
5364 CHECK_ENTSIZE (section, i, Rela);
252b5132 5365 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5366 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5367 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5368 || do_debug_str || do_debug_loc || do_debug_ranges
5369 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5370 && (const_strneq (name, ".debug_")
5371 || const_strneq (name, ".zdebug_")))
252b5132 5372 {
1b315056
CS
5373 if (name[1] == 'z')
5374 name += sizeof (".zdebug_") - 1;
5375 else
5376 name += sizeof (".debug_") - 1;
252b5132
RH
5377
5378 if (do_debugging
4723351a
CC
5379 || (do_debug_info && const_strneq (name, "info"))
5380 || (do_debug_info && const_strneq (name, "types"))
5381 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5382 || (do_debug_lines && strcmp (name, "line") == 0)
5383 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5384 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5385 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5386 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5387 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5388 || (do_debug_aranges && const_strneq (name, "aranges"))
5389 || (do_debug_ranges && const_strneq (name, "ranges"))
5390 || (do_debug_frames && const_strneq (name, "frame"))
5391 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5392 || (do_debug_macinfo && const_strneq (name, "macro"))
5393 || (do_debug_str && const_strneq (name, "str"))
5394 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5395 || (do_debug_addr && const_strneq (name, "addr"))
5396 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5397 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5398 )
09c11c86 5399 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5400 }
a262ae96 5401 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5402 else if ((do_debugging || do_debug_info)
0112cd26 5403 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5404 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5405 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5406 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5407 else if (do_gdb_index && streq (name, ".gdb_index"))
5408 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5409 /* Trace sections for Itanium VMS. */
5410 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5411 || do_trace_aranges)
5412 && const_strneq (name, ".trace_"))
5413 {
5414 name += sizeof (".trace_") - 1;
5415
5416 if (do_debugging
5417 || (do_trace_info && streq (name, "info"))
5418 || (do_trace_abbrevs && streq (name, "abbrev"))
5419 || (do_trace_aranges && streq (name, "aranges"))
5420 )
5421 request_dump_bynumber (i, DEBUG_DUMP);
5422 }
252b5132
RH
5423 }
5424
5425 if (! do_sections)
5426 return 1;
5427
3a1a2036
NC
5428 if (elf_header.e_shnum > 1)
5429 printf (_("\nSection Headers:\n"));
5430 else
5431 printf (_("\nSection Header:\n"));
76da6bbe 5432
f7a99963 5433 if (is_32bit_elf)
595cf52e 5434 {
5477e8a0 5435 if (do_section_details)
595cf52e
L
5436 {
5437 printf (_(" [Nr] Name\n"));
5477e8a0 5438 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5439 }
5440 else
5441 printf
5442 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5443 }
d974e256 5444 else if (do_wide)
595cf52e 5445 {
5477e8a0 5446 if (do_section_details)
595cf52e
L
5447 {
5448 printf (_(" [Nr] Name\n"));
5477e8a0 5449 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5450 }
5451 else
5452 printf
5453 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5454 }
f7a99963
NC
5455 else
5456 {
5477e8a0 5457 if (do_section_details)
595cf52e
L
5458 {
5459 printf (_(" [Nr] Name\n"));
5477e8a0
L
5460 printf (_(" Type Address Offset Link\n"));
5461 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5462 }
5463 else
5464 {
5465 printf (_(" [Nr] Name Type Address Offset\n"));
5466 printf (_(" Size EntSize Flags Link Info Align\n"));
5467 }
f7a99963 5468 }
252b5132 5469
5477e8a0
L
5470 if (do_section_details)
5471 printf (_(" Flags\n"));
5472
252b5132
RH
5473 for (i = 0, section = section_headers;
5474 i < elf_header.e_shnum;
b34976b6 5475 i++, section++)
252b5132 5476 {
7bfd842d 5477 printf (" [%2u] ", i);
5477e8a0 5478 if (do_section_details)
74e1a04b 5479 printf ("%s\n ", printable_section_name (section));
595cf52e 5480 else
74e1a04b 5481 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5482
ea52a088
NC
5483 printf (do_wide ? " %-15s " : " %-15.15s ",
5484 get_section_type_name (section->sh_type));
0b4362b0 5485
f7a99963
NC
5486 if (is_32bit_elf)
5487 {
cfcac11d
NC
5488 const char * link_too_big = NULL;
5489
f7a99963 5490 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5491
f7a99963
NC
5492 printf ( " %6.6lx %6.6lx %2.2lx",
5493 (unsigned long) section->sh_offset,
5494 (unsigned long) section->sh_size,
5495 (unsigned long) section->sh_entsize);
d1133906 5496
5477e8a0
L
5497 if (do_section_details)
5498 fputs (" ", stdout);
5499 else
5500 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5501
cfcac11d
NC
5502 if (section->sh_link >= elf_header.e_shnum)
5503 {
5504 link_too_big = "";
5505 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5506 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5507 switch (elf_header.e_machine)
5508 {
caa83f8b
NC
5509 case EM_386:
5510 case EM_486:
5511 case EM_X86_64:
7f502d6c 5512 case EM_L1OM:
7a9068fe 5513 case EM_K1OM:
cfcac11d
NC
5514 case EM_OLD_SPARCV9:
5515 case EM_SPARC32PLUS:
5516 case EM_SPARCV9:
5517 case EM_SPARC:
5518 if (section->sh_link == (SHN_BEFORE & 0xffff))
5519 link_too_big = "BEFORE";
5520 else if (section->sh_link == (SHN_AFTER & 0xffff))
5521 link_too_big = "AFTER";
5522 break;
5523 default:
5524 break;
5525 }
5526 }
5527
5528 if (do_section_details)
5529 {
5530 if (link_too_big != NULL && * link_too_big)
5531 printf ("<%s> ", link_too_big);
5532 else
5533 printf ("%2u ", section->sh_link);
5534 printf ("%3u %2lu\n", section->sh_info,
5535 (unsigned long) section->sh_addralign);
5536 }
5537 else
5538 printf ("%2u %3u %2lu\n",
5539 section->sh_link,
5540 section->sh_info,
5541 (unsigned long) section->sh_addralign);
5542
5543 if (link_too_big && ! * link_too_big)
5544 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5545 i, section->sh_link);
f7a99963 5546 }
d974e256
JJ
5547 else if (do_wide)
5548 {
5549 print_vma (section->sh_addr, LONG_HEX);
5550
5551 if ((long) section->sh_offset == section->sh_offset)
5552 printf (" %6.6lx", (unsigned long) section->sh_offset);
5553 else
5554 {
5555 putchar (' ');
5556 print_vma (section->sh_offset, LONG_HEX);
5557 }
5558
5559 if ((unsigned long) section->sh_size == section->sh_size)
5560 printf (" %6.6lx", (unsigned long) section->sh_size);
5561 else
5562 {
5563 putchar (' ');
5564 print_vma (section->sh_size, LONG_HEX);
5565 }
5566
5567 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5568 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5569 else
5570 {
5571 putchar (' ');
5572 print_vma (section->sh_entsize, LONG_HEX);
5573 }
5574
5477e8a0
L
5575 if (do_section_details)
5576 fputs (" ", stdout);
5577 else
5578 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5579
72de5009 5580 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5581
5582 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5583 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5584 else
5585 {
5586 print_vma (section->sh_addralign, DEC);
5587 putchar ('\n');
5588 }
5589 }
5477e8a0 5590 else if (do_section_details)
595cf52e 5591 {
5477e8a0 5592 printf (" %-15.15s ",
595cf52e 5593 get_section_type_name (section->sh_type));
595cf52e
L
5594 print_vma (section->sh_addr, LONG_HEX);
5595 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5596 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5597 else
5598 {
5599 printf (" ");
5600 print_vma (section->sh_offset, LONG_HEX);
5601 }
72de5009 5602 printf (" %u\n ", section->sh_link);
595cf52e 5603 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5604 putchar (' ');
595cf52e
L
5605 print_vma (section->sh_entsize, LONG_HEX);
5606
72de5009
AM
5607 printf (" %-16u %lu\n",
5608 section->sh_info,
595cf52e
L
5609 (unsigned long) section->sh_addralign);
5610 }
f7a99963
NC
5611 else
5612 {
5613 putchar (' ');
5614 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5615 if ((long) section->sh_offset == section->sh_offset)
5616 printf (" %8.8lx", (unsigned long) section->sh_offset);
5617 else
5618 {
5619 printf (" ");
5620 print_vma (section->sh_offset, LONG_HEX);
5621 }
f7a99963
NC
5622 printf ("\n ");
5623 print_vma (section->sh_size, LONG_HEX);
5624 printf (" ");
5625 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5626
d1133906 5627 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5628
72de5009
AM
5629 printf (" %2u %3u %lu\n",
5630 section->sh_link,
5631 section->sh_info,
f7a99963
NC
5632 (unsigned long) section->sh_addralign);
5633 }
5477e8a0
L
5634
5635 if (do_section_details)
5636 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5637 }
5638
5477e8a0 5639 if (!do_section_details)
3dbcc61d
NC
5640 {
5641 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5642 || elf_header.e_machine == EM_L1OM
5643 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5644 printf (_("Key to Flags:\n\
5645 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5646 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5647 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5648 else
5649 printf (_("Key to Flags:\n\
e3c8793a 5650 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5651 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5652 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5653 }
d1133906 5654
252b5132
RH
5655 return 1;
5656}
5657
f5842774
L
5658static const char *
5659get_group_flags (unsigned int flags)
5660{
5661 static char buff[32];
5662 switch (flags)
5663 {
220453ec
AM
5664 case 0:
5665 return "";
5666
f5842774 5667 case GRP_COMDAT:
220453ec 5668 return "COMDAT ";
f5842774
L
5669
5670 default:
220453ec 5671 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5672 break;
5673 }
5674 return buff;
5675}
5676
5677static int
2cf0635d 5678process_section_groups (FILE * file)
f5842774 5679{
2cf0635d 5680 Elf_Internal_Shdr * section;
f5842774 5681 unsigned int i;
2cf0635d
NC
5682 struct group * group;
5683 Elf_Internal_Shdr * symtab_sec;
5684 Elf_Internal_Shdr * strtab_sec;
5685 Elf_Internal_Sym * symtab;
ba5cdace 5686 unsigned long num_syms;
2cf0635d 5687 char * strtab;
c256ffe7 5688 size_t strtab_size;
d1f5c6e3
L
5689
5690 /* Don't process section groups unless needed. */
5691 if (!do_unwind && !do_section_groups)
5692 return 1;
f5842774
L
5693
5694 if (elf_header.e_shnum == 0)
5695 {
5696 if (do_section_groups)
82f2dbf7 5697 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5698
5699 return 1;
5700 }
5701
5702 if (section_headers == NULL)
5703 {
5704 error (_("Section headers are not available!\n"));
fa1908fd
NC
5705 /* PR 13622: This can happen with a corrupt ELF header. */
5706 return 0;
f5842774
L
5707 }
5708
3f5e193b
NC
5709 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5710 sizeof (struct group *));
e4b17d5c
L
5711
5712 if (section_headers_groups == NULL)
5713 {
8b73c356
NC
5714 error (_("Out of memory reading %u section group headers\n"),
5715 elf_header.e_shnum);
e4b17d5c
L
5716 return 0;
5717 }
5718
f5842774 5719 /* Scan the sections for the group section. */
d1f5c6e3 5720 group_count = 0;
f5842774
L
5721 for (i = 0, section = section_headers;
5722 i < elf_header.e_shnum;
5723 i++, section++)
e4b17d5c
L
5724 if (section->sh_type == SHT_GROUP)
5725 group_count++;
5726
d1f5c6e3
L
5727 if (group_count == 0)
5728 {
5729 if (do_section_groups)
5730 printf (_("\nThere are no section groups in this file.\n"));
5731
5732 return 1;
5733 }
5734
3f5e193b 5735 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5736
5737 if (section_groups == NULL)
5738 {
8b73c356
NC
5739 error (_("Out of memory reading %lu groups\n"),
5740 (unsigned long) group_count);
e4b17d5c
L
5741 return 0;
5742 }
5743
d1f5c6e3
L
5744 symtab_sec = NULL;
5745 strtab_sec = NULL;
5746 symtab = NULL;
ba5cdace 5747 num_syms = 0;
d1f5c6e3 5748 strtab = NULL;
c256ffe7 5749 strtab_size = 0;
e4b17d5c
L
5750 for (i = 0, section = section_headers, group = section_groups;
5751 i < elf_header.e_shnum;
5752 i++, section++)
f5842774
L
5753 {
5754 if (section->sh_type == SHT_GROUP)
5755 {
74e1a04b
NC
5756 const char * name = printable_section_name (section);
5757 const char * group_name;
2cf0635d
NC
5758 unsigned char * start;
5759 unsigned char * indices;
f5842774 5760 unsigned int entry, j, size;
2cf0635d
NC
5761 Elf_Internal_Shdr * sec;
5762 Elf_Internal_Sym * sym;
f5842774
L
5763
5764 /* Get the symbol table. */
4fbb74a6
AM
5765 if (section->sh_link >= elf_header.e_shnum
5766 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5767 != SHT_SYMTAB))
f5842774
L
5768 {
5769 error (_("Bad sh_link in group section `%s'\n"), name);
5770 continue;
5771 }
d1f5c6e3
L
5772
5773 if (symtab_sec != sec)
5774 {
5775 symtab_sec = sec;
5776 if (symtab)
5777 free (symtab);
ba5cdace 5778 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5779 }
f5842774 5780
dd24e3da
NC
5781 if (symtab == NULL)
5782 {
5783 error (_("Corrupt header in group section `%s'\n"), name);
5784 continue;
5785 }
5786
ba5cdace
NC
5787 if (section->sh_info >= num_syms)
5788 {
5789 error (_("Bad sh_info in group section `%s'\n"), name);
5790 continue;
5791 }
5792
f5842774
L
5793 sym = symtab + section->sh_info;
5794
5795 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5796 {
4fbb74a6
AM
5797 if (sym->st_shndx == 0
5798 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5799 {
5800 error (_("Bad sh_info in group section `%s'\n"), name);
5801 continue;
5802 }
ba2685cc 5803
4fbb74a6 5804 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5805 strtab_sec = NULL;
5806 if (strtab)
5807 free (strtab);
f5842774 5808 strtab = NULL;
c256ffe7 5809 strtab_size = 0;
f5842774
L
5810 }
5811 else
5812 {
5813 /* Get the string table. */
4fbb74a6 5814 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5815 {
5816 strtab_sec = NULL;
5817 if (strtab)
5818 free (strtab);
5819 strtab = NULL;
5820 strtab_size = 0;
5821 }
5822 else if (strtab_sec
4fbb74a6 5823 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5824 {
5825 strtab_sec = sec;
5826 if (strtab)
5827 free (strtab);
071436c6 5828
3f5e193b 5829 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5830 1, strtab_sec->sh_size,
5831 _("string table"));
c256ffe7 5832 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5833 }
c256ffe7 5834 group_name = sym->st_name < strtab_size
2b692964 5835 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5836 }
5837
c9c1d674
EG
5838 /* PR 17531: file: loop. */
5839 if (section->sh_entsize > section->sh_size)
5840 {
5841 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
5842 printable_section_name (section),
5843 section->sh_entsize, section->sh_size);
5844 break;
5845 }
5846
3f5e193b
NC
5847 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5848 1, section->sh_size,
5849 _("section data"));
59245841
NC
5850 if (start == NULL)
5851 continue;
f5842774
L
5852
5853 indices = start;
5854 size = (section->sh_size / section->sh_entsize) - 1;
5855 entry = byte_get (indices, 4);
5856 indices += 4;
e4b17d5c
L
5857
5858 if (do_section_groups)
5859 {
2b692964 5860 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5861 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5862
e4b17d5c
L
5863 printf (_(" [Index] Name\n"));
5864 }
5865
5866 group->group_index = i;
5867
f5842774
L
5868 for (j = 0; j < size; j++)
5869 {
2cf0635d 5870 struct group_list * g;
e4b17d5c 5871
f5842774
L
5872 entry = byte_get (indices, 4);
5873 indices += 4;
5874
4fbb74a6 5875 if (entry >= elf_header.e_shnum)
391cb864
L
5876 {
5877 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5878 entry, i, elf_header.e_shnum - 1);
5879 continue;
5880 }
391cb864 5881
4fbb74a6 5882 if (section_headers_groups [entry] != NULL)
e4b17d5c 5883 {
d1f5c6e3
L
5884 if (entry)
5885 {
391cb864
L
5886 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5887 entry, i,
4fbb74a6 5888 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5889 continue;
5890 }
5891 else
5892 {
5893 /* Intel C/C++ compiler may put section 0 in a
5894 section group. We just warn it the first time
5895 and ignore it afterwards. */
5896 static int warned = 0;
5897 if (!warned)
5898 {
5899 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5900 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5901 warned++;
5902 }
5903 }
e4b17d5c
L
5904 }
5905
4fbb74a6 5906 section_headers_groups [entry] = group;
e4b17d5c
L
5907
5908 if (do_section_groups)
5909 {
4fbb74a6 5910 sec = section_headers + entry;
74e1a04b 5911 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
5912 }
5913
3f5e193b 5914 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5915 g->section_index = entry;
5916 g->next = group->root;
5917 group->root = g;
f5842774
L
5918 }
5919
f5842774
L
5920 if (start)
5921 free (start);
e4b17d5c
L
5922
5923 group++;
f5842774
L
5924 }
5925 }
5926
d1f5c6e3
L
5927 if (symtab)
5928 free (symtab);
5929 if (strtab)
5930 free (strtab);
f5842774
L
5931 return 1;
5932}
5933
28f997cf
TG
5934/* Data used to display dynamic fixups. */
5935
5936struct ia64_vms_dynfixup
5937{
5938 bfd_vma needed_ident; /* Library ident number. */
5939 bfd_vma needed; /* Index in the dstrtab of the library name. */
5940 bfd_vma fixup_needed; /* Index of the library. */
5941 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5942 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5943};
5944
5945/* Data used to display dynamic relocations. */
5946
5947struct ia64_vms_dynimgrela
5948{
5949 bfd_vma img_rela_cnt; /* Number of relocations. */
5950 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5951};
5952
5953/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5954 library). */
5955
5956static void
5957dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5958 const char *strtab, unsigned int strtab_sz)
5959{
5960 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5961 long i;
5962 const char *lib_name;
5963
5964 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5965 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5966 _("dynamic section image fixups"));
5967 if (!imfs)
5968 return;
5969
5970 if (fixup->needed < strtab_sz)
5971 lib_name = strtab + fixup->needed;
5972 else
5973 {
5974 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5975 (unsigned long) fixup->needed);
28f997cf
TG
5976 lib_name = "???";
5977 }
5978 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5979 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5980 printf
5981 (_("Seg Offset Type SymVec DataType\n"));
5982
5983 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5984 {
5985 unsigned int type;
5986 const char *rtype;
5987
5988 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5989 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5990 type = BYTE_GET (imfs [i].type);
5991 rtype = elf_ia64_reloc_type (type);
5992 if (rtype == NULL)
5993 printf (" 0x%08x ", type);
5994 else
5995 printf (" %-32s ", rtype);
5996 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5997 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5998 }
5999
6000 free (imfs);
6001}
6002
6003/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6004
6005static void
6006dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6007{
6008 Elf64_External_VMS_IMAGE_RELA *imrs;
6009 long i;
6010
6011 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6012 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6013 _("dynamic section image relocations"));
28f997cf
TG
6014 if (!imrs)
6015 return;
6016
6017 printf (_("\nImage relocs\n"));
6018 printf
6019 (_("Seg Offset Type Addend Seg Sym Off\n"));
6020
6021 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6022 {
6023 unsigned int type;
6024 const char *rtype;
6025
6026 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6027 printf ("%08" BFD_VMA_FMT "x ",
6028 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6029 type = BYTE_GET (imrs [i].type);
6030 rtype = elf_ia64_reloc_type (type);
6031 if (rtype == NULL)
6032 printf ("0x%08x ", type);
6033 else
6034 printf ("%-31s ", rtype);
6035 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6036 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6037 printf ("%08" BFD_VMA_FMT "x\n",
6038 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6039 }
6040
6041 free (imrs);
6042}
6043
6044/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6045
6046static int
6047process_ia64_vms_dynamic_relocs (FILE *file)
6048{
6049 struct ia64_vms_dynfixup fixup;
6050 struct ia64_vms_dynimgrela imgrela;
6051 Elf_Internal_Dyn *entry;
6052 int res = 0;
6053 bfd_vma strtab_off = 0;
6054 bfd_vma strtab_sz = 0;
6055 char *strtab = NULL;
6056
6057 memset (&fixup, 0, sizeof (fixup));
6058 memset (&imgrela, 0, sizeof (imgrela));
6059
6060 /* Note: the order of the entries is specified by the OpenVMS specs. */
6061 for (entry = dynamic_section;
6062 entry < dynamic_section + dynamic_nent;
6063 entry++)
6064 {
6065 switch (entry->d_tag)
6066 {
6067 case DT_IA_64_VMS_STRTAB_OFFSET:
6068 strtab_off = entry->d_un.d_val;
6069 break;
6070 case DT_STRSZ:
6071 strtab_sz = entry->d_un.d_val;
6072 if (strtab == NULL)
6073 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6074 1, strtab_sz, _("dynamic string section"));
6075 break;
6076
6077 case DT_IA_64_VMS_NEEDED_IDENT:
6078 fixup.needed_ident = entry->d_un.d_val;
6079 break;
6080 case DT_NEEDED:
6081 fixup.needed = entry->d_un.d_val;
6082 break;
6083 case DT_IA_64_VMS_FIXUP_NEEDED:
6084 fixup.fixup_needed = entry->d_un.d_val;
6085 break;
6086 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6087 fixup.fixup_rela_cnt = entry->d_un.d_val;
6088 break;
6089 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6090 fixup.fixup_rela_off = entry->d_un.d_val;
6091 res++;
6092 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6093 break;
6094
6095 case DT_IA_64_VMS_IMG_RELA_CNT:
6096 imgrela.img_rela_cnt = entry->d_un.d_val;
6097 break;
6098 case DT_IA_64_VMS_IMG_RELA_OFF:
6099 imgrela.img_rela_off = entry->d_un.d_val;
6100 res++;
6101 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6102 break;
6103
6104 default:
6105 break;
6106 }
6107 }
6108
6109 if (strtab != NULL)
6110 free (strtab);
6111
6112 return res;
6113}
6114
85b1c36d 6115static struct
566b0d53 6116{
2cf0635d 6117 const char * name;
566b0d53
L
6118 int reloc;
6119 int size;
6120 int rela;
6121} dynamic_relocations [] =
6122{
6123 { "REL", DT_REL, DT_RELSZ, FALSE },
6124 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6125 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6126};
6127
252b5132 6128/* Process the reloc section. */
18bd398b 6129
252b5132 6130static int
2cf0635d 6131process_relocs (FILE * file)
252b5132 6132{
b34976b6
AM
6133 unsigned long rel_size;
6134 unsigned long rel_offset;
252b5132
RH
6135
6136
6137 if (!do_reloc)
6138 return 1;
6139
6140 if (do_using_dynamic)
6141 {
566b0d53 6142 int is_rela;
2cf0635d 6143 const char * name;
566b0d53
L
6144 int has_dynamic_reloc;
6145 unsigned int i;
0de14b54 6146
566b0d53 6147 has_dynamic_reloc = 0;
252b5132 6148
566b0d53 6149 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6150 {
566b0d53
L
6151 is_rela = dynamic_relocations [i].rela;
6152 name = dynamic_relocations [i].name;
6153 rel_size = dynamic_info [dynamic_relocations [i].size];
6154 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6155
566b0d53
L
6156 has_dynamic_reloc |= rel_size;
6157
6158 if (is_rela == UNKNOWN)
aa903cfb 6159 {
566b0d53
L
6160 if (dynamic_relocations [i].reloc == DT_JMPREL)
6161 switch (dynamic_info[DT_PLTREL])
6162 {
6163 case DT_REL:
6164 is_rela = FALSE;
6165 break;
6166 case DT_RELA:
6167 is_rela = TRUE;
6168 break;
6169 }
aa903cfb 6170 }
252b5132 6171
566b0d53
L
6172 if (rel_size)
6173 {
6174 printf
6175 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6176 name, rel_offset, rel_size);
252b5132 6177
d93f0186
NC
6178 dump_relocations (file,
6179 offset_from_vma (file, rel_offset, rel_size),
6180 rel_size,
566b0d53 6181 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6182 dynamic_strings, dynamic_strings_length,
6183 is_rela, 1);
566b0d53 6184 }
252b5132 6185 }
566b0d53 6186
28f997cf
TG
6187 if (is_ia64_vms ())
6188 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6189
566b0d53 6190 if (! has_dynamic_reloc)
252b5132
RH
6191 printf (_("\nThere are no dynamic relocations in this file.\n"));
6192 }
6193 else
6194 {
2cf0635d 6195 Elf_Internal_Shdr * section;
b34976b6
AM
6196 unsigned long i;
6197 int found = 0;
252b5132
RH
6198
6199 for (i = 0, section = section_headers;
6200 i < elf_header.e_shnum;
b34976b6 6201 i++, section++)
252b5132
RH
6202 {
6203 if ( section->sh_type != SHT_RELA
6204 && section->sh_type != SHT_REL)
6205 continue;
6206
6207 rel_offset = section->sh_offset;
6208 rel_size = section->sh_size;
6209
6210 if (rel_size)
6211 {
2cf0635d 6212 Elf_Internal_Shdr * strsec;
b34976b6 6213 int is_rela;
103f02d3 6214
252b5132
RH
6215 printf (_("\nRelocation section "));
6216
6217 if (string_table == NULL)
19936277 6218 printf ("%d", section->sh_name);
252b5132 6219 else
74e1a04b 6220 printf ("'%s'", printable_section_name (section));
252b5132
RH
6221
6222 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6223 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6224
d79b3d50
NC
6225 is_rela = section->sh_type == SHT_RELA;
6226
4fbb74a6
AM
6227 if (section->sh_link != 0
6228 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6229 {
2cf0635d
NC
6230 Elf_Internal_Shdr * symsec;
6231 Elf_Internal_Sym * symtab;
d79b3d50 6232 unsigned long nsyms;
c256ffe7 6233 unsigned long strtablen = 0;
2cf0635d 6234 char * strtab = NULL;
57346661 6235
4fbb74a6 6236 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6237 if (symsec->sh_type != SHT_SYMTAB
6238 && symsec->sh_type != SHT_DYNSYM)
6239 continue;
6240
ba5cdace 6241 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6242
af3fc3bc
AM
6243 if (symtab == NULL)
6244 continue;
252b5132 6245
4fbb74a6
AM
6246 if (symsec->sh_link != 0
6247 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6248 {
4fbb74a6 6249 strsec = section_headers + symsec->sh_link;
103f02d3 6250
3f5e193b 6251 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6252 1, strsec->sh_size,
6253 _("string table"));
c256ffe7
JJ
6254 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6255 }
252b5132 6256
d79b3d50 6257 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6258 symtab, nsyms, strtab, strtablen,
6259 is_rela,
6260 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6261 if (strtab)
6262 free (strtab);
6263 free (symtab);
6264 }
6265 else
6266 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6267 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6268
6269 found = 1;
6270 }
6271 }
6272
6273 if (! found)
6274 printf (_("\nThere are no relocations in this file.\n"));
6275 }
6276
6277 return 1;
6278}
6279
57346661
AM
6280/* Process the unwind section. */
6281
4d6ed7c8
NC
6282#include "unwind-ia64.h"
6283
6284/* An absolute address consists of a section and an offset. If the
6285 section is NULL, the offset itself is the address, otherwise, the
6286 address equals to LOAD_ADDRESS(section) + offset. */
6287
6288struct absaddr
6289 {
6290 unsigned short section;
6291 bfd_vma offset;
6292 };
6293
1949de15
L
6294#define ABSADDR(a) \
6295 ((a).section \
6296 ? section_headers [(a).section].sh_addr + (a).offset \
6297 : (a).offset)
6298
3f5e193b
NC
6299struct ia64_unw_table_entry
6300 {
6301 struct absaddr start;
6302 struct absaddr end;
6303 struct absaddr info;
6304 };
6305
57346661 6306struct ia64_unw_aux_info
4d6ed7c8 6307 {
3f5e193b
NC
6308
6309 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6310 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6311 unsigned char * info; /* Unwind info. */
b34976b6
AM
6312 unsigned long info_size; /* Size of unwind info. */
6313 bfd_vma info_addr; /* starting address of unwind info. */
6314 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6315 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6316 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6317 char * strtab; /* The string table. */
b34976b6 6318 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6319 };
6320
4d6ed7c8 6321static void
2cf0635d 6322find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6323 unsigned long nsyms,
2cf0635d 6324 const char * strtab,
57346661 6325 unsigned long strtab_size,
d3ba0551 6326 struct absaddr addr,
2cf0635d
NC
6327 const char ** symname,
6328 bfd_vma * offset)
4d6ed7c8 6329{
d3ba0551 6330 bfd_vma dist = 0x100000;
2cf0635d
NC
6331 Elf_Internal_Sym * sym;
6332 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6333 unsigned long i;
6334
0b6ae522
DJ
6335 REMOVE_ARCH_BITS (addr.offset);
6336
57346661 6337 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6338 {
0b6ae522
DJ
6339 bfd_vma value = sym->st_value;
6340
6341 REMOVE_ARCH_BITS (value);
6342
4d6ed7c8
NC
6343 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6344 && sym->st_name != 0
6345 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6346 && addr.offset >= value
6347 && addr.offset - value < dist)
4d6ed7c8
NC
6348 {
6349 best = sym;
0b6ae522 6350 dist = addr.offset - value;
4d6ed7c8
NC
6351 if (!dist)
6352 break;
6353 }
6354 }
1b31d05e 6355
4d6ed7c8
NC
6356 if (best)
6357 {
57346661 6358 *symname = (best->st_name >= strtab_size
2b692964 6359 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6360 *offset = dist;
6361 return;
6362 }
1b31d05e 6363
4d6ed7c8
NC
6364 *symname = NULL;
6365 *offset = addr.offset;
6366}
6367
6368static void
2cf0635d 6369dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6370{
2cf0635d 6371 struct ia64_unw_table_entry * tp;
4d6ed7c8 6372 int in_body;
7036c0e1 6373
4d6ed7c8
NC
6374 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6375 {
6376 bfd_vma stamp;
6377 bfd_vma offset;
2cf0635d
NC
6378 const unsigned char * dp;
6379 const unsigned char * head;
6380 const char * procname;
4d6ed7c8 6381
57346661
AM
6382 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6383 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6384
6385 fputs ("\n<", stdout);
6386
6387 if (procname)
6388 {
6389 fputs (procname, stdout);
6390
6391 if (offset)
6392 printf ("+%lx", (unsigned long) offset);
6393 }
6394
6395 fputs (">: [", stdout);
6396 print_vma (tp->start.offset, PREFIX_HEX);
6397 fputc ('-', stdout);
6398 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6399 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6400 (unsigned long) (tp->info.offset - aux->seg_base));
6401
1949de15 6402 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6403 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6404
86f55779 6405 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6406 (unsigned) UNW_VER (stamp),
6407 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6408 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6409 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6410 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6411
6412 if (UNW_VER (stamp) != 1)
6413 {
2b692964 6414 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6415 continue;
6416 }
6417
6418 in_body = 0;
89fac5e3 6419 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
6420 dp = unw_decode (dp, in_body, & in_body);
6421 }
6422}
6423
6424static int
2cf0635d
NC
6425slurp_ia64_unwind_table (FILE * file,
6426 struct ia64_unw_aux_info * aux,
6427 Elf_Internal_Shdr * sec)
4d6ed7c8 6428{
89fac5e3 6429 unsigned long size, nrelas, i;
2cf0635d
NC
6430 Elf_Internal_Phdr * seg;
6431 struct ia64_unw_table_entry * tep;
6432 Elf_Internal_Shdr * relsec;
6433 Elf_Internal_Rela * rela;
6434 Elf_Internal_Rela * rp;
6435 unsigned char * table;
6436 unsigned char * tp;
6437 Elf_Internal_Sym * sym;
6438 const char * relname;
4d6ed7c8 6439
4d6ed7c8
NC
6440 /* First, find the starting address of the segment that includes
6441 this section: */
6442
6443 if (elf_header.e_phnum)
6444 {
d93f0186 6445 if (! get_program_headers (file))
4d6ed7c8 6446 return 0;
4d6ed7c8 6447
d93f0186
NC
6448 for (seg = program_headers;
6449 seg < program_headers + elf_header.e_phnum;
6450 ++seg)
4d6ed7c8
NC
6451 {
6452 if (seg->p_type != PT_LOAD)
6453 continue;
6454
6455 if (sec->sh_addr >= seg->p_vaddr
6456 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6457 {
6458 aux->seg_base = seg->p_vaddr;
6459 break;
6460 }
6461 }
4d6ed7c8
NC
6462 }
6463
6464 /* Second, build the unwind table from the contents of the unwind section: */
6465 size = sec->sh_size;
3f5e193b
NC
6466 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6467 _("unwind table"));
a6e9f9df
AM
6468 if (!table)
6469 return 0;
4d6ed7c8 6470
3f5e193b
NC
6471 aux->table = (struct ia64_unw_table_entry *)
6472 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 6473 tep = aux->table;
c6a0c689 6474 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
6475 {
6476 tep->start.section = SHN_UNDEF;
6477 tep->end.section = SHN_UNDEF;
6478 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6479 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6480 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6481 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6482 tep->start.offset += aux->seg_base;
6483 tep->end.offset += aux->seg_base;
6484 tep->info.offset += aux->seg_base;
6485 }
6486 free (table);
6487
41e92641 6488 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6489 for (relsec = section_headers;
6490 relsec < section_headers + elf_header.e_shnum;
6491 ++relsec)
6492 {
6493 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6494 || relsec->sh_info >= elf_header.e_shnum
6495 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6496 continue;
6497
6498 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6499 & rela, & nrelas))
6500 return 0;
6501
6502 for (rp = rela; rp < rela + nrelas; ++rp)
6503 {
aca88567
NC
6504 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6505 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6506
0112cd26 6507 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6508 {
e5fb9629 6509 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6510 continue;
6511 }
6512
89fac5e3 6513 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6514
89fac5e3 6515 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6516 {
6517 case 0:
6518 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6519 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6520 break;
6521 case 1:
6522 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6523 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6524 break;
6525 case 2:
6526 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6527 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6528 break;
6529 default:
6530 break;
6531 }
6532 }
6533
6534 free (rela);
6535 }
6536
89fac5e3 6537 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6538 return 1;
6539}
6540
1b31d05e 6541static void
2cf0635d 6542ia64_process_unwind (FILE * file)
4d6ed7c8 6543{
2cf0635d
NC
6544 Elf_Internal_Shdr * sec;
6545 Elf_Internal_Shdr * unwsec = NULL;
6546 Elf_Internal_Shdr * strsec;
89fac5e3 6547 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6548 struct ia64_unw_aux_info aux;
f1467e33 6549
4d6ed7c8
NC
6550 memset (& aux, 0, sizeof (aux));
6551
4d6ed7c8
NC
6552 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6553 {
c256ffe7 6554 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6555 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6556 {
ba5cdace 6557 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6558
4fbb74a6 6559 strsec = section_headers + sec->sh_link;
4082ef84
NC
6560 if (aux.strtab != NULL)
6561 {
6562 error (_("Multiple auxillary string tables encountered\n"));
6563 free (aux.strtab);
6564 }
3f5e193b
NC
6565 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6566 1, strsec->sh_size,
6567 _("string table"));
c256ffe7 6568 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6569 }
6570 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6571 unwcount++;
6572 }
6573
6574 if (!unwcount)
6575 printf (_("\nThere are no unwind sections in this file.\n"));
6576
6577 while (unwcount-- > 0)
6578 {
2cf0635d 6579 char * suffix;
579f31ac
JJ
6580 size_t len, len2;
6581
4082ef84 6582 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6583 i < elf_header.e_shnum; ++i, ++sec)
6584 if (sec->sh_type == SHT_IA_64_UNWIND)
6585 {
6586 unwsec = sec;
6587 break;
6588 }
4082ef84
NC
6589 /* We have already counted the number of SHT_IA64_UNWIND
6590 sections so the loop above should never fail. */
6591 assert (unwsec != NULL);
579f31ac
JJ
6592
6593 unwstart = i + 1;
6594 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6595
e4b17d5c
L
6596 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6597 {
6598 /* We need to find which section group it is in. */
4082ef84 6599 struct group_list * g;
e4b17d5c 6600
4082ef84
NC
6601 if (section_headers_groups == NULL
6602 || section_headers_groups [i] == NULL)
6603 i = elf_header.e_shnum;
6604 else
e4b17d5c 6605 {
4082ef84 6606 g = section_headers_groups [i]->root;
18bd398b 6607
4082ef84
NC
6608 for (; g != NULL; g = g->next)
6609 {
6610 sec = section_headers + g->section_index;
e4b17d5c 6611
4082ef84
NC
6612 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6613 break;
6614 }
6615
6616 if (g == NULL)
6617 i = elf_header.e_shnum;
6618 }
e4b17d5c 6619 }
18bd398b 6620 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6621 {
18bd398b 6622 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6623 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6624 suffix = SECTION_NAME (unwsec) + len;
6625 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6626 ++i, ++sec)
18bd398b
NC
6627 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6628 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6629 break;
6630 }
6631 else
6632 {
6633 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6634 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6635 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6636 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6637 suffix = "";
18bd398b 6638 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6639 suffix = SECTION_NAME (unwsec) + len;
6640 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6641 ++i, ++sec)
18bd398b
NC
6642 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6643 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6644 break;
6645 }
6646
6647 if (i == elf_header.e_shnum)
6648 {
6649 printf (_("\nCould not find unwind info section for "));
6650
6651 if (string_table == NULL)
6652 printf ("%d", unwsec->sh_name);
6653 else
74e1a04b 6654 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6655 }
6656 else
4d6ed7c8 6657 {
4d6ed7c8 6658 aux.info_addr = sec->sh_addr;
3f5e193b 6659 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6660 sec->sh_size,
6661 _("unwind info"));
59245841 6662 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6663
579f31ac 6664 printf (_("\nUnwind section "));
4d6ed7c8 6665
579f31ac
JJ
6666 if (string_table == NULL)
6667 printf ("%d", unwsec->sh_name);
6668 else
74e1a04b 6669 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6670
579f31ac 6671 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6672 (unsigned long) unwsec->sh_offset,
89fac5e3 6673 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6674
579f31ac 6675 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6676
579f31ac
JJ
6677 if (aux.table_len > 0)
6678 dump_ia64_unwind (& aux);
6679
6680 if (aux.table)
6681 free ((char *) aux.table);
6682 if (aux.info)
6683 free ((char *) aux.info);
6684 aux.table = NULL;
6685 aux.info = NULL;
6686 }
4d6ed7c8 6687 }
4d6ed7c8 6688
4d6ed7c8
NC
6689 if (aux.symtab)
6690 free (aux.symtab);
6691 if (aux.strtab)
6692 free ((char *) aux.strtab);
4d6ed7c8
NC
6693}
6694
3f5e193b
NC
6695struct hppa_unw_table_entry
6696 {
6697 struct absaddr start;
6698 struct absaddr end;
6699 unsigned int Cannot_unwind:1; /* 0 */
6700 unsigned int Millicode:1; /* 1 */
6701 unsigned int Millicode_save_sr0:1; /* 2 */
6702 unsigned int Region_description:2; /* 3..4 */
6703 unsigned int reserved1:1; /* 5 */
6704 unsigned int Entry_SR:1; /* 6 */
6705 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6706 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6707 unsigned int Args_stored:1; /* 16 */
6708 unsigned int Variable_Frame:1; /* 17 */
6709 unsigned int Separate_Package_Body:1; /* 18 */
6710 unsigned int Frame_Extension_Millicode:1; /* 19 */
6711 unsigned int Stack_Overflow_Check:1; /* 20 */
6712 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6713 unsigned int Ada_Region:1; /* 22 */
6714 unsigned int cxx_info:1; /* 23 */
6715 unsigned int cxx_try_catch:1; /* 24 */
6716 unsigned int sched_entry_seq:1; /* 25 */
6717 unsigned int reserved2:1; /* 26 */
6718 unsigned int Save_SP:1; /* 27 */
6719 unsigned int Save_RP:1; /* 28 */
6720 unsigned int Save_MRP_in_frame:1; /* 29 */
6721 unsigned int extn_ptr_defined:1; /* 30 */
6722 unsigned int Cleanup_defined:1; /* 31 */
6723
6724 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6725 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6726 unsigned int Large_frame:1; /* 2 */
6727 unsigned int Pseudo_SP_Set:1; /* 3 */
6728 unsigned int reserved4:1; /* 4 */
6729 unsigned int Total_frame_size:27; /* 5..31 */
6730 };
6731
57346661
AM
6732struct hppa_unw_aux_info
6733 {
3f5e193b 6734 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6735 unsigned long table_len; /* Length of unwind table. */
6736 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6737 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6738 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6739 char * strtab; /* The string table. */
57346661
AM
6740 unsigned long strtab_size; /* Size of string table. */
6741 };
6742
6743static void
2cf0635d 6744dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6745{
2cf0635d 6746 struct hppa_unw_table_entry * tp;
57346661 6747
57346661
AM
6748 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6749 {
6750 bfd_vma offset;
2cf0635d 6751 const char * procname;
57346661
AM
6752
6753 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6754 aux->strtab_size, tp->start, &procname,
6755 &offset);
6756
6757 fputs ("\n<", stdout);
6758
6759 if (procname)
6760 {
6761 fputs (procname, stdout);
6762
6763 if (offset)
6764 printf ("+%lx", (unsigned long) offset);
6765 }
6766
6767 fputs (">: [", stdout);
6768 print_vma (tp->start.offset, PREFIX_HEX);
6769 fputc ('-', stdout);
6770 print_vma (tp->end.offset, PREFIX_HEX);
6771 printf ("]\n\t");
6772
18bd398b
NC
6773#define PF(_m) if (tp->_m) printf (#_m " ");
6774#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6775 PF(Cannot_unwind);
6776 PF(Millicode);
6777 PF(Millicode_save_sr0);
18bd398b 6778 /* PV(Region_description); */
57346661
AM
6779 PF(Entry_SR);
6780 PV(Entry_FR);
6781 PV(Entry_GR);
6782 PF(Args_stored);
6783 PF(Variable_Frame);
6784 PF(Separate_Package_Body);
6785 PF(Frame_Extension_Millicode);
6786 PF(Stack_Overflow_Check);
6787 PF(Two_Instruction_SP_Increment);
6788 PF(Ada_Region);
6789 PF(cxx_info);
6790 PF(cxx_try_catch);
6791 PF(sched_entry_seq);
6792 PF(Save_SP);
6793 PF(Save_RP);
6794 PF(Save_MRP_in_frame);
6795 PF(extn_ptr_defined);
6796 PF(Cleanup_defined);
6797 PF(MPE_XL_interrupt_marker);
6798 PF(HP_UX_interrupt_marker);
6799 PF(Large_frame);
6800 PF(Pseudo_SP_Set);
6801 PV(Total_frame_size);
6802#undef PF
6803#undef PV
6804 }
6805
18bd398b 6806 printf ("\n");
57346661
AM
6807}
6808
6809static int
2cf0635d
NC
6810slurp_hppa_unwind_table (FILE * file,
6811 struct hppa_unw_aux_info * aux,
6812 Elf_Internal_Shdr * sec)
57346661 6813{
1c0751b2 6814 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6815 Elf_Internal_Phdr * seg;
6816 struct hppa_unw_table_entry * tep;
6817 Elf_Internal_Shdr * relsec;
6818 Elf_Internal_Rela * rela;
6819 Elf_Internal_Rela * rp;
6820 unsigned char * table;
6821 unsigned char * tp;
6822 Elf_Internal_Sym * sym;
6823 const char * relname;
57346661 6824
57346661
AM
6825 /* First, find the starting address of the segment that includes
6826 this section. */
6827
6828 if (elf_header.e_phnum)
6829 {
6830 if (! get_program_headers (file))
6831 return 0;
6832
6833 for (seg = program_headers;
6834 seg < program_headers + elf_header.e_phnum;
6835 ++seg)
6836 {
6837 if (seg->p_type != PT_LOAD)
6838 continue;
6839
6840 if (sec->sh_addr >= seg->p_vaddr
6841 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6842 {
6843 aux->seg_base = seg->p_vaddr;
6844 break;
6845 }
6846 }
6847 }
6848
6849 /* Second, build the unwind table from the contents of the unwind
6850 section. */
6851 size = sec->sh_size;
3f5e193b
NC
6852 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6853 _("unwind table"));
57346661
AM
6854 if (!table)
6855 return 0;
6856
1c0751b2
DA
6857 unw_ent_size = 16;
6858 nentries = size / unw_ent_size;
6859 size = unw_ent_size * nentries;
57346661 6860
3f5e193b
NC
6861 tep = aux->table = (struct hppa_unw_table_entry *)
6862 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6863
1c0751b2 6864 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6865 {
6866 unsigned int tmp1, tmp2;
6867
6868 tep->start.section = SHN_UNDEF;
6869 tep->end.section = SHN_UNDEF;
6870
1c0751b2
DA
6871 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6872 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6873 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6874 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6875
6876 tep->start.offset += aux->seg_base;
6877 tep->end.offset += aux->seg_base;
57346661
AM
6878
6879 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6880 tep->Millicode = (tmp1 >> 30) & 0x1;
6881 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6882 tep->Region_description = (tmp1 >> 27) & 0x3;
6883 tep->reserved1 = (tmp1 >> 26) & 0x1;
6884 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6885 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6886 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6887 tep->Args_stored = (tmp1 >> 15) & 0x1;
6888 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6889 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6890 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6891 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6892 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6893 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6894 tep->cxx_info = (tmp1 >> 8) & 0x1;
6895 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6896 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6897 tep->reserved2 = (tmp1 >> 5) & 0x1;
6898 tep->Save_SP = (tmp1 >> 4) & 0x1;
6899 tep->Save_RP = (tmp1 >> 3) & 0x1;
6900 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6901 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6902 tep->Cleanup_defined = tmp1 & 0x1;
6903
6904 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6905 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6906 tep->Large_frame = (tmp2 >> 29) & 0x1;
6907 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6908 tep->reserved4 = (tmp2 >> 27) & 0x1;
6909 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6910 }
6911 free (table);
6912
6913 /* Third, apply any relocations to the unwind table. */
57346661
AM
6914 for (relsec = section_headers;
6915 relsec < section_headers + elf_header.e_shnum;
6916 ++relsec)
6917 {
6918 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6919 || relsec->sh_info >= elf_header.e_shnum
6920 || section_headers + relsec->sh_info != sec)
57346661
AM
6921 continue;
6922
6923 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6924 & rela, & nrelas))
6925 return 0;
6926
6927 for (rp = rela; rp < rela + nrelas; ++rp)
6928 {
aca88567
NC
6929 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6930 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6931
6932 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6933 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6934 {
6935 warn (_("Skipping unexpected relocation type %s\n"), relname);
6936 continue;
6937 }
6938
6939 i = rp->r_offset / unw_ent_size;
6940
89fac5e3 6941 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6942 {
6943 case 0:
6944 aux->table[i].start.section = sym->st_shndx;
1e456d54 6945 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6946 break;
6947 case 1:
6948 aux->table[i].end.section = sym->st_shndx;
1e456d54 6949 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6950 break;
6951 default:
6952 break;
6953 }
6954 }
6955
6956 free (rela);
6957 }
6958
1c0751b2 6959 aux->table_len = nentries;
57346661
AM
6960
6961 return 1;
6962}
6963
1b31d05e 6964static void
2cf0635d 6965hppa_process_unwind (FILE * file)
57346661 6966{
57346661 6967 struct hppa_unw_aux_info aux;
2cf0635d
NC
6968 Elf_Internal_Shdr * unwsec = NULL;
6969 Elf_Internal_Shdr * strsec;
6970 Elf_Internal_Shdr * sec;
18bd398b 6971 unsigned long i;
57346661 6972
c256ffe7 6973 if (string_table == NULL)
1b31d05e
NC
6974 return;
6975
6976 memset (& aux, 0, sizeof (aux));
57346661
AM
6977
6978 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6979 {
c256ffe7 6980 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6981 && sec->sh_link < elf_header.e_shnum)
57346661 6982 {
ba5cdace 6983 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6984
4fbb74a6 6985 strsec = section_headers + sec->sh_link;
4082ef84
NC
6986 if (aux.strtab != NULL)
6987 {
6988 error (_("Multiple auxillary string tables encountered\n"));
6989 free (aux.strtab);
6990 }
3f5e193b
NC
6991 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6992 1, strsec->sh_size,
6993 _("string table"));
c256ffe7 6994 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6995 }
18bd398b 6996 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6997 unwsec = sec;
6998 }
6999
7000 if (!unwsec)
7001 printf (_("\nThere are no unwind sections in this file.\n"));
7002
7003 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7004 {
18bd398b 7005 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7006 {
74e1a04b
NC
7007 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7008 printable_section_name (sec),
57346661 7009 (unsigned long) sec->sh_offset,
89fac5e3 7010 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7011
7012 slurp_hppa_unwind_table (file, &aux, sec);
7013 if (aux.table_len > 0)
7014 dump_hppa_unwind (&aux);
7015
7016 if (aux.table)
7017 free ((char *) aux.table);
7018 aux.table = NULL;
7019 }
7020 }
7021
7022 if (aux.symtab)
7023 free (aux.symtab);
7024 if (aux.strtab)
7025 free ((char *) aux.strtab);
57346661
AM
7026}
7027
0b6ae522
DJ
7028struct arm_section
7029{
a734115a
NC
7030 unsigned char * data; /* The unwind data. */
7031 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7032 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7033 unsigned long nrelas; /* The number of relocations. */
7034 unsigned int rel_type; /* REL or RELA ? */
7035 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7036};
7037
7038struct arm_unw_aux_info
7039{
a734115a
NC
7040 FILE * file; /* The file containing the unwind sections. */
7041 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7042 unsigned long nsyms; /* Number of symbols. */
7043 char * strtab; /* The file's string table. */
7044 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7045};
7046
7047static const char *
7048arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7049 bfd_vma fn, struct absaddr addr)
7050{
7051 const char *procname;
7052 bfd_vma sym_offset;
7053
7054 if (addr.section == SHN_UNDEF)
7055 addr.offset = fn;
7056
7057 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
7058 aux->strtab_size, addr, &procname,
7059 &sym_offset);
7060
7061 print_vma (fn, PREFIX_HEX);
7062
7063 if (procname)
7064 {
7065 fputs (" <", stdout);
7066 fputs (procname, stdout);
7067
7068 if (sym_offset)
7069 printf ("+0x%lx", (unsigned long) sym_offset);
7070 fputc ('>', stdout);
7071 }
7072
7073 return procname;
7074}
7075
7076static void
7077arm_free_section (struct arm_section *arm_sec)
7078{
7079 if (arm_sec->data != NULL)
7080 free (arm_sec->data);
7081
7082 if (arm_sec->rela != NULL)
7083 free (arm_sec->rela);
7084}
7085
a734115a
NC
7086/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7087 cached section and install SEC instead.
7088 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7089 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7090 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7091 relocation's offset in ADDR.
1b31d05e
NC
7092 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7093 into the string table of the symbol associated with the reloc. If no
7094 reloc was applied store -1 there.
7095 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7096
7097static bfd_boolean
1b31d05e
NC
7098get_unwind_section_word (struct arm_unw_aux_info * aux,
7099 struct arm_section * arm_sec,
7100 Elf_Internal_Shdr * sec,
7101 bfd_vma word_offset,
7102 unsigned int * wordp,
7103 struct absaddr * addr,
7104 bfd_vma * sym_name)
0b6ae522
DJ
7105{
7106 Elf_Internal_Rela *rp;
7107 Elf_Internal_Sym *sym;
7108 const char * relname;
7109 unsigned int word;
7110 bfd_boolean wrapped;
7111
e0a31db1
NC
7112 if (sec == NULL || arm_sec == NULL)
7113 return FALSE;
7114
0b6ae522
DJ
7115 addr->section = SHN_UNDEF;
7116 addr->offset = 0;
7117
1b31d05e
NC
7118 if (sym_name != NULL)
7119 *sym_name = (bfd_vma) -1;
7120
a734115a 7121 /* If necessary, update the section cache. */
0b6ae522
DJ
7122 if (sec != arm_sec->sec)
7123 {
7124 Elf_Internal_Shdr *relsec;
7125
7126 arm_free_section (arm_sec);
7127
7128 arm_sec->sec = sec;
7129 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7130 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7131 arm_sec->rela = NULL;
7132 arm_sec->nrelas = 0;
7133
7134 for (relsec = section_headers;
7135 relsec < section_headers + elf_header.e_shnum;
7136 ++relsec)
7137 {
7138 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7139 || section_headers + relsec->sh_info != sec
7140 /* PR 15745: Check the section type as well. */
7141 || (relsec->sh_type != SHT_REL
7142 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7143 continue;
7144
a734115a 7145 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7146 if (relsec->sh_type == SHT_REL)
7147 {
7148 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7149 relsec->sh_size,
7150 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7151 return FALSE;
0b6ae522 7152 }
1ae40aa4 7153 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7154 {
7155 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7156 relsec->sh_size,
7157 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7158 return FALSE;
0b6ae522 7159 }
1ae40aa4 7160 break;
0b6ae522
DJ
7161 }
7162
7163 arm_sec->next_rela = arm_sec->rela;
7164 }
7165
a734115a 7166 /* If there is no unwind data we can do nothing. */
0b6ae522 7167 if (arm_sec->data == NULL)
a734115a 7168 return FALSE;
0b6ae522 7169
e0a31db1
NC
7170 /* If the offset is invalid then fail. */
7171 if (word_offset > sec->sh_size - 4)
7172 return FALSE;
7173
a734115a 7174 /* Get the word at the required offset. */
0b6ae522
DJ
7175 word = byte_get (arm_sec->data + word_offset, 4);
7176
0eff7165
NC
7177 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7178 if (arm_sec->rela == NULL)
7179 {
7180 * wordp = word;
7181 return TRUE;
7182 }
7183
a734115a 7184 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7185 wrapped = FALSE;
7186 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7187 {
7188 bfd_vma prelval, offset;
7189
7190 if (rp->r_offset > word_offset && !wrapped)
7191 {
7192 rp = arm_sec->rela;
7193 wrapped = TRUE;
7194 }
7195 if (rp->r_offset > word_offset)
7196 break;
7197
7198 if (rp->r_offset & 3)
7199 {
7200 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7201 (unsigned long) rp->r_offset);
7202 continue;
7203 }
7204
7205 if (rp->r_offset < word_offset)
7206 continue;
7207
74e1a04b
NC
7208 /* PR 17531: file: 027-161405-0.004 */
7209 if (aux->symtab == NULL)
7210 continue;
7211
0b6ae522
DJ
7212 if (arm_sec->rel_type == SHT_REL)
7213 {
7214 offset = word & 0x7fffffff;
7215 if (offset & 0x40000000)
7216 offset |= ~ (bfd_vma) 0x7fffffff;
7217 }
a734115a 7218 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7219 offset = rp->r_addend;
a734115a 7220 else
74e1a04b
NC
7221 {
7222 error (_("Unknown section relocation type %d encountered\n"),
7223 arm_sec->rel_type);
7224 break;
7225 }
0b6ae522 7226
071436c6
NC
7227 /* PR 17531 file: 027-1241568-0.004. */
7228 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7229 {
7230 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7231 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7232 break;
7233 }
7234
7235 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7236 offset += sym->st_value;
7237 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7238
a734115a
NC
7239 /* Check that we are processing the expected reloc type. */
7240 if (elf_header.e_machine == EM_ARM)
7241 {
7242 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7243 if (relname == NULL)
7244 {
7245 warn (_("Skipping unknown ARM relocation type: %d\n"),
7246 (int) ELF32_R_TYPE (rp->r_info));
7247 continue;
7248 }
a734115a
NC
7249
7250 if (streq (relname, "R_ARM_NONE"))
7251 continue;
0b4362b0 7252
a734115a
NC
7253 if (! streq (relname, "R_ARM_PREL31"))
7254 {
071436c6 7255 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7256 continue;
7257 }
7258 }
7259 else if (elf_header.e_machine == EM_TI_C6000)
7260 {
7261 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7262 if (relname == NULL)
7263 {
7264 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7265 (int) ELF32_R_TYPE (rp->r_info));
7266 continue;
7267 }
0b4362b0 7268
a734115a
NC
7269 if (streq (relname, "R_C6000_NONE"))
7270 continue;
7271
7272 if (! streq (relname, "R_C6000_PREL31"))
7273 {
071436c6 7274 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7275 continue;
7276 }
7277
7278 prelval >>= 1;
7279 }
7280 else
74e1a04b
NC
7281 {
7282 /* This function currently only supports ARM and TI unwinders. */
7283 warn (_("Only TI and ARM unwinders are currently supported\n"));
7284 break;
7285 }
fa197c1c 7286
0b6ae522
DJ
7287 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7288 addr->section = sym->st_shndx;
7289 addr->offset = offset;
74e1a04b 7290
1b31d05e
NC
7291 if (sym_name)
7292 * sym_name = sym->st_name;
0b6ae522
DJ
7293 break;
7294 }
7295
7296 *wordp = word;
7297 arm_sec->next_rela = rp;
7298
a734115a 7299 return TRUE;
0b6ae522
DJ
7300}
7301
a734115a
NC
7302static const char *tic6x_unwind_regnames[16] =
7303{
0b4362b0
RM
7304 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7305 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7306 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7307};
fa197c1c 7308
0b6ae522 7309static void
fa197c1c 7310decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7311{
fa197c1c
PB
7312 int i;
7313
7314 for (i = 12; mask; mask >>= 1, i--)
7315 {
7316 if (mask & 1)
7317 {
7318 fputs (tic6x_unwind_regnames[i], stdout);
7319 if (mask > 1)
7320 fputs (", ", stdout);
7321 }
7322 }
7323}
0b6ae522
DJ
7324
7325#define ADVANCE \
7326 if (remaining == 0 && more_words) \
7327 { \
7328 data_offset += 4; \
1b31d05e
NC
7329 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7330 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7331 return; \
7332 remaining = 4; \
7333 more_words--; \
7334 } \
7335
7336#define GET_OP(OP) \
7337 ADVANCE; \
7338 if (remaining) \
7339 { \
7340 remaining--; \
7341 (OP) = word >> 24; \
7342 word <<= 8; \
7343 } \
7344 else \
7345 { \
2b692964 7346 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7347 return; \
7348 } \
cc5914eb 7349 printf ("0x%02x ", OP)
0b6ae522 7350
fa197c1c
PB
7351static void
7352decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7353 unsigned int word, unsigned int remaining,
7354 unsigned int more_words,
7355 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7356 struct arm_section *data_arm_sec)
7357{
7358 struct absaddr addr;
0b6ae522
DJ
7359
7360 /* Decode the unwinding instructions. */
7361 while (1)
7362 {
7363 unsigned int op, op2;
7364
7365 ADVANCE;
7366 if (remaining == 0)
7367 break;
7368 remaining--;
7369 op = word >> 24;
7370 word <<= 8;
7371
cc5914eb 7372 printf (" 0x%02x ", op);
0b6ae522
DJ
7373
7374 if ((op & 0xc0) == 0x00)
7375 {
7376 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7377
cc5914eb 7378 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7379 }
7380 else if ((op & 0xc0) == 0x40)
7381 {
7382 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7383
cc5914eb 7384 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7385 }
7386 else if ((op & 0xf0) == 0x80)
7387 {
7388 GET_OP (op2);
7389 if (op == 0x80 && op2 == 0)
7390 printf (_("Refuse to unwind"));
7391 else
7392 {
7393 unsigned int mask = ((op & 0x0f) << 8) | op2;
7394 int first = 1;
7395 int i;
2b692964 7396
0b6ae522
DJ
7397 printf ("pop {");
7398 for (i = 0; i < 12; i++)
7399 if (mask & (1 << i))
7400 {
7401 if (first)
7402 first = 0;
7403 else
7404 printf (", ");
7405 printf ("r%d", 4 + i);
7406 }
7407 printf ("}");
7408 }
7409 }
7410 else if ((op & 0xf0) == 0x90)
7411 {
7412 if (op == 0x9d || op == 0x9f)
7413 printf (_(" [Reserved]"));
7414 else
cc5914eb 7415 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7416 }
7417 else if ((op & 0xf0) == 0xa0)
7418 {
7419 int end = 4 + (op & 0x07);
7420 int first = 1;
7421 int i;
61865e30 7422
0b6ae522
DJ
7423 printf (" pop {");
7424 for (i = 4; i <= end; i++)
7425 {
7426 if (first)
7427 first = 0;
7428 else
7429 printf (", ");
7430 printf ("r%d", i);
7431 }
7432 if (op & 0x08)
7433 {
1b31d05e 7434 if (!first)
0b6ae522
DJ
7435 printf (", ");
7436 printf ("r14");
7437 }
7438 printf ("}");
7439 }
7440 else if (op == 0xb0)
7441 printf (_(" finish"));
7442 else if (op == 0xb1)
7443 {
7444 GET_OP (op2);
7445 if (op2 == 0 || (op2 & 0xf0) != 0)
7446 printf (_("[Spare]"));
7447 else
7448 {
7449 unsigned int mask = op2 & 0x0f;
7450 int first = 1;
7451 int i;
61865e30 7452
0b6ae522
DJ
7453 printf ("pop {");
7454 for (i = 0; i < 12; i++)
7455 if (mask & (1 << i))
7456 {
7457 if (first)
7458 first = 0;
7459 else
7460 printf (", ");
7461 printf ("r%d", i);
7462 }
7463 printf ("}");
7464 }
7465 }
7466 else if (op == 0xb2)
7467 {
b115cf96 7468 unsigned char buf[9];
0b6ae522
DJ
7469 unsigned int i, len;
7470 unsigned long offset;
61865e30 7471
b115cf96 7472 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7473 {
7474 GET_OP (buf[i]);
7475 if ((buf[i] & 0x80) == 0)
7476 break;
7477 }
4082ef84
NC
7478 if (i == sizeof (buf))
7479 printf (_("corrupt change to vsp"));
7480 else
7481 {
7482 offset = read_uleb128 (buf, &len, buf + i + 1);
7483 assert (len == i + 1);
7484 offset = offset * 4 + 0x204;
7485 printf ("vsp = vsp + %ld", offset);
7486 }
0b6ae522 7487 }
61865e30 7488 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7489 {
61865e30
NC
7490 unsigned int first, last;
7491
7492 GET_OP (op2);
7493 first = op2 >> 4;
7494 last = op2 & 0x0f;
7495 if (op == 0xc8)
7496 first = first + 16;
7497 printf ("pop {D%d", first);
7498 if (last)
7499 printf ("-D%d", first + last);
7500 printf ("}");
7501 }
7502 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7503 {
7504 unsigned int count = op & 0x07;
7505
7506 printf ("pop {D8");
7507 if (count)
7508 printf ("-D%d", 8 + count);
7509 printf ("}");
7510 }
7511 else if (op >= 0xc0 && op <= 0xc5)
7512 {
7513 unsigned int count = op & 0x07;
7514
7515 printf (" pop {wR10");
7516 if (count)
7517 printf ("-wR%d", 10 + count);
7518 printf ("}");
7519 }
7520 else if (op == 0xc6)
7521 {
7522 unsigned int first, last;
7523
7524 GET_OP (op2);
7525 first = op2 >> 4;
7526 last = op2 & 0x0f;
7527 printf ("pop {wR%d", first);
7528 if (last)
7529 printf ("-wR%d", first + last);
7530 printf ("}");
7531 }
7532 else if (op == 0xc7)
7533 {
7534 GET_OP (op2);
7535 if (op2 == 0 || (op2 & 0xf0) != 0)
7536 printf (_("[Spare]"));
0b6ae522
DJ
7537 else
7538 {
61865e30
NC
7539 unsigned int mask = op2 & 0x0f;
7540 int first = 1;
7541 int i;
7542
7543 printf ("pop {");
7544 for (i = 0; i < 4; i++)
7545 if (mask & (1 << i))
7546 {
7547 if (first)
7548 first = 0;
7549 else
7550 printf (", ");
7551 printf ("wCGR%d", i);
7552 }
7553 printf ("}");
0b6ae522
DJ
7554 }
7555 }
61865e30
NC
7556 else
7557 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7558 printf ("\n");
7559 }
fa197c1c
PB
7560}
7561
7562static void
7563decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7564 unsigned int word, unsigned int remaining,
7565 unsigned int more_words,
7566 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7567 struct arm_section *data_arm_sec)
7568{
7569 struct absaddr addr;
7570
7571 /* Decode the unwinding instructions. */
7572 while (1)
7573 {
7574 unsigned int op, op2;
7575
7576 ADVANCE;
7577 if (remaining == 0)
7578 break;
7579 remaining--;
7580 op = word >> 24;
7581 word <<= 8;
7582
9cf03b7e 7583 printf (" 0x%02x ", op);
fa197c1c
PB
7584
7585 if ((op & 0xc0) == 0x00)
7586 {
7587 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7588 printf (" sp = sp + %d", offset);
fa197c1c
PB
7589 }
7590 else if ((op & 0xc0) == 0x80)
7591 {
7592 GET_OP (op2);
7593 if (op == 0x80 && op2 == 0)
7594 printf (_("Refuse to unwind"));
7595 else
7596 {
7597 unsigned int mask = ((op & 0x1f) << 8) | op2;
7598 if (op & 0x20)
7599 printf ("pop compact {");
7600 else
7601 printf ("pop {");
7602
7603 decode_tic6x_unwind_regmask (mask);
7604 printf("}");
7605 }
7606 }
7607 else if ((op & 0xf0) == 0xc0)
7608 {
7609 unsigned int reg;
7610 unsigned int nregs;
7611 unsigned int i;
7612 const char *name;
a734115a
NC
7613 struct
7614 {
fa197c1c
PB
7615 unsigned int offset;
7616 unsigned int reg;
7617 } regpos[16];
7618
7619 /* Scan entire instruction first so that GET_OP output is not
7620 interleaved with disassembly. */
7621 nregs = 0;
7622 for (i = 0; nregs < (op & 0xf); i++)
7623 {
7624 GET_OP (op2);
7625 reg = op2 >> 4;
7626 if (reg != 0xf)
7627 {
7628 regpos[nregs].offset = i * 2;
7629 regpos[nregs].reg = reg;
7630 nregs++;
7631 }
7632
7633 reg = op2 & 0xf;
7634 if (reg != 0xf)
7635 {
7636 regpos[nregs].offset = i * 2 + 1;
7637 regpos[nregs].reg = reg;
7638 nregs++;
7639 }
7640 }
7641
7642 printf (_("pop frame {"));
7643 reg = nregs - 1;
7644 for (i = i * 2; i > 0; i--)
7645 {
7646 if (regpos[reg].offset == i - 1)
7647 {
7648 name = tic6x_unwind_regnames[regpos[reg].reg];
7649 if (reg > 0)
7650 reg--;
7651 }
7652 else
7653 name = _("[pad]");
7654
7655 fputs (name, stdout);
7656 if (i > 1)
7657 printf (", ");
7658 }
7659
7660 printf ("}");
7661 }
7662 else if (op == 0xd0)
7663 printf (" MOV FP, SP");
7664 else if (op == 0xd1)
7665 printf (" __c6xabi_pop_rts");
7666 else if (op == 0xd2)
7667 {
7668 unsigned char buf[9];
7669 unsigned int i, len;
7670 unsigned long offset;
a734115a 7671
fa197c1c
PB
7672 for (i = 0; i < sizeof (buf); i++)
7673 {
7674 GET_OP (buf[i]);
7675 if ((buf[i] & 0x80) == 0)
7676 break;
7677 }
0eff7165
NC
7678 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7679 if (i == sizeof (buf))
7680 {
7681 printf ("<corrupt sp adjust>\n");
7682 warn (_("Corrupt stack pointer adjustment detected\n"));
7683 return;
7684 }
7685
f6f0e17b 7686 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7687 assert (len == i + 1);
7688 offset = offset * 8 + 0x408;
7689 printf (_("sp = sp + %ld"), offset);
7690 }
7691 else if ((op & 0xf0) == 0xe0)
7692 {
7693 if ((op & 0x0f) == 7)
7694 printf (" RETURN");
7695 else
7696 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7697 }
7698 else
7699 {
7700 printf (_(" [unsupported opcode]"));
7701 }
7702 putchar ('\n');
7703 }
7704}
7705
7706static bfd_vma
a734115a 7707arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7708{
7709 bfd_vma offset;
7710
7711 offset = word & 0x7fffffff;
7712 if (offset & 0x40000000)
7713 offset |= ~ (bfd_vma) 0x7fffffff;
7714
7715 if (elf_header.e_machine == EM_TI_C6000)
7716 offset <<= 1;
7717
7718 return offset + where;
7719}
7720
7721static void
1b31d05e
NC
7722decode_arm_unwind (struct arm_unw_aux_info * aux,
7723 unsigned int word,
7724 unsigned int remaining,
7725 bfd_vma data_offset,
7726 Elf_Internal_Shdr * data_sec,
7727 struct arm_section * data_arm_sec)
fa197c1c
PB
7728{
7729 int per_index;
7730 unsigned int more_words = 0;
37e14bc3 7731 struct absaddr addr;
1b31d05e 7732 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7733
7734 if (remaining == 0)
7735 {
1b31d05e
NC
7736 /* Fetch the first word.
7737 Note - when decoding an object file the address extracted
7738 here will always be 0. So we also pass in the sym_name
7739 parameter so that we can find the symbol associated with
7740 the personality routine. */
7741 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7742 & word, & addr, & sym_name))
fa197c1c 7743 return;
1b31d05e 7744
fa197c1c
PB
7745 remaining = 4;
7746 }
7747
7748 if ((word & 0x80000000) == 0)
7749 {
7750 /* Expand prel31 for personality routine. */
7751 bfd_vma fn;
7752 const char *procname;
7753
a734115a 7754 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7755 printf (_(" Personality routine: "));
1b31d05e
NC
7756 if (fn == 0
7757 && addr.section == SHN_UNDEF && addr.offset == 0
7758 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7759 {
7760 procname = aux->strtab + sym_name;
7761 print_vma (fn, PREFIX_HEX);
7762 if (procname)
7763 {
7764 fputs (" <", stdout);
7765 fputs (procname, stdout);
7766 fputc ('>', stdout);
7767 }
7768 }
7769 else
7770 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7771 fputc ('\n', stdout);
7772
7773 /* The GCC personality routines use the standard compact
7774 encoding, starting with one byte giving the number of
7775 words. */
7776 if (procname != NULL
7777 && (const_strneq (procname, "__gcc_personality_v0")
7778 || const_strneq (procname, "__gxx_personality_v0")
7779 || const_strneq (procname, "__gcj_personality_v0")
7780 || const_strneq (procname, "__gnu_objc_personality_v0")))
7781 {
7782 remaining = 0;
7783 more_words = 1;
7784 ADVANCE;
7785 if (!remaining)
7786 {
7787 printf (_(" [Truncated data]\n"));
7788 return;
7789 }
7790 more_words = word >> 24;
7791 word <<= 8;
7792 remaining--;
7793 per_index = -1;
7794 }
7795 else
7796 return;
7797 }
7798 else
7799 {
1b31d05e 7800 /* ARM EHABI Section 6.3:
0b4362b0 7801
1b31d05e 7802 An exception-handling table entry for the compact model looks like:
0b4362b0 7803
1b31d05e
NC
7804 31 30-28 27-24 23-0
7805 -- ----- ----- ----
7806 1 0 index Data for personalityRoutine[index] */
7807
7808 if (elf_header.e_machine == EM_ARM
7809 && (word & 0x70000000))
83c257ca 7810 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7811
fa197c1c 7812 per_index = (word >> 24) & 0x7f;
1b31d05e 7813 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7814 if (per_index == 0)
7815 {
7816 more_words = 0;
7817 word <<= 8;
7818 remaining--;
7819 }
7820 else if (per_index < 3)
7821 {
7822 more_words = (word >> 16) & 0xff;
7823 word <<= 16;
7824 remaining -= 2;
7825 }
7826 }
7827
7828 switch (elf_header.e_machine)
7829 {
7830 case EM_ARM:
7831 if (per_index < 3)
7832 {
7833 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7834 data_offset, data_sec, data_arm_sec);
7835 }
7836 else
1b31d05e
NC
7837 {
7838 warn (_("Unknown ARM compact model index encountered\n"));
7839 printf (_(" [reserved]\n"));
7840 }
fa197c1c
PB
7841 break;
7842
7843 case EM_TI_C6000:
7844 if (per_index < 3)
7845 {
7846 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7847 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7848 }
7849 else if (per_index < 5)
7850 {
7851 if (((word >> 17) & 0x7f) == 0x7f)
7852 printf (_(" Restore stack from frame pointer\n"));
7853 else
7854 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7855 printf (_(" Registers restored: "));
7856 if (per_index == 4)
7857 printf (" (compact) ");
7858 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7859 putchar ('\n');
7860 printf (_(" Return register: %s\n"),
7861 tic6x_unwind_regnames[word & 0xf]);
7862 }
7863 else
1b31d05e 7864 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7865 break;
7866
7867 default:
74e1a04b 7868 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 7869 elf_header.e_machine);
fa197c1c 7870 }
0b6ae522
DJ
7871
7872 /* Decode the descriptors. Not implemented. */
7873}
7874
7875static void
7876dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7877{
7878 struct arm_section exidx_arm_sec, extab_arm_sec;
7879 unsigned int i, exidx_len;
7880
7881 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7882 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7883 exidx_len = exidx_sec->sh_size / 8;
7884
7885 for (i = 0; i < exidx_len; i++)
7886 {
7887 unsigned int exidx_fn, exidx_entry;
7888 struct absaddr fn_addr, entry_addr;
7889 bfd_vma fn;
7890
7891 fputc ('\n', stdout);
7892
1b31d05e
NC
7893 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7894 8 * i, & exidx_fn, & fn_addr, NULL)
7895 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7896 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7897 {
1b31d05e
NC
7898 arm_free_section (& exidx_arm_sec);
7899 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7900 return;
7901 }
7902
83c257ca
NC
7903 /* ARM EHABI, Section 5:
7904 An index table entry consists of 2 words.
7905 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7906 if (exidx_fn & 0x80000000)
7907 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7908
a734115a 7909 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7910
a734115a 7911 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7912 fputs (": ", stdout);
7913
7914 if (exidx_entry == 1)
7915 {
7916 print_vma (exidx_entry, PREFIX_HEX);
7917 fputs (" [cantunwind]\n", stdout);
7918 }
7919 else if (exidx_entry & 0x80000000)
7920 {
7921 print_vma (exidx_entry, PREFIX_HEX);
7922 fputc ('\n', stdout);
7923 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7924 }
7925 else
7926 {
8f73510c 7927 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7928 Elf_Internal_Shdr *table_sec;
7929
7930 fputs ("@", stdout);
a734115a 7931 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7932 print_vma (table, PREFIX_HEX);
7933 printf ("\n");
7934
7935 /* Locate the matching .ARM.extab. */
7936 if (entry_addr.section != SHN_UNDEF
7937 && entry_addr.section < elf_header.e_shnum)
7938 {
7939 table_sec = section_headers + entry_addr.section;
7940 table_offset = entry_addr.offset;
7941 }
7942 else
7943 {
7944 table_sec = find_section_by_address (table);
7945 if (table_sec != NULL)
7946 table_offset = table - table_sec->sh_addr;
7947 }
7948 if (table_sec == NULL)
7949 {
7950 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7951 (unsigned long) table);
7952 continue;
7953 }
7954 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7955 &extab_arm_sec);
7956 }
7957 }
7958
7959 printf ("\n");
7960
7961 arm_free_section (&exidx_arm_sec);
7962 arm_free_section (&extab_arm_sec);
7963}
7964
fa197c1c 7965/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7966
7967static void
0b6ae522
DJ
7968arm_process_unwind (FILE *file)
7969{
7970 struct arm_unw_aux_info aux;
7971 Elf_Internal_Shdr *unwsec = NULL;
7972 Elf_Internal_Shdr *strsec;
7973 Elf_Internal_Shdr *sec;
7974 unsigned long i;
fa197c1c 7975 unsigned int sec_type;
0b6ae522 7976
fa197c1c
PB
7977 switch (elf_header.e_machine)
7978 {
7979 case EM_ARM:
7980 sec_type = SHT_ARM_EXIDX;
7981 break;
7982
7983 case EM_TI_C6000:
7984 sec_type = SHT_C6000_UNWIND;
7985 break;
7986
0b4362b0 7987 default:
74e1a04b 7988 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
7989 elf_header.e_machine);
7990 return;
fa197c1c
PB
7991 }
7992
0b6ae522 7993 if (string_table == NULL)
1b31d05e
NC
7994 return;
7995
7996 memset (& aux, 0, sizeof (aux));
7997 aux.file = file;
0b6ae522
DJ
7998
7999 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8000 {
8001 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8002 {
ba5cdace 8003 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8004
8005 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8006
8007 /* PR binutils/17531 file: 011-12666-0.004. */
8008 if (aux.strtab != NULL)
8009 {
4082ef84 8010 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8011 free (aux.strtab);
8012 }
0b6ae522
DJ
8013 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8014 1, strsec->sh_size, _("string table"));
8015 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8016 }
fa197c1c 8017 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8018 unwsec = sec;
8019 }
8020
1b31d05e 8021 if (unwsec == NULL)
0b6ae522 8022 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8023 else
8024 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8025 {
8026 if (sec->sh_type == sec_type)
8027 {
8028 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8029 printable_section_name (sec),
1b31d05e
NC
8030 (unsigned long) sec->sh_offset,
8031 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8032
1b31d05e
NC
8033 dump_arm_unwind (&aux, sec);
8034 }
8035 }
0b6ae522
DJ
8036
8037 if (aux.symtab)
8038 free (aux.symtab);
8039 if (aux.strtab)
8040 free ((char *) aux.strtab);
0b6ae522
DJ
8041}
8042
1b31d05e 8043static void
2cf0635d 8044process_unwind (FILE * file)
57346661 8045{
2cf0635d
NC
8046 struct unwind_handler
8047 {
57346661 8048 int machtype;
1b31d05e 8049 void (* handler)(FILE *);
2cf0635d
NC
8050 } handlers[] =
8051 {
0b6ae522 8052 { EM_ARM, arm_process_unwind },
57346661
AM
8053 { EM_IA_64, ia64_process_unwind },
8054 { EM_PARISC, hppa_process_unwind },
fa197c1c 8055 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8056 { 0, 0 }
8057 };
8058 int i;
8059
8060 if (!do_unwind)
1b31d05e 8061 return;
57346661
AM
8062
8063 for (i = 0; handlers[i].handler != NULL; i++)
8064 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8065 {
8066 handlers[i].handler (file);
8067 return;
8068 }
57346661 8069
1b31d05e
NC
8070 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8071 get_machine_name (elf_header.e_machine));
57346661
AM
8072}
8073
252b5132 8074static void
2cf0635d 8075dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8076{
8077 switch (entry->d_tag)
8078 {
8079 case DT_MIPS_FLAGS:
8080 if (entry->d_un.d_val == 0)
4b68bca3 8081 printf (_("NONE"));
252b5132
RH
8082 else
8083 {
8084 static const char * opts[] =
8085 {
8086 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8087 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8088 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8089 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8090 "RLD_ORDER_SAFE"
8091 };
8092 unsigned int cnt;
8093 int first = 1;
2b692964 8094
60bca95a 8095 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8096 if (entry->d_un.d_val & (1 << cnt))
8097 {
8098 printf ("%s%s", first ? "" : " ", opts[cnt]);
8099 first = 0;
8100 }
252b5132
RH
8101 }
8102 break;
103f02d3 8103
252b5132 8104 case DT_MIPS_IVERSION:
d79b3d50 8105 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8106 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8107 else
76ca31c0
NC
8108 {
8109 char buf[40];
8110 sprintf_vma (buf, entry->d_un.d_ptr);
8111 /* Note: coded this way so that there is a single string for translation. */
8112 printf (_("<corrupt: %s>"), buf);
8113 }
252b5132 8114 break;
103f02d3 8115
252b5132
RH
8116 case DT_MIPS_TIME_STAMP:
8117 {
8118 char timebuf[20];
2cf0635d 8119 struct tm * tmp;
50da7a9c 8120
91d6fa6a
NC
8121 time_t atime = entry->d_un.d_val;
8122 tmp = gmtime (&atime);
e9e44622
JJ
8123 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8124 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8125 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8126 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8127 }
8128 break;
103f02d3 8129
252b5132
RH
8130 case DT_MIPS_RLD_VERSION:
8131 case DT_MIPS_LOCAL_GOTNO:
8132 case DT_MIPS_CONFLICTNO:
8133 case DT_MIPS_LIBLISTNO:
8134 case DT_MIPS_SYMTABNO:
8135 case DT_MIPS_UNREFEXTNO:
8136 case DT_MIPS_HIPAGENO:
8137 case DT_MIPS_DELTA_CLASS_NO:
8138 case DT_MIPS_DELTA_INSTANCE_NO:
8139 case DT_MIPS_DELTA_RELOC_NO:
8140 case DT_MIPS_DELTA_SYM_NO:
8141 case DT_MIPS_DELTA_CLASSSYM_NO:
8142 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8143 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8144 break;
103f02d3
UD
8145
8146 default:
4b68bca3 8147 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8148 }
4b68bca3 8149 putchar ('\n');
103f02d3
UD
8150}
8151
103f02d3 8152static void
2cf0635d 8153dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8154{
8155 switch (entry->d_tag)
8156 {
8157 case DT_HP_DLD_FLAGS:
8158 {
8159 static struct
8160 {
8161 long int bit;
2cf0635d 8162 const char * str;
5e220199
NC
8163 }
8164 flags[] =
8165 {
8166 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8167 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8168 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8169 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8170 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8171 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8172 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8173 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8174 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8175 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8176 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8177 { DT_HP_GST, "HP_GST" },
8178 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8179 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8180 { DT_HP_NODELETE, "HP_NODELETE" },
8181 { DT_HP_GROUP, "HP_GROUP" },
8182 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8183 };
103f02d3 8184 int first = 1;
5e220199 8185 size_t cnt;
f7a99963 8186 bfd_vma val = entry->d_un.d_val;
103f02d3 8187
60bca95a 8188 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8189 if (val & flags[cnt].bit)
30800947
NC
8190 {
8191 if (! first)
8192 putchar (' ');
8193 fputs (flags[cnt].str, stdout);
8194 first = 0;
8195 val ^= flags[cnt].bit;
8196 }
76da6bbe 8197
103f02d3 8198 if (val != 0 || first)
f7a99963
NC
8199 {
8200 if (! first)
8201 putchar (' ');
8202 print_vma (val, HEX);
8203 }
103f02d3
UD
8204 }
8205 break;
76da6bbe 8206
252b5132 8207 default:
f7a99963
NC
8208 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8209 break;
252b5132 8210 }
35b1837e 8211 putchar ('\n');
252b5132
RH
8212}
8213
28f997cf
TG
8214#ifdef BFD64
8215
8216/* VMS vs Unix time offset and factor. */
8217
8218#define VMS_EPOCH_OFFSET 35067168000000000LL
8219#define VMS_GRANULARITY_FACTOR 10000000
8220
8221/* Display a VMS time in a human readable format. */
8222
8223static void
8224print_vms_time (bfd_int64_t vmstime)
8225{
8226 struct tm *tm;
8227 time_t unxtime;
8228
8229 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8230 tm = gmtime (&unxtime);
8231 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8232 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8233 tm->tm_hour, tm->tm_min, tm->tm_sec);
8234}
8235#endif /* BFD64 */
8236
ecc51f48 8237static void
2cf0635d 8238dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8239{
8240 switch (entry->d_tag)
8241 {
0de14b54 8242 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8243 /* First 3 slots reserved. */
ecc51f48
NC
8244 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8245 printf (" -- ");
8246 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8247 break;
8248
28f997cf
TG
8249 case DT_IA_64_VMS_LINKTIME:
8250#ifdef BFD64
8251 print_vms_time (entry->d_un.d_val);
8252#endif
8253 break;
8254
8255 case DT_IA_64_VMS_LNKFLAGS:
8256 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8257 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8258 printf (" CALL_DEBUG");
8259 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8260 printf (" NOP0BUFS");
8261 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8262 printf (" P0IMAGE");
8263 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8264 printf (" MKTHREADS");
8265 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8266 printf (" UPCALLS");
8267 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8268 printf (" IMGSTA");
8269 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8270 printf (" INITIALIZE");
8271 if (entry->d_un.d_val & VMS_LF_MAIN)
8272 printf (" MAIN");
8273 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8274 printf (" EXE_INIT");
8275 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8276 printf (" TBK_IN_IMG");
8277 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8278 printf (" DBG_IN_IMG");
8279 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8280 printf (" TBK_IN_DSF");
8281 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8282 printf (" DBG_IN_DSF");
8283 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8284 printf (" SIGNATURES");
8285 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8286 printf (" REL_SEG_OFF");
8287 break;
8288
bdf4d63a
JJ
8289 default:
8290 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8291 break;
ecc51f48 8292 }
bdf4d63a 8293 putchar ('\n');
ecc51f48
NC
8294}
8295
252b5132 8296static int
2cf0635d 8297get_32bit_dynamic_section (FILE * file)
252b5132 8298{
2cf0635d
NC
8299 Elf32_External_Dyn * edyn;
8300 Elf32_External_Dyn * ext;
8301 Elf_Internal_Dyn * entry;
103f02d3 8302
3f5e193b
NC
8303 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8304 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8305 if (!edyn)
8306 return 0;
103f02d3 8307
071436c6
NC
8308 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8309 might not have the luxury of section headers. Look for the DT_NULL
8310 terminator to determine the number of entries. */
ba2685cc 8311 for (ext = edyn, dynamic_nent = 0;
071436c6 8312 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8313 ext++)
8314 {
8315 dynamic_nent++;
8316 if (BYTE_GET (ext->d_tag) == DT_NULL)
8317 break;
8318 }
252b5132 8319
3f5e193b
NC
8320 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8321 sizeof (* entry));
b2d38a17 8322 if (dynamic_section == NULL)
252b5132 8323 {
8b73c356
NC
8324 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8325 (unsigned long) dynamic_nent);
9ea033b2
NC
8326 free (edyn);
8327 return 0;
8328 }
252b5132 8329
fb514b26 8330 for (ext = edyn, entry = dynamic_section;
ba2685cc 8331 entry < dynamic_section + dynamic_nent;
fb514b26 8332 ext++, entry++)
9ea033b2 8333 {
fb514b26
AM
8334 entry->d_tag = BYTE_GET (ext->d_tag);
8335 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8336 }
8337
9ea033b2
NC
8338 free (edyn);
8339
8340 return 1;
8341}
8342
8343static int
2cf0635d 8344get_64bit_dynamic_section (FILE * file)
9ea033b2 8345{
2cf0635d
NC
8346 Elf64_External_Dyn * edyn;
8347 Elf64_External_Dyn * ext;
8348 Elf_Internal_Dyn * entry;
103f02d3 8349
071436c6 8350 /* Read in the data. */
3f5e193b
NC
8351 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8352 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8353 if (!edyn)
8354 return 0;
103f02d3 8355
071436c6
NC
8356 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8357 might not have the luxury of section headers. Look for the DT_NULL
8358 terminator to determine the number of entries. */
ba2685cc 8359 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8360 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8361 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8362 ext++)
8363 {
8364 dynamic_nent++;
66543521 8365 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8366 break;
8367 }
252b5132 8368
3f5e193b
NC
8369 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8370 sizeof (* entry));
b2d38a17 8371 if (dynamic_section == NULL)
252b5132 8372 {
8b73c356
NC
8373 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8374 (unsigned long) dynamic_nent);
252b5132
RH
8375 free (edyn);
8376 return 0;
8377 }
8378
071436c6 8379 /* Convert from external to internal formats. */
fb514b26 8380 for (ext = edyn, entry = dynamic_section;
ba2685cc 8381 entry < dynamic_section + dynamic_nent;
fb514b26 8382 ext++, entry++)
252b5132 8383 {
66543521
AM
8384 entry->d_tag = BYTE_GET (ext->d_tag);
8385 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8386 }
8387
8388 free (edyn);
8389
9ea033b2
NC
8390 return 1;
8391}
8392
e9e44622
JJ
8393static void
8394print_dynamic_flags (bfd_vma flags)
d1133906 8395{
e9e44622 8396 int first = 1;
13ae64f3 8397
d1133906
NC
8398 while (flags)
8399 {
8400 bfd_vma flag;
8401
8402 flag = flags & - flags;
8403 flags &= ~ flag;
8404
e9e44622
JJ
8405 if (first)
8406 first = 0;
8407 else
8408 putc (' ', stdout);
13ae64f3 8409
d1133906
NC
8410 switch (flag)
8411 {
e9e44622
JJ
8412 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8413 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8414 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8415 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8416 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8417 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8418 }
8419 }
e9e44622 8420 puts ("");
d1133906
NC
8421}
8422
b2d38a17
NC
8423/* Parse and display the contents of the dynamic section. */
8424
9ea033b2 8425static int
2cf0635d 8426process_dynamic_section (FILE * file)
9ea033b2 8427{
2cf0635d 8428 Elf_Internal_Dyn * entry;
9ea033b2
NC
8429
8430 if (dynamic_size == 0)
8431 {
8432 if (do_dynamic)
b2d38a17 8433 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8434
8435 return 1;
8436 }
8437
8438 if (is_32bit_elf)
8439 {
b2d38a17 8440 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8441 return 0;
8442 }
b2d38a17 8443 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8444 return 0;
8445
252b5132
RH
8446 /* Find the appropriate symbol table. */
8447 if (dynamic_symbols == NULL)
8448 {
86dba8ee
AM
8449 for (entry = dynamic_section;
8450 entry < dynamic_section + dynamic_nent;
8451 ++entry)
252b5132 8452 {
c8286bd1 8453 Elf_Internal_Shdr section;
252b5132
RH
8454
8455 if (entry->d_tag != DT_SYMTAB)
8456 continue;
8457
8458 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8459
8460 /* Since we do not know how big the symbol table is,
8461 we default to reading in the entire file (!) and
8462 processing that. This is overkill, I know, but it
e3c8793a 8463 should work. */
d93f0186 8464 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8465
fb52b2f4
NC
8466 if (archive_file_offset != 0)
8467 section.sh_size = archive_file_size - section.sh_offset;
8468 else
8469 {
8470 if (fseek (file, 0, SEEK_END))
591a748a 8471 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8472
8473 section.sh_size = ftell (file) - section.sh_offset;
8474 }
252b5132 8475
9ea033b2 8476 if (is_32bit_elf)
9ad5cbcf 8477 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8478 else
9ad5cbcf 8479 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8480 section.sh_name = string_table_length;
252b5132 8481
ba5cdace 8482 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8483 if (num_dynamic_syms < 1)
252b5132
RH
8484 {
8485 error (_("Unable to determine the number of symbols to load\n"));
8486 continue;
8487 }
252b5132
RH
8488 }
8489 }
8490
8491 /* Similarly find a string table. */
8492 if (dynamic_strings == NULL)
8493 {
86dba8ee
AM
8494 for (entry = dynamic_section;
8495 entry < dynamic_section + dynamic_nent;
8496 ++entry)
252b5132
RH
8497 {
8498 unsigned long offset;
b34976b6 8499 long str_tab_len;
252b5132
RH
8500
8501 if (entry->d_tag != DT_STRTAB)
8502 continue;
8503
8504 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8505
8506 /* Since we do not know how big the string table is,
8507 we default to reading in the entire file (!) and
8508 processing that. This is overkill, I know, but it
e3c8793a 8509 should work. */
252b5132 8510
d93f0186 8511 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8512
8513 if (archive_file_offset != 0)
8514 str_tab_len = archive_file_size - offset;
8515 else
8516 {
8517 if (fseek (file, 0, SEEK_END))
8518 error (_("Unable to seek to end of file\n"));
8519 str_tab_len = ftell (file) - offset;
8520 }
252b5132
RH
8521
8522 if (str_tab_len < 1)
8523 {
8524 error
8525 (_("Unable to determine the length of the dynamic string table\n"));
8526 continue;
8527 }
8528
3f5e193b
NC
8529 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8530 str_tab_len,
8531 _("dynamic string table"));
59245841 8532 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8533 break;
8534 }
8535 }
8536
8537 /* And find the syminfo section if available. */
8538 if (dynamic_syminfo == NULL)
8539 {
3e8bba36 8540 unsigned long syminsz = 0;
252b5132 8541
86dba8ee
AM
8542 for (entry = dynamic_section;
8543 entry < dynamic_section + dynamic_nent;
8544 ++entry)
252b5132
RH
8545 {
8546 if (entry->d_tag == DT_SYMINENT)
8547 {
8548 /* Note: these braces are necessary to avoid a syntax
8549 error from the SunOS4 C compiler. */
049b0c3a
NC
8550 /* PR binutils/17531: A corrupt file can trigger this test.
8551 So do not use an assert, instead generate an error message. */
8552 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8553 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8554 (int) entry->d_un.d_val);
252b5132
RH
8555 }
8556 else if (entry->d_tag == DT_SYMINSZ)
8557 syminsz = entry->d_un.d_val;
8558 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8559 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8560 syminsz);
252b5132
RH
8561 }
8562
8563 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8564 {
2cf0635d
NC
8565 Elf_External_Syminfo * extsyminfo;
8566 Elf_External_Syminfo * extsym;
8567 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8568
8569 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8570 extsyminfo = (Elf_External_Syminfo *)
8571 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8572 _("symbol information"));
a6e9f9df
AM
8573 if (!extsyminfo)
8574 return 0;
252b5132 8575
3f5e193b 8576 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8577 if (dynamic_syminfo == NULL)
8578 {
8b73c356
NC
8579 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8580 (unsigned long) syminsz);
252b5132
RH
8581 return 0;
8582 }
8583
8584 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8585 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8586 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8587 ++syminfo, ++extsym)
252b5132 8588 {
86dba8ee
AM
8589 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8590 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8591 }
8592
8593 free (extsyminfo);
8594 }
8595 }
8596
8597 if (do_dynamic && dynamic_addr)
8b73c356
NC
8598 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8599 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8600 if (do_dynamic)
8601 printf (_(" Tag Type Name/Value\n"));
8602
86dba8ee
AM
8603 for (entry = dynamic_section;
8604 entry < dynamic_section + dynamic_nent;
8605 entry++)
252b5132
RH
8606 {
8607 if (do_dynamic)
f7a99963 8608 {
2cf0635d 8609 const char * dtype;
e699b9ff 8610
f7a99963
NC
8611 putchar (' ');
8612 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8613 dtype = get_dynamic_type (entry->d_tag);
8614 printf (" (%s)%*s", dtype,
8615 ((is_32bit_elf ? 27 : 19)
8616 - (int) strlen (dtype)),
f7a99963
NC
8617 " ");
8618 }
252b5132
RH
8619
8620 switch (entry->d_tag)
8621 {
d1133906
NC
8622 case DT_FLAGS:
8623 if (do_dynamic)
e9e44622 8624 print_dynamic_flags (entry->d_un.d_val);
d1133906 8625 break;
76da6bbe 8626
252b5132
RH
8627 case DT_AUXILIARY:
8628 case DT_FILTER:
019148e4
L
8629 case DT_CONFIG:
8630 case DT_DEPAUDIT:
8631 case DT_AUDIT:
252b5132
RH
8632 if (do_dynamic)
8633 {
019148e4 8634 switch (entry->d_tag)
b34976b6 8635 {
019148e4
L
8636 case DT_AUXILIARY:
8637 printf (_("Auxiliary library"));
8638 break;
8639
8640 case DT_FILTER:
8641 printf (_("Filter library"));
8642 break;
8643
b34976b6 8644 case DT_CONFIG:
019148e4
L
8645 printf (_("Configuration file"));
8646 break;
8647
8648 case DT_DEPAUDIT:
8649 printf (_("Dependency audit library"));
8650 break;
8651
8652 case DT_AUDIT:
8653 printf (_("Audit library"));
8654 break;
8655 }
252b5132 8656
d79b3d50
NC
8657 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8658 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8659 else
f7a99963
NC
8660 {
8661 printf (": ");
8662 print_vma (entry->d_un.d_val, PREFIX_HEX);
8663 putchar ('\n');
8664 }
252b5132
RH
8665 }
8666 break;
8667
dcefbbbd 8668 case DT_FEATURE:
252b5132
RH
8669 if (do_dynamic)
8670 {
8671 printf (_("Flags:"));
86f55779 8672
252b5132
RH
8673 if (entry->d_un.d_val == 0)
8674 printf (_(" None\n"));
8675 else
8676 {
8677 unsigned long int val = entry->d_un.d_val;
86f55779 8678
252b5132
RH
8679 if (val & DTF_1_PARINIT)
8680 {
8681 printf (" PARINIT");
8682 val ^= DTF_1_PARINIT;
8683 }
dcefbbbd
L
8684 if (val & DTF_1_CONFEXP)
8685 {
8686 printf (" CONFEXP");
8687 val ^= DTF_1_CONFEXP;
8688 }
252b5132
RH
8689 if (val != 0)
8690 printf (" %lx", val);
8691 puts ("");
8692 }
8693 }
8694 break;
8695
8696 case DT_POSFLAG_1:
8697 if (do_dynamic)
8698 {
8699 printf (_("Flags:"));
86f55779 8700
252b5132
RH
8701 if (entry->d_un.d_val == 0)
8702 printf (_(" None\n"));
8703 else
8704 {
8705 unsigned long int val = entry->d_un.d_val;
86f55779 8706
252b5132
RH
8707 if (val & DF_P1_LAZYLOAD)
8708 {
8709 printf (" LAZYLOAD");
8710 val ^= DF_P1_LAZYLOAD;
8711 }
8712 if (val & DF_P1_GROUPPERM)
8713 {
8714 printf (" GROUPPERM");
8715 val ^= DF_P1_GROUPPERM;
8716 }
8717 if (val != 0)
8718 printf (" %lx", val);
8719 puts ("");
8720 }
8721 }
8722 break;
8723
8724 case DT_FLAGS_1:
8725 if (do_dynamic)
8726 {
8727 printf (_("Flags:"));
8728 if (entry->d_un.d_val == 0)
8729 printf (_(" None\n"));
8730 else
8731 {
8732 unsigned long int val = entry->d_un.d_val;
86f55779 8733
252b5132
RH
8734 if (val & DF_1_NOW)
8735 {
8736 printf (" NOW");
8737 val ^= DF_1_NOW;
8738 }
8739 if (val & DF_1_GLOBAL)
8740 {
8741 printf (" GLOBAL");
8742 val ^= DF_1_GLOBAL;
8743 }
8744 if (val & DF_1_GROUP)
8745 {
8746 printf (" GROUP");
8747 val ^= DF_1_GROUP;
8748 }
8749 if (val & DF_1_NODELETE)
8750 {
8751 printf (" NODELETE");
8752 val ^= DF_1_NODELETE;
8753 }
8754 if (val & DF_1_LOADFLTR)
8755 {
8756 printf (" LOADFLTR");
8757 val ^= DF_1_LOADFLTR;
8758 }
8759 if (val & DF_1_INITFIRST)
8760 {
8761 printf (" INITFIRST");
8762 val ^= DF_1_INITFIRST;
8763 }
8764 if (val & DF_1_NOOPEN)
8765 {
8766 printf (" NOOPEN");
8767 val ^= DF_1_NOOPEN;
8768 }
8769 if (val & DF_1_ORIGIN)
8770 {
8771 printf (" ORIGIN");
8772 val ^= DF_1_ORIGIN;
8773 }
8774 if (val & DF_1_DIRECT)
8775 {
8776 printf (" DIRECT");
8777 val ^= DF_1_DIRECT;
8778 }
8779 if (val & DF_1_TRANS)
8780 {
8781 printf (" TRANS");
8782 val ^= DF_1_TRANS;
8783 }
8784 if (val & DF_1_INTERPOSE)
8785 {
8786 printf (" INTERPOSE");
8787 val ^= DF_1_INTERPOSE;
8788 }
f7db6139 8789 if (val & DF_1_NODEFLIB)
dcefbbbd 8790 {
f7db6139
L
8791 printf (" NODEFLIB");
8792 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8793 }
8794 if (val & DF_1_NODUMP)
8795 {
8796 printf (" NODUMP");
8797 val ^= DF_1_NODUMP;
8798 }
34b60028 8799 if (val & DF_1_CONFALT)
dcefbbbd 8800 {
34b60028
L
8801 printf (" CONFALT");
8802 val ^= DF_1_CONFALT;
8803 }
8804 if (val & DF_1_ENDFILTEE)
8805 {
8806 printf (" ENDFILTEE");
8807 val ^= DF_1_ENDFILTEE;
8808 }
8809 if (val & DF_1_DISPRELDNE)
8810 {
8811 printf (" DISPRELDNE");
8812 val ^= DF_1_DISPRELDNE;
8813 }
8814 if (val & DF_1_DISPRELPND)
8815 {
8816 printf (" DISPRELPND");
8817 val ^= DF_1_DISPRELPND;
8818 }
8819 if (val & DF_1_NODIRECT)
8820 {
8821 printf (" NODIRECT");
8822 val ^= DF_1_NODIRECT;
8823 }
8824 if (val & DF_1_IGNMULDEF)
8825 {
8826 printf (" IGNMULDEF");
8827 val ^= DF_1_IGNMULDEF;
8828 }
8829 if (val & DF_1_NOKSYMS)
8830 {
8831 printf (" NOKSYMS");
8832 val ^= DF_1_NOKSYMS;
8833 }
8834 if (val & DF_1_NOHDR)
8835 {
8836 printf (" NOHDR");
8837 val ^= DF_1_NOHDR;
8838 }
8839 if (val & DF_1_EDITED)
8840 {
8841 printf (" EDITED");
8842 val ^= DF_1_EDITED;
8843 }
8844 if (val & DF_1_NORELOC)
8845 {
8846 printf (" NORELOC");
8847 val ^= DF_1_NORELOC;
8848 }
8849 if (val & DF_1_SYMINTPOSE)
8850 {
8851 printf (" SYMINTPOSE");
8852 val ^= DF_1_SYMINTPOSE;
8853 }
8854 if (val & DF_1_GLOBAUDIT)
8855 {
8856 printf (" GLOBAUDIT");
8857 val ^= DF_1_GLOBAUDIT;
8858 }
8859 if (val & DF_1_SINGLETON)
8860 {
8861 printf (" SINGLETON");
8862 val ^= DF_1_SINGLETON;
dcefbbbd 8863 }
252b5132
RH
8864 if (val != 0)
8865 printf (" %lx", val);
8866 puts ("");
8867 }
8868 }
8869 break;
8870
8871 case DT_PLTREL:
566b0d53 8872 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8873 if (do_dynamic)
8874 puts (get_dynamic_type (entry->d_un.d_val));
8875 break;
8876
8877 case DT_NULL :
8878 case DT_NEEDED :
8879 case DT_PLTGOT :
8880 case DT_HASH :
8881 case DT_STRTAB :
8882 case DT_SYMTAB :
8883 case DT_RELA :
8884 case DT_INIT :
8885 case DT_FINI :
8886 case DT_SONAME :
8887 case DT_RPATH :
8888 case DT_SYMBOLIC:
8889 case DT_REL :
8890 case DT_DEBUG :
8891 case DT_TEXTREL :
8892 case DT_JMPREL :
019148e4 8893 case DT_RUNPATH :
252b5132
RH
8894 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8895
8896 if (do_dynamic)
8897 {
2cf0635d 8898 char * name;
252b5132 8899
d79b3d50
NC
8900 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8901 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8902 else
d79b3d50 8903 name = NULL;
252b5132
RH
8904
8905 if (name)
8906 {
8907 switch (entry->d_tag)
8908 {
8909 case DT_NEEDED:
8910 printf (_("Shared library: [%s]"), name);
8911
18bd398b 8912 if (streq (name, program_interpreter))
f7a99963 8913 printf (_(" program interpreter"));
252b5132
RH
8914 break;
8915
8916 case DT_SONAME:
f7a99963 8917 printf (_("Library soname: [%s]"), name);
252b5132
RH
8918 break;
8919
8920 case DT_RPATH:
f7a99963 8921 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8922 break;
8923
019148e4
L
8924 case DT_RUNPATH:
8925 printf (_("Library runpath: [%s]"), name);
8926 break;
8927
252b5132 8928 default:
f7a99963
NC
8929 print_vma (entry->d_un.d_val, PREFIX_HEX);
8930 break;
252b5132
RH
8931 }
8932 }
8933 else
f7a99963
NC
8934 print_vma (entry->d_un.d_val, PREFIX_HEX);
8935
8936 putchar ('\n');
252b5132
RH
8937 }
8938 break;
8939
8940 case DT_PLTRELSZ:
8941 case DT_RELASZ :
8942 case DT_STRSZ :
8943 case DT_RELSZ :
8944 case DT_RELAENT :
8945 case DT_SYMENT :
8946 case DT_RELENT :
566b0d53 8947 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8948 case DT_PLTPADSZ:
8949 case DT_MOVEENT :
8950 case DT_MOVESZ :
8951 case DT_INIT_ARRAYSZ:
8952 case DT_FINI_ARRAYSZ:
047b2264
JJ
8953 case DT_GNU_CONFLICTSZ:
8954 case DT_GNU_LIBLISTSZ:
252b5132 8955 if (do_dynamic)
f7a99963
NC
8956 {
8957 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8958 printf (_(" (bytes)\n"));
f7a99963 8959 }
252b5132
RH
8960 break;
8961
8962 case DT_VERDEFNUM:
8963 case DT_VERNEEDNUM:
8964 case DT_RELACOUNT:
8965 case DT_RELCOUNT:
8966 if (do_dynamic)
f7a99963
NC
8967 {
8968 print_vma (entry->d_un.d_val, UNSIGNED);
8969 putchar ('\n');
8970 }
252b5132
RH
8971 break;
8972
8973 case DT_SYMINSZ:
8974 case DT_SYMINENT:
8975 case DT_SYMINFO:
8976 case DT_USED:
8977 case DT_INIT_ARRAY:
8978 case DT_FINI_ARRAY:
8979 if (do_dynamic)
8980 {
d79b3d50
NC
8981 if (entry->d_tag == DT_USED
8982 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8983 {
2cf0635d 8984 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8985
b34976b6 8986 if (*name)
252b5132
RH
8987 {
8988 printf (_("Not needed object: [%s]\n"), name);
8989 break;
8990 }
8991 }
103f02d3 8992
f7a99963
NC
8993 print_vma (entry->d_un.d_val, PREFIX_HEX);
8994 putchar ('\n');
252b5132
RH
8995 }
8996 break;
8997
8998 case DT_BIND_NOW:
8999 /* The value of this entry is ignored. */
35b1837e
AM
9000 if (do_dynamic)
9001 putchar ('\n');
252b5132 9002 break;
103f02d3 9003
047b2264
JJ
9004 case DT_GNU_PRELINKED:
9005 if (do_dynamic)
9006 {
2cf0635d 9007 struct tm * tmp;
91d6fa6a 9008 time_t atime = entry->d_un.d_val;
047b2264 9009
91d6fa6a 9010 tmp = gmtime (&atime);
071436c6
NC
9011 /* PR 17533 file: 041-1244816-0.004. */
9012 if (tmp == NULL)
5a2cbcf4
L
9013 printf (_("<corrupt time val: %lx"),
9014 (unsigned long) atime);
071436c6
NC
9015 else
9016 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9017 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9018 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9019
9020 }
9021 break;
9022
fdc90cb4
JJ
9023 case DT_GNU_HASH:
9024 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9025 if (do_dynamic)
9026 {
9027 print_vma (entry->d_un.d_val, PREFIX_HEX);
9028 putchar ('\n');
9029 }
9030 break;
9031
252b5132
RH
9032 default:
9033 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9034 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9035 entry->d_un.d_val;
9036
9037 if (do_dynamic)
9038 {
9039 switch (elf_header.e_machine)
9040 {
9041 case EM_MIPS:
4fe85591 9042 case EM_MIPS_RS3_LE:
b2d38a17 9043 dynamic_section_mips_val (entry);
252b5132 9044 break;
103f02d3 9045 case EM_PARISC:
b2d38a17 9046 dynamic_section_parisc_val (entry);
103f02d3 9047 break;
ecc51f48 9048 case EM_IA_64:
b2d38a17 9049 dynamic_section_ia64_val (entry);
ecc51f48 9050 break;
252b5132 9051 default:
f7a99963
NC
9052 print_vma (entry->d_un.d_val, PREFIX_HEX);
9053 putchar ('\n');
252b5132
RH
9054 }
9055 }
9056 break;
9057 }
9058 }
9059
9060 return 1;
9061}
9062
9063static char *
d3ba0551 9064get_ver_flags (unsigned int flags)
252b5132 9065{
b34976b6 9066 static char buff[32];
252b5132
RH
9067
9068 buff[0] = 0;
9069
9070 if (flags == 0)
9071 return _("none");
9072
9073 if (flags & VER_FLG_BASE)
9074 strcat (buff, "BASE ");
9075
9076 if (flags & VER_FLG_WEAK)
9077 {
9078 if (flags & VER_FLG_BASE)
9079 strcat (buff, "| ");
9080
9081 strcat (buff, "WEAK ");
9082 }
9083
44ec90b9
RO
9084 if (flags & VER_FLG_INFO)
9085 {
9086 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9087 strcat (buff, "| ");
9088
9089 strcat (buff, "INFO ");
9090 }
9091
9092 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9093 strcat (buff, _("| <unknown>"));
252b5132
RH
9094
9095 return buff;
9096}
9097
9098/* Display the contents of the version sections. */
98fb390a 9099
252b5132 9100static int
2cf0635d 9101process_version_sections (FILE * file)
252b5132 9102{
2cf0635d 9103 Elf_Internal_Shdr * section;
b34976b6
AM
9104 unsigned i;
9105 int found = 0;
252b5132
RH
9106
9107 if (! do_version)
9108 return 1;
9109
9110 for (i = 0, section = section_headers;
9111 i < elf_header.e_shnum;
b34976b6 9112 i++, section++)
252b5132
RH
9113 {
9114 switch (section->sh_type)
9115 {
9116 case SHT_GNU_verdef:
9117 {
2cf0635d 9118 Elf_External_Verdef * edefs;
b34976b6
AM
9119 unsigned int idx;
9120 unsigned int cnt;
2cf0635d 9121 char * endbuf;
252b5132
RH
9122
9123 found = 1;
9124
74e1a04b
NC
9125 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9126 printable_section_name (section),
9127 section->sh_info);
252b5132
RH
9128
9129 printf (_(" Addr: 0x"));
9130 printf_vma (section->sh_addr);
74e1a04b 9131 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9132 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9133 printable_section_name_from_index (section->sh_link));
252b5132 9134
3f5e193b
NC
9135 edefs = (Elf_External_Verdef *)
9136 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9137 _("version definition section"));
a6e9f9df
AM
9138 if (!edefs)
9139 break;
59245841 9140 endbuf = (char *) edefs + section->sh_size;
252b5132 9141
b34976b6 9142 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9143 {
2cf0635d
NC
9144 char * vstart;
9145 Elf_External_Verdef * edef;
b34976b6 9146 Elf_Internal_Verdef ent;
2cf0635d 9147 Elf_External_Verdaux * eaux;
b34976b6
AM
9148 Elf_Internal_Verdaux aux;
9149 int j;
9150 int isum;
103f02d3 9151
7e26601c
NC
9152 /* Check for very large indicies. */
9153 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9154 break;
9155
252b5132 9156 vstart = ((char *) edefs) + idx;
54806181
AM
9157 if (vstart + sizeof (*edef) > endbuf)
9158 break;
252b5132
RH
9159
9160 edef = (Elf_External_Verdef *) vstart;
9161
9162 ent.vd_version = BYTE_GET (edef->vd_version);
9163 ent.vd_flags = BYTE_GET (edef->vd_flags);
9164 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9165 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9166 ent.vd_hash = BYTE_GET (edef->vd_hash);
9167 ent.vd_aux = BYTE_GET (edef->vd_aux);
9168 ent.vd_next = BYTE_GET (edef->vd_next);
9169
9170 printf (_(" %#06x: Rev: %d Flags: %s"),
9171 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9172
9173 printf (_(" Index: %d Cnt: %d "),
9174 ent.vd_ndx, ent.vd_cnt);
9175
dd24e3da 9176 /* Check for overflow. */
7e26601c 9177 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9178 break;
9179
252b5132
RH
9180 vstart += ent.vd_aux;
9181
9182 eaux = (Elf_External_Verdaux *) vstart;
9183
9184 aux.vda_name = BYTE_GET (eaux->vda_name);
9185 aux.vda_next = BYTE_GET (eaux->vda_next);
9186
d79b3d50
NC
9187 if (VALID_DYNAMIC_NAME (aux.vda_name))
9188 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9189 else
9190 printf (_("Name index: %ld\n"), aux.vda_name);
9191
9192 isum = idx + ent.vd_aux;
9193
b34976b6 9194 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9195 {
dd24e3da 9196 /* Check for overflow. */
7e26601c 9197 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9198 break;
9199
252b5132
RH
9200 isum += aux.vda_next;
9201 vstart += aux.vda_next;
9202
9203 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9204 if (vstart + sizeof (*eaux) > endbuf)
9205 break;
252b5132
RH
9206
9207 aux.vda_name = BYTE_GET (eaux->vda_name);
9208 aux.vda_next = BYTE_GET (eaux->vda_next);
9209
d79b3d50 9210 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9211 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9212 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9213 else
9214 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9215 isum, j, aux.vda_name);
9216 }
dd24e3da 9217
54806181
AM
9218 if (j < ent.vd_cnt)
9219 printf (_(" Version def aux past end of section\n"));
252b5132 9220
5d921cbd
NC
9221 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9222 if (idx + ent.vd_next <= idx)
9223 break;
9224
252b5132
RH
9225 idx += ent.vd_next;
9226 }
dd24e3da 9227
54806181
AM
9228 if (cnt < section->sh_info)
9229 printf (_(" Version definition past end of section\n"));
252b5132
RH
9230
9231 free (edefs);
9232 }
9233 break;
103f02d3 9234
252b5132
RH
9235 case SHT_GNU_verneed:
9236 {
2cf0635d 9237 Elf_External_Verneed * eneed;
b34976b6
AM
9238 unsigned int idx;
9239 unsigned int cnt;
2cf0635d 9240 char * endbuf;
252b5132
RH
9241
9242 found = 1;
9243
72de5009 9244 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9245 printable_section_name (section), section->sh_info);
252b5132
RH
9246
9247 printf (_(" Addr: 0x"));
9248 printf_vma (section->sh_addr);
72de5009 9249 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9250 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9251 printable_section_name_from_index (section->sh_link));
252b5132 9252
3f5e193b
NC
9253 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9254 section->sh_offset, 1,
9255 section->sh_size,
9cf03b7e 9256 _("Version Needs section"));
a6e9f9df
AM
9257 if (!eneed)
9258 break;
59245841 9259 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9260
9261 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9262 {
2cf0635d 9263 Elf_External_Verneed * entry;
b34976b6
AM
9264 Elf_Internal_Verneed ent;
9265 int j;
9266 int isum;
2cf0635d 9267 char * vstart;
252b5132 9268
7e26601c 9269 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9270 break;
9271
252b5132 9272 vstart = ((char *) eneed) + idx;
54806181
AM
9273 if (vstart + sizeof (*entry) > endbuf)
9274 break;
252b5132
RH
9275
9276 entry = (Elf_External_Verneed *) vstart;
9277
9278 ent.vn_version = BYTE_GET (entry->vn_version);
9279 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9280 ent.vn_file = BYTE_GET (entry->vn_file);
9281 ent.vn_aux = BYTE_GET (entry->vn_aux);
9282 ent.vn_next = BYTE_GET (entry->vn_next);
9283
9284 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9285
d79b3d50
NC
9286 if (VALID_DYNAMIC_NAME (ent.vn_file))
9287 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9288 else
9289 printf (_(" File: %lx"), ent.vn_file);
9290
9291 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9292
dd24e3da 9293 /* Check for overflow. */
7e26601c 9294 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9295 break;
9296
252b5132
RH
9297 vstart += ent.vn_aux;
9298
9299 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9300 {
2cf0635d 9301 Elf_External_Vernaux * eaux;
b34976b6 9302 Elf_Internal_Vernaux aux;
252b5132 9303
54806181
AM
9304 if (vstart + sizeof (*eaux) > endbuf)
9305 break;
252b5132
RH
9306 eaux = (Elf_External_Vernaux *) vstart;
9307
9308 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9309 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9310 aux.vna_other = BYTE_GET (eaux->vna_other);
9311 aux.vna_name = BYTE_GET (eaux->vna_name);
9312 aux.vna_next = BYTE_GET (eaux->vna_next);
9313
d79b3d50 9314 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9315 printf (_(" %#06x: Name: %s"),
d79b3d50 9316 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9317 else
ecc2063b 9318 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9319 isum, aux.vna_name);
9320
9321 printf (_(" Flags: %s Version: %d\n"),
9322 get_ver_flags (aux.vna_flags), aux.vna_other);
9323
dd24e3da 9324 /* Check for overflow. */
7e26601c 9325 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9326 break;
9327
252b5132
RH
9328 isum += aux.vna_next;
9329 vstart += aux.vna_next;
9330 }
9cf03b7e 9331
54806181 9332 if (j < ent.vn_cnt)
9cf03b7e 9333 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9334
bcf83b2a 9335 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9336 {
9337 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9338 cnt = section->sh_info;
9339 break;
9340 }
252b5132
RH
9341 idx += ent.vn_next;
9342 }
9cf03b7e 9343
54806181 9344 if (cnt < section->sh_info)
9cf03b7e 9345 warn (_("Missing Version Needs information\n"));
103f02d3 9346
252b5132
RH
9347 free (eneed);
9348 }
9349 break;
9350
9351 case SHT_GNU_versym:
9352 {
2cf0635d 9353 Elf_Internal_Shdr * link_section;
8b73c356
NC
9354 size_t total;
9355 unsigned int cnt;
2cf0635d
NC
9356 unsigned char * edata;
9357 unsigned short * data;
9358 char * strtab;
9359 Elf_Internal_Sym * symbols;
9360 Elf_Internal_Shdr * string_sec;
ba5cdace 9361 unsigned long num_syms;
d3ba0551 9362 long off;
252b5132 9363
4fbb74a6 9364 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9365 break;
9366
4fbb74a6 9367 link_section = section_headers + section->sh_link;
08d8fa11 9368 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9369
4fbb74a6 9370 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9371 break;
9372
252b5132
RH
9373 found = 1;
9374
ba5cdace 9375 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9376 if (symbols == NULL)
9377 break;
252b5132 9378
4fbb74a6 9379 string_sec = section_headers + link_section->sh_link;
252b5132 9380
3f5e193b
NC
9381 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9382 string_sec->sh_size,
9383 _("version string table"));
a6e9f9df 9384 if (!strtab)
0429c154
MS
9385 {
9386 free (symbols);
9387 break;
9388 }
252b5132 9389
8b73c356
NC
9390 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9391 printable_section_name (section), (unsigned long) total);
252b5132
RH
9392
9393 printf (_(" Addr: "));
9394 printf_vma (section->sh_addr);
72de5009 9395 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9396 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9397 printable_section_name (link_section));
252b5132 9398
d3ba0551
AM
9399 off = offset_from_vma (file,
9400 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9401 total * sizeof (short));
3f5e193b
NC
9402 edata = (unsigned char *) get_data (NULL, file, off, total,
9403 sizeof (short),
9404 _("version symbol data"));
a6e9f9df
AM
9405 if (!edata)
9406 {
9407 free (strtab);
0429c154 9408 free (symbols);
a6e9f9df
AM
9409 break;
9410 }
252b5132 9411
3f5e193b 9412 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9413
9414 for (cnt = total; cnt --;)
b34976b6
AM
9415 data[cnt] = byte_get (edata + cnt * sizeof (short),
9416 sizeof (short));
252b5132
RH
9417
9418 free (edata);
9419
9420 for (cnt = 0; cnt < total; cnt += 4)
9421 {
9422 int j, nn;
00d93f34 9423 int check_def, check_need;
2cf0635d 9424 char * name;
252b5132
RH
9425
9426 printf (" %03x:", cnt);
9427
9428 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9429 switch (data[cnt + j])
252b5132
RH
9430 {
9431 case 0:
9432 fputs (_(" 0 (*local*) "), stdout);
9433 break;
9434
9435 case 1:
9436 fputs (_(" 1 (*global*) "), stdout);
9437 break;
9438
9439 default:
c244d050
NC
9440 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9441 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9442
dd24e3da 9443 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9444 array, break to avoid an out-of-bounds read. */
9445 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9446 {
9447 warn (_("invalid index into symbol array\n"));
9448 break;
9449 }
9450
00d93f34
JJ
9451 check_def = 1;
9452 check_need = 1;
4fbb74a6
AM
9453 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9454 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9455 != SHT_NOBITS)
252b5132 9456 {
b34976b6 9457 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9458 check_def = 0;
9459 else
9460 check_need = 0;
252b5132 9461 }
00d93f34
JJ
9462
9463 if (check_need
b34976b6 9464 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9465 {
b34976b6
AM
9466 Elf_Internal_Verneed ivn;
9467 unsigned long offset;
252b5132 9468
d93f0186
NC
9469 offset = offset_from_vma
9470 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9471 sizeof (Elf_External_Verneed));
252b5132 9472
b34976b6 9473 do
252b5132 9474 {
b34976b6
AM
9475 Elf_Internal_Vernaux ivna;
9476 Elf_External_Verneed evn;
9477 Elf_External_Vernaux evna;
9478 unsigned long a_off;
252b5132 9479
59245841
NC
9480 if (get_data (&evn, file, offset, sizeof (evn), 1,
9481 _("version need")) == NULL)
9482 break;
0b4362b0 9483
252b5132
RH
9484 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9485 ivn.vn_next = BYTE_GET (evn.vn_next);
9486
9487 a_off = offset + ivn.vn_aux;
9488
9489 do
9490 {
59245841
NC
9491 if (get_data (&evna, file, a_off, sizeof (evna),
9492 1, _("version need aux (2)")) == NULL)
9493 {
9494 ivna.vna_next = 0;
9495 ivna.vna_other = 0;
9496 }
9497 else
9498 {
9499 ivna.vna_next = BYTE_GET (evna.vna_next);
9500 ivna.vna_other = BYTE_GET (evna.vna_other);
9501 }
252b5132
RH
9502
9503 a_off += ivna.vna_next;
9504 }
b34976b6 9505 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9506 && ivna.vna_next != 0);
9507
b34976b6 9508 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9509 {
9510 ivna.vna_name = BYTE_GET (evna.vna_name);
9511
54806181
AM
9512 if (ivna.vna_name >= string_sec->sh_size)
9513 name = _("*invalid*");
9514 else
9515 name = strtab + ivna.vna_name;
252b5132 9516 nn += printf ("(%s%-*s",
16062207
ILT
9517 name,
9518 12 - (int) strlen (name),
252b5132 9519 ")");
00d93f34 9520 check_def = 0;
252b5132
RH
9521 break;
9522 }
9523
9524 offset += ivn.vn_next;
9525 }
9526 while (ivn.vn_next);
9527 }
00d93f34 9528
b34976b6
AM
9529 if (check_def && data[cnt + j] != 0x8001
9530 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9531 {
b34976b6
AM
9532 Elf_Internal_Verdef ivd;
9533 Elf_External_Verdef evd;
9534 unsigned long offset;
252b5132 9535
d93f0186
NC
9536 offset = offset_from_vma
9537 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9538 sizeof evd);
252b5132
RH
9539
9540 do
9541 {
59245841
NC
9542 if (get_data (&evd, file, offset, sizeof (evd), 1,
9543 _("version def")) == NULL)
9544 {
9545 ivd.vd_next = 0;
3102e897
NC
9546 /* PR 17531: file: 046-1082287-0.004. */
9547 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9548 break;
59245841
NC
9549 }
9550 else
9551 {
9552 ivd.vd_next = BYTE_GET (evd.vd_next);
9553 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9554 }
252b5132
RH
9555
9556 offset += ivd.vd_next;
9557 }
c244d050 9558 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9559 && ivd.vd_next != 0);
9560
c244d050 9561 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9562 {
b34976b6
AM
9563 Elf_External_Verdaux evda;
9564 Elf_Internal_Verdaux ivda;
252b5132
RH
9565
9566 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9567
59245841
NC
9568 if (get_data (&evda, file,
9569 offset - ivd.vd_next + ivd.vd_aux,
9570 sizeof (evda), 1,
9571 _("version def aux")) == NULL)
9572 break;
252b5132
RH
9573
9574 ivda.vda_name = BYTE_GET (evda.vda_name);
9575
54806181
AM
9576 if (ivda.vda_name >= string_sec->sh_size)
9577 name = _("*invalid*");
9578 else
9579 name = strtab + ivda.vda_name;
252b5132 9580 nn += printf ("(%s%-*s",
16062207
ILT
9581 name,
9582 12 - (int) strlen (name),
252b5132
RH
9583 ")");
9584 }
9585 }
9586
9587 if (nn < 18)
9588 printf ("%*c", 18 - nn, ' ');
9589 }
9590
9591 putchar ('\n');
9592 }
9593
9594 free (data);
9595 free (strtab);
9596 free (symbols);
9597 }
9598 break;
103f02d3 9599
252b5132
RH
9600 default:
9601 break;
9602 }
9603 }
9604
9605 if (! found)
9606 printf (_("\nNo version information found in this file.\n"));
9607
9608 return 1;
9609}
9610
d1133906 9611static const char *
d3ba0551 9612get_symbol_binding (unsigned int binding)
252b5132 9613{
b34976b6 9614 static char buff[32];
252b5132
RH
9615
9616 switch (binding)
9617 {
b34976b6
AM
9618 case STB_LOCAL: return "LOCAL";
9619 case STB_GLOBAL: return "GLOBAL";
9620 case STB_WEAK: return "WEAK";
252b5132
RH
9621 default:
9622 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9623 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9624 binding);
252b5132 9625 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9626 {
9627 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9628 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9629 /* GNU is still using the default value 0. */
3e7a7d11
NC
9630 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9631 return "UNIQUE";
9632 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9633 }
252b5132 9634 else
e9e44622 9635 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9636 return buff;
9637 }
9638}
9639
d1133906 9640static const char *
d3ba0551 9641get_symbol_type (unsigned int type)
252b5132 9642{
b34976b6 9643 static char buff[32];
252b5132
RH
9644
9645 switch (type)
9646 {
b34976b6
AM
9647 case STT_NOTYPE: return "NOTYPE";
9648 case STT_OBJECT: return "OBJECT";
9649 case STT_FUNC: return "FUNC";
9650 case STT_SECTION: return "SECTION";
9651 case STT_FILE: return "FILE";
9652 case STT_COMMON: return "COMMON";
9653 case STT_TLS: return "TLS";
15ab5209
DB
9654 case STT_RELC: return "RELC";
9655 case STT_SRELC: return "SRELC";
252b5132
RH
9656 default:
9657 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9658 {
3510a7b8
NC
9659 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9660 return "THUMB_FUNC";
103f02d3 9661
351b4b40 9662 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9663 return "REGISTER";
9664
9665 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9666 return "PARISC_MILLI";
9667
e9e44622 9668 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9669 }
252b5132 9670 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9671 {
9672 if (elf_header.e_machine == EM_PARISC)
9673 {
9674 if (type == STT_HP_OPAQUE)
9675 return "HP_OPAQUE";
9676 if (type == STT_HP_STUB)
9677 return "HP_STUB";
9678 }
9679
d8045f23 9680 if (type == STT_GNU_IFUNC
9c55345c 9681 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9682 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9683 /* GNU is still using the default value 0. */
d8045f23
NC
9684 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9685 return "IFUNC";
9686
e9e44622 9687 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9688 }
252b5132 9689 else
e9e44622 9690 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9691 return buff;
9692 }
9693}
9694
d1133906 9695static const char *
d3ba0551 9696get_symbol_visibility (unsigned int visibility)
d1133906
NC
9697{
9698 switch (visibility)
9699 {
b34976b6
AM
9700 case STV_DEFAULT: return "DEFAULT";
9701 case STV_INTERNAL: return "INTERNAL";
9702 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9703 case STV_PROTECTED: return "PROTECTED";
9704 default: abort ();
9705 }
9706}
9707
5e2b0d47
NC
9708static const char *
9709get_mips_symbol_other (unsigned int other)
9710{
9711 switch (other)
9712 {
df58fc94
RS
9713 case STO_OPTIONAL:
9714 return "OPTIONAL";
9715 case STO_MIPS_PLT:
9716 return "MIPS PLT";
9717 case STO_MIPS_PIC:
9718 return "MIPS PIC";
9719 case STO_MICROMIPS:
9720 return "MICROMIPS";
9721 case STO_MICROMIPS | STO_MIPS_PIC:
9722 return "MICROMIPS, MIPS PIC";
9723 case STO_MIPS16:
9724 return "MIPS16";
9725 default:
9726 return NULL;
5e2b0d47
NC
9727 }
9728}
9729
28f997cf
TG
9730static const char *
9731get_ia64_symbol_other (unsigned int other)
9732{
9733 if (is_ia64_vms ())
9734 {
9735 static char res[32];
9736
9737 res[0] = 0;
9738
9739 /* Function types is for images and .STB files only. */
9740 switch (elf_header.e_type)
9741 {
9742 case ET_DYN:
9743 case ET_EXEC:
9744 switch (VMS_ST_FUNC_TYPE (other))
9745 {
9746 case VMS_SFT_CODE_ADDR:
9747 strcat (res, " CA");
9748 break;
9749 case VMS_SFT_SYMV_IDX:
9750 strcat (res, " VEC");
9751 break;
9752 case VMS_SFT_FD:
9753 strcat (res, " FD");
9754 break;
9755 case VMS_SFT_RESERVE:
9756 strcat (res, " RSV");
9757 break;
9758 default:
9759 abort ();
9760 }
9761 break;
9762 default:
9763 break;
9764 }
9765 switch (VMS_ST_LINKAGE (other))
9766 {
9767 case VMS_STL_IGNORE:
9768 strcat (res, " IGN");
9769 break;
9770 case VMS_STL_RESERVE:
9771 strcat (res, " RSV");
9772 break;
9773 case VMS_STL_STD:
9774 strcat (res, " STD");
9775 break;
9776 case VMS_STL_LNK:
9777 strcat (res, " LNK");
9778 break;
9779 default:
9780 abort ();
9781 }
9782
9783 if (res[0] != 0)
9784 return res + 1;
9785 else
9786 return res;
9787 }
9788 return NULL;
9789}
9790
6911b7dc
AM
9791static const char *
9792get_ppc64_symbol_other (unsigned int other)
9793{
9794 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9795 {
9796 static char buf[32];
9797 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9798 PPC64_LOCAL_ENTRY_OFFSET (other));
9799 return buf;
9800 }
9801 return NULL;
9802}
9803
5e2b0d47
NC
9804static const char *
9805get_symbol_other (unsigned int other)
9806{
9807 const char * result = NULL;
9808 static char buff [32];
9809
9810 if (other == 0)
9811 return "";
9812
9813 switch (elf_header.e_machine)
9814 {
9815 case EM_MIPS:
9816 result = get_mips_symbol_other (other);
28f997cf
TG
9817 break;
9818 case EM_IA_64:
9819 result = get_ia64_symbol_other (other);
9820 break;
6911b7dc
AM
9821 case EM_PPC64:
9822 result = get_ppc64_symbol_other (other);
9823 break;
5e2b0d47
NC
9824 default:
9825 break;
9826 }
9827
9828 if (result)
9829 return result;
9830
9831 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9832 return buff;
9833}
9834
d1133906 9835static const char *
d3ba0551 9836get_symbol_index_type (unsigned int type)
252b5132 9837{
b34976b6 9838 static char buff[32];
5cf1065c 9839
252b5132
RH
9840 switch (type)
9841 {
b34976b6
AM
9842 case SHN_UNDEF: return "UND";
9843 case SHN_ABS: return "ABS";
9844 case SHN_COMMON: return "COM";
252b5132 9845 default:
9ce701e2
L
9846 if (type == SHN_IA_64_ANSI_COMMON
9847 && elf_header.e_machine == EM_IA_64
9848 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9849 return "ANSI_COM";
8a9036a4 9850 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9851 || elf_header.e_machine == EM_L1OM
9852 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9853 && type == SHN_X86_64_LCOMMON)
9854 return "LARGE_COM";
ac145307
BS
9855 else if ((type == SHN_MIPS_SCOMMON
9856 && elf_header.e_machine == EM_MIPS)
9857 || (type == SHN_TIC6X_SCOMMON
9858 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9859 return "SCOM";
9860 else if (type == SHN_MIPS_SUNDEFINED
9861 && elf_header.e_machine == EM_MIPS)
9862 return "SUND";
9ce701e2 9863 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9864 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9865 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9866 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9867 else if (type >= SHN_LORESERVE)
9868 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 9869 else if (type >= elf_header.e_shnum)
e0a31db1 9870 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 9871 else
232e7cb8 9872 sprintf (buff, "%3d", type);
5cf1065c 9873 break;
252b5132 9874 }
5cf1065c
NC
9875
9876 return buff;
252b5132
RH
9877}
9878
66543521 9879static bfd_vma *
8b73c356 9880get_dynamic_data (FILE * file, size_t number, unsigned int ent_size)
252b5132 9881{
2cf0635d
NC
9882 unsigned char * e_data;
9883 bfd_vma * i_data;
252b5132 9884
3102e897
NC
9885 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
9886 attempting to allocate memory when the read is bound to fail. */
9887 if (ent_size * number > current_file_size)
9888 {
9889 error (_("Invalid number of dynamic entries: %lu\n"),
9890 (unsigned long) number);
9891 return NULL;
9892 }
9893
3f5e193b 9894 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9895 if (e_data == NULL)
9896 {
8b73c356
NC
9897 error (_("Out of memory reading %lu dynamic entries\n"),
9898 (unsigned long) number);
252b5132
RH
9899 return NULL;
9900 }
9901
66543521 9902 if (fread (e_data, ent_size, number, file) != number)
252b5132 9903 {
3102e897
NC
9904 error (_("Unable to read in %lu bytes of dynamic data\n"),
9905 (unsigned long) (number * ent_size));
9906 free (e_data);
252b5132
RH
9907 return NULL;
9908 }
9909
3f5e193b 9910 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9911 if (i_data == NULL)
9912 {
8b73c356
NC
9913 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9914 (unsigned long) number);
252b5132
RH
9915 free (e_data);
9916 return NULL;
9917 }
9918
9919 while (number--)
66543521 9920 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9921
9922 free (e_data);
9923
9924 return i_data;
9925}
9926
6bd1a22c
L
9927static void
9928print_dynamic_symbol (bfd_vma si, unsigned long hn)
9929{
2cf0635d 9930 Elf_Internal_Sym * psym;
6bd1a22c
L
9931 int n;
9932
6bd1a22c
L
9933 n = print_vma (si, DEC_5);
9934 if (n < 5)
0b4362b0 9935 fputs (&" "[n], stdout);
6bd1a22c 9936 printf (" %3lu: ", hn);
e0a31db1
NC
9937
9938 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
9939 {
3102e897
NC
9940 printf (_("<No info available for dynamic symbol number %lu>\n"),
9941 (unsigned long) si);
e0a31db1
NC
9942 return;
9943 }
9944
9945 psym = dynamic_symbols + si;
6bd1a22c
L
9946 print_vma (psym->st_value, LONG_HEX);
9947 putchar (' ');
9948 print_vma (psym->st_size, DEC_5);
9949
f4be36b3
AM
9950 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9951 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9952 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9953 /* Check to see if any other bits in the st_other field are set.
9954 Note - displaying this information disrupts the layout of the
9955 table being generated, but for the moment this case is very
9956 rare. */
9957 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9958 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9959 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9960 if (VALID_DYNAMIC_NAME (psym->st_name))
9961 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9962 else
2b692964 9963 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9964 putchar ('\n');
9965}
9966
bb4d2ac2
L
9967static const char *
9968get_symbol_version_string (FILE *file, int is_dynsym,
9969 const char *strtab,
9970 unsigned long int strtab_size,
9971 unsigned int si, Elf_Internal_Sym *psym,
9972 enum versioned_symbol_info *sym_info,
9973 unsigned short *vna_other)
9974{
9975 const char *version_string = NULL;
9976
9977 if (is_dynsym
9978 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
9979 {
9980 unsigned char data[2];
9981 unsigned short vers_data;
9982 unsigned long offset;
9983 int is_nobits;
9984 int check_def;
9985
9986 offset = offset_from_vma
9987 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9988 sizeof data + si * sizeof (vers_data));
9989
9990 if (get_data (&data, file, offset + si * sizeof (vers_data),
9991 sizeof (data), 1, _("version data")) == NULL)
9992 return NULL;
9993
9994 vers_data = byte_get (data, 2);
9995
9996 is_nobits = (psym->st_shndx < elf_header.e_shnum
9997 && section_headers[psym->st_shndx].sh_type
9998 == SHT_NOBITS);
9999
10000 check_def = (psym->st_shndx != SHN_UNDEF);
10001
10002 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10003 {
10004 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10005 && (is_nobits || ! check_def))
10006 {
10007 Elf_External_Verneed evn;
10008 Elf_Internal_Verneed ivn;
10009 Elf_Internal_Vernaux ivna;
10010
10011 /* We must test both. */
10012 offset = offset_from_vma
10013 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10014 sizeof evn);
10015
10016 do
10017 {
10018 unsigned long vna_off;
10019
10020 if (get_data (&evn, file, offset, sizeof (evn), 1,
10021 _("version need")) == NULL)
10022 {
10023 ivna.vna_next = 0;
10024 ivna.vna_other = 0;
10025 ivna.vna_name = 0;
10026 break;
10027 }
10028
10029 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10030 ivn.vn_next = BYTE_GET (evn.vn_next);
10031
10032 vna_off = offset + ivn.vn_aux;
10033
10034 do
10035 {
10036 Elf_External_Vernaux evna;
10037
10038 if (get_data (&evna, file, vna_off,
10039 sizeof (evna), 1,
10040 _("version need aux (3)")) == NULL)
10041 {
10042 ivna.vna_next = 0;
10043 ivna.vna_other = 0;
10044 ivna.vna_name = 0;
10045 }
10046 else
10047 {
10048 ivna.vna_other = BYTE_GET (evna.vna_other);
10049 ivna.vna_next = BYTE_GET (evna.vna_next);
10050 ivna.vna_name = BYTE_GET (evna.vna_name);
10051 }
10052
10053 vna_off += ivna.vna_next;
10054 }
10055 while (ivna.vna_other != vers_data
10056 && ivna.vna_next != 0);
10057
10058 if (ivna.vna_other == vers_data)
10059 break;
10060
10061 offset += ivn.vn_next;
10062 }
10063 while (ivn.vn_next != 0);
10064
10065 if (ivna.vna_other == vers_data)
10066 {
10067 *sym_info = symbol_undefined;
10068 *vna_other = ivna.vna_other;
10069 version_string = (ivna.vna_name < strtab_size
10070 ? strtab + ivna.vna_name
10071 : _("<corrupt>"));
10072 check_def = 0;
10073 }
10074 else if (! is_nobits)
10075 error (_("bad dynamic symbol\n"));
10076 else
10077 check_def = 1;
10078 }
10079
10080 if (check_def)
10081 {
10082 if (vers_data != 0x8001
10083 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10084 {
10085 Elf_Internal_Verdef ivd;
10086 Elf_Internal_Verdaux ivda;
10087 Elf_External_Verdaux evda;
10088 unsigned long off;
10089
10090 off = offset_from_vma
10091 (file,
10092 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10093 sizeof (Elf_External_Verdef));
10094
10095 do
10096 {
10097 Elf_External_Verdef evd;
10098
10099 if (get_data (&evd, file, off, sizeof (evd),
10100 1, _("version def")) == NULL)
10101 {
10102 ivd.vd_ndx = 0;
10103 ivd.vd_aux = 0;
10104 ivd.vd_next = 0;
10105 }
10106 else
10107 {
10108 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10109 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10110 ivd.vd_next = BYTE_GET (evd.vd_next);
10111 }
10112
10113 off += ivd.vd_next;
10114 }
10115 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10116 && ivd.vd_next != 0);
10117
10118 off -= ivd.vd_next;
10119 off += ivd.vd_aux;
10120
10121 if (get_data (&evda, file, off, sizeof (evda),
10122 1, _("version def aux")) == NULL)
10123 return version_string;
10124
10125 ivda.vda_name = BYTE_GET (evda.vda_name);
10126
10127 if (psym->st_name != ivda.vda_name)
10128 {
10129 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10130 ? symbol_hidden : symbol_public);
10131 version_string = (ivda.vda_name < strtab_size
10132 ? strtab + ivda.vda_name
10133 : _("<corrupt>"));
10134 }
10135 }
10136 }
10137 }
10138 }
10139 return version_string;
10140}
10141
e3c8793a 10142/* Dump the symbol table. */
252b5132 10143static int
2cf0635d 10144process_symbol_table (FILE * file)
252b5132 10145{
2cf0635d 10146 Elf_Internal_Shdr * section;
8b73c356
NC
10147 bfd_size_type nbuckets = 0;
10148 bfd_size_type nchains = 0;
2cf0635d
NC
10149 bfd_vma * buckets = NULL;
10150 bfd_vma * chains = NULL;
fdc90cb4 10151 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10152 bfd_vma * gnubuckets = NULL;
10153 bfd_vma * gnuchains = NULL;
6bd1a22c 10154 bfd_vma gnusymidx = 0;
071436c6 10155 bfd_size_type ngnuchains = 0;
252b5132 10156
2c610e4b 10157 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10158 return 1;
10159
6bd1a22c
L
10160 if (dynamic_info[DT_HASH]
10161 && (do_histogram
2c610e4b
L
10162 || (do_using_dynamic
10163 && !do_dyn_syms
10164 && dynamic_strings != NULL)))
252b5132 10165 {
66543521
AM
10166 unsigned char nb[8];
10167 unsigned char nc[8];
8b73c356 10168 unsigned int hash_ent_size = 4;
66543521
AM
10169
10170 if ((elf_header.e_machine == EM_ALPHA
10171 || elf_header.e_machine == EM_S390
10172 || elf_header.e_machine == EM_S390_OLD)
10173 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10174 hash_ent_size = 8;
10175
fb52b2f4
NC
10176 if (fseek (file,
10177 (archive_file_offset
10178 + offset_from_vma (file, dynamic_info[DT_HASH],
10179 sizeof nb + sizeof nc)),
d93f0186 10180 SEEK_SET))
252b5132 10181 {
591a748a 10182 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10183 goto no_hash;
252b5132
RH
10184 }
10185
66543521 10186 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10187 {
10188 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10189 goto no_hash;
252b5132
RH
10190 }
10191
66543521 10192 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10193 {
10194 error (_("Failed to read in number of chains\n"));
d3a44ec6 10195 goto no_hash;
252b5132
RH
10196 }
10197
66543521
AM
10198 nbuckets = byte_get (nb, hash_ent_size);
10199 nchains = byte_get (nc, hash_ent_size);
252b5132 10200
66543521
AM
10201 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10202 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10203
d3a44ec6 10204 no_hash:
252b5132 10205 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10206 {
10207 if (do_using_dynamic)
10208 return 0;
10209 free (buckets);
10210 free (chains);
10211 buckets = NULL;
10212 chains = NULL;
10213 nbuckets = 0;
10214 nchains = 0;
10215 }
252b5132
RH
10216 }
10217
6bd1a22c
L
10218 if (dynamic_info_DT_GNU_HASH
10219 && (do_histogram
2c610e4b
L
10220 || (do_using_dynamic
10221 && !do_dyn_syms
10222 && dynamic_strings != NULL)))
252b5132 10223 {
6bd1a22c
L
10224 unsigned char nb[16];
10225 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10226 bfd_vma buckets_vma;
10227
10228 if (fseek (file,
10229 (archive_file_offset
10230 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10231 sizeof nb)),
10232 SEEK_SET))
10233 {
10234 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10235 goto no_gnu_hash;
6bd1a22c 10236 }
252b5132 10237
6bd1a22c
L
10238 if (fread (nb, 16, 1, file) != 1)
10239 {
10240 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10241 goto no_gnu_hash;
6bd1a22c
L
10242 }
10243
10244 ngnubuckets = byte_get (nb, 4);
10245 gnusymidx = byte_get (nb + 4, 4);
10246 bitmaskwords = byte_get (nb + 8, 4);
10247 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10248 if (is_32bit_elf)
6bd1a22c 10249 buckets_vma += bitmaskwords * 4;
f7a99963 10250 else
6bd1a22c 10251 buckets_vma += bitmaskwords * 8;
252b5132 10252
6bd1a22c
L
10253 if (fseek (file,
10254 (archive_file_offset
10255 + offset_from_vma (file, buckets_vma, 4)),
10256 SEEK_SET))
252b5132 10257 {
6bd1a22c 10258 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10259 goto no_gnu_hash;
6bd1a22c
L
10260 }
10261
10262 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10263
6bd1a22c 10264 if (gnubuckets == NULL)
d3a44ec6 10265 goto no_gnu_hash;
6bd1a22c
L
10266
10267 for (i = 0; i < ngnubuckets; i++)
10268 if (gnubuckets[i] != 0)
10269 {
10270 if (gnubuckets[i] < gnusymidx)
10271 return 0;
10272
10273 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10274 maxchain = gnubuckets[i];
10275 }
10276
10277 if (maxchain == 0xffffffff)
d3a44ec6 10278 goto no_gnu_hash;
6bd1a22c
L
10279
10280 maxchain -= gnusymidx;
10281
10282 if (fseek (file,
10283 (archive_file_offset
10284 + offset_from_vma (file, buckets_vma
10285 + 4 * (ngnubuckets + maxchain), 4)),
10286 SEEK_SET))
10287 {
10288 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10289 goto no_gnu_hash;
6bd1a22c
L
10290 }
10291
10292 do
10293 {
10294 if (fread (nb, 4, 1, file) != 1)
252b5132 10295 {
6bd1a22c 10296 error (_("Failed to determine last chain length\n"));
d3a44ec6 10297 goto no_gnu_hash;
6bd1a22c 10298 }
252b5132 10299
6bd1a22c 10300 if (maxchain + 1 == 0)
d3a44ec6 10301 goto no_gnu_hash;
252b5132 10302
6bd1a22c
L
10303 ++maxchain;
10304 }
10305 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10306
6bd1a22c
L
10307 if (fseek (file,
10308 (archive_file_offset
10309 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10310 SEEK_SET))
10311 {
10312 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10313 goto no_gnu_hash;
6bd1a22c
L
10314 }
10315
10316 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10317 ngnuchains = maxchain;
6bd1a22c 10318
d3a44ec6 10319 no_gnu_hash:
6bd1a22c 10320 if (gnuchains == NULL)
d3a44ec6
JJ
10321 {
10322 free (gnubuckets);
d3a44ec6
JJ
10323 gnubuckets = NULL;
10324 ngnubuckets = 0;
f64fddf1
NC
10325 if (do_using_dynamic)
10326 return 0;
d3a44ec6 10327 }
6bd1a22c
L
10328 }
10329
10330 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10331 && do_syms
10332 && do_using_dynamic
3102e897
NC
10333 && dynamic_strings != NULL
10334 && dynamic_symbols != NULL)
6bd1a22c
L
10335 {
10336 unsigned long hn;
10337
10338 if (dynamic_info[DT_HASH])
10339 {
10340 bfd_vma si;
10341
10342 printf (_("\nSymbol table for image:\n"));
10343 if (is_32bit_elf)
10344 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10345 else
10346 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10347
10348 for (hn = 0; hn < nbuckets; hn++)
10349 {
10350 if (! buckets[hn])
10351 continue;
10352
10353 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10354 print_dynamic_symbol (si, hn);
252b5132
RH
10355 }
10356 }
6bd1a22c
L
10357
10358 if (dynamic_info_DT_GNU_HASH)
10359 {
10360 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10361 if (is_32bit_elf)
10362 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10363 else
10364 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10365
10366 for (hn = 0; hn < ngnubuckets; ++hn)
10367 if (gnubuckets[hn] != 0)
10368 {
10369 bfd_vma si = gnubuckets[hn];
10370 bfd_vma off = si - gnusymidx;
10371
10372 do
10373 {
10374 print_dynamic_symbol (si, hn);
10375 si++;
10376 }
071436c6 10377 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10378 }
10379 }
252b5132 10380 }
8b73c356
NC
10381 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10382 && section_headers != NULL)
252b5132 10383 {
b34976b6 10384 unsigned int i;
252b5132
RH
10385
10386 for (i = 0, section = section_headers;
10387 i < elf_header.e_shnum;
10388 i++, section++)
10389 {
b34976b6 10390 unsigned int si;
2cf0635d 10391 char * strtab = NULL;
c256ffe7 10392 unsigned long int strtab_size = 0;
2cf0635d
NC
10393 Elf_Internal_Sym * symtab;
10394 Elf_Internal_Sym * psym;
ba5cdace 10395 unsigned long num_syms;
252b5132 10396
2c610e4b
L
10397 if ((section->sh_type != SHT_SYMTAB
10398 && section->sh_type != SHT_DYNSYM)
10399 || (!do_syms
10400 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10401 continue;
10402
dd24e3da
NC
10403 if (section->sh_entsize == 0)
10404 {
10405 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10406 printable_section_name (section));
dd24e3da
NC
10407 continue;
10408 }
10409
252b5132 10410 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10411 printable_section_name (section),
252b5132 10412 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10413
f7a99963 10414 if (is_32bit_elf)
ca47b30c 10415 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10416 else
ca47b30c 10417 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10418
ba5cdace 10419 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10420 if (symtab == NULL)
10421 continue;
10422
10423 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10424 {
10425 strtab = string_table;
10426 strtab_size = string_table_length;
10427 }
4fbb74a6 10428 else if (section->sh_link < elf_header.e_shnum)
252b5132 10429 {
2cf0635d 10430 Elf_Internal_Shdr * string_sec;
252b5132 10431
4fbb74a6 10432 string_sec = section_headers + section->sh_link;
252b5132 10433
3f5e193b
NC
10434 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10435 1, string_sec->sh_size,
10436 _("string table"));
c256ffe7 10437 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10438 }
10439
ba5cdace 10440 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10441 {
bb4d2ac2
L
10442 const char *version_string;
10443 enum versioned_symbol_info sym_info;
10444 unsigned short vna_other;
10445
5e220199 10446 printf ("%6d: ", si);
f7a99963
NC
10447 print_vma (psym->st_value, LONG_HEX);
10448 putchar (' ');
10449 print_vma (psym->st_size, DEC_5);
d1133906
NC
10450 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10451 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10452 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10453 /* Check to see if any other bits in the st_other field are set.
10454 Note - displaying this information disrupts the layout of the
10455 table being generated, but for the moment this case is very rare. */
10456 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10457 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10458 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10459 print_symbol (25, psym->st_name < strtab_size
2b692964 10460 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10461
bb4d2ac2
L
10462 version_string
10463 = get_symbol_version_string (file,
10464 section->sh_type == SHT_DYNSYM,
10465 strtab, strtab_size, si,
10466 psym, &sym_info, &vna_other);
10467 if (version_string)
252b5132 10468 {
bb4d2ac2
L
10469 if (sym_info == symbol_undefined)
10470 printf ("@%s (%d)", version_string, vna_other);
10471 else
10472 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10473 version_string);
252b5132
RH
10474 }
10475
10476 putchar ('\n');
10477 }
10478
10479 free (symtab);
10480 if (strtab != string_table)
10481 free (strtab);
10482 }
10483 }
10484 else if (do_syms)
10485 printf
10486 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10487
10488 if (do_histogram && buckets != NULL)
10489 {
2cf0635d
NC
10490 unsigned long * lengths;
10491 unsigned long * counts;
66543521
AM
10492 unsigned long hn;
10493 bfd_vma si;
10494 unsigned long maxlength = 0;
10495 unsigned long nzero_counts = 0;
10496 unsigned long nsyms = 0;
252b5132 10497
66543521
AM
10498 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10499 (unsigned long) nbuckets);
252b5132 10500
3f5e193b 10501 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10502 if (lengths == NULL)
10503 {
8b73c356 10504 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10505 return 0;
10506 }
8b73c356
NC
10507
10508 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10509 for (hn = 0; hn < nbuckets; ++hn)
10510 {
f7a99963 10511 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10512 {
b34976b6 10513 ++nsyms;
252b5132 10514 if (maxlength < ++lengths[hn])
b34976b6 10515 ++maxlength;
049b0c3a
NC
10516
10517 /* PR binutils/17531: A corrupt binary could contain broken
10518 histogram data. Do not go into an infinite loop trying
10519 to process it. */
10520 if (chains[si] == si)
10521 {
10522 error (_("histogram chain links to itself\n"));
10523 break;
10524 }
252b5132
RH
10525 }
10526 }
10527
3f5e193b 10528 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10529 if (counts == NULL)
10530 {
b2e951ec 10531 free (lengths);
8b73c356 10532 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10533 return 0;
10534 }
10535
10536 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10537 ++counts[lengths[hn]];
252b5132 10538
103f02d3 10539 if (nbuckets > 0)
252b5132 10540 {
66543521
AM
10541 unsigned long i;
10542 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10543 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10544 for (i = 1; i <= maxlength; ++i)
103f02d3 10545 {
66543521
AM
10546 nzero_counts += counts[i] * i;
10547 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10548 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10549 (nzero_counts * 100.0) / nsyms);
10550 }
252b5132
RH
10551 }
10552
10553 free (counts);
10554 free (lengths);
10555 }
10556
10557 if (buckets != NULL)
10558 {
10559 free (buckets);
10560 free (chains);
10561 }
10562
d3a44ec6 10563 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10564 {
2cf0635d
NC
10565 unsigned long * lengths;
10566 unsigned long * counts;
fdc90cb4
JJ
10567 unsigned long hn;
10568 unsigned long maxlength = 0;
10569 unsigned long nzero_counts = 0;
10570 unsigned long nsyms = 0;
fdc90cb4 10571
8b73c356
NC
10572 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10573 (unsigned long) ngnubuckets);
10574
3f5e193b 10575 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10576 if (lengths == NULL)
10577 {
8b73c356 10578 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10579 return 0;
10580 }
10581
fdc90cb4
JJ
10582 printf (_(" Length Number %% of total Coverage\n"));
10583
10584 for (hn = 0; hn < ngnubuckets; ++hn)
10585 if (gnubuckets[hn] != 0)
10586 {
10587 bfd_vma off, length = 1;
10588
6bd1a22c 10589 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10590 /* PR 17531 file: 010-77222-0.004. */
10591 off < ngnuchains && (gnuchains[off] & 1) == 0;
10592 ++off)
fdc90cb4
JJ
10593 ++length;
10594 lengths[hn] = length;
10595 if (length > maxlength)
10596 maxlength = length;
10597 nsyms += length;
10598 }
10599
3f5e193b 10600 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10601 if (counts == NULL)
10602 {
b2e951ec 10603 free (lengths);
8b73c356 10604 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10605 return 0;
10606 }
10607
10608 for (hn = 0; hn < ngnubuckets; ++hn)
10609 ++counts[lengths[hn]];
10610
10611 if (ngnubuckets > 0)
10612 {
10613 unsigned long j;
10614 printf (" 0 %-10lu (%5.1f%%)\n",
10615 counts[0], (counts[0] * 100.0) / ngnubuckets);
10616 for (j = 1; j <= maxlength; ++j)
10617 {
10618 nzero_counts += counts[j] * j;
10619 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10620 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10621 (nzero_counts * 100.0) / nsyms);
10622 }
10623 }
10624
10625 free (counts);
10626 free (lengths);
10627 free (gnubuckets);
10628 free (gnuchains);
10629 }
10630
252b5132
RH
10631 return 1;
10632}
10633
10634static int
2cf0635d 10635process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10636{
b4c96d0d 10637 unsigned int i;
252b5132
RH
10638
10639 if (dynamic_syminfo == NULL
10640 || !do_dynamic)
10641 /* No syminfo, this is ok. */
10642 return 1;
10643
10644 /* There better should be a dynamic symbol section. */
10645 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10646 return 0;
10647
10648 if (dynamic_addr)
10649 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10650 dynamic_syminfo_offset, dynamic_syminfo_nent);
10651
10652 printf (_(" Num: Name BoundTo Flags\n"));
10653 for (i = 0; i < dynamic_syminfo_nent; ++i)
10654 {
10655 unsigned short int flags = dynamic_syminfo[i].si_flags;
10656
31104126 10657 printf ("%4d: ", i);
4082ef84
NC
10658 if (i >= num_dynamic_syms)
10659 printf (_("<corrupt index>"));
10660 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10661 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10662 else
2b692964 10663 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10664 putchar (' ');
252b5132
RH
10665
10666 switch (dynamic_syminfo[i].si_boundto)
10667 {
10668 case SYMINFO_BT_SELF:
10669 fputs ("SELF ", stdout);
10670 break;
10671 case SYMINFO_BT_PARENT:
10672 fputs ("PARENT ", stdout);
10673 break;
10674 default:
10675 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10676 && dynamic_syminfo[i].si_boundto < dynamic_nent
10677 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10678 {
d79b3d50 10679 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10680 putchar (' ' );
10681 }
252b5132
RH
10682 else
10683 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10684 break;
10685 }
10686
10687 if (flags & SYMINFO_FLG_DIRECT)
10688 printf (" DIRECT");
10689 if (flags & SYMINFO_FLG_PASSTHRU)
10690 printf (" PASSTHRU");
10691 if (flags & SYMINFO_FLG_COPY)
10692 printf (" COPY");
10693 if (flags & SYMINFO_FLG_LAZYLOAD)
10694 printf (" LAZYLOAD");
10695
10696 puts ("");
10697 }
10698
10699 return 1;
10700}
10701
cf13d699
NC
10702/* Check to see if the given reloc needs to be handled in a target specific
10703 manner. If so then process the reloc and return TRUE otherwise return
10704 FALSE. */
09c11c86 10705
cf13d699
NC
10706static bfd_boolean
10707target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10708 unsigned char * start,
10709 Elf_Internal_Sym * symtab)
252b5132 10710{
cf13d699 10711 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10712
cf13d699 10713 switch (elf_header.e_machine)
252b5132 10714 {
13761a11
NC
10715 case EM_MSP430:
10716 case EM_MSP430_OLD:
10717 {
10718 static Elf_Internal_Sym * saved_sym = NULL;
10719
10720 switch (reloc_type)
10721 {
10722 case 10: /* R_MSP430_SYM_DIFF */
10723 if (uses_msp430x_relocs ())
10724 break;
10725 case 21: /* R_MSP430X_SYM_DIFF */
10726 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10727 return TRUE;
10728
10729 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10730 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10731 goto handle_sym_diff;
0b4362b0 10732
13761a11
NC
10733 case 5: /* R_MSP430_16_BYTE */
10734 case 9: /* R_MSP430_8 */
10735 if (uses_msp430x_relocs ())
10736 break;
10737 goto handle_sym_diff;
10738
10739 case 2: /* R_MSP430_ABS16 */
10740 case 15: /* R_MSP430X_ABS16 */
10741 if (! uses_msp430x_relocs ())
10742 break;
10743 goto handle_sym_diff;
0b4362b0 10744
13761a11
NC
10745 handle_sym_diff:
10746 if (saved_sym != NULL)
10747 {
10748 bfd_vma value;
10749
10750 value = reloc->r_addend
10751 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10752 - saved_sym->st_value);
10753
10754 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10755
10756 saved_sym = NULL;
10757 return TRUE;
10758 }
10759 break;
10760
10761 default:
10762 if (saved_sym != NULL)
071436c6 10763 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
10764 break;
10765 }
10766 break;
10767 }
10768
cf13d699
NC
10769 case EM_MN10300:
10770 case EM_CYGNUS_MN10300:
10771 {
10772 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10773
cf13d699
NC
10774 switch (reloc_type)
10775 {
10776 case 34: /* R_MN10300_ALIGN */
10777 return TRUE;
10778 case 33: /* R_MN10300_SYM_DIFF */
10779 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10780 return TRUE;
10781 case 1: /* R_MN10300_32 */
10782 case 2: /* R_MN10300_16 */
10783 if (saved_sym != NULL)
10784 {
10785 bfd_vma value;
252b5132 10786
cf13d699
NC
10787 value = reloc->r_addend
10788 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10789 - saved_sym->st_value);
252b5132 10790
cf13d699 10791 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10792
cf13d699
NC
10793 saved_sym = NULL;
10794 return TRUE;
10795 }
10796 break;
10797 default:
10798 if (saved_sym != NULL)
071436c6 10799 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
10800 break;
10801 }
10802 break;
10803 }
252b5132
RH
10804 }
10805
cf13d699 10806 return FALSE;
252b5132
RH
10807}
10808
aca88567
NC
10809/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10810 DWARF debug sections. This is a target specific test. Note - we do not
10811 go through the whole including-target-headers-multiple-times route, (as
10812 we have already done with <elf/h8.h>) because this would become very
10813 messy and even then this function would have to contain target specific
10814 information (the names of the relocs instead of their numeric values).
10815 FIXME: This is not the correct way to solve this problem. The proper way
10816 is to have target specific reloc sizing and typing functions created by
10817 the reloc-macros.h header, in the same way that it already creates the
10818 reloc naming functions. */
10819
10820static bfd_boolean
10821is_32bit_abs_reloc (unsigned int reloc_type)
10822{
10823 switch (elf_header.e_machine)
10824 {
41e92641
NC
10825 case EM_386:
10826 case EM_486:
10827 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10828 case EM_68K:
10829 return reloc_type == 1; /* R_68K_32. */
10830 case EM_860:
10831 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10832 case EM_960:
10833 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10834 case EM_AARCH64:
10835 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10836 case EM_ALPHA:
137b6b5f 10837 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10838 case EM_ARC:
10839 return reloc_type == 1; /* R_ARC_32. */
10840 case EM_ARM:
10841 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10842 case EM_AVR_OLD:
aca88567
NC
10843 case EM_AVR:
10844 return reloc_type == 1;
cfb8c092
NC
10845 case EM_ADAPTEVA_EPIPHANY:
10846 return reloc_type == 3;
aca88567
NC
10847 case EM_BLACKFIN:
10848 return reloc_type == 0x12; /* R_byte4_data. */
10849 case EM_CRIS:
10850 return reloc_type == 3; /* R_CRIS_32. */
10851 case EM_CR16:
10852 return reloc_type == 3; /* R_CR16_NUM32. */
10853 case EM_CRX:
10854 return reloc_type == 15; /* R_CRX_NUM32. */
10855 case EM_CYGNUS_FRV:
10856 return reloc_type == 1;
41e92641
NC
10857 case EM_CYGNUS_D10V:
10858 case EM_D10V:
10859 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10860 case EM_CYGNUS_D30V:
10861 case EM_D30V:
10862 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10863 case EM_DLX:
10864 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10865 case EM_CYGNUS_FR30:
10866 case EM_FR30:
10867 return reloc_type == 3; /* R_FR30_32. */
10868 case EM_H8S:
10869 case EM_H8_300:
10870 case EM_H8_300H:
10871 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10872 case EM_IA_64:
10873 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10874 case EM_IP2K_OLD:
10875 case EM_IP2K:
10876 return reloc_type == 2; /* R_IP2K_32. */
10877 case EM_IQ2000:
10878 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10879 case EM_LATTICEMICO32:
10880 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10881 case EM_M32C_OLD:
aca88567
NC
10882 case EM_M32C:
10883 return reloc_type == 3; /* R_M32C_32. */
10884 case EM_M32R:
10885 return reloc_type == 34; /* R_M32R_32_RELA. */
10886 case EM_MCORE:
10887 return reloc_type == 1; /* R_MCORE_ADDR32. */
10888 case EM_CYGNUS_MEP:
10889 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10890 case EM_METAG:
10891 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10892 case EM_MICROBLAZE:
10893 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10894 case EM_MIPS:
10895 return reloc_type == 2; /* R_MIPS_32. */
10896 case EM_MMIX:
10897 return reloc_type == 4; /* R_MMIX_32. */
10898 case EM_CYGNUS_MN10200:
10899 case EM_MN10200:
10900 return reloc_type == 1; /* R_MN10200_32. */
10901 case EM_CYGNUS_MN10300:
10902 case EM_MN10300:
10903 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10904 case EM_MOXIE:
10905 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10906 case EM_MSP430_OLD:
10907 case EM_MSP430:
13761a11 10908 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10909 case EM_MT:
10910 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
10911 case EM_NDS32:
10912 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 10913 case EM_ALTERA_NIOS2:
36591ba1 10914 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10915 case EM_NIOS32:
10916 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
10917 case EM_OR1K:
10918 return reloc_type == 1; /* R_OR1K_32. */
aca88567 10919 case EM_PARISC:
5fda8eca
NC
10920 return (reloc_type == 1 /* R_PARISC_DIR32. */
10921 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10922 case EM_PJ:
10923 case EM_PJ_OLD:
10924 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10925 case EM_PPC64:
10926 return reloc_type == 1; /* R_PPC64_ADDR32. */
10927 case EM_PPC:
10928 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10929 case EM_RL78:
10930 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10931 case EM_RX:
10932 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10933 case EM_S370:
10934 return reloc_type == 1; /* R_I370_ADDR31. */
10935 case EM_S390_OLD:
10936 case EM_S390:
10937 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10938 case EM_SCORE:
10939 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10940 case EM_SH:
10941 return reloc_type == 1; /* R_SH_DIR32. */
10942 case EM_SPARC32PLUS:
10943 case EM_SPARCV9:
10944 case EM_SPARC:
10945 return reloc_type == 3 /* R_SPARC_32. */
10946 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10947 case EM_SPU:
10948 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10949 case EM_TI_C6000:
10950 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10951 case EM_TILEGX:
10952 return reloc_type == 2; /* R_TILEGX_32. */
10953 case EM_TILEPRO:
10954 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10955 case EM_CYGNUS_V850:
10956 case EM_V850:
10957 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10958 case EM_V800:
10959 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10960 case EM_VAX:
10961 return reloc_type == 1; /* R_VAX_32. */
10962 case EM_X86_64:
8a9036a4 10963 case EM_L1OM:
7a9068fe 10964 case EM_K1OM:
aca88567 10965 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10966 case EM_XC16X:
10967 case EM_C166:
10968 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10969 case EM_XGATE:
10970 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10971 case EM_XSTORMY16:
10972 return reloc_type == 1; /* R_XSTROMY16_32. */
10973 case EM_XTENSA_OLD:
10974 case EM_XTENSA:
10975 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10976 default:
10977 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10978 elf_header.e_machine);
10979 abort ();
10980 }
10981}
10982
10983/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10984 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10985
10986static bfd_boolean
10987is_32bit_pcrel_reloc (unsigned int reloc_type)
10988{
10989 switch (elf_header.e_machine)
10990 {
41e92641
NC
10991 case EM_386:
10992 case EM_486:
3e0873ac 10993 return reloc_type == 2; /* R_386_PC32. */
aca88567 10994 case EM_68K:
3e0873ac 10995 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10996 case EM_AARCH64:
10997 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10998 case EM_ADAPTEVA_EPIPHANY:
10999 return reloc_type == 6;
aca88567
NC
11000 case EM_ALPHA:
11001 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11002 case EM_ARM:
3e0873ac 11003 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11004 case EM_MICROBLAZE:
11005 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11006 case EM_OR1K:
11007 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11008 case EM_PARISC:
85acf597 11009 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11010 case EM_PPC:
11011 return reloc_type == 26; /* R_PPC_REL32. */
11012 case EM_PPC64:
3e0873ac 11013 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11014 case EM_S390_OLD:
11015 case EM_S390:
3e0873ac 11016 return reloc_type == 5; /* R_390_PC32. */
aca88567 11017 case EM_SH:
3e0873ac 11018 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11019 case EM_SPARC32PLUS:
11020 case EM_SPARCV9:
11021 case EM_SPARC:
3e0873ac 11022 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11023 case EM_SPU:
11024 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11025 case EM_TILEGX:
11026 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11027 case EM_TILEPRO:
11028 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 11029 case EM_X86_64:
8a9036a4 11030 case EM_L1OM:
7a9068fe 11031 case EM_K1OM:
3e0873ac 11032 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11033 case EM_XTENSA_OLD:
11034 case EM_XTENSA:
11035 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11036 default:
11037 /* Do not abort or issue an error message here. Not all targets use
11038 pc-relative 32-bit relocs in their DWARF debug information and we
11039 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11040 more helpful warning message will be generated by apply_relocations
11041 anyway, so just return. */
aca88567
NC
11042 return FALSE;
11043 }
11044}
11045
11046/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11047 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11048
11049static bfd_boolean
11050is_64bit_abs_reloc (unsigned int reloc_type)
11051{
11052 switch (elf_header.e_machine)
11053 {
a06ea964
NC
11054 case EM_AARCH64:
11055 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11056 case EM_ALPHA:
11057 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11058 case EM_IA_64:
11059 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11060 case EM_PARISC:
11061 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11062 case EM_PPC64:
11063 return reloc_type == 38; /* R_PPC64_ADDR64. */
11064 case EM_SPARC32PLUS:
11065 case EM_SPARCV9:
11066 case EM_SPARC:
11067 return reloc_type == 54; /* R_SPARC_UA64. */
11068 case EM_X86_64:
8a9036a4 11069 case EM_L1OM:
7a9068fe 11070 case EM_K1OM:
aca88567 11071 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11072 case EM_S390_OLD:
11073 case EM_S390:
aa137e4d
NC
11074 return reloc_type == 22; /* R_S390_64. */
11075 case EM_TILEGX:
11076 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11077 case EM_MIPS:
aa137e4d 11078 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11079 default:
11080 return FALSE;
11081 }
11082}
11083
85acf597
RH
11084/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11085 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11086
11087static bfd_boolean
11088is_64bit_pcrel_reloc (unsigned int reloc_type)
11089{
11090 switch (elf_header.e_machine)
11091 {
a06ea964
NC
11092 case EM_AARCH64:
11093 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11094 case EM_ALPHA:
aa137e4d 11095 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11096 case EM_IA_64:
aa137e4d 11097 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11098 case EM_PARISC:
aa137e4d 11099 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11100 case EM_PPC64:
aa137e4d 11101 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11102 case EM_SPARC32PLUS:
11103 case EM_SPARCV9:
11104 case EM_SPARC:
aa137e4d 11105 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11106 case EM_X86_64:
8a9036a4 11107 case EM_L1OM:
7a9068fe 11108 case EM_K1OM:
aa137e4d 11109 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11110 case EM_S390_OLD:
11111 case EM_S390:
aa137e4d
NC
11112 return reloc_type == 23; /* R_S390_PC64. */
11113 case EM_TILEGX:
11114 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11115 default:
11116 return FALSE;
11117 }
11118}
11119
4dc3c23d
AM
11120/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11121 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11122
11123static bfd_boolean
11124is_24bit_abs_reloc (unsigned int reloc_type)
11125{
11126 switch (elf_header.e_machine)
11127 {
11128 case EM_CYGNUS_MN10200:
11129 case EM_MN10200:
11130 return reloc_type == 4; /* R_MN10200_24. */
11131 default:
11132 return FALSE;
11133 }
11134}
11135
aca88567
NC
11136/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11137 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11138
11139static bfd_boolean
11140is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11141{
11142 switch (elf_header.e_machine)
11143 {
aca88567
NC
11144 case EM_AVR_OLD:
11145 case EM_AVR:
11146 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11147 case EM_ADAPTEVA_EPIPHANY:
11148 return reloc_type == 5;
41e92641
NC
11149 case EM_CYGNUS_D10V:
11150 case EM_D10V:
11151 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11152 case EM_H8S:
11153 case EM_H8_300:
11154 case EM_H8_300H:
aca88567
NC
11155 return reloc_type == R_H8_DIR16;
11156 case EM_IP2K_OLD:
11157 case EM_IP2K:
11158 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11159 case EM_M32C_OLD:
f4236fe4
DD
11160 case EM_M32C:
11161 return reloc_type == 1; /* R_M32C_16 */
aca88567 11162 case EM_MSP430:
13761a11
NC
11163 if (uses_msp430x_relocs ())
11164 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11165 case EM_MSP430_OLD:
aca88567 11166 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11167 case EM_NDS32:
11168 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11169 case EM_ALTERA_NIOS2:
36591ba1 11170 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11171 case EM_NIOS32:
11172 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11173 case EM_OR1K:
11174 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11175 case EM_TI_C6000:
11176 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11177 case EM_XC16X:
11178 case EM_C166:
11179 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11180 case EM_CYGNUS_MN10200:
11181 case EM_MN10200:
11182 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11183 case EM_CYGNUS_MN10300:
11184 case EM_MN10300:
11185 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
11186 case EM_XGATE:
11187 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11188 default:
aca88567 11189 return FALSE;
4b78141a
NC
11190 }
11191}
11192
2a7b2e88
JK
11193/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11194 relocation entries (possibly formerly used for SHT_GROUP sections). */
11195
11196static bfd_boolean
11197is_none_reloc (unsigned int reloc_type)
11198{
11199 switch (elf_header.e_machine)
11200 {
cb8f3167
NC
11201 case EM_68K: /* R_68K_NONE. */
11202 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11203 case EM_SPARC32PLUS:
11204 case EM_SPARCV9:
cb8f3167
NC
11205 case EM_SPARC: /* R_SPARC_NONE. */
11206 case EM_MIPS: /* R_MIPS_NONE. */
11207 case EM_PARISC: /* R_PARISC_NONE. */
11208 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11209 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11210 case EM_PPC: /* R_PPC_NONE. */
11211 case EM_PPC64: /* R_PPC64_NONE. */
11212 case EM_ARM: /* R_ARM_NONE. */
11213 case EM_IA_64: /* R_IA64_NONE. */
11214 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11215 case EM_S390_OLD:
cb8f3167
NC
11216 case EM_S390: /* R_390_NONE. */
11217 case EM_CRIS: /* R_CRIS_NONE. */
11218 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11219 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11220 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11221 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 11222 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11223 case EM_M32R: /* R_M32R_NONE. */
40b36596 11224 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11225 case EM_TILEGX: /* R_TILEGX_NONE. */
11226 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11227 case EM_XC16X:
11228 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11229 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11230 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11231 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11232 return reloc_type == 0;
a06ea964
NC
11233 case EM_AARCH64:
11234 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11235 case EM_NDS32:
11236 return (reloc_type == 0 /* R_XTENSA_NONE. */
11237 || reloc_type == 204 /* R_NDS32_DIFF8. */
11238 || reloc_type == 205 /* R_NDS32_DIFF16. */
11239 || reloc_type == 206 /* R_NDS32_DIFF32. */
11240 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11241 case EM_XTENSA_OLD:
11242 case EM_XTENSA:
4dc3c23d
AM
11243 return (reloc_type == 0 /* R_XTENSA_NONE. */
11244 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11245 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11246 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11247 case EM_METAG:
11248 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11249 }
11250 return FALSE;
11251}
11252
cf13d699
NC
11253/* Apply relocations to a section.
11254 Note: So far support has been added only for those relocations
11255 which can be found in debug sections.
11256 FIXME: Add support for more relocations ? */
1b315056 11257
cf13d699
NC
11258static void
11259apply_relocations (void * file,
11260 Elf_Internal_Shdr * section,
11261 unsigned char * start)
1b315056 11262{
cf13d699
NC
11263 Elf_Internal_Shdr * relsec;
11264 unsigned char * end = start + section->sh_size;
cb8f3167 11265
cf13d699
NC
11266 if (elf_header.e_type != ET_REL)
11267 return;
1b315056 11268
cf13d699 11269 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11270 for (relsec = section_headers;
11271 relsec < section_headers + elf_header.e_shnum;
11272 ++relsec)
252b5132 11273 {
41e92641
NC
11274 bfd_boolean is_rela;
11275 unsigned long num_relocs;
2cf0635d
NC
11276 Elf_Internal_Rela * relocs;
11277 Elf_Internal_Rela * rp;
11278 Elf_Internal_Shdr * symsec;
11279 Elf_Internal_Sym * symtab;
ba5cdace 11280 unsigned long num_syms;
2cf0635d 11281 Elf_Internal_Sym * sym;
252b5132 11282
41e92641 11283 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11284 || relsec->sh_info >= elf_header.e_shnum
11285 || section_headers + relsec->sh_info != section
c256ffe7 11286 || relsec->sh_size == 0
4fbb74a6 11287 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11288 continue;
428409d5 11289
41e92641
NC
11290 is_rela = relsec->sh_type == SHT_RELA;
11291
11292 if (is_rela)
11293 {
3f5e193b
NC
11294 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11295 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11296 return;
11297 }
11298 else
11299 {
3f5e193b
NC
11300 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11301 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11302 return;
11303 }
11304
11305 /* SH uses RELA but uses in place value instead of the addend field. */
11306 if (elf_header.e_machine == EM_SH)
11307 is_rela = FALSE;
428409d5 11308
4fbb74a6 11309 symsec = section_headers + relsec->sh_link;
ba5cdace 11310 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11311
41e92641 11312 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11313 {
41e92641
NC
11314 bfd_vma addend;
11315 unsigned int reloc_type;
11316 unsigned int reloc_size;
91d6fa6a 11317 unsigned char * rloc;
ba5cdace 11318 unsigned long sym_index;
4b78141a 11319
aca88567 11320 reloc_type = get_reloc_type (rp->r_info);
41e92641 11321
98fb390a 11322 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11323 continue;
98fb390a
NC
11324 else if (is_none_reloc (reloc_type))
11325 continue;
11326 else if (is_32bit_abs_reloc (reloc_type)
11327 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11328 reloc_size = 4;
85acf597
RH
11329 else if (is_64bit_abs_reloc (reloc_type)
11330 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11331 reloc_size = 8;
4dc3c23d
AM
11332 else if (is_24bit_abs_reloc (reloc_type))
11333 reloc_size = 3;
aca88567
NC
11334 else if (is_16bit_abs_reloc (reloc_type))
11335 reloc_size = 2;
11336 else
4b78141a 11337 {
41e92641 11338 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
74e1a04b 11339 reloc_type, printable_section_name (section));
4b78141a
NC
11340 continue;
11341 }
103f02d3 11342
91d6fa6a 11343 rloc = start + rp->r_offset;
c8da6823 11344 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11345 {
11346 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11347 (unsigned long) rp->r_offset,
74e1a04b 11348 printable_section_name (section));
700dd8b7
L
11349 continue;
11350 }
103f02d3 11351
ba5cdace
NC
11352 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11353 if (sym_index >= num_syms)
11354 {
11355 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11356 sym_index, printable_section_name (section));
ba5cdace
NC
11357 continue;
11358 }
11359 sym = symtab + sym_index;
41e92641
NC
11360
11361 /* If the reloc has a symbol associated with it,
55f25fc3
L
11362 make sure that it is of an appropriate type.
11363
11364 Relocations against symbols without type can happen.
11365 Gcc -feliminate-dwarf2-dups may generate symbols
11366 without type for debug info.
11367
11368 Icc generates relocations against function symbols
11369 instead of local labels.
11370
11371 Relocations against object symbols can happen, eg when
11372 referencing a global array. For an example of this see
11373 the _clz.o binary in libgcc.a. */
aca88567 11374 if (sym != symtab
55f25fc3 11375 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11376 {
41e92641 11377 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11378 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11379 (long int)(rp - relocs),
74e1a04b 11380 printable_section_name (relsec));
aca88567 11381 continue;
5b18a4bc 11382 }
252b5132 11383
4dc3c23d
AM
11384 addend = 0;
11385 if (is_rela)
11386 addend += rp->r_addend;
c47320c3
AM
11387 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11388 partial_inplace. */
4dc3c23d
AM
11389 if (!is_rela
11390 || (elf_header.e_machine == EM_XTENSA
11391 && reloc_type == 1)
11392 || ((elf_header.e_machine == EM_PJ
11393 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11394 && reloc_type == 1)
11395 || ((elf_header.e_machine == EM_D30V
11396 || elf_header.e_machine == EM_CYGNUS_D30V)
11397 && reloc_type == 12))
91d6fa6a 11398 addend += byte_get (rloc, reloc_size);
cb8f3167 11399
85acf597
RH
11400 if (is_32bit_pcrel_reloc (reloc_type)
11401 || is_64bit_pcrel_reloc (reloc_type))
11402 {
11403 /* On HPPA, all pc-relative relocations are biased by 8. */
11404 if (elf_header.e_machine == EM_PARISC)
11405 addend -= 8;
91d6fa6a 11406 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11407 reloc_size);
11408 }
41e92641 11409 else
91d6fa6a 11410 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11411 }
252b5132 11412
5b18a4bc 11413 free (symtab);
41e92641 11414 free (relocs);
5b18a4bc
NC
11415 break;
11416 }
5b18a4bc 11417}
103f02d3 11418
cf13d699
NC
11419#ifdef SUPPORT_DISASSEMBLY
11420static int
11421disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11422{
74e1a04b 11423 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11424
74e1a04b 11425 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11426
11427 return 1;
11428}
11429#endif
11430
11431/* Reads in the contents of SECTION from FILE, returning a pointer
11432 to a malloc'ed buffer or NULL if something went wrong. */
11433
11434static char *
11435get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11436{
11437 bfd_size_type num_bytes;
11438
11439 num_bytes = section->sh_size;
11440
11441 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11442 {
11443 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11444 printable_section_name (section));
cf13d699
NC
11445 return NULL;
11446 }
11447
3f5e193b
NC
11448 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11449 _("section contents"));
cf13d699
NC
11450}
11451
dd24e3da 11452
cf13d699
NC
11453static void
11454dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11455{
11456 Elf_Internal_Shdr * relsec;
11457 bfd_size_type num_bytes;
cf13d699
NC
11458 char * data;
11459 char * end;
11460 char * start;
cf13d699
NC
11461 bfd_boolean some_strings_shown;
11462
11463 start = get_section_contents (section, file);
11464 if (start == NULL)
11465 return;
11466
74e1a04b 11467 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11468
11469 /* If the section being dumped has relocations against it the user might
11470 be expecting these relocations to have been applied. Check for this
11471 case and issue a warning message in order to avoid confusion.
11472 FIXME: Maybe we ought to have an option that dumps a section with
11473 relocs applied ? */
11474 for (relsec = section_headers;
11475 relsec < section_headers + elf_header.e_shnum;
11476 ++relsec)
11477 {
11478 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11479 || relsec->sh_info >= elf_header.e_shnum
11480 || section_headers + relsec->sh_info != section
11481 || relsec->sh_size == 0
11482 || relsec->sh_link >= elf_header.e_shnum)
11483 continue;
11484
11485 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11486 break;
11487 }
11488
11489 num_bytes = section->sh_size;
cf13d699
NC
11490 data = start;
11491 end = start + num_bytes;
11492 some_strings_shown = FALSE;
11493
11494 while (data < end)
11495 {
11496 while (!ISPRINT (* data))
11497 if (++ data >= end)
11498 break;
11499
11500 if (data < end)
11501 {
071436c6
NC
11502 size_t maxlen = end - data;
11503
cf13d699 11504#ifndef __MSVCRT__
c975cc98
NC
11505 /* PR 11128: Use two separate invocations in order to work
11506 around bugs in the Solaris 8 implementation of printf. */
11507 printf (" [%6tx] ", data - start);
cf13d699 11508#else
071436c6 11509 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11510#endif
4082ef84
NC
11511 if (maxlen > 0)
11512 {
11513 print_symbol ((int) maxlen, data);
11514 putchar ('\n');
11515 data += strnlen (data, maxlen);
11516 }
11517 else
11518 {
11519 printf (_("<corrupt>\n"));
11520 data = end;
11521 }
cf13d699
NC
11522 some_strings_shown = TRUE;
11523 }
11524 }
11525
11526 if (! some_strings_shown)
11527 printf (_(" No strings found in this section."));
11528
11529 free (start);
11530
11531 putchar ('\n');
11532}
11533
11534static void
11535dump_section_as_bytes (Elf_Internal_Shdr * section,
11536 FILE * file,
11537 bfd_boolean relocate)
11538{
11539 Elf_Internal_Shdr * relsec;
11540 bfd_size_type bytes;
11541 bfd_vma addr;
11542 unsigned char * data;
11543 unsigned char * start;
11544
11545 start = (unsigned char *) get_section_contents (section, file);
11546 if (start == NULL)
11547 return;
11548
74e1a04b 11549 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11550
11551 if (relocate)
11552 {
11553 apply_relocations (file, section, start);
11554 }
11555 else
11556 {
11557 /* If the section being dumped has relocations against it the user might
11558 be expecting these relocations to have been applied. Check for this
11559 case and issue a warning message in order to avoid confusion.
11560 FIXME: Maybe we ought to have an option that dumps a section with
11561 relocs applied ? */
11562 for (relsec = section_headers;
11563 relsec < section_headers + elf_header.e_shnum;
11564 ++relsec)
11565 {
11566 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11567 || relsec->sh_info >= elf_header.e_shnum
11568 || section_headers + relsec->sh_info != section
11569 || relsec->sh_size == 0
11570 || relsec->sh_link >= elf_header.e_shnum)
11571 continue;
11572
11573 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11574 break;
11575 }
11576 }
11577
11578 addr = section->sh_addr;
11579 bytes = section->sh_size;
11580 data = start;
11581
11582 while (bytes)
11583 {
11584 int j;
11585 int k;
11586 int lbytes;
11587
11588 lbytes = (bytes > 16 ? 16 : bytes);
11589
11590 printf (" 0x%8.8lx ", (unsigned long) addr);
11591
11592 for (j = 0; j < 16; j++)
11593 {
11594 if (j < lbytes)
11595 printf ("%2.2x", data[j]);
11596 else
11597 printf (" ");
11598
11599 if ((j & 3) == 3)
11600 printf (" ");
11601 }
11602
11603 for (j = 0; j < lbytes; j++)
11604 {
11605 k = data[j];
11606 if (k >= ' ' && k < 0x7f)
11607 printf ("%c", k);
11608 else
11609 printf (".");
11610 }
11611
11612 putchar ('\n');
11613
11614 data += lbytes;
11615 addr += lbytes;
11616 bytes -= lbytes;
11617 }
11618
11619 free (start);
11620
11621 putchar ('\n');
11622}
11623
4a114e3e 11624/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11625
11626static int
d3dbc530
AM
11627uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11628 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11629{
11630#ifndef HAVE_ZLIB_H
cf13d699
NC
11631 return FALSE;
11632#else
11633 dwarf_size_type compressed_size = *size;
11634 unsigned char * compressed_buffer = *buffer;
11635 dwarf_size_type uncompressed_size;
11636 unsigned char * uncompressed_buffer;
11637 z_stream strm;
11638 int rc;
11639 dwarf_size_type header_size = 12;
11640
11641 /* Read the zlib header. In this case, it should be "ZLIB" followed
11642 by the uncompressed section size, 8 bytes in big-endian order. */
11643 if (compressed_size < header_size
11644 || ! streq ((char *) compressed_buffer, "ZLIB"))
11645 return 0;
11646
11647 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11648 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11649 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11650 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11651 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11652 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11653 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11654 uncompressed_size += compressed_buffer[11];
11655
11656 /* It is possible the section consists of several compressed
11657 buffers concatenated together, so we uncompress in a loop. */
11658 strm.zalloc = NULL;
11659 strm.zfree = NULL;
11660 strm.opaque = NULL;
11661 strm.avail_in = compressed_size - header_size;
11662 strm.next_in = (Bytef *) compressed_buffer + header_size;
11663 strm.avail_out = uncompressed_size;
3f5e193b 11664 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11665
11666 rc = inflateInit (& strm);
11667 while (strm.avail_in > 0)
11668 {
11669 if (rc != Z_OK)
11670 goto fail;
11671 strm.next_out = ((Bytef *) uncompressed_buffer
11672 + (uncompressed_size - strm.avail_out));
11673 rc = inflate (&strm, Z_FINISH);
11674 if (rc != Z_STREAM_END)
11675 goto fail;
11676 rc = inflateReset (& strm);
11677 }
11678 rc = inflateEnd (& strm);
11679 if (rc != Z_OK
11680 || strm.avail_out != 0)
11681 goto fail;
11682
11683 free (compressed_buffer);
11684 *buffer = uncompressed_buffer;
11685 *size = uncompressed_size;
11686 return 1;
11687
11688 fail:
11689 free (uncompressed_buffer);
4a114e3e
L
11690 /* Indicate decompression failure. */
11691 *buffer = NULL;
cf13d699
NC
11692 return 0;
11693#endif /* HAVE_ZLIB_H */
11694}
11695
d966045b
DJ
11696static int
11697load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11698 Elf_Internal_Shdr * sec, void * file)
1007acb3 11699{
2cf0635d 11700 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11701 char buf [64];
1007acb3 11702
19e6b90e
L
11703 /* If it is already loaded, do nothing. */
11704 if (section->start != NULL)
11705 return 1;
1007acb3 11706
19e6b90e
L
11707 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11708 section->address = sec->sh_addr;
3f5e193b
NC
11709 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11710 sec->sh_offset, 1,
11711 sec->sh_size, buf);
59245841
NC
11712 if (section->start == NULL)
11713 section->size = 0;
11714 else
11715 {
11716 section->size = sec->sh_size;
11717 if (uncompress_section_contents (&section->start, &section->size))
11718 sec->sh_size = section->size;
11719 }
4a114e3e 11720
1b315056
CS
11721 if (section->start == NULL)
11722 return 0;
11723
19e6b90e 11724 if (debug_displays [debug].relocate)
3f5e193b 11725 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11726
1b315056 11727 return 1;
1007acb3
L
11728}
11729
657d0d47
CC
11730/* If this is not NULL, load_debug_section will only look for sections
11731 within the list of sections given here. */
11732unsigned int *section_subset = NULL;
11733
d966045b 11734int
2cf0635d 11735load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11736{
2cf0635d
NC
11737 struct dwarf_section * section = &debug_displays [debug].section;
11738 Elf_Internal_Shdr * sec;
d966045b
DJ
11739
11740 /* Locate the debug section. */
657d0d47 11741 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11742 if (sec != NULL)
11743 section->name = section->uncompressed_name;
11744 else
11745 {
657d0d47 11746 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11747 if (sec != NULL)
11748 section->name = section->compressed_name;
11749 }
11750 if (sec == NULL)
11751 return 0;
11752
657d0d47
CC
11753 /* If we're loading from a subset of sections, and we've loaded
11754 a section matching this name before, it's likely that it's a
11755 different one. */
11756 if (section_subset != NULL)
11757 free_debug_section (debug);
11758
3f5e193b 11759 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11760}
11761
19e6b90e
L
11762void
11763free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11764{
2cf0635d 11765 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11766
19e6b90e
L
11767 if (section->start == NULL)
11768 return;
1007acb3 11769
19e6b90e
L
11770 free ((char *) section->start);
11771 section->start = NULL;
11772 section->address = 0;
11773 section->size = 0;
1007acb3
L
11774}
11775
1007acb3 11776static int
657d0d47 11777display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11778{
2cf0635d 11779 char * name = SECTION_NAME (section);
74e1a04b 11780 const char * print_name = printable_section_name (section);
19e6b90e
L
11781 bfd_size_type length;
11782 int result = 1;
3f5e193b 11783 int i;
1007acb3 11784
19e6b90e
L
11785 length = section->sh_size;
11786 if (length == 0)
1007acb3 11787 {
74e1a04b 11788 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 11789 return 0;
1007acb3 11790 }
5dff79d8
NC
11791 if (section->sh_type == SHT_NOBITS)
11792 {
11793 /* There is no point in dumping the contents of a debugging section
11794 which has the NOBITS type - the bits in the file will be random.
11795 This can happen when a file containing a .eh_frame section is
11796 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
11797 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
11798 print_name);
5dff79d8
NC
11799 return 0;
11800 }
1007acb3 11801
0112cd26 11802 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11803 name = ".debug_info";
1007acb3 11804
19e6b90e
L
11805 /* See if we know how to display the contents of this section. */
11806 for (i = 0; i < max; i++)
1b315056 11807 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11808 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11809 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11810 {
2cf0635d 11811 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11812 int secondary = (section != find_section (name));
11813
11814 if (secondary)
3f5e193b 11815 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11816
b40bf0a2
NC
11817 if (i == line && const_strneq (name, ".debug_line."))
11818 sec->name = name;
11819 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11820 sec->name = sec->uncompressed_name;
11821 else
11822 sec->name = sec->compressed_name;
3f5e193b
NC
11823 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11824 section, file))
19e6b90e 11825 {
657d0d47
CC
11826 /* If this debug section is part of a CU/TU set in a .dwp file,
11827 restrict load_debug_section to the sections in that set. */
11828 section_subset = find_cu_tu_set (file, shndx);
11829
19e6b90e 11830 result &= debug_displays[i].display (sec, file);
1007acb3 11831
657d0d47
CC
11832 section_subset = NULL;
11833
d966045b 11834 if (secondary || (i != info && i != abbrev))
3f5e193b 11835 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11836 }
1007acb3 11837
19e6b90e
L
11838 break;
11839 }
1007acb3 11840
19e6b90e 11841 if (i == max)
1007acb3 11842 {
74e1a04b 11843 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 11844 result = 0;
1007acb3
L
11845 }
11846
19e6b90e 11847 return result;
5b18a4bc 11848}
103f02d3 11849
aef1f6d0
DJ
11850/* Set DUMP_SECTS for all sections where dumps were requested
11851 based on section name. */
11852
11853static void
11854initialise_dumps_byname (void)
11855{
2cf0635d 11856 struct dump_list_entry * cur;
aef1f6d0
DJ
11857
11858 for (cur = dump_sects_byname; cur; cur = cur->next)
11859 {
11860 unsigned int i;
11861 int any;
11862
11863 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11864 if (streq (SECTION_NAME (section_headers + i), cur->name))
11865 {
09c11c86 11866 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11867 any = 1;
11868 }
11869
11870 if (!any)
11871 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11872 cur->name);
11873 }
11874}
11875
5b18a4bc 11876static void
2cf0635d 11877process_section_contents (FILE * file)
5b18a4bc 11878{
2cf0635d 11879 Elf_Internal_Shdr * section;
19e6b90e 11880 unsigned int i;
103f02d3 11881
19e6b90e
L
11882 if (! do_dump)
11883 return;
103f02d3 11884
aef1f6d0
DJ
11885 initialise_dumps_byname ();
11886
19e6b90e
L
11887 for (i = 0, section = section_headers;
11888 i < elf_header.e_shnum && i < num_dump_sects;
11889 i++, section++)
11890 {
11891#ifdef SUPPORT_DISASSEMBLY
11892 if (dump_sects[i] & DISASS_DUMP)
11893 disassemble_section (section, file);
11894#endif
11895 if (dump_sects[i] & HEX_DUMP)
cf13d699 11896 dump_section_as_bytes (section, file, FALSE);
103f02d3 11897
cf13d699
NC
11898 if (dump_sects[i] & RELOC_DUMP)
11899 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11900
11901 if (dump_sects[i] & STRING_DUMP)
11902 dump_section_as_strings (section, file);
cf13d699
NC
11903
11904 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11905 display_debug_section (i, section, file);
5b18a4bc 11906 }
103f02d3 11907
19e6b90e
L
11908 /* Check to see if the user requested a
11909 dump of a section that does not exist. */
11910 while (i++ < num_dump_sects)
11911 if (dump_sects[i])
11912 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11913}
103f02d3 11914
5b18a4bc 11915static void
19e6b90e 11916process_mips_fpe_exception (int mask)
5b18a4bc 11917{
19e6b90e
L
11918 if (mask)
11919 {
11920 int first = 1;
11921 if (mask & OEX_FPU_INEX)
11922 fputs ("INEX", stdout), first = 0;
11923 if (mask & OEX_FPU_UFLO)
11924 printf ("%sUFLO", first ? "" : "|"), first = 0;
11925 if (mask & OEX_FPU_OFLO)
11926 printf ("%sOFLO", first ? "" : "|"), first = 0;
11927 if (mask & OEX_FPU_DIV0)
11928 printf ("%sDIV0", first ? "" : "|"), first = 0;
11929 if (mask & OEX_FPU_INVAL)
11930 printf ("%sINVAL", first ? "" : "|");
11931 }
5b18a4bc 11932 else
19e6b90e 11933 fputs ("0", stdout);
5b18a4bc 11934}
103f02d3 11935
f6f0e17b
NC
11936/* Display's the value of TAG at location P. If TAG is
11937 greater than 0 it is assumed to be an unknown tag, and
11938 a message is printed to this effect. Otherwise it is
11939 assumed that a message has already been printed.
11940
11941 If the bottom bit of TAG is set it assumed to have a
11942 string value, otherwise it is assumed to have an integer
11943 value.
11944
11945 Returns an updated P pointing to the first unread byte
11946 beyond the end of TAG's value.
11947
11948 Reads at or beyond END will not be made. */
11949
11950static unsigned char *
11951display_tag_value (int tag,
11952 unsigned char * p,
11953 const unsigned char * const end)
11954{
11955 unsigned long val;
11956
11957 if (tag > 0)
11958 printf (" Tag_unknown_%d: ", tag);
11959
11960 if (p >= end)
11961 {
4082ef84 11962 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
11963 }
11964 else if (tag & 1)
11965 {
071436c6
NC
11966 /* PR 17531 file: 027-19978-0.004. */
11967 size_t maxlen = (end - p) - 1;
11968
11969 putchar ('"');
4082ef84
NC
11970 if (maxlen > 0)
11971 {
11972 print_symbol ((int) maxlen, (const char *) p);
11973 p += strnlen ((char *) p, maxlen) + 1;
11974 }
11975 else
11976 {
11977 printf (_("<corrupt string tag>"));
11978 p = (unsigned char *) end;
11979 }
071436c6 11980 printf ("\"\n");
f6f0e17b
NC
11981 }
11982 else
11983 {
11984 unsigned int len;
11985
11986 val = read_uleb128 (p, &len, end);
11987 p += len;
11988 printf ("%ld (0x%lx)\n", val, val);
11989 }
11990
4082ef84 11991 assert (p <= end);
f6f0e17b
NC
11992 return p;
11993}
11994
11c1ff18
PB
11995/* ARM EABI attributes section. */
11996typedef struct
11997{
70e99720 11998 unsigned int tag;
2cf0635d 11999 const char * name;
11c1ff18 12000 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12001 unsigned int type;
2cf0635d 12002 const char ** table;
11c1ff18
PB
12003} arm_attr_public_tag;
12004
2cf0635d 12005static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12006 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12007 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12008static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12009static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12010 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12011static const char * arm_attr_tag_FP_arch[] =
bca38921 12012 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12013 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12014static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12015static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12016 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12017static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12018 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12019 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12020static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12021 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12022static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12023 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12024static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12025 {"Absolute", "PC-relative", "None"};
2cf0635d 12026static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12027 {"None", "direct", "GOT-indirect"};
2cf0635d 12028static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12029 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12030static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12031static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12032 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12033static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12034static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12035static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12036 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12037static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12038 {"Unused", "small", "int", "forced to int"};
2cf0635d 12039static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12040 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12041static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 12042 {"AAPCS", "VFP registers", "custom"};
2cf0635d 12043static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12044 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12045static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12046 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12047 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12048static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12049 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12050 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12051static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12052static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12053 {"Not Allowed", "Allowed"};
2cf0635d 12054static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12055 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12056static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12057 {"Not Allowed", "Allowed"};
12058static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12059 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12060 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12061static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12062static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12063 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12064 "TrustZone and Virtualization Extensions"};
dd24e3da 12065static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12066 {"Not Allowed", "Allowed"};
11c1ff18
PB
12067
12068#define LOOKUP(id, name) \
12069 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12070static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12071{
12072 {4, "CPU_raw_name", 1, NULL},
12073 {5, "CPU_name", 1, NULL},
12074 LOOKUP(6, CPU_arch),
12075 {7, "CPU_arch_profile", 0, NULL},
12076 LOOKUP(8, ARM_ISA_use),
12077 LOOKUP(9, THUMB_ISA_use),
75375b3e 12078 LOOKUP(10, FP_arch),
11c1ff18 12079 LOOKUP(11, WMMX_arch),
f5f53991
AS
12080 LOOKUP(12, Advanced_SIMD_arch),
12081 LOOKUP(13, PCS_config),
11c1ff18
PB
12082 LOOKUP(14, ABI_PCS_R9_use),
12083 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12084 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12085 LOOKUP(17, ABI_PCS_GOT_use),
12086 LOOKUP(18, ABI_PCS_wchar_t),
12087 LOOKUP(19, ABI_FP_rounding),
12088 LOOKUP(20, ABI_FP_denormal),
12089 LOOKUP(21, ABI_FP_exceptions),
12090 LOOKUP(22, ABI_FP_user_exceptions),
12091 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12092 {24, "ABI_align_needed", 0, NULL},
12093 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12094 LOOKUP(26, ABI_enum_size),
12095 LOOKUP(27, ABI_HardFP_use),
12096 LOOKUP(28, ABI_VFP_args),
12097 LOOKUP(29, ABI_WMMX_args),
12098 LOOKUP(30, ABI_optimization_goals),
12099 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12100 {32, "compatibility", 0, NULL},
f5f53991 12101 LOOKUP(34, CPU_unaligned_access),
75375b3e 12102 LOOKUP(36, FP_HP_extension),
8e79c3df 12103 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12104 LOOKUP(42, MPextension_use),
12105 LOOKUP(44, DIV_use),
f5f53991
AS
12106 {64, "nodefaults", 0, NULL},
12107 {65, "also_compatible_with", 0, NULL},
12108 LOOKUP(66, T2EE_use),
12109 {67, "conformance", 1, NULL},
12110 LOOKUP(68, Virtualization_use),
cd21e546 12111 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12112};
12113#undef LOOKUP
12114
11c1ff18 12115static unsigned char *
f6f0e17b
NC
12116display_arm_attribute (unsigned char * p,
12117 const unsigned char * const end)
11c1ff18 12118{
70e99720 12119 unsigned int tag;
11c1ff18 12120 unsigned int len;
70e99720 12121 unsigned int val;
2cf0635d 12122 arm_attr_public_tag * attr;
11c1ff18 12123 unsigned i;
70e99720 12124 unsigned int type;
11c1ff18 12125
f6f0e17b 12126 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12127 p += len;
12128 attr = NULL;
2cf0635d 12129 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12130 {
12131 if (arm_attr_public_tags[i].tag == tag)
12132 {
12133 attr = &arm_attr_public_tags[i];
12134 break;
12135 }
12136 }
12137
12138 if (attr)
12139 {
12140 printf (" Tag_%s: ", attr->name);
12141 switch (attr->type)
12142 {
12143 case 0:
12144 switch (tag)
12145 {
12146 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12147 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12148 p += len;
12149 switch (val)
12150 {
2b692964
NC
12151 case 0: printf (_("None\n")); break;
12152 case 'A': printf (_("Application\n")); break;
12153 case 'R': printf (_("Realtime\n")); break;
12154 case 'M': printf (_("Microcontroller\n")); break;
12155 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12156 default: printf ("??? (%d)\n", val); break;
12157 }
12158 break;
12159
75375b3e 12160 case 24: /* Tag_align_needed. */
f6f0e17b 12161 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12162 p += len;
12163 switch (val)
12164 {
2b692964
NC
12165 case 0: printf (_("None\n")); break;
12166 case 1: printf (_("8-byte\n")); break;
12167 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12168 case 3: printf ("??? 3\n"); break;
12169 default:
12170 if (val <= 12)
dd24e3da 12171 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12172 1 << val);
12173 else
12174 printf ("??? (%d)\n", val);
12175 break;
12176 }
12177 break;
12178
12179 case 25: /* Tag_align_preserved. */
f6f0e17b 12180 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12181 p += len;
12182 switch (val)
12183 {
2b692964
NC
12184 case 0: printf (_("None\n")); break;
12185 case 1: printf (_("8-byte, except leaf SP\n")); break;
12186 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12187 case 3: printf ("??? 3\n"); break;
12188 default:
12189 if (val <= 12)
dd24e3da 12190 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12191 1 << val);
12192 else
12193 printf ("??? (%d)\n", val);
12194 break;
12195 }
12196 break;
12197
11c1ff18 12198 case 32: /* Tag_compatibility. */
071436c6 12199 {
071436c6
NC
12200 val = read_uleb128 (p, &len, end);
12201 p += len;
071436c6 12202 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12203 if (p < end - 1)
12204 {
12205 size_t maxlen = (end - p) - 1;
12206
12207 print_symbol ((int) maxlen, (const char *) p);
12208 p += strnlen ((char *) p, maxlen) + 1;
12209 }
12210 else
12211 {
12212 printf (_("<corrupt>"));
12213 p = (unsigned char *) end;
12214 }
071436c6 12215 putchar ('\n');
071436c6 12216 }
11c1ff18
PB
12217 break;
12218
f5f53991 12219 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12220 /* PR 17531: file: 001-505008-0.01. */
12221 if (p < end)
12222 p++;
2b692964 12223 printf (_("True\n"));
f5f53991
AS
12224 break;
12225
12226 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12227 val = read_uleb128 (p, &len, end);
f5f53991
AS
12228 p += len;
12229 if (val == 6 /* Tag_CPU_arch. */)
12230 {
f6f0e17b 12231 val = read_uleb128 (p, &len, end);
f5f53991 12232 p += len;
071436c6 12233 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12234 printf ("??? (%d)\n", val);
12235 else
12236 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12237 }
12238 else
12239 printf ("???\n");
071436c6
NC
12240 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12241 ;
f5f53991
AS
12242 break;
12243
11c1ff18 12244 default:
2cf0635d 12245 abort ();
11c1ff18
PB
12246 }
12247 return p;
12248
12249 case 1:
f6f0e17b 12250 return display_tag_value (-1, p, end);
11c1ff18 12251 case 2:
f6f0e17b 12252 return display_tag_value (0, p, end);
11c1ff18
PB
12253
12254 default:
12255 assert (attr->type & 0x80);
f6f0e17b 12256 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12257 p += len;
12258 type = attr->type & 0x7f;
12259 if (val >= type)
12260 printf ("??? (%d)\n", val);
12261 else
12262 printf ("%s\n", attr->table[val]);
12263 return p;
12264 }
12265 }
11c1ff18 12266
f6f0e17b 12267 return display_tag_value (tag, p, end);
11c1ff18
PB
12268}
12269
104d59d1 12270static unsigned char *
60bca95a 12271display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12272 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12273 const unsigned char * const end)
104d59d1
JM
12274{
12275 int tag;
12276 unsigned int len;
12277 int val;
104d59d1 12278
f6f0e17b 12279 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12280 p += len;
12281
12282 /* Tag_compatibility is the only generic GNU attribute defined at
12283 present. */
12284 if (tag == 32)
12285 {
f6f0e17b 12286 val = read_uleb128 (p, &len, end);
104d59d1 12287 p += len;
071436c6
NC
12288
12289 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12290 if (p == end)
12291 {
071436c6 12292 printf (_("<corrupt>\n"));
f6f0e17b
NC
12293 warn (_("corrupt vendor attribute\n"));
12294 }
12295 else
12296 {
4082ef84
NC
12297 if (p < end - 1)
12298 {
12299 size_t maxlen = (end - p) - 1;
071436c6 12300
4082ef84
NC
12301 print_symbol ((int) maxlen, (const char *) p);
12302 p += strnlen ((char *) p, maxlen) + 1;
12303 }
12304 else
12305 {
12306 printf (_("<corrupt>"));
12307 p = (unsigned char *) end;
12308 }
071436c6 12309 putchar ('\n');
f6f0e17b 12310 }
104d59d1
JM
12311 return p;
12312 }
12313
12314 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12315 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12316
f6f0e17b 12317 return display_tag_value (tag, p, end);
104d59d1
JM
12318}
12319
34c8bcba 12320static unsigned char *
f6f0e17b
NC
12321display_power_gnu_attribute (unsigned char * p,
12322 int tag,
12323 const unsigned char * const end)
34c8bcba 12324{
34c8bcba
JM
12325 unsigned int len;
12326 int val;
12327
12328 if (tag == Tag_GNU_Power_ABI_FP)
12329 {
f6f0e17b 12330 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12331 p += len;
12332 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12333
34c8bcba
JM
12334 switch (val)
12335 {
12336 case 0:
2b692964 12337 printf (_("Hard or soft float\n"));
34c8bcba
JM
12338 break;
12339 case 1:
2b692964 12340 printf (_("Hard float\n"));
34c8bcba
JM
12341 break;
12342 case 2:
2b692964 12343 printf (_("Soft float\n"));
34c8bcba 12344 break;
3c7b9897 12345 case 3:
2b692964 12346 printf (_("Single-precision hard float\n"));
3c7b9897 12347 break;
34c8bcba
JM
12348 default:
12349 printf ("??? (%d)\n", val);
12350 break;
12351 }
12352 return p;
12353 }
12354
c6e65352
DJ
12355 if (tag == Tag_GNU_Power_ABI_Vector)
12356 {
f6f0e17b 12357 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12358 p += len;
12359 printf (" Tag_GNU_Power_ABI_Vector: ");
12360 switch (val)
12361 {
12362 case 0:
2b692964 12363 printf (_("Any\n"));
c6e65352
DJ
12364 break;
12365 case 1:
2b692964 12366 printf (_("Generic\n"));
c6e65352
DJ
12367 break;
12368 case 2:
12369 printf ("AltiVec\n");
12370 break;
12371 case 3:
12372 printf ("SPE\n");
12373 break;
12374 default:
12375 printf ("??? (%d)\n", val);
12376 break;
12377 }
12378 return p;
12379 }
12380
f82e0623
NF
12381 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12382 {
f6f0e17b
NC
12383 if (p == end)
12384 {
071436c6 12385 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12386 return p;
12387 }
0b4362b0 12388
f6f0e17b 12389 val = read_uleb128 (p, &len, end);
f82e0623
NF
12390 p += len;
12391 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12392 switch (val)
12393 {
12394 case 0:
2b692964 12395 printf (_("Any\n"));
f82e0623
NF
12396 break;
12397 case 1:
12398 printf ("r3/r4\n");
12399 break;
12400 case 2:
2b692964 12401 printf (_("Memory\n"));
f82e0623
NF
12402 break;
12403 default:
12404 printf ("??? (%d)\n", val);
12405 break;
12406 }
12407 return p;
12408 }
12409
f6f0e17b 12410 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12411}
12412
9e8c70f9
DM
12413static void
12414display_sparc_hwcaps (int mask)
12415{
12416 if (mask)
12417 {
12418 int first = 1;
071436c6 12419
9e8c70f9
DM
12420 if (mask & ELF_SPARC_HWCAP_MUL32)
12421 fputs ("mul32", stdout), first = 0;
12422 if (mask & ELF_SPARC_HWCAP_DIV32)
12423 printf ("%sdiv32", first ? "" : "|"), first = 0;
12424 if (mask & ELF_SPARC_HWCAP_FSMULD)
12425 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12426 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12427 printf ("%sv8plus", first ? "" : "|"), first = 0;
12428 if (mask & ELF_SPARC_HWCAP_POPC)
12429 printf ("%spopc", first ? "" : "|"), first = 0;
12430 if (mask & ELF_SPARC_HWCAP_VIS)
12431 printf ("%svis", first ? "" : "|"), first = 0;
12432 if (mask & ELF_SPARC_HWCAP_VIS2)
12433 printf ("%svis2", first ? "" : "|"), first = 0;
12434 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12435 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12436 if (mask & ELF_SPARC_HWCAP_FMAF)
12437 printf ("%sfmaf", first ? "" : "|"), first = 0;
12438 if (mask & ELF_SPARC_HWCAP_VIS3)
12439 printf ("%svis3", first ? "" : "|"), first = 0;
12440 if (mask & ELF_SPARC_HWCAP_HPC)
12441 printf ("%shpc", first ? "" : "|"), first = 0;
12442 if (mask & ELF_SPARC_HWCAP_RANDOM)
12443 printf ("%srandom", first ? "" : "|"), first = 0;
12444 if (mask & ELF_SPARC_HWCAP_TRANS)
12445 printf ("%strans", first ? "" : "|"), first = 0;
12446 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12447 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12448 if (mask & ELF_SPARC_HWCAP_IMA)
12449 printf ("%sima", first ? "" : "|"), first = 0;
12450 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12451 printf ("%scspare", first ? "" : "|"), first = 0;
12452 }
12453 else
071436c6
NC
12454 fputc ('0', stdout);
12455 fputc ('\n', stdout);
9e8c70f9
DM
12456}
12457
3d68f91c
JM
12458static void
12459display_sparc_hwcaps2 (int mask)
12460{
12461 if (mask)
12462 {
12463 int first = 1;
071436c6 12464
3d68f91c
JM
12465 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12466 fputs ("fjathplus", stdout), first = 0;
12467 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12468 printf ("%svis3b", first ? "" : "|"), first = 0;
12469 if (mask & ELF_SPARC_HWCAP2_ADP)
12470 printf ("%sadp", first ? "" : "|"), first = 0;
12471 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12472 printf ("%ssparc5", first ? "" : "|"), first = 0;
12473 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12474 printf ("%smwait", first ? "" : "|"), first = 0;
12475 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12476 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12477 if (mask & ELF_SPARC_HWCAP2_XMONT)
12478 printf ("%sxmont2", first ? "" : "|"), first = 0;
12479 if (mask & ELF_SPARC_HWCAP2_NSEC)
12480 printf ("%snsec", first ? "" : "|"), first = 0;
12481 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12482 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12483 if (mask & ELF_SPARC_HWCAP2_FJDES)
12484 printf ("%sfjdes", first ? "" : "|"), first = 0;
12485 if (mask & ELF_SPARC_HWCAP2_FJAES)
12486 printf ("%sfjaes", first ? "" : "|"), first = 0;
12487 }
12488 else
071436c6
NC
12489 fputc ('0', stdout);
12490 fputc ('\n', stdout);
3d68f91c
JM
12491}
12492
9e8c70f9 12493static unsigned char *
f6f0e17b
NC
12494display_sparc_gnu_attribute (unsigned char * p,
12495 int tag,
12496 const unsigned char * const end)
9e8c70f9 12497{
3d68f91c
JM
12498 unsigned int len;
12499 int val;
12500
9e8c70f9
DM
12501 if (tag == Tag_GNU_Sparc_HWCAPS)
12502 {
f6f0e17b 12503 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12504 p += len;
12505 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12506 display_sparc_hwcaps (val);
12507 return p;
3d68f91c
JM
12508 }
12509 if (tag == Tag_GNU_Sparc_HWCAPS2)
12510 {
12511 val = read_uleb128 (p, &len, end);
12512 p += len;
12513 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12514 display_sparc_hwcaps2 (val);
12515 return p;
12516 }
9e8c70f9 12517
f6f0e17b 12518 return display_tag_value (tag, p, end);
9e8c70f9
DM
12519}
12520
351cdf24
MF
12521static void
12522print_mips_fp_abi_value (int val)
12523{
12524 switch (val)
12525 {
12526 case Val_GNU_MIPS_ABI_FP_ANY:
12527 printf (_("Hard or soft float\n"));
12528 break;
12529 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12530 printf (_("Hard float (double precision)\n"));
12531 break;
12532 case Val_GNU_MIPS_ABI_FP_SINGLE:
12533 printf (_("Hard float (single precision)\n"));
12534 break;
12535 case Val_GNU_MIPS_ABI_FP_SOFT:
12536 printf (_("Soft float\n"));
12537 break;
12538 case Val_GNU_MIPS_ABI_FP_OLD_64:
12539 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12540 break;
12541 case Val_GNU_MIPS_ABI_FP_XX:
12542 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12543 break;
12544 case Val_GNU_MIPS_ABI_FP_64:
12545 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12546 break;
12547 case Val_GNU_MIPS_ABI_FP_64A:
12548 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12549 break;
12550 default:
12551 printf ("??? (%d)\n", val);
12552 break;
12553 }
12554}
12555
2cf19d5c 12556static unsigned char *
f6f0e17b
NC
12557display_mips_gnu_attribute (unsigned char * p,
12558 int tag,
12559 const unsigned char * const end)
2cf19d5c 12560{
2cf19d5c
JM
12561 if (tag == Tag_GNU_MIPS_ABI_FP)
12562 {
f6f0e17b
NC
12563 unsigned int len;
12564 int val;
12565
12566 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12567 p += len;
12568 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12569
351cdf24
MF
12570 print_mips_fp_abi_value (val);
12571
2cf19d5c
JM
12572 return p;
12573 }
12574
a9f58168
CF
12575 if (tag == Tag_GNU_MIPS_ABI_MSA)
12576 {
12577 unsigned int len;
12578 int val;
12579
12580 val = read_uleb128 (p, &len, end);
12581 p += len;
12582 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12583
12584 switch (val)
12585 {
12586 case Val_GNU_MIPS_ABI_MSA_ANY:
12587 printf (_("Any MSA or not\n"));
12588 break;
12589 case Val_GNU_MIPS_ABI_MSA_128:
12590 printf (_("128-bit MSA\n"));
12591 break;
12592 default:
12593 printf ("??? (%d)\n", val);
12594 break;
12595 }
12596 return p;
12597 }
12598
f6f0e17b 12599 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12600}
12601
59e6276b 12602static unsigned char *
f6f0e17b
NC
12603display_tic6x_attribute (unsigned char * p,
12604 const unsigned char * const end)
59e6276b
JM
12605{
12606 int tag;
12607 unsigned int len;
12608 int val;
12609
f6f0e17b 12610 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12611 p += len;
12612
12613 switch (tag)
12614 {
75fa6dc1 12615 case Tag_ISA:
f6f0e17b 12616 val = read_uleb128 (p, &len, end);
59e6276b 12617 p += len;
75fa6dc1 12618 printf (" Tag_ISA: ");
59e6276b
JM
12619
12620 switch (val)
12621 {
75fa6dc1 12622 case C6XABI_Tag_ISA_none:
59e6276b
JM
12623 printf (_("None\n"));
12624 break;
75fa6dc1 12625 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12626 printf ("C62x\n");
12627 break;
75fa6dc1 12628 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12629 printf ("C67x\n");
12630 break;
75fa6dc1 12631 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12632 printf ("C67x+\n");
12633 break;
75fa6dc1 12634 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12635 printf ("C64x\n");
12636 break;
75fa6dc1 12637 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12638 printf ("C64x+\n");
12639 break;
75fa6dc1 12640 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12641 printf ("C674x\n");
12642 break;
12643 default:
12644 printf ("??? (%d)\n", val);
12645 break;
12646 }
12647 return p;
12648
87779176 12649 case Tag_ABI_wchar_t:
f6f0e17b 12650 val = read_uleb128 (p, &len, end);
87779176
JM
12651 p += len;
12652 printf (" Tag_ABI_wchar_t: ");
12653 switch (val)
12654 {
12655 case 0:
12656 printf (_("Not used\n"));
12657 break;
12658 case 1:
12659 printf (_("2 bytes\n"));
12660 break;
12661 case 2:
12662 printf (_("4 bytes\n"));
12663 break;
12664 default:
12665 printf ("??? (%d)\n", val);
12666 break;
12667 }
12668 return p;
12669
12670 case Tag_ABI_stack_align_needed:
f6f0e17b 12671 val = read_uleb128 (p, &len, end);
87779176
JM
12672 p += len;
12673 printf (" Tag_ABI_stack_align_needed: ");
12674 switch (val)
12675 {
12676 case 0:
12677 printf (_("8-byte\n"));
12678 break;
12679 case 1:
12680 printf (_("16-byte\n"));
12681 break;
12682 default:
12683 printf ("??? (%d)\n", val);
12684 break;
12685 }
12686 return p;
12687
12688 case Tag_ABI_stack_align_preserved:
f6f0e17b 12689 val = read_uleb128 (p, &len, end);
87779176
JM
12690 p += len;
12691 printf (" Tag_ABI_stack_align_preserved: ");
12692 switch (val)
12693 {
12694 case 0:
12695 printf (_("8-byte\n"));
12696 break;
12697 case 1:
12698 printf (_("16-byte\n"));
12699 break;
12700 default:
12701 printf ("??? (%d)\n", val);
12702 break;
12703 }
12704 return p;
12705
b5593623 12706 case Tag_ABI_DSBT:
f6f0e17b 12707 val = read_uleb128 (p, &len, end);
b5593623
JM
12708 p += len;
12709 printf (" Tag_ABI_DSBT: ");
12710 switch (val)
12711 {
12712 case 0:
12713 printf (_("DSBT addressing not used\n"));
12714 break;
12715 case 1:
12716 printf (_("DSBT addressing used\n"));
12717 break;
12718 default:
12719 printf ("??? (%d)\n", val);
12720 break;
12721 }
12722 return p;
12723
87779176 12724 case Tag_ABI_PID:
f6f0e17b 12725 val = read_uleb128 (p, &len, end);
87779176
JM
12726 p += len;
12727 printf (" Tag_ABI_PID: ");
12728 switch (val)
12729 {
12730 case 0:
12731 printf (_("Data addressing position-dependent\n"));
12732 break;
12733 case 1:
12734 printf (_("Data addressing position-independent, GOT near DP\n"));
12735 break;
12736 case 2:
12737 printf (_("Data addressing position-independent, GOT far from DP\n"));
12738 break;
12739 default:
12740 printf ("??? (%d)\n", val);
12741 break;
12742 }
12743 return p;
12744
12745 case Tag_ABI_PIC:
f6f0e17b 12746 val = read_uleb128 (p, &len, end);
87779176
JM
12747 p += len;
12748 printf (" Tag_ABI_PIC: ");
12749 switch (val)
12750 {
12751 case 0:
12752 printf (_("Code addressing position-dependent\n"));
12753 break;
12754 case 1:
12755 printf (_("Code addressing position-independent\n"));
12756 break;
12757 default:
12758 printf ("??? (%d)\n", val);
12759 break;
12760 }
12761 return p;
12762
12763 case Tag_ABI_array_object_alignment:
f6f0e17b 12764 val = read_uleb128 (p, &len, end);
87779176
JM
12765 p += len;
12766 printf (" Tag_ABI_array_object_alignment: ");
12767 switch (val)
12768 {
12769 case 0:
12770 printf (_("8-byte\n"));
12771 break;
12772 case 1:
12773 printf (_("4-byte\n"));
12774 break;
12775 case 2:
12776 printf (_("16-byte\n"));
12777 break;
12778 default:
12779 printf ("??? (%d)\n", val);
12780 break;
12781 }
12782 return p;
12783
12784 case Tag_ABI_array_object_align_expected:
f6f0e17b 12785 val = read_uleb128 (p, &len, end);
87779176
JM
12786 p += len;
12787 printf (" Tag_ABI_array_object_align_expected: ");
12788 switch (val)
12789 {
12790 case 0:
12791 printf (_("8-byte\n"));
12792 break;
12793 case 1:
12794 printf (_("4-byte\n"));
12795 break;
12796 case 2:
12797 printf (_("16-byte\n"));
12798 break;
12799 default:
12800 printf ("??? (%d)\n", val);
12801 break;
12802 }
12803 return p;
12804
3cbd1c06 12805 case Tag_ABI_compatibility:
071436c6 12806 {
071436c6
NC
12807 val = read_uleb128 (p, &len, end);
12808 p += len;
12809 printf (" Tag_ABI_compatibility: ");
071436c6 12810 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12811 if (p < end - 1)
12812 {
12813 size_t maxlen = (end - p) - 1;
12814
12815 print_symbol ((int) maxlen, (const char *) p);
12816 p += strnlen ((char *) p, maxlen) + 1;
12817 }
12818 else
12819 {
12820 printf (_("<corrupt>"));
12821 p = (unsigned char *) end;
12822 }
071436c6 12823 putchar ('\n');
071436c6
NC
12824 return p;
12825 }
87779176
JM
12826
12827 case Tag_ABI_conformance:
071436c6 12828 {
4082ef84
NC
12829 printf (" Tag_ABI_conformance: \"");
12830 if (p < end - 1)
12831 {
12832 size_t maxlen = (end - p) - 1;
071436c6 12833
4082ef84
NC
12834 print_symbol ((int) maxlen, (const char *) p);
12835 p += strnlen ((char *) p, maxlen) + 1;
12836 }
12837 else
12838 {
12839 printf (_("<corrupt>"));
12840 p = (unsigned char *) end;
12841 }
071436c6 12842 printf ("\"\n");
071436c6
NC
12843 return p;
12844 }
59e6276b
JM
12845 }
12846
f6f0e17b
NC
12847 return display_tag_value (tag, p, end);
12848}
59e6276b 12849
f6f0e17b
NC
12850static void
12851display_raw_attribute (unsigned char * p, unsigned char * end)
12852{
12853 unsigned long addr = 0;
12854 size_t bytes = end - p;
12855
e0a31db1 12856 assert (end > p);
f6f0e17b 12857 while (bytes)
87779176 12858 {
f6f0e17b
NC
12859 int j;
12860 int k;
12861 int lbytes = (bytes > 16 ? 16 : bytes);
12862
12863 printf (" 0x%8.8lx ", addr);
12864
12865 for (j = 0; j < 16; j++)
12866 {
12867 if (j < lbytes)
12868 printf ("%2.2x", p[j]);
12869 else
12870 printf (" ");
12871
12872 if ((j & 3) == 3)
12873 printf (" ");
12874 }
12875
12876 for (j = 0; j < lbytes; j++)
12877 {
12878 k = p[j];
12879 if (k >= ' ' && k < 0x7f)
12880 printf ("%c", k);
12881 else
12882 printf (".");
12883 }
12884
12885 putchar ('\n');
12886
12887 p += lbytes;
12888 bytes -= lbytes;
12889 addr += lbytes;
87779176 12890 }
59e6276b 12891
f6f0e17b 12892 putchar ('\n');
59e6276b
JM
12893}
12894
13761a11
NC
12895static unsigned char *
12896display_msp430x_attribute (unsigned char * p,
12897 const unsigned char * const end)
12898{
12899 unsigned int len;
12900 int val;
12901 int tag;
12902
12903 tag = read_uleb128 (p, & len, end);
12904 p += len;
0b4362b0 12905
13761a11
NC
12906 switch (tag)
12907 {
12908 case OFBA_MSPABI_Tag_ISA:
12909 val = read_uleb128 (p, &len, end);
12910 p += len;
12911 printf (" Tag_ISA: ");
12912 switch (val)
12913 {
12914 case 0: printf (_("None\n")); break;
12915 case 1: printf (_("MSP430\n")); break;
12916 case 2: printf (_("MSP430X\n")); break;
12917 default: printf ("??? (%d)\n", val); break;
12918 }
12919 break;
12920
12921 case OFBA_MSPABI_Tag_Code_Model:
12922 val = read_uleb128 (p, &len, end);
12923 p += len;
12924 printf (" Tag_Code_Model: ");
12925 switch (val)
12926 {
12927 case 0: printf (_("None\n")); break;
12928 case 1: printf (_("Small\n")); break;
12929 case 2: printf (_("Large\n")); break;
12930 default: printf ("??? (%d)\n", val); break;
12931 }
12932 break;
12933
12934 case OFBA_MSPABI_Tag_Data_Model:
12935 val = read_uleb128 (p, &len, end);
12936 p += len;
12937 printf (" Tag_Data_Model: ");
12938 switch (val)
12939 {
12940 case 0: printf (_("None\n")); break;
12941 case 1: printf (_("Small\n")); break;
12942 case 2: printf (_("Large\n")); break;
12943 case 3: printf (_("Restricted Large\n")); break;
12944 default: printf ("??? (%d)\n", val); break;
12945 }
12946 break;
12947
12948 default:
12949 printf (_(" <unknown tag %d>: "), tag);
12950
12951 if (tag & 1)
12952 {
071436c6 12953 putchar ('"');
4082ef84
NC
12954 if (p < end - 1)
12955 {
12956 size_t maxlen = (end - p) - 1;
12957
12958 print_symbol ((int) maxlen, (const char *) p);
12959 p += strnlen ((char *) p, maxlen) + 1;
12960 }
12961 else
12962 {
12963 printf (_("<corrupt>"));
12964 p = (unsigned char *) end;
12965 }
071436c6 12966 printf ("\"\n");
13761a11
NC
12967 }
12968 else
12969 {
12970 val = read_uleb128 (p, &len, end);
12971 p += len;
12972 printf ("%d (0x%x)\n", val, val);
12973 }
12974 break;
12975 }
12976
4082ef84 12977 assert (p <= end);
13761a11
NC
12978 return p;
12979}
12980
11c1ff18 12981static int
60bca95a
NC
12982process_attributes (FILE * file,
12983 const char * public_name,
104d59d1 12984 unsigned int proc_type,
f6f0e17b
NC
12985 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12986 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12987{
2cf0635d 12988 Elf_Internal_Shdr * sect;
11c1ff18
PB
12989 unsigned i;
12990
12991 /* Find the section header so that we get the size. */
12992 for (i = 0, sect = section_headers;
12993 i < elf_header.e_shnum;
12994 i++, sect++)
12995 {
071436c6
NC
12996 unsigned char * contents;
12997 unsigned char * p;
12998
104d59d1 12999 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13000 continue;
13001
3f5e193b
NC
13002 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13003 sect->sh_size, _("attributes"));
60bca95a 13004 if (contents == NULL)
11c1ff18 13005 continue;
60bca95a 13006
11c1ff18
PB
13007 p = contents;
13008 if (*p == 'A')
13009 {
071436c6
NC
13010 bfd_vma section_len;
13011
13012 section_len = sect->sh_size - 1;
11c1ff18 13013 p++;
60bca95a 13014
071436c6 13015 while (section_len > 0)
11c1ff18 13016 {
071436c6 13017 bfd_vma attr_len;
e9847026 13018 unsigned int namelen;
11c1ff18 13019 bfd_boolean public_section;
104d59d1 13020 bfd_boolean gnu_section;
11c1ff18 13021
071436c6 13022 if (section_len <= 4)
e0a31db1
NC
13023 {
13024 error (_("Tag section ends prematurely\n"));
13025 break;
13026 }
071436c6 13027 attr_len = byte_get (p, 4);
11c1ff18 13028 p += 4;
60bca95a 13029
071436c6 13030 if (attr_len > section_len)
11c1ff18 13031 {
071436c6
NC
13032 error (_("Bad attribute length (%u > %u)\n"),
13033 (unsigned) attr_len, (unsigned) section_len);
13034 attr_len = section_len;
11c1ff18 13035 }
74e1a04b 13036 /* PR 17531: file: 001-101425-0.004 */
071436c6 13037 else if (attr_len < 5)
74e1a04b 13038 {
071436c6 13039 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13040 break;
13041 }
e9847026 13042
071436c6
NC
13043 section_len -= attr_len;
13044 attr_len -= 4;
13045
13046 namelen = strnlen ((char *) p, attr_len) + 1;
13047 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13048 {
13049 error (_("Corrupt attribute section name\n"));
13050 break;
13051 }
13052
071436c6
NC
13053 printf (_("Attribute Section: "));
13054 print_symbol (INT_MAX, (const char *) p);
13055 putchar ('\n');
60bca95a
NC
13056
13057 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13058 public_section = TRUE;
13059 else
13060 public_section = FALSE;
60bca95a
NC
13061
13062 if (streq ((char *) p, "gnu"))
104d59d1
JM
13063 gnu_section = TRUE;
13064 else
13065 gnu_section = FALSE;
60bca95a 13066
11c1ff18 13067 p += namelen;
071436c6 13068 attr_len -= namelen;
e0a31db1 13069
071436c6 13070 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13071 {
e0a31db1 13072 int tag;
11c1ff18
PB
13073 int val;
13074 bfd_vma size;
071436c6 13075 unsigned char * end;
60bca95a 13076
e0a31db1 13077 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13078 if (attr_len < 6)
e0a31db1
NC
13079 {
13080 error (_("Unused bytes at end of section\n"));
13081 section_len = 0;
13082 break;
13083 }
13084
13085 tag = *(p++);
11c1ff18 13086 size = byte_get (p, 4);
071436c6 13087 if (size > attr_len)
11c1ff18 13088 {
e9847026 13089 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13090 (unsigned) size, (unsigned) attr_len);
13091 size = attr_len;
11c1ff18 13092 }
e0a31db1
NC
13093 /* PR binutils/17531: Safe handling of corrupt files. */
13094 if (size < 6)
13095 {
13096 error (_("Bad subsection length (%u < 6)\n"),
13097 (unsigned) size);
13098 section_len = 0;
13099 break;
13100 }
60bca95a 13101
071436c6 13102 attr_len -= size;
11c1ff18 13103 end = p + size - 1;
071436c6 13104 assert (end <= contents + sect->sh_size);
11c1ff18 13105 p += 4;
60bca95a 13106
11c1ff18
PB
13107 switch (tag)
13108 {
13109 case 1:
2b692964 13110 printf (_("File Attributes\n"));
11c1ff18
PB
13111 break;
13112 case 2:
2b692964 13113 printf (_("Section Attributes:"));
11c1ff18
PB
13114 goto do_numlist;
13115 case 3:
2b692964 13116 printf (_("Symbol Attributes:"));
11c1ff18
PB
13117 do_numlist:
13118 for (;;)
13119 {
91d6fa6a 13120 unsigned int j;
60bca95a 13121
f6f0e17b 13122 val = read_uleb128 (p, &j, end);
91d6fa6a 13123 p += j;
11c1ff18
PB
13124 if (val == 0)
13125 break;
13126 printf (" %d", val);
13127 }
13128 printf ("\n");
13129 break;
13130 default:
2b692964 13131 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13132 public_section = FALSE;
13133 break;
13134 }
60bca95a 13135
071436c6 13136 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13137 {
13138 while (p < end)
f6f0e17b 13139 p = display_pub_attribute (p, end);
071436c6 13140 assert (p <= end);
104d59d1 13141 }
071436c6 13142 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13143 {
13144 while (p < end)
13145 p = display_gnu_attribute (p,
f6f0e17b
NC
13146 display_proc_gnu_attribute,
13147 end);
071436c6 13148 assert (p <= end);
11c1ff18 13149 }
071436c6 13150 else if (p < end)
11c1ff18 13151 {
071436c6 13152 printf (_(" Unknown attribute:\n"));
f6f0e17b 13153 display_raw_attribute (p, end);
11c1ff18
PB
13154 p = end;
13155 }
071436c6
NC
13156 else
13157 attr_len = 0;
11c1ff18
PB
13158 }
13159 }
13160 }
13161 else
e9847026 13162 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13163
60bca95a 13164 free (contents);
11c1ff18
PB
13165 }
13166 return 1;
13167}
13168
104d59d1 13169static int
2cf0635d 13170process_arm_specific (FILE * file)
104d59d1
JM
13171{
13172 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13173 display_arm_attribute, NULL);
13174}
13175
34c8bcba 13176static int
2cf0635d 13177process_power_specific (FILE * file)
34c8bcba
JM
13178{
13179 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13180 display_power_gnu_attribute);
13181}
13182
9e8c70f9
DM
13183static int
13184process_sparc_specific (FILE * file)
13185{
13186 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13187 display_sparc_gnu_attribute);
13188}
13189
59e6276b
JM
13190static int
13191process_tic6x_specific (FILE * file)
13192{
13193 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13194 display_tic6x_attribute, NULL);
13195}
13196
13761a11
NC
13197static int
13198process_msp430x_specific (FILE * file)
13199{
13200 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13201 display_msp430x_attribute, NULL);
13202}
13203
ccb4c951
RS
13204/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13205 Print the Address, Access and Initial fields of an entry at VMA ADDR
13206 and return the VMA of the next entry. */
13207
13208static bfd_vma
2cf0635d 13209print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
13210{
13211 printf (" ");
13212 print_vma (addr, LONG_HEX);
13213 printf (" ");
13214 if (addr < pltgot + 0xfff0)
13215 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13216 else
13217 printf ("%10s", "");
13218 printf (" ");
13219 if (data == NULL)
2b692964 13220 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13221 else
13222 {
13223 bfd_vma entry;
13224
13225 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13226 print_vma (entry, LONG_HEX);
13227 }
13228 return addr + (is_32bit_elf ? 4 : 8);
13229}
13230
861fb55a
DJ
13231/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13232 PLTGOT. Print the Address and Initial fields of an entry at VMA
13233 ADDR and return the VMA of the next entry. */
13234
13235static bfd_vma
2cf0635d 13236print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13237{
13238 printf (" ");
13239 print_vma (addr, LONG_HEX);
13240 printf (" ");
13241 if (data == NULL)
2b692964 13242 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13243 else
13244 {
13245 bfd_vma entry;
13246
13247 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13248 print_vma (entry, LONG_HEX);
13249 }
13250 return addr + (is_32bit_elf ? 4 : 8);
13251}
13252
351cdf24
MF
13253static void
13254print_mips_ases (unsigned int mask)
13255{
13256 if (mask & AFL_ASE_DSP)
13257 fputs ("\n\tDSP ASE", stdout);
13258 if (mask & AFL_ASE_DSPR2)
13259 fputs ("\n\tDSP R2 ASE", stdout);
13260 if (mask & AFL_ASE_EVA)
13261 fputs ("\n\tEnhanced VA Scheme", stdout);
13262 if (mask & AFL_ASE_MCU)
13263 fputs ("\n\tMCU (MicroController) ASE", stdout);
13264 if (mask & AFL_ASE_MDMX)
13265 fputs ("\n\tMDMX ASE", stdout);
13266 if (mask & AFL_ASE_MIPS3D)
13267 fputs ("\n\tMIPS-3D ASE", stdout);
13268 if (mask & AFL_ASE_MT)
13269 fputs ("\n\tMT ASE", stdout);
13270 if (mask & AFL_ASE_SMARTMIPS)
13271 fputs ("\n\tSmartMIPS ASE", stdout);
13272 if (mask & AFL_ASE_VIRT)
13273 fputs ("\n\tVZ ASE", stdout);
13274 if (mask & AFL_ASE_MSA)
13275 fputs ("\n\tMSA ASE", stdout);
13276 if (mask & AFL_ASE_MIPS16)
13277 fputs ("\n\tMIPS16 ASE", stdout);
13278 if (mask & AFL_ASE_MICROMIPS)
13279 fputs ("\n\tMICROMIPS ASE", stdout);
13280 if (mask & AFL_ASE_XPA)
13281 fputs ("\n\tXPA ASE", stdout);
13282 if (mask == 0)
13283 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13284 else if ((mask & ~AFL_ASE_MASK) != 0)
13285 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13286}
13287
13288static void
13289print_mips_isa_ext (unsigned int isa_ext)
13290{
13291 switch (isa_ext)
13292 {
13293 case 0:
13294 fputs (_("None"), stdout);
13295 break;
13296 case AFL_EXT_XLR:
13297 fputs ("RMI XLR", stdout);
13298 break;
2c629856
N
13299 case AFL_EXT_OCTEON3:
13300 fputs ("Cavium Networks Octeon3", stdout);
13301 break;
351cdf24
MF
13302 case AFL_EXT_OCTEON2:
13303 fputs ("Cavium Networks Octeon2", stdout);
13304 break;
13305 case AFL_EXT_OCTEONP:
13306 fputs ("Cavium Networks OcteonP", stdout);
13307 break;
13308 case AFL_EXT_LOONGSON_3A:
13309 fputs ("Loongson 3A", stdout);
13310 break;
13311 case AFL_EXT_OCTEON:
13312 fputs ("Cavium Networks Octeon", stdout);
13313 break;
13314 case AFL_EXT_5900:
13315 fputs ("Toshiba R5900", stdout);
13316 break;
13317 case AFL_EXT_4650:
13318 fputs ("MIPS R4650", stdout);
13319 break;
13320 case AFL_EXT_4010:
13321 fputs ("LSI R4010", stdout);
13322 break;
13323 case AFL_EXT_4100:
13324 fputs ("NEC VR4100", stdout);
13325 break;
13326 case AFL_EXT_3900:
13327 fputs ("Toshiba R3900", stdout);
13328 break;
13329 case AFL_EXT_10000:
13330 fputs ("MIPS R10000", stdout);
13331 break;
13332 case AFL_EXT_SB1:
13333 fputs ("Broadcom SB-1", stdout);
13334 break;
13335 case AFL_EXT_4111:
13336 fputs ("NEC VR4111/VR4181", stdout);
13337 break;
13338 case AFL_EXT_4120:
13339 fputs ("NEC VR4120", stdout);
13340 break;
13341 case AFL_EXT_5400:
13342 fputs ("NEC VR5400", stdout);
13343 break;
13344 case AFL_EXT_5500:
13345 fputs ("NEC VR5500", stdout);
13346 break;
13347 case AFL_EXT_LOONGSON_2E:
13348 fputs ("ST Microelectronics Loongson 2E", stdout);
13349 break;
13350 case AFL_EXT_LOONGSON_2F:
13351 fputs ("ST Microelectronics Loongson 2F", stdout);
13352 break;
13353 default:
00ac7aa0 13354 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13355 }
13356}
13357
13358static int
13359get_mips_reg_size (int reg_size)
13360{
13361 return (reg_size == AFL_REG_NONE) ? 0
13362 : (reg_size == AFL_REG_32) ? 32
13363 : (reg_size == AFL_REG_64) ? 64
13364 : (reg_size == AFL_REG_128) ? 128
13365 : -1;
13366}
13367
19e6b90e 13368static int
2cf0635d 13369process_mips_specific (FILE * file)
5b18a4bc 13370{
2cf0635d 13371 Elf_Internal_Dyn * entry;
351cdf24 13372 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13373 size_t liblist_offset = 0;
13374 size_t liblistno = 0;
13375 size_t conflictsno = 0;
13376 size_t options_offset = 0;
13377 size_t conflicts_offset = 0;
861fb55a
DJ
13378 size_t pltrelsz = 0;
13379 size_t pltrel = 0;
ccb4c951 13380 bfd_vma pltgot = 0;
861fb55a
DJ
13381 bfd_vma mips_pltgot = 0;
13382 bfd_vma jmprel = 0;
ccb4c951
RS
13383 bfd_vma local_gotno = 0;
13384 bfd_vma gotsym = 0;
13385 bfd_vma symtabno = 0;
103f02d3 13386
2cf19d5c
JM
13387 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13388 display_mips_gnu_attribute);
13389
351cdf24
MF
13390 sect = find_section (".MIPS.abiflags");
13391
13392 if (sect != NULL)
13393 {
13394 Elf_External_ABIFlags_v0 *abiflags_ext;
13395 Elf_Internal_ABIFlags_v0 abiflags_in;
13396
13397 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13398 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13399 else
13400 {
13401 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13402 sect->sh_size, _("MIPS ABI Flags section"));
13403 if (abiflags_ext)
13404 {
13405 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13406 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13407 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13408 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13409 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13410 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13411 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13412 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13413 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13414 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13415 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13416
13417 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13418 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13419 if (abiflags_in.isa_rev > 1)
13420 printf ("r%d", abiflags_in.isa_rev);
13421 printf ("\nGPR size: %d",
13422 get_mips_reg_size (abiflags_in.gpr_size));
13423 printf ("\nCPR1 size: %d",
13424 get_mips_reg_size (abiflags_in.cpr1_size));
13425 printf ("\nCPR2 size: %d",
13426 get_mips_reg_size (abiflags_in.cpr2_size));
13427 fputs ("\nFP ABI: ", stdout);
13428 print_mips_fp_abi_value (abiflags_in.fp_abi);
13429 fputs ("ISA Extension: ", stdout);
13430 print_mips_isa_ext (abiflags_in.isa_ext);
13431 fputs ("\nASEs:", stdout);
13432 print_mips_ases (abiflags_in.ases);
13433 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13434 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13435 fputc ('\n', stdout);
13436 free (abiflags_ext);
13437 }
13438 }
13439 }
13440
19e6b90e
L
13441 /* We have a lot of special sections. Thanks SGI! */
13442 if (dynamic_section == NULL)
13443 /* No information available. */
13444 return 0;
252b5132 13445
071436c6
NC
13446 for (entry = dynamic_section;
13447 /* PR 17531 file: 012-50589-0.004. */
13448 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13449 ++entry)
252b5132
RH
13450 switch (entry->d_tag)
13451 {
13452 case DT_MIPS_LIBLIST:
d93f0186
NC
13453 liblist_offset
13454 = offset_from_vma (file, entry->d_un.d_val,
13455 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13456 break;
13457 case DT_MIPS_LIBLISTNO:
13458 liblistno = entry->d_un.d_val;
13459 break;
13460 case DT_MIPS_OPTIONS:
d93f0186 13461 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13462 break;
13463 case DT_MIPS_CONFLICT:
d93f0186
NC
13464 conflicts_offset
13465 = offset_from_vma (file, entry->d_un.d_val,
13466 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13467 break;
13468 case DT_MIPS_CONFLICTNO:
13469 conflictsno = entry->d_un.d_val;
13470 break;
ccb4c951 13471 case DT_PLTGOT:
861fb55a
DJ
13472 pltgot = entry->d_un.d_ptr;
13473 break;
ccb4c951
RS
13474 case DT_MIPS_LOCAL_GOTNO:
13475 local_gotno = entry->d_un.d_val;
13476 break;
13477 case DT_MIPS_GOTSYM:
13478 gotsym = entry->d_un.d_val;
13479 break;
13480 case DT_MIPS_SYMTABNO:
13481 symtabno = entry->d_un.d_val;
13482 break;
861fb55a
DJ
13483 case DT_MIPS_PLTGOT:
13484 mips_pltgot = entry->d_un.d_ptr;
13485 break;
13486 case DT_PLTREL:
13487 pltrel = entry->d_un.d_val;
13488 break;
13489 case DT_PLTRELSZ:
13490 pltrelsz = entry->d_un.d_val;
13491 break;
13492 case DT_JMPREL:
13493 jmprel = entry->d_un.d_ptr;
13494 break;
252b5132
RH
13495 default:
13496 break;
13497 }
13498
13499 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13500 {
2cf0635d 13501 Elf32_External_Lib * elib;
252b5132
RH
13502 size_t cnt;
13503
3f5e193b
NC
13504 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13505 liblistno,
13506 sizeof (Elf32_External_Lib),
9cf03b7e 13507 _("liblist section data"));
a6e9f9df 13508 if (elib)
252b5132 13509 {
2b692964 13510 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13511 (unsigned long) liblistno);
2b692964 13512 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13513 stdout);
13514
13515 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13516 {
a6e9f9df 13517 Elf32_Lib liblist;
91d6fa6a 13518 time_t atime;
a6e9f9df 13519 char timebuf[20];
2cf0635d 13520 struct tm * tmp;
a6e9f9df
AM
13521
13522 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13523 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13524 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13525 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13526 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13527
91d6fa6a 13528 tmp = gmtime (&atime);
e9e44622
JJ
13529 snprintf (timebuf, sizeof (timebuf),
13530 "%04u-%02u-%02uT%02u:%02u:%02u",
13531 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13532 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13533
31104126 13534 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13535 if (VALID_DYNAMIC_NAME (liblist.l_name))
13536 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13537 else
2b692964 13538 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13539 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13540 liblist.l_version);
a6e9f9df
AM
13541
13542 if (liblist.l_flags == 0)
2b692964 13543 puts (_(" NONE"));
a6e9f9df
AM
13544 else
13545 {
13546 static const struct
252b5132 13547 {
2cf0635d 13548 const char * name;
a6e9f9df 13549 int bit;
252b5132 13550 }
a6e9f9df
AM
13551 l_flags_vals[] =
13552 {
13553 { " EXACT_MATCH", LL_EXACT_MATCH },
13554 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13555 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13556 { " EXPORTS", LL_EXPORTS },
13557 { " DELAY_LOAD", LL_DELAY_LOAD },
13558 { " DELTA", LL_DELTA }
13559 };
13560 int flags = liblist.l_flags;
13561 size_t fcnt;
13562
60bca95a 13563 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13564 if ((flags & l_flags_vals[fcnt].bit) != 0)
13565 {
13566 fputs (l_flags_vals[fcnt].name, stdout);
13567 flags ^= l_flags_vals[fcnt].bit;
13568 }
13569 if (flags != 0)
13570 printf (" %#x", (unsigned int) flags);
252b5132 13571
a6e9f9df
AM
13572 puts ("");
13573 }
252b5132 13574 }
252b5132 13575
a6e9f9df
AM
13576 free (elib);
13577 }
252b5132
RH
13578 }
13579
13580 if (options_offset != 0)
13581 {
2cf0635d 13582 Elf_External_Options * eopt;
2cf0635d
NC
13583 Elf_Internal_Options * iopt;
13584 Elf_Internal_Options * option;
252b5132
RH
13585 size_t offset;
13586 int cnt;
351cdf24 13587 sect = section_headers;
252b5132
RH
13588
13589 /* Find the section header so that we get the size. */
071436c6
NC
13590 sect = find_section_by_type (SHT_MIPS_OPTIONS);
13591 /* PR 17533 file: 012-277276-0.004. */
13592 if (sect == NULL)
13593 {
13594 error (_("No MIPS_OPTIONS header found\n"));
13595 return 0;
13596 }
252b5132 13597
3f5e193b
NC
13598 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13599 sect->sh_size, _("options"));
a6e9f9df 13600 if (eopt)
252b5132 13601 {
3f5e193b
NC
13602 iopt = (Elf_Internal_Options *)
13603 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13604 if (iopt == NULL)
13605 {
8b73c356 13606 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13607 return 0;
13608 }
76da6bbe 13609
a6e9f9df
AM
13610 offset = cnt = 0;
13611 option = iopt;
252b5132 13612
a6e9f9df
AM
13613 while (offset < sect->sh_size)
13614 {
2cf0635d 13615 Elf_External_Options * eoption;
252b5132 13616
a6e9f9df 13617 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13618
a6e9f9df
AM
13619 option->kind = BYTE_GET (eoption->kind);
13620 option->size = BYTE_GET (eoption->size);
13621 option->section = BYTE_GET (eoption->section);
13622 option->info = BYTE_GET (eoption->info);
76da6bbe 13623
a6e9f9df 13624 offset += option->size;
252b5132 13625
a6e9f9df
AM
13626 ++option;
13627 ++cnt;
13628 }
252b5132 13629
a6e9f9df 13630 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13631 printable_section_name (sect), cnt);
76da6bbe 13632
a6e9f9df 13633 option = iopt;
252b5132 13634
a6e9f9df 13635 while (cnt-- > 0)
252b5132 13636 {
a6e9f9df
AM
13637 size_t len;
13638
13639 switch (option->kind)
252b5132 13640 {
a6e9f9df
AM
13641 case ODK_NULL:
13642 /* This shouldn't happen. */
13643 printf (" NULL %d %lx", option->section, option->info);
13644 break;
13645 case ODK_REGINFO:
13646 printf (" REGINFO ");
13647 if (elf_header.e_machine == EM_MIPS)
13648 {
13649 /* 32bit form. */
2cf0635d 13650 Elf32_External_RegInfo * ereg;
b34976b6 13651 Elf32_RegInfo reginfo;
a6e9f9df
AM
13652
13653 ereg = (Elf32_External_RegInfo *) (option + 1);
13654 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13655 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13656 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13657 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13658 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13659 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13660
13661 printf ("GPR %08lx GP 0x%lx\n",
13662 reginfo.ri_gprmask,
13663 (unsigned long) reginfo.ri_gp_value);
13664 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13665 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13666 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13667 }
13668 else
13669 {
13670 /* 64 bit form. */
2cf0635d 13671 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13672 Elf64_Internal_RegInfo reginfo;
13673
13674 ereg = (Elf64_External_RegInfo *) (option + 1);
13675 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13676 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13677 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13678 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13679 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13680 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13681
13682 printf ("GPR %08lx GP 0x",
13683 reginfo.ri_gprmask);
13684 printf_vma (reginfo.ri_gp_value);
13685 printf ("\n");
13686
13687 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13688 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13689 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13690 }
13691 ++option;
13692 continue;
13693 case ODK_EXCEPTIONS:
13694 fputs (" EXCEPTIONS fpe_min(", stdout);
13695 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13696 fputs (") fpe_max(", stdout);
13697 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13698 fputs (")", stdout);
13699
13700 if (option->info & OEX_PAGE0)
13701 fputs (" PAGE0", stdout);
13702 if (option->info & OEX_SMM)
13703 fputs (" SMM", stdout);
13704 if (option->info & OEX_FPDBUG)
13705 fputs (" FPDBUG", stdout);
13706 if (option->info & OEX_DISMISS)
13707 fputs (" DISMISS", stdout);
13708 break;
13709 case ODK_PAD:
13710 fputs (" PAD ", stdout);
13711 if (option->info & OPAD_PREFIX)
13712 fputs (" PREFIX", stdout);
13713 if (option->info & OPAD_POSTFIX)
13714 fputs (" POSTFIX", stdout);
13715 if (option->info & OPAD_SYMBOL)
13716 fputs (" SYMBOL", stdout);
13717 break;
13718 case ODK_HWPATCH:
13719 fputs (" HWPATCH ", stdout);
13720 if (option->info & OHW_R4KEOP)
13721 fputs (" R4KEOP", stdout);
13722 if (option->info & OHW_R8KPFETCH)
13723 fputs (" R8KPFETCH", stdout);
13724 if (option->info & OHW_R5KEOP)
13725 fputs (" R5KEOP", stdout);
13726 if (option->info & OHW_R5KCVTL)
13727 fputs (" R5KCVTL", stdout);
13728 break;
13729 case ODK_FILL:
13730 fputs (" FILL ", stdout);
13731 /* XXX Print content of info word? */
13732 break;
13733 case ODK_TAGS:
13734 fputs (" TAGS ", stdout);
13735 /* XXX Print content of info word? */
13736 break;
13737 case ODK_HWAND:
13738 fputs (" HWAND ", stdout);
13739 if (option->info & OHWA0_R4KEOP_CHECKED)
13740 fputs (" R4KEOP_CHECKED", stdout);
13741 if (option->info & OHWA0_R4KEOP_CLEAN)
13742 fputs (" R4KEOP_CLEAN", stdout);
13743 break;
13744 case ODK_HWOR:
13745 fputs (" HWOR ", stdout);
13746 if (option->info & OHWA0_R4KEOP_CHECKED)
13747 fputs (" R4KEOP_CHECKED", stdout);
13748 if (option->info & OHWA0_R4KEOP_CLEAN)
13749 fputs (" R4KEOP_CLEAN", stdout);
13750 break;
13751 case ODK_GP_GROUP:
13752 printf (" GP_GROUP %#06lx self-contained %#06lx",
13753 option->info & OGP_GROUP,
13754 (option->info & OGP_SELF) >> 16);
13755 break;
13756 case ODK_IDENT:
13757 printf (" IDENT %#06lx self-contained %#06lx",
13758 option->info & OGP_GROUP,
13759 (option->info & OGP_SELF) >> 16);
13760 break;
13761 default:
13762 /* This shouldn't happen. */
13763 printf (" %3d ??? %d %lx",
13764 option->kind, option->section, option->info);
13765 break;
252b5132 13766 }
a6e9f9df 13767
2cf0635d 13768 len = sizeof (* eopt);
a6e9f9df
AM
13769 while (len < option->size)
13770 if (((char *) option)[len] >= ' '
13771 && ((char *) option)[len] < 0x7f)
13772 printf ("%c", ((char *) option)[len++]);
13773 else
13774 printf ("\\%03o", ((char *) option)[len++]);
13775
13776 fputs ("\n", stdout);
252b5132 13777 ++option;
252b5132
RH
13778 }
13779
a6e9f9df 13780 free (eopt);
252b5132 13781 }
252b5132
RH
13782 }
13783
13784 if (conflicts_offset != 0 && conflictsno != 0)
13785 {
2cf0635d 13786 Elf32_Conflict * iconf;
252b5132
RH
13787 size_t cnt;
13788
13789 if (dynamic_symbols == NULL)
13790 {
591a748a 13791 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
13792 return 0;
13793 }
13794
3f5e193b 13795 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
13796 if (iconf == NULL)
13797 {
8b73c356 13798 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
13799 return 0;
13800 }
13801
9ea033b2 13802 if (is_32bit_elf)
252b5132 13803 {
2cf0635d 13804 Elf32_External_Conflict * econf32;
a6e9f9df 13805
3f5e193b
NC
13806 econf32 = (Elf32_External_Conflict *)
13807 get_data (NULL, file, conflicts_offset, conflictsno,
13808 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
13809 if (!econf32)
13810 return 0;
252b5132
RH
13811
13812 for (cnt = 0; cnt < conflictsno; ++cnt)
13813 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13814
13815 free (econf32);
252b5132
RH
13816 }
13817 else
13818 {
2cf0635d 13819 Elf64_External_Conflict * econf64;
a6e9f9df 13820
3f5e193b
NC
13821 econf64 = (Elf64_External_Conflict *)
13822 get_data (NULL, file, conflicts_offset, conflictsno,
13823 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13824 if (!econf64)
13825 return 0;
252b5132
RH
13826
13827 for (cnt = 0; cnt < conflictsno; ++cnt)
13828 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
13829
13830 free (econf64);
252b5132
RH
13831 }
13832
c7e7ca54
NC
13833 printf (_("\nSection '.conflict' contains %lu entries:\n"),
13834 (unsigned long) conflictsno);
252b5132
RH
13835 puts (_(" Num: Index Value Name"));
13836
13837 for (cnt = 0; cnt < conflictsno; ++cnt)
13838 {
b34976b6 13839 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
13840
13841 if (iconf[cnt] >= num_dynamic_syms)
13842 printf (_("<corrupt symbol index>"));
d79b3d50 13843 else
e0a31db1
NC
13844 {
13845 Elf_Internal_Sym * psym;
13846
13847 psym = & dynamic_symbols[iconf[cnt]];
13848 print_vma (psym->st_value, FULL_HEX);
13849 putchar (' ');
13850 if (VALID_DYNAMIC_NAME (psym->st_name))
13851 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
13852 else
13853 printf (_("<corrupt: %14ld>"), psym->st_name);
13854 }
31104126 13855 putchar ('\n');
252b5132
RH
13856 }
13857
252b5132
RH
13858 free (iconf);
13859 }
13860
ccb4c951
RS
13861 if (pltgot != 0 && local_gotno != 0)
13862 {
91d6fa6a 13863 bfd_vma ent, local_end, global_end;
bbeee7ea 13864 size_t i, offset;
2cf0635d 13865 unsigned char * data;
bbeee7ea 13866 int addr_size;
ccb4c951 13867
91d6fa6a 13868 ent = pltgot;
ccb4c951
RS
13869 addr_size = (is_32bit_elf ? 4 : 8);
13870 local_end = pltgot + local_gotno * addr_size;
ccb4c951 13871
74e1a04b
NC
13872 /* PR binutils/17533 file: 012-111227-0.004 */
13873 if (symtabno < gotsym)
13874 {
13875 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
13876 (long) gotsym, (long) symtabno);
13877 return 0;
13878 }
13879
13880 global_end = local_end + (symtabno - gotsym) * addr_size;
13881 assert (global_end >= local_end);
ccb4c951 13882 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 13883 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
13884 global_end - pltgot, 1,
13885 _("Global Offset Table data"));
59245841
NC
13886 if (data == NULL)
13887 return 0;
13888
ccb4c951
RS
13889 printf (_("\nPrimary GOT:\n"));
13890 printf (_(" Canonical gp value: "));
13891 print_vma (pltgot + 0x7ff0, LONG_HEX);
13892 printf ("\n\n");
13893
13894 printf (_(" Reserved entries:\n"));
13895 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
13896 addr_size * 2, _("Address"), _("Access"),
13897 addr_size * 2, _("Initial"));
91d6fa6a 13898 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13899 printf (_(" Lazy resolver\n"));
ccb4c951 13900 if (data
91d6fa6a 13901 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
13902 >> (addr_size * 8 - 1)) != 0)
13903 {
91d6fa6a 13904 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13905 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
13906 }
13907 printf ("\n");
13908
91d6fa6a 13909 if (ent < local_end)
ccb4c951
RS
13910 {
13911 printf (_(" Local entries:\n"));
cc5914eb 13912 printf (" %*s %10s %*s\n",
2b692964
NC
13913 addr_size * 2, _("Address"), _("Access"),
13914 addr_size * 2, _("Initial"));
91d6fa6a 13915 while (ent < local_end)
ccb4c951 13916 {
91d6fa6a 13917 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13918 printf ("\n");
13919 }
13920 printf ("\n");
13921 }
13922
13923 if (gotsym < symtabno)
13924 {
13925 int sym_width;
13926
13927 printf (_(" Global entries:\n"));
cc5914eb 13928 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
13929 addr_size * 2, _("Address"),
13930 _("Access"),
2b692964 13931 addr_size * 2, _("Initial"),
9cf03b7e
NC
13932 addr_size * 2, _("Sym.Val."),
13933 _("Type"),
13934 /* Note for translators: "Ndx" = abbreviated form of "Index". */
13935 _("Ndx"), _("Name"));
0b4362b0 13936
ccb4c951 13937 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 13938
ccb4c951
RS
13939 for (i = gotsym; i < symtabno; i++)
13940 {
91d6fa6a 13941 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951 13942 printf (" ");
e0a31db1
NC
13943
13944 if (dynamic_symbols == NULL)
13945 printf (_("<no dynamic symbols>"));
13946 else if (i < num_dynamic_syms)
13947 {
13948 Elf_Internal_Sym * psym = dynamic_symbols + i;
13949
13950 print_vma (psym->st_value, LONG_HEX);
13951 printf (" %-7s %3s ",
13952 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13953 get_symbol_index_type (psym->st_shndx));
13954
13955 if (VALID_DYNAMIC_NAME (psym->st_name))
13956 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13957 else
13958 printf (_("<corrupt: %14ld>"), psym->st_name);
13959 }
ccb4c951 13960 else
7fc5ac57
JBG
13961 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
13962 (unsigned long) i);
e0a31db1 13963
ccb4c951
RS
13964 printf ("\n");
13965 }
13966 printf ("\n");
13967 }
13968
13969 if (data)
13970 free (data);
13971 }
13972
861fb55a
DJ
13973 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
13974 {
91d6fa6a 13975 bfd_vma ent, end;
861fb55a
DJ
13976 size_t offset, rel_offset;
13977 unsigned long count, i;
2cf0635d 13978 unsigned char * data;
861fb55a 13979 int addr_size, sym_width;
2cf0635d 13980 Elf_Internal_Rela * rels;
861fb55a
DJ
13981
13982 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
13983 if (pltrel == DT_RELA)
13984 {
13985 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
13986 return 0;
13987 }
13988 else
13989 {
13990 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
13991 return 0;
13992 }
13993
91d6fa6a 13994 ent = mips_pltgot;
861fb55a
DJ
13995 addr_size = (is_32bit_elf ? 4 : 8);
13996 end = mips_pltgot + (2 + count) * addr_size;
13997
13998 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 13999 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14000 1, _("Procedure Linkage Table data"));
59245841
NC
14001 if (data == NULL)
14002 return 0;
14003
9cf03b7e 14004 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14005 printf (_(" Reserved entries:\n"));
14006 printf (_(" %*s %*s Purpose\n"),
2b692964 14007 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14008 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14009 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14010 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14011 printf (_(" Module pointer\n"));
861fb55a
DJ
14012 printf ("\n");
14013
14014 printf (_(" Entries:\n"));
cc5914eb 14015 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14016 addr_size * 2, _("Address"),
14017 addr_size * 2, _("Initial"),
14018 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14019 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14020 for (i = 0; i < count; i++)
14021 {
df97ab2a 14022 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14023
91d6fa6a 14024 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14025 printf (" ");
e0a31db1 14026
df97ab2a
MF
14027 if (idx >= num_dynamic_syms)
14028 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14029 else
e0a31db1 14030 {
df97ab2a 14031 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14032
14033 print_vma (psym->st_value, LONG_HEX);
14034 printf (" %-7s %3s ",
14035 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14036 get_symbol_index_type (psym->st_shndx));
14037 if (VALID_DYNAMIC_NAME (psym->st_name))
14038 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14039 else
14040 printf (_("<corrupt: %14ld>"), psym->st_name);
14041 }
861fb55a
DJ
14042 printf ("\n");
14043 }
14044 printf ("\n");
14045
14046 if (data)
14047 free (data);
14048 free (rels);
14049 }
14050
252b5132
RH
14051 return 1;
14052}
14053
35c08157
KLC
14054static int
14055process_nds32_specific (FILE * file)
14056{
14057 Elf_Internal_Shdr *sect = NULL;
14058
14059 sect = find_section (".nds32_e_flags");
14060 if (sect != NULL)
14061 {
14062 unsigned int *flag;
14063
14064 printf ("\nNDS32 elf flags section:\n");
14065 flag = get_data (NULL, file, sect->sh_offset, 1,
14066 sect->sh_size, _("NDS32 elf flags section"));
14067
14068 switch ((*flag) & 0x3)
14069 {
14070 case 0:
14071 printf ("(VEC_SIZE):\tNo entry.\n");
14072 break;
14073 case 1:
14074 printf ("(VEC_SIZE):\t4 bytes\n");
14075 break;
14076 case 2:
14077 printf ("(VEC_SIZE):\t16 bytes\n");
14078 break;
14079 case 3:
14080 printf ("(VEC_SIZE):\treserved\n");
14081 break;
14082 }
14083 }
14084
14085 return TRUE;
14086}
14087
047b2264 14088static int
2cf0635d 14089process_gnu_liblist (FILE * file)
047b2264 14090{
2cf0635d
NC
14091 Elf_Internal_Shdr * section;
14092 Elf_Internal_Shdr * string_sec;
14093 Elf32_External_Lib * elib;
14094 char * strtab;
c256ffe7 14095 size_t strtab_size;
047b2264
JJ
14096 size_t cnt;
14097 unsigned i;
14098
14099 if (! do_arch)
14100 return 0;
14101
14102 for (i = 0, section = section_headers;
14103 i < elf_header.e_shnum;
b34976b6 14104 i++, section++)
047b2264
JJ
14105 {
14106 switch (section->sh_type)
14107 {
14108 case SHT_GNU_LIBLIST:
4fbb74a6 14109 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14110 break;
14111
3f5e193b
NC
14112 elib = (Elf32_External_Lib *)
14113 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14114 _("liblist section data"));
047b2264
JJ
14115
14116 if (elib == NULL)
14117 break;
4fbb74a6 14118 string_sec = section_headers + section->sh_link;
047b2264 14119
3f5e193b
NC
14120 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14121 string_sec->sh_size,
14122 _("liblist string table"));
047b2264
JJ
14123 if (strtab == NULL
14124 || section->sh_entsize != sizeof (Elf32_External_Lib))
14125 {
14126 free (elib);
2842702f 14127 free (strtab);
047b2264
JJ
14128 break;
14129 }
59245841 14130 strtab_size = string_sec->sh_size;
047b2264
JJ
14131
14132 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14133 printable_section_name (section),
0af1713e 14134 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14135
2b692964 14136 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14137
14138 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14139 ++cnt)
14140 {
14141 Elf32_Lib liblist;
91d6fa6a 14142 time_t atime;
047b2264 14143 char timebuf[20];
2cf0635d 14144 struct tm * tmp;
047b2264
JJ
14145
14146 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14147 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14148 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14149 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14150 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14151
91d6fa6a 14152 tmp = gmtime (&atime);
e9e44622
JJ
14153 snprintf (timebuf, sizeof (timebuf),
14154 "%04u-%02u-%02uT%02u:%02u:%02u",
14155 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14156 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14157
14158 printf ("%3lu: ", (unsigned long) cnt);
14159 if (do_wide)
c256ffe7 14160 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14161 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14162 else
c256ffe7 14163 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14164 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14165 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14166 liblist.l_version, liblist.l_flags);
14167 }
14168
14169 free (elib);
2842702f 14170 free (strtab);
047b2264
JJ
14171 }
14172 }
14173
14174 return 1;
14175}
14176
9437c45b 14177static const char *
d3ba0551 14178get_note_type (unsigned e_type)
779fe533
NC
14179{
14180 static char buff[64];
103f02d3 14181
1ec5cd37
NC
14182 if (elf_header.e_type == ET_CORE)
14183 switch (e_type)
14184 {
57346661 14185 case NT_AUXV:
1ec5cd37 14186 return _("NT_AUXV (auxiliary vector)");
57346661 14187 case NT_PRSTATUS:
1ec5cd37 14188 return _("NT_PRSTATUS (prstatus structure)");
57346661 14189 case NT_FPREGSET:
1ec5cd37 14190 return _("NT_FPREGSET (floating point registers)");
57346661 14191 case NT_PRPSINFO:
1ec5cd37 14192 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14193 case NT_TASKSTRUCT:
1ec5cd37 14194 return _("NT_TASKSTRUCT (task structure)");
57346661 14195 case NT_PRXFPREG:
1ec5cd37 14196 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14197 case NT_PPC_VMX:
14198 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14199 case NT_PPC_VSX:
14200 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14201 case NT_386_TLS:
14202 return _("NT_386_TLS (x86 TLS information)");
14203 case NT_386_IOPERM:
14204 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14205 case NT_X86_XSTATE:
14206 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14207 case NT_S390_HIGH_GPRS:
14208 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14209 case NT_S390_TIMER:
14210 return _("NT_S390_TIMER (s390 timer register)");
14211 case NT_S390_TODCMP:
14212 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14213 case NT_S390_TODPREG:
14214 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14215 case NT_S390_CTRS:
14216 return _("NT_S390_CTRS (s390 control registers)");
14217 case NT_S390_PREFIX:
14218 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14219 case NT_S390_LAST_BREAK:
14220 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14221 case NT_S390_SYSTEM_CALL:
14222 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14223 case NT_S390_TDB:
14224 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
14225 case NT_ARM_VFP:
14226 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14227 case NT_ARM_TLS:
14228 return _("NT_ARM_TLS (AArch TLS registers)");
14229 case NT_ARM_HW_BREAK:
14230 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14231 case NT_ARM_HW_WATCH:
14232 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14233 case NT_PSTATUS:
1ec5cd37 14234 return _("NT_PSTATUS (pstatus structure)");
57346661 14235 case NT_FPREGS:
1ec5cd37 14236 return _("NT_FPREGS (floating point registers)");
57346661 14237 case NT_PSINFO:
1ec5cd37 14238 return _("NT_PSINFO (psinfo structure)");
57346661 14239 case NT_LWPSTATUS:
1ec5cd37 14240 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14241 case NT_LWPSINFO:
1ec5cd37 14242 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14243 case NT_WIN32PSTATUS:
1ec5cd37 14244 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14245 case NT_SIGINFO:
14246 return _("NT_SIGINFO (siginfo_t data)");
14247 case NT_FILE:
14248 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14249 default:
14250 break;
14251 }
14252 else
14253 switch (e_type)
14254 {
14255 case NT_VERSION:
14256 return _("NT_VERSION (version)");
14257 case NT_ARCH:
14258 return _("NT_ARCH (architecture)");
14259 default:
14260 break;
14261 }
14262
e9e44622 14263 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14264 return buff;
779fe533
NC
14265}
14266
9ece1fa9
TT
14267static int
14268print_core_note (Elf_Internal_Note *pnote)
14269{
14270 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14271 bfd_vma count, page_size;
14272 unsigned char *descdata, *filenames, *descend;
14273
14274 if (pnote->type != NT_FILE)
14275 return 1;
14276
14277#ifndef BFD64
14278 if (!is_32bit_elf)
14279 {
14280 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14281 /* Still "successful". */
14282 return 1;
14283 }
14284#endif
14285
14286 if (pnote->descsz < 2 * addr_size)
14287 {
14288 printf (_(" Malformed note - too short for header\n"));
14289 return 0;
14290 }
14291
14292 descdata = (unsigned char *) pnote->descdata;
14293 descend = descdata + pnote->descsz;
14294
14295 if (descdata[pnote->descsz - 1] != '\0')
14296 {
14297 printf (_(" Malformed note - does not end with \\0\n"));
14298 return 0;
14299 }
14300
14301 count = byte_get (descdata, addr_size);
14302 descdata += addr_size;
14303
14304 page_size = byte_get (descdata, addr_size);
14305 descdata += addr_size;
14306
14307 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14308 {
14309 printf (_(" Malformed note - too short for supplied file count\n"));
14310 return 0;
14311 }
14312
14313 printf (_(" Page size: "));
14314 print_vma (page_size, DEC);
14315 printf ("\n");
14316
14317 printf (_(" %*s%*s%*s\n"),
14318 (int) (2 + 2 * addr_size), _("Start"),
14319 (int) (4 + 2 * addr_size), _("End"),
14320 (int) (4 + 2 * addr_size), _("Page Offset"));
14321 filenames = descdata + count * 3 * addr_size;
14322 while (--count > 0)
14323 {
14324 bfd_vma start, end, file_ofs;
14325
14326 if (filenames == descend)
14327 {
14328 printf (_(" Malformed note - filenames end too early\n"));
14329 return 0;
14330 }
14331
14332 start = byte_get (descdata, addr_size);
14333 descdata += addr_size;
14334 end = byte_get (descdata, addr_size);
14335 descdata += addr_size;
14336 file_ofs = byte_get (descdata, addr_size);
14337 descdata += addr_size;
14338
14339 printf (" ");
14340 print_vma (start, FULL_HEX);
14341 printf (" ");
14342 print_vma (end, FULL_HEX);
14343 printf (" ");
14344 print_vma (file_ofs, FULL_HEX);
14345 printf ("\n %s\n", filenames);
14346
14347 filenames += 1 + strlen ((char *) filenames);
14348 }
14349
14350 return 1;
14351}
14352
1118d252
RM
14353static const char *
14354get_gnu_elf_note_type (unsigned e_type)
14355{
14356 static char buff[64];
14357
14358 switch (e_type)
14359 {
14360 case NT_GNU_ABI_TAG:
14361 return _("NT_GNU_ABI_TAG (ABI version tag)");
14362 case NT_GNU_HWCAP:
14363 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14364 case NT_GNU_BUILD_ID:
14365 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14366 case NT_GNU_GOLD_VERSION:
14367 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14368 default:
14369 break;
14370 }
14371
14372 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14373 return buff;
14374}
14375
664f90a3
TT
14376static int
14377print_gnu_note (Elf_Internal_Note *pnote)
14378{
14379 switch (pnote->type)
14380 {
14381 case NT_GNU_BUILD_ID:
14382 {
14383 unsigned long i;
14384
14385 printf (_(" Build ID: "));
14386 for (i = 0; i < pnote->descsz; ++i)
14387 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14388 printf ("\n");
664f90a3
TT
14389 }
14390 break;
14391
14392 case NT_GNU_ABI_TAG:
14393 {
14394 unsigned long os, major, minor, subminor;
14395 const char *osname;
14396
3102e897
NC
14397 /* PR 17531: file: 030-599401-0.004. */
14398 if (pnote->descsz < 16)
14399 {
14400 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14401 break;
14402 }
14403
664f90a3
TT
14404 os = byte_get ((unsigned char *) pnote->descdata, 4);
14405 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14406 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14407 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14408
14409 switch (os)
14410 {
14411 case GNU_ABI_TAG_LINUX:
14412 osname = "Linux";
14413 break;
14414 case GNU_ABI_TAG_HURD:
14415 osname = "Hurd";
14416 break;
14417 case GNU_ABI_TAG_SOLARIS:
14418 osname = "Solaris";
14419 break;
14420 case GNU_ABI_TAG_FREEBSD:
14421 osname = "FreeBSD";
14422 break;
14423 case GNU_ABI_TAG_NETBSD:
14424 osname = "NetBSD";
14425 break;
14426 default:
14427 osname = "Unknown";
14428 break;
14429 }
14430
14431 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14432 major, minor, subminor);
14433 }
14434 break;
926c5385
CC
14435
14436 case NT_GNU_GOLD_VERSION:
14437 {
14438 unsigned long i;
14439
14440 printf (_(" Version: "));
14441 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14442 printf ("%c", pnote->descdata[i]);
14443 printf ("\n");
14444 }
14445 break;
664f90a3
TT
14446 }
14447
14448 return 1;
14449}
14450
9437c45b 14451static const char *
d3ba0551 14452get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14453{
14454 static char buff[64];
14455
b4db1224 14456 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14457 {
14458 /* NetBSD core "procinfo" structure. */
14459 return _("NetBSD procinfo structure");
14460 }
14461
14462 /* As of Jan 2002 there are no other machine-independent notes
14463 defined for NetBSD core files. If the note type is less
14464 than the start of the machine-dependent note types, we don't
14465 understand it. */
14466
b4db1224 14467 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14468 {
e9e44622 14469 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14470 return buff;
14471 }
14472
14473 switch (elf_header.e_machine)
14474 {
14475 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14476 and PT_GETFPREGS == mach+2. */
14477
14478 case EM_OLD_ALPHA:
14479 case EM_ALPHA:
14480 case EM_SPARC:
14481 case EM_SPARC32PLUS:
14482 case EM_SPARCV9:
14483 switch (e_type)
14484 {
2b692964 14485 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14486 return _("PT_GETREGS (reg structure)");
2b692964 14487 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14488 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14489 default:
14490 break;
14491 }
14492 break;
14493
14494 /* On all other arch's, PT_GETREGS == mach+1 and
14495 PT_GETFPREGS == mach+3. */
14496 default:
14497 switch (e_type)
14498 {
2b692964 14499 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14500 return _("PT_GETREGS (reg structure)");
2b692964 14501 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14502 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14503 default:
14504 break;
14505 }
14506 }
14507
9cf03b7e 14508 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14509 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14510 return buff;
14511}
14512
70616151
TT
14513static const char *
14514get_stapsdt_note_type (unsigned e_type)
14515{
14516 static char buff[64];
14517
14518 switch (e_type)
14519 {
14520 case NT_STAPSDT:
14521 return _("NT_STAPSDT (SystemTap probe descriptors)");
14522
14523 default:
14524 break;
14525 }
14526
14527 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14528 return buff;
14529}
14530
c6a9fc58
TT
14531static int
14532print_stapsdt_note (Elf_Internal_Note *pnote)
14533{
14534 int addr_size = is_32bit_elf ? 4 : 8;
14535 char *data = pnote->descdata;
14536 char *data_end = pnote->descdata + pnote->descsz;
14537 bfd_vma pc, base_addr, semaphore;
14538 char *provider, *probe, *arg_fmt;
14539
14540 pc = byte_get ((unsigned char *) data, addr_size);
14541 data += addr_size;
14542 base_addr = byte_get ((unsigned char *) data, addr_size);
14543 data += addr_size;
14544 semaphore = byte_get ((unsigned char *) data, addr_size);
14545 data += addr_size;
14546
14547 provider = data;
14548 data += strlen (data) + 1;
14549 probe = data;
14550 data += strlen (data) + 1;
14551 arg_fmt = data;
14552 data += strlen (data) + 1;
14553
14554 printf (_(" Provider: %s\n"), provider);
14555 printf (_(" Name: %s\n"), probe);
14556 printf (_(" Location: "));
14557 print_vma (pc, FULL_HEX);
14558 printf (_(", Base: "));
14559 print_vma (base_addr, FULL_HEX);
14560 printf (_(", Semaphore: "));
14561 print_vma (semaphore, FULL_HEX);
9cf03b7e 14562 printf ("\n");
c6a9fc58
TT
14563 printf (_(" Arguments: %s\n"), arg_fmt);
14564
14565 return data == data_end;
14566}
14567
00e98fc7
TG
14568static const char *
14569get_ia64_vms_note_type (unsigned e_type)
14570{
14571 static char buff[64];
14572
14573 switch (e_type)
14574 {
14575 case NT_VMS_MHD:
14576 return _("NT_VMS_MHD (module header)");
14577 case NT_VMS_LNM:
14578 return _("NT_VMS_LNM (language name)");
14579 case NT_VMS_SRC:
14580 return _("NT_VMS_SRC (source files)");
14581 case NT_VMS_TITLE:
9cf03b7e 14582 return "NT_VMS_TITLE";
00e98fc7
TG
14583 case NT_VMS_EIDC:
14584 return _("NT_VMS_EIDC (consistency check)");
14585 case NT_VMS_FPMODE:
14586 return _("NT_VMS_FPMODE (FP mode)");
14587 case NT_VMS_LINKTIME:
9cf03b7e 14588 return "NT_VMS_LINKTIME";
00e98fc7
TG
14589 case NT_VMS_IMGNAM:
14590 return _("NT_VMS_IMGNAM (image name)");
14591 case NT_VMS_IMGID:
14592 return _("NT_VMS_IMGID (image id)");
14593 case NT_VMS_LINKID:
14594 return _("NT_VMS_LINKID (link id)");
14595 case NT_VMS_IMGBID:
14596 return _("NT_VMS_IMGBID (build id)");
14597 case NT_VMS_GSTNAM:
14598 return _("NT_VMS_GSTNAM (sym table name)");
14599 case NT_VMS_ORIG_DYN:
9cf03b7e 14600 return "NT_VMS_ORIG_DYN";
00e98fc7 14601 case NT_VMS_PATCHTIME:
9cf03b7e 14602 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14603 default:
14604 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14605 return buff;
14606 }
14607}
14608
14609static int
14610print_ia64_vms_note (Elf_Internal_Note * pnote)
14611{
14612 switch (pnote->type)
14613 {
14614 case NT_VMS_MHD:
14615 if (pnote->descsz > 36)
14616 {
14617 size_t l = strlen (pnote->descdata + 34);
14618 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14619 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14620 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14621 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14622 }
14623 else
14624 printf (_(" Invalid size\n"));
14625 break;
14626 case NT_VMS_LNM:
14627 printf (_(" Language: %s\n"), pnote->descdata);
14628 break;
14629#ifdef BFD64
14630 case NT_VMS_FPMODE:
9cf03b7e 14631 printf (_(" Floating Point mode: "));
4a5cb34f 14632 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14633 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14634 break;
14635 case NT_VMS_LINKTIME:
14636 printf (_(" Link time: "));
14637 print_vms_time
14638 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14639 printf ("\n");
14640 break;
14641 case NT_VMS_PATCHTIME:
14642 printf (_(" Patch time: "));
14643 print_vms_time
14644 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14645 printf ("\n");
14646 break;
14647 case NT_VMS_ORIG_DYN:
14648 printf (_(" Major id: %u, minor id: %u\n"),
14649 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14650 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14651 printf (_(" Last modified : "));
00e98fc7
TG
14652 print_vms_time
14653 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14654 printf (_("\n Link flags : "));
4a5cb34f 14655 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14656 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14657 printf (_(" Header flags: 0x%08x\n"),
14658 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14659 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14660 break;
14661#endif
14662 case NT_VMS_IMGNAM:
14663 printf (_(" Image name: %s\n"), pnote->descdata);
14664 break;
14665 case NT_VMS_GSTNAM:
14666 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14667 break;
14668 case NT_VMS_IMGID:
14669 printf (_(" Image id: %s\n"), pnote->descdata);
14670 break;
14671 case NT_VMS_LINKID:
14672 printf (_(" Linker id: %s\n"), pnote->descdata);
14673 break;
14674 default:
14675 break;
14676 }
14677 return 1;
14678}
14679
6d118b09
NC
14680/* Note that by the ELF standard, the name field is already null byte
14681 terminated, and namesz includes the terminating null byte.
14682 I.E. the value of namesz for the name "FSF" is 4.
14683
e3c8793a 14684 If the value of namesz is zero, there is no name present. */
779fe533 14685static int
2cf0635d 14686process_note (Elf_Internal_Note * pnote)
779fe533 14687{
2cf0635d
NC
14688 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14689 const char * nt;
9437c45b
JT
14690
14691 if (pnote->namesz == 0)
1ec5cd37
NC
14692 /* If there is no note name, then use the default set of
14693 note type strings. */
14694 nt = get_note_type (pnote->type);
14695
1118d252
RM
14696 else if (const_strneq (pnote->namedata, "GNU"))
14697 /* GNU-specific object file notes. */
14698 nt = get_gnu_elf_note_type (pnote->type);
14699
0112cd26 14700 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14701 /* NetBSD-specific core file notes. */
14702 nt = get_netbsd_elfcore_note_type (pnote->type);
14703
b15fa79e
AM
14704 else if (strneq (pnote->namedata, "SPU/", 4))
14705 {
14706 /* SPU-specific core file notes. */
14707 nt = pnote->namedata + 4;
14708 name = "SPU";
14709 }
14710
00e98fc7
TG
14711 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14712 /* VMS/ia64-specific file notes. */
14713 nt = get_ia64_vms_note_type (pnote->type);
14714
70616151
TT
14715 else if (const_strneq (pnote->namedata, "stapsdt"))
14716 nt = get_stapsdt_note_type (pnote->type);
14717
9437c45b 14718 else
1ec5cd37
NC
14719 /* Don't recognize this note name; just use the default set of
14720 note type strings. */
00e98fc7 14721 nt = get_note_type (pnote->type);
9437c45b 14722
2aee03ae 14723 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
14724
14725 if (const_strneq (pnote->namedata, "IPF/VMS"))
14726 return print_ia64_vms_note (pnote);
664f90a3
TT
14727 else if (const_strneq (pnote->namedata, "GNU"))
14728 return print_gnu_note (pnote);
c6a9fc58
TT
14729 else if (const_strneq (pnote->namedata, "stapsdt"))
14730 return print_stapsdt_note (pnote);
9ece1fa9
TT
14731 else if (const_strneq (pnote->namedata, "CORE"))
14732 return print_core_note (pnote);
00e98fc7
TG
14733 else
14734 return 1;
779fe533
NC
14735}
14736
6d118b09 14737
779fe533 14738static int
2cf0635d 14739process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 14740{
2cf0635d
NC
14741 Elf_External_Note * pnotes;
14742 Elf_External_Note * external;
b34976b6 14743 int res = 1;
103f02d3 14744
779fe533
NC
14745 if (length <= 0)
14746 return 0;
103f02d3 14747
3f5e193b 14748 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 14749 _("notes"));
dd24e3da 14750 if (pnotes == NULL)
a6e9f9df 14751 return 0;
779fe533 14752
103f02d3 14753 external = pnotes;
103f02d3 14754
9dd3a467 14755 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 14756 (unsigned long) offset, (unsigned long) length);
2aee03ae 14757 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 14758
15b42fb0 14759 while ((char *) external < (char *) pnotes + length)
779fe533 14760 {
b34976b6 14761 Elf_Internal_Note inote;
15b42fb0
AM
14762 size_t min_notesz;
14763 char *next;
2cf0635d 14764 char * temp = NULL;
15b42fb0 14765 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 14766
00e98fc7 14767 if (!is_ia64_vms ())
15b42fb0 14768 {
9dd3a467
NC
14769 /* PR binutils/15191
14770 Make sure that there is enough data to read. */
15b42fb0
AM
14771 min_notesz = offsetof (Elf_External_Note, name);
14772 if (data_remaining < min_notesz)
9dd3a467
NC
14773 {
14774 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14775 (int) data_remaining);
14776 break;
14777 }
15b42fb0
AM
14778 inote.type = BYTE_GET (external->type);
14779 inote.namesz = BYTE_GET (external->namesz);
14780 inote.namedata = external->name;
14781 inote.descsz = BYTE_GET (external->descsz);
14782 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
14783 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14784 next = inote.descdata + align_power (inote.descsz, 2);
14785 }
00e98fc7 14786 else
15b42fb0
AM
14787 {
14788 Elf64_External_VMS_Note *vms_external;
00e98fc7 14789
9dd3a467
NC
14790 /* PR binutils/15191
14791 Make sure that there is enough data to read. */
15b42fb0
AM
14792 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14793 if (data_remaining < min_notesz)
9dd3a467
NC
14794 {
14795 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14796 (int) data_remaining);
14797 break;
14798 }
3e55a963 14799
15b42fb0
AM
14800 vms_external = (Elf64_External_VMS_Note *) external;
14801 inote.type = BYTE_GET (vms_external->type);
14802 inote.namesz = BYTE_GET (vms_external->namesz);
14803 inote.namedata = vms_external->name;
14804 inote.descsz = BYTE_GET (vms_external->descsz);
14805 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14806 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14807 next = inote.descdata + align_power (inote.descsz, 3);
14808 }
14809
14810 if (inote.descdata < (char *) external + min_notesz
14811 || next < (char *) external + min_notesz
5d921cbd
NC
14812 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
14813 || inote.namedata + inote.namesz < inote.namedata
14814 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 14815 || data_remaining < (size_t)(next - (char *) external))
3e55a963 14816 {
15b42fb0 14817 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 14818 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 14819 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
14820 inote.type, inote.namesz, inote.descsz);
14821 break;
14822 }
14823
15b42fb0 14824 external = (Elf_External_Note *) next;
dd24e3da 14825
6d118b09
NC
14826 /* Verify that name is null terminated. It appears that at least
14827 one version of Linux (RedHat 6.0) generates corefiles that don't
14828 comply with the ELF spec by failing to include the null byte in
14829 namesz. */
8b971f9f 14830 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 14831 {
3f5e193b 14832 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
14833 if (temp == NULL)
14834 {
8b73c356 14835 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
14836 res = 0;
14837 break;
14838 }
76da6bbe 14839
6d118b09
NC
14840 strncpy (temp, inote.namedata, inote.namesz);
14841 temp[inote.namesz] = 0;
76da6bbe 14842
6d118b09
NC
14843 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
14844 inote.namedata = temp;
14845 }
14846
14847 res &= process_note (& inote);
103f02d3 14848
6d118b09
NC
14849 if (temp != NULL)
14850 {
14851 free (temp);
14852 temp = NULL;
14853 }
779fe533
NC
14854 }
14855
14856 free (pnotes);
103f02d3 14857
779fe533
NC
14858 return res;
14859}
14860
14861static int
2cf0635d 14862process_corefile_note_segments (FILE * file)
779fe533 14863{
2cf0635d 14864 Elf_Internal_Phdr * segment;
b34976b6
AM
14865 unsigned int i;
14866 int res = 1;
103f02d3 14867
d93f0186 14868 if (! get_program_headers (file))
779fe533 14869 return 0;
103f02d3 14870
779fe533
NC
14871 for (i = 0, segment = program_headers;
14872 i < elf_header.e_phnum;
b34976b6 14873 i++, segment++)
779fe533
NC
14874 {
14875 if (segment->p_type == PT_NOTE)
103f02d3 14876 res &= process_corefile_note_segment (file,
30800947
NC
14877 (bfd_vma) segment->p_offset,
14878 (bfd_vma) segment->p_filesz);
779fe533 14879 }
103f02d3 14880
779fe533
NC
14881 return res;
14882}
14883
14884static int
2cf0635d 14885process_note_sections (FILE * file)
1ec5cd37 14886{
2cf0635d 14887 Elf_Internal_Shdr * section;
1ec5cd37 14888 unsigned long i;
df565f32 14889 int n = 0;
1ec5cd37
NC
14890 int res = 1;
14891
14892 for (i = 0, section = section_headers;
fa1908fd 14893 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
14894 i++, section++)
14895 if (section->sh_type == SHT_NOTE)
df565f32
NC
14896 {
14897 res &= process_corefile_note_segment (file,
14898 (bfd_vma) section->sh_offset,
14899 (bfd_vma) section->sh_size);
14900 n++;
14901 }
14902
14903 if (n == 0)
14904 /* Try processing NOTE segments instead. */
14905 return process_corefile_note_segments (file);
1ec5cd37
NC
14906
14907 return res;
14908}
14909
14910static int
2cf0635d 14911process_notes (FILE * file)
779fe533
NC
14912{
14913 /* If we have not been asked to display the notes then do nothing. */
14914 if (! do_notes)
14915 return 1;
103f02d3 14916
779fe533 14917 if (elf_header.e_type != ET_CORE)
1ec5cd37 14918 return process_note_sections (file);
103f02d3 14919
779fe533 14920 /* No program headers means no NOTE segment. */
1ec5cd37
NC
14921 if (elf_header.e_phnum > 0)
14922 return process_corefile_note_segments (file);
779fe533 14923
1ec5cd37
NC
14924 printf (_("No note segments present in the core file.\n"));
14925 return 1;
779fe533
NC
14926}
14927
252b5132 14928static int
2cf0635d 14929process_arch_specific (FILE * file)
252b5132 14930{
a952a375
NC
14931 if (! do_arch)
14932 return 1;
14933
252b5132
RH
14934 switch (elf_header.e_machine)
14935 {
11c1ff18
PB
14936 case EM_ARM:
14937 return process_arm_specific (file);
252b5132 14938 case EM_MIPS:
4fe85591 14939 case EM_MIPS_RS3_LE:
252b5132
RH
14940 return process_mips_specific (file);
14941 break;
35c08157
KLC
14942 case EM_NDS32:
14943 return process_nds32_specific (file);
14944 break;
34c8bcba
JM
14945 case EM_PPC:
14946 return process_power_specific (file);
14947 break;
9e8c70f9
DM
14948 case EM_SPARC:
14949 case EM_SPARC32PLUS:
14950 case EM_SPARCV9:
14951 return process_sparc_specific (file);
14952 break;
59e6276b
JM
14953 case EM_TI_C6000:
14954 return process_tic6x_specific (file);
14955 break;
13761a11
NC
14956 case EM_MSP430:
14957 return process_msp430x_specific (file);
252b5132
RH
14958 default:
14959 break;
14960 }
14961 return 1;
14962}
14963
14964static int
2cf0635d 14965get_file_header (FILE * file)
252b5132 14966{
9ea033b2
NC
14967 /* Read in the identity array. */
14968 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
14969 return 0;
14970
9ea033b2 14971 /* Determine how to read the rest of the header. */
b34976b6 14972 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
14973 {
14974 default: /* fall through */
14975 case ELFDATANONE: /* fall through */
adab8cdc
AO
14976 case ELFDATA2LSB:
14977 byte_get = byte_get_little_endian;
14978 byte_put = byte_put_little_endian;
14979 break;
14980 case ELFDATA2MSB:
14981 byte_get = byte_get_big_endian;
14982 byte_put = byte_put_big_endian;
14983 break;
9ea033b2
NC
14984 }
14985
14986 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 14987 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
14988
14989 /* Read in the rest of the header. */
14990 if (is_32bit_elf)
14991 {
14992 Elf32_External_Ehdr ehdr32;
252b5132 14993
9ea033b2
NC
14994 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
14995 return 0;
103f02d3 14996
9ea033b2
NC
14997 elf_header.e_type = BYTE_GET (ehdr32.e_type);
14998 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
14999 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15000 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15001 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15002 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15003 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15004 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15005 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15006 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15007 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15008 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15009 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15010 }
252b5132 15011 else
9ea033b2
NC
15012 {
15013 Elf64_External_Ehdr ehdr64;
a952a375
NC
15014
15015 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15016 we will not be able to cope with the 64bit data found in
15017 64 ELF files. Detect this now and abort before we start
50c2245b 15018 overwriting things. */
a952a375
NC
15019 if (sizeof (bfd_vma) < 8)
15020 {
e3c8793a
NC
15021 error (_("This instance of readelf has been built without support for a\n\
1502264 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15023 return 0;
15024 }
103f02d3 15025
9ea033b2
NC
15026 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15027 return 0;
103f02d3 15028
9ea033b2
NC
15029 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15030 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15031 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15032 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15033 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15034 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15035 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15036 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15037 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15038 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15039 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15040 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15041 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15042 }
252b5132 15043
7ece0d85
JJ
15044 if (elf_header.e_shoff)
15045 {
15046 /* There may be some extensions in the first section header. Don't
15047 bomb if we can't read it. */
15048 if (is_32bit_elf)
049b0c3a 15049 get_32bit_section_headers (file, TRUE);
7ece0d85 15050 else
049b0c3a 15051 get_64bit_section_headers (file, TRUE);
7ece0d85 15052 }
560f3c1c 15053
252b5132
RH
15054 return 1;
15055}
15056
fb52b2f4
NC
15057/* Process one ELF object file according to the command line options.
15058 This file may actually be stored in an archive. The file is
15059 positioned at the start of the ELF object. */
15060
ff78d6d6 15061static int
2cf0635d 15062process_object (char * file_name, FILE * file)
252b5132 15063{
252b5132
RH
15064 unsigned int i;
15065
252b5132
RH
15066 if (! get_file_header (file))
15067 {
15068 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15069 return 1;
252b5132
RH
15070 }
15071
15072 /* Initialise per file variables. */
60bca95a 15073 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15074 version_info[i] = 0;
15075
60bca95a 15076 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15077 dynamic_info[i] = 0;
5115b233 15078 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15079
15080 /* Process the file. */
15081 if (show_name)
15082 printf (_("\nFile: %s\n"), file_name);
15083
18bd398b
NC
15084 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15085 Note we do this even if cmdline_dump_sects is empty because we
15086 must make sure that the dump_sets array is zeroed out before each
15087 object file is processed. */
15088 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15089 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15090
15091 if (num_cmdline_dump_sects > 0)
15092 {
15093 if (num_dump_sects == 0)
15094 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15095 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15096
15097 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15098 memcpy (dump_sects, cmdline_dump_sects,
15099 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15100 }
d70c5fc7 15101
252b5132 15102 if (! process_file_header ())
fb52b2f4 15103 return 1;
252b5132 15104
d1f5c6e3 15105 if (! process_section_headers (file))
2f62977e 15106 {
d1f5c6e3
L
15107 /* Without loaded section headers we cannot process lots of
15108 things. */
2f62977e 15109 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15110
2f62977e 15111 if (! do_using_dynamic)
2c610e4b 15112 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15113 }
252b5132 15114
d1f5c6e3
L
15115 if (! process_section_groups (file))
15116 {
15117 /* Without loaded section groups we cannot process unwind. */
15118 do_unwind = 0;
15119 }
15120
2f62977e 15121 if (process_program_headers (file))
b2d38a17 15122 process_dynamic_section (file);
252b5132
RH
15123
15124 process_relocs (file);
15125
4d6ed7c8
NC
15126 process_unwind (file);
15127
252b5132
RH
15128 process_symbol_table (file);
15129
15130 process_syminfo (file);
15131
15132 process_version_sections (file);
15133
15134 process_section_contents (file);
f5842774 15135
1ec5cd37 15136 process_notes (file);
103f02d3 15137
047b2264
JJ
15138 process_gnu_liblist (file);
15139
252b5132
RH
15140 process_arch_specific (file);
15141
d93f0186
NC
15142 if (program_headers)
15143 {
15144 free (program_headers);
15145 program_headers = NULL;
15146 }
15147
252b5132
RH
15148 if (section_headers)
15149 {
15150 free (section_headers);
15151 section_headers = NULL;
15152 }
15153
15154 if (string_table)
15155 {
15156 free (string_table);
15157 string_table = NULL;
d40ac9bd 15158 string_table_length = 0;
252b5132
RH
15159 }
15160
15161 if (dynamic_strings)
15162 {
15163 free (dynamic_strings);
15164 dynamic_strings = NULL;
d79b3d50 15165 dynamic_strings_length = 0;
252b5132
RH
15166 }
15167
15168 if (dynamic_symbols)
15169 {
15170 free (dynamic_symbols);
15171 dynamic_symbols = NULL;
19936277 15172 num_dynamic_syms = 0;
252b5132
RH
15173 }
15174
15175 if (dynamic_syminfo)
15176 {
15177 free (dynamic_syminfo);
15178 dynamic_syminfo = NULL;
15179 }
ff78d6d6 15180
293c573e
MR
15181 if (dynamic_section)
15182 {
15183 free (dynamic_section);
15184 dynamic_section = NULL;
15185 }
15186
e4b17d5c
L
15187 if (section_headers_groups)
15188 {
15189 free (section_headers_groups);
15190 section_headers_groups = NULL;
15191 }
15192
15193 if (section_groups)
15194 {
2cf0635d
NC
15195 struct group_list * g;
15196 struct group_list * next;
e4b17d5c
L
15197
15198 for (i = 0; i < group_count; i++)
15199 {
15200 for (g = section_groups [i].root; g != NULL; g = next)
15201 {
15202 next = g->next;
15203 free (g);
15204 }
15205 }
15206
15207 free (section_groups);
15208 section_groups = NULL;
15209 }
15210
19e6b90e 15211 free_debug_memory ();
18bd398b 15212
ff78d6d6 15213 return 0;
252b5132
RH
15214}
15215
2cf0635d
NC
15216/* Process an ELF archive.
15217 On entry the file is positioned just after the ARMAG string. */
15218
15219static int
15220process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15221{
15222 struct archive_info arch;
15223 struct archive_info nested_arch;
15224 size_t got;
2cf0635d
NC
15225 int ret;
15226
15227 show_name = 1;
15228
15229 /* The ARCH structure is used to hold information about this archive. */
15230 arch.file_name = NULL;
15231 arch.file = NULL;
15232 arch.index_array = NULL;
15233 arch.sym_table = NULL;
15234 arch.longnames = NULL;
15235
15236 /* The NESTED_ARCH structure is used as a single-item cache of information
15237 about a nested archive (when members of a thin archive reside within
15238 another regular archive file). */
15239 nested_arch.file_name = NULL;
15240 nested_arch.file = NULL;
15241 nested_arch.index_array = NULL;
15242 nested_arch.sym_table = NULL;
15243 nested_arch.longnames = NULL;
15244
15245 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15246 {
15247 ret = 1;
15248 goto out;
4145f1d5 15249 }
fb52b2f4 15250
4145f1d5
NC
15251 if (do_archive_index)
15252 {
2cf0635d 15253 if (arch.sym_table == NULL)
4145f1d5
NC
15254 error (_("%s: unable to dump the index as none was found\n"), file_name);
15255 else
15256 {
2cf0635d 15257 unsigned int i, l;
4145f1d5
NC
15258 unsigned long current_pos;
15259
15260 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 15261 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
15262 current_pos = ftell (file);
15263
2cf0635d 15264 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15265 {
2cf0635d
NC
15266 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15267 {
15268 char * member_name;
4145f1d5 15269
2cf0635d
NC
15270 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15271
15272 if (member_name != NULL)
15273 {
15274 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15275
15276 if (qualified_name != NULL)
15277 {
c2a7d3f5
NC
15278 printf (_("Contents of binary %s at offset "), qualified_name);
15279 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15280 putchar ('\n');
2cf0635d
NC
15281 free (qualified_name);
15282 }
4145f1d5
NC
15283 }
15284 }
2cf0635d
NC
15285
15286 if (l >= arch.sym_size)
4145f1d5
NC
15287 {
15288 error (_("%s: end of the symbol table reached before the end of the index\n"),
15289 file_name);
cb8f3167 15290 break;
4145f1d5 15291 }
2cf0635d
NC
15292 printf ("\t%s\n", arch.sym_table + l);
15293 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
15294 }
15295
c2a7d3f5
NC
15296 if (arch.uses_64bit_indicies)
15297 l = (l + 7) & ~ 7;
15298 else
15299 l += l & 1;
15300
2cf0635d 15301 if (l < arch.sym_size)
c2a7d3f5
NC
15302 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15303 file_name, arch.sym_size - l);
4145f1d5 15304
4145f1d5
NC
15305 if (fseek (file, current_pos, SEEK_SET) != 0)
15306 {
15307 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15308 ret = 1;
15309 goto out;
4145f1d5 15310 }
fb52b2f4 15311 }
4145f1d5
NC
15312
15313 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15314 && !do_segments && !do_header && !do_dump && !do_version
15315 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15316 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15317 {
15318 ret = 0; /* Archive index only. */
15319 goto out;
15320 }
fb52b2f4
NC
15321 }
15322
d989285c 15323 ret = 0;
fb52b2f4
NC
15324
15325 while (1)
15326 {
2cf0635d
NC
15327 char * name;
15328 size_t namelen;
15329 char * qualified_name;
15330
15331 /* Read the next archive header. */
15332 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15333 {
15334 error (_("%s: failed to seek to next archive header\n"), file_name);
15335 return 1;
15336 }
15337 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15338 if (got != sizeof arch.arhdr)
15339 {
15340 if (got == 0)
15341 break;
15342 error (_("%s: failed to read archive header\n"), file_name);
15343 ret = 1;
15344 break;
15345 }
15346 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15347 {
15348 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15349 ret = 1;
15350 break;
15351 }
15352
15353 arch.next_arhdr_offset += sizeof arch.arhdr;
15354
15355 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15356 if (archive_file_size & 01)
15357 ++archive_file_size;
15358
15359 name = get_archive_member_name (&arch, &nested_arch);
15360 if (name == NULL)
fb52b2f4 15361 {
0fd3a477 15362 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15363 ret = 1;
15364 break;
fb52b2f4 15365 }
2cf0635d 15366 namelen = strlen (name);
fb52b2f4 15367
2cf0635d
NC
15368 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15369 if (qualified_name == NULL)
fb52b2f4 15370 {
2cf0635d 15371 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15372 ret = 1;
15373 break;
fb52b2f4
NC
15374 }
15375
2cf0635d
NC
15376 if (is_thin_archive && arch.nested_member_origin == 0)
15377 {
15378 /* This is a proxy for an external member of a thin archive. */
15379 FILE * member_file;
15380 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15381 if (member_file_name == NULL)
15382 {
15383 ret = 1;
15384 break;
15385 }
15386
15387 member_file = fopen (member_file_name, "rb");
15388 if (member_file == NULL)
15389 {
15390 error (_("Input file '%s' is not readable.\n"), member_file_name);
15391 free (member_file_name);
15392 ret = 1;
15393 break;
15394 }
15395
15396 archive_file_offset = arch.nested_member_origin;
15397
15398 ret |= process_object (qualified_name, member_file);
15399
15400 fclose (member_file);
15401 free (member_file_name);
15402 }
15403 else if (is_thin_archive)
15404 {
a043396b
NC
15405 /* PR 15140: Allow for corrupt thin archives. */
15406 if (nested_arch.file == NULL)
15407 {
15408 error (_("%s: contains corrupt thin archive: %s\n"),
15409 file_name, name);
15410 ret = 1;
15411 break;
15412 }
15413
2cf0635d
NC
15414 /* This is a proxy for a member of a nested archive. */
15415 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15416
15417 /* The nested archive file will have been opened and setup by
15418 get_archive_member_name. */
15419 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15420 {
15421 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15422 ret = 1;
15423 break;
15424 }
15425
15426 ret |= process_object (qualified_name, nested_arch.file);
15427 }
15428 else
15429 {
15430 archive_file_offset = arch.next_arhdr_offset;
15431 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15432
2cf0635d
NC
15433 ret |= process_object (qualified_name, file);
15434 }
fb52b2f4 15435
2b52916e
L
15436 if (dump_sects != NULL)
15437 {
15438 free (dump_sects);
15439 dump_sects = NULL;
15440 num_dump_sects = 0;
15441 }
15442
2cf0635d 15443 free (qualified_name);
fb52b2f4
NC
15444 }
15445
4145f1d5 15446 out:
2cf0635d
NC
15447 if (nested_arch.file != NULL)
15448 fclose (nested_arch.file);
15449 release_archive (&nested_arch);
15450 release_archive (&arch);
fb52b2f4 15451
d989285c 15452 return ret;
fb52b2f4
NC
15453}
15454
15455static int
2cf0635d 15456process_file (char * file_name)
fb52b2f4 15457{
2cf0635d 15458 FILE * file;
fb52b2f4
NC
15459 struct stat statbuf;
15460 char armag[SARMAG];
15461 int ret;
15462
15463 if (stat (file_name, &statbuf) < 0)
15464 {
f24ddbdd
NC
15465 if (errno == ENOENT)
15466 error (_("'%s': No such file\n"), file_name);
15467 else
15468 error (_("Could not locate '%s'. System error message: %s\n"),
15469 file_name, strerror (errno));
15470 return 1;
15471 }
15472
15473 if (! S_ISREG (statbuf.st_mode))
15474 {
15475 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15476 return 1;
15477 }
15478
15479 file = fopen (file_name, "rb");
15480 if (file == NULL)
15481 {
f24ddbdd 15482 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15483 return 1;
15484 }
15485
15486 if (fread (armag, SARMAG, 1, file) != 1)
15487 {
4145f1d5 15488 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15489 fclose (file);
15490 return 1;
15491 }
15492
f54498b4
NC
15493 current_file_size = (bfd_size_type) statbuf.st_size;
15494
fb52b2f4 15495 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15496 ret = process_archive (file_name, file, FALSE);
15497 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15498 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15499 else
15500 {
4145f1d5
NC
15501 if (do_archive_index)
15502 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15503 file_name);
15504
fb52b2f4
NC
15505 rewind (file);
15506 archive_file_size = archive_file_offset = 0;
15507 ret = process_object (file_name, file);
15508 }
15509
15510 fclose (file);
15511
f54498b4 15512 current_file_size = 0;
fb52b2f4
NC
15513 return ret;
15514}
15515
252b5132
RH
15516#ifdef SUPPORT_DISASSEMBLY
15517/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15518 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15519 symbols. */
252b5132
RH
15520
15521void
2cf0635d 15522print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15523{
15524 fprintf (outfile,"0x%8.8x", addr);
15525}
15526
e3c8793a 15527/* Needed by the i386 disassembler. */
252b5132
RH
15528void
15529db_task_printsym (unsigned int addr)
15530{
15531 print_address (addr, stderr);
15532}
15533#endif
15534
15535int
2cf0635d 15536main (int argc, char ** argv)
252b5132 15537{
ff78d6d6
L
15538 int err;
15539
252b5132
RH
15540#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15541 setlocale (LC_MESSAGES, "");
3882b010
L
15542#endif
15543#if defined (HAVE_SETLOCALE)
15544 setlocale (LC_CTYPE, "");
252b5132
RH
15545#endif
15546 bindtextdomain (PACKAGE, LOCALEDIR);
15547 textdomain (PACKAGE);
15548
869b9d07
MM
15549 expandargv (&argc, &argv);
15550
252b5132
RH
15551 parse_args (argc, argv);
15552
18bd398b 15553 if (num_dump_sects > 0)
59f14fc0 15554 {
18bd398b 15555 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15556 cmdline_dump_sects = (dump_type *)
15557 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15558 if (cmdline_dump_sects == NULL)
591a748a 15559 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15560 else
15561 {
09c11c86
NC
15562 memcpy (cmdline_dump_sects, dump_sects,
15563 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15564 num_cmdline_dump_sects = num_dump_sects;
15565 }
15566 }
15567
18bd398b
NC
15568 if (optind < (argc - 1))
15569 show_name = 1;
15570
ff78d6d6 15571 err = 0;
252b5132 15572 while (optind < argc)
18bd398b 15573 err |= process_file (argv[optind++]);
252b5132
RH
15574
15575 if (dump_sects != NULL)
15576 free (dump_sects);
59f14fc0
AS
15577 if (cmdline_dump_sects != NULL)
15578 free (cmdline_dump_sects);
252b5132 15579
ff78d6d6 15580 return err;
252b5132 15581}
This page took 2.12311 seconds and 4 git commands to generate.